dendrite/clientapi/routing/voip.go

76 lines
1.9 KiB
Go

// Copyright 2024 New Vector Ltd.
// Copyright 2017 Michael Telatysnki <7t3chguy@gmail.com>
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
package routing
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"net/http"
"time"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/util"
"github.com/element-hq/dendrite/setup/config"
"github.com/element-hq/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib/spec"
)
// RequestTurnServer implements:
//
// GET /voip/turnServer
func RequestTurnServer(req *http.Request, device *api.Device, cfg *config.ClientAPI) util.JSONResponse {
turnConfig := cfg.TURN
// TODO Guest Support
if len(turnConfig.URIs) == 0 || turnConfig.UserLifetime == "" {
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
// Duration checked at startup, err not possible
duration, _ := time.ParseDuration(turnConfig.UserLifetime)
resp := gomatrix.RespTurnServer{
URIs: turnConfig.URIs,
TTL: int(duration.Seconds()),
}
if turnConfig.SharedSecret != "" {
expiry := time.Now().Add(duration).Unix()
resp.Username = fmt.Sprintf("%d:%s", expiry, device.UserID)
mac := hmac.New(sha1.New, []byte(turnConfig.SharedSecret))
_, err := mac.Write([]byte(resp.Username))
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("mac.Write failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
resp.Password = base64.StdEncoding.EncodeToString(mac.Sum(nil))
} else if turnConfig.Username != "" && turnConfig.Password != "" {
resp.Username = turnConfig.Username
resp.Password = turnConfig.Password
} else {
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: resp,
}
}