Skip to content

Commit

Permalink
Authenticate WebRTC channel
Browse files Browse the repository at this point in the history
  • Loading branch information
muzzammilshahid committed Dec 11, 2024
1 parent db84752 commit 7692d4a
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 7 deletions.
8 changes: 8 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/google/uuid"
"github.com/pion/webrtc/v4"

"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/xconn-go"
)

Expand All @@ -16,6 +17,7 @@ type ClientConfig struct {
ProcedureWebRTCOffer string
TopicAnswererOnCandidate string
Serializer xconn.WSSerializerSpec
Authenticator auth.ClientAuthenticator
}

func ConnectWebRTC(config *ClientConfig) (*WebRTCSession, error) {
Expand Down Expand Up @@ -60,6 +62,12 @@ func ConnectWebRTC(config *ClientConfig) (*WebRTCSession, error) {

channel := <-offerer.WaitReady()

peer := NewWebRTCPeer(channel)
_, err = xconn.Join(peer, config.Realm, config.Serializer.Serializer(), config.Authenticator)
if err != nil {
return nil, err
}

return &WebRTCSession{
Channel: channel,
Connection: offerer.connection,
Expand Down
4 changes: 3 additions & 1 deletion cmd/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
log "github.com/sirupsen/logrus"

"github.com/xconnio/wamp-webrtc-go"
"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/xconn-go"
)

Expand All @@ -19,8 +20,9 @@ func main() {
ProcedureWebRTCOffer: procedureWebRTCOffer,
TopicAnswererOnCandidate: topicAnswererOnCandidate,
Serializer: xconn.CBORSerializerSpec,
Authenticator: auth.NewCRAAuthenticator("john", map[string]any{}, "hello"),
}
session, err := wamp_webrtc_go.ConnectWAMP(config)
session, err := wamp_webrtc_go.ConnectWebRTC(config)
if err != nil {
log.Fatal(err)
}
Expand Down
63 changes: 63 additions & 0 deletions cmd/provider/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package main

import (
"context"
"fmt"
"os"
"os/signal"

log "github.com/sirupsen/logrus"

"github.com/xconnio/wamp-webrtc-go"
"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/wampproto-go/serializers"
"github.com/xconnio/xconn-go"
)
Expand All @@ -16,8 +18,68 @@ const (
procedureWebRTCOffer = "io.xconn.webrtc.offer"
topicOffererOnCandidate = "io.xconn.webrtc.offerer.on_candidate"
topicAnswererOnCandidate = "io.xconn.webrtc.answerer.on_candidate"

testRealm = "realm1"
testSecret = "hello"
testTicket = "hello"
testPublicKey = "f0e3cff77bd851015a99d873e302803d83e693cde41ffe545b26124713bdb08b"
)

type Authenticator struct{}

func NewAuthenticator() *Authenticator {
return &Authenticator{}
}

func (a *Authenticator) Methods() []auth.Method {
return []auth.Method{auth.MethodAnonymous, auth.MethodTicket, auth.MethodCRA, auth.MethodCryptoSign}
}

func (a *Authenticator) Authenticate(request auth.Request) (auth.Response, error) {
switch request.AuthMethod() {
case auth.MethodAnonymous:
if request.Realm() == testRealm {
return auth.NewResponse(request.AuthID(), request.AuthRole(), 0)
}

return nil, fmt.Errorf("invalid realm")

case auth.MethodTicket:
ticketRequest, ok := request.(*auth.TicketRequest)
if !ok {
return nil, fmt.Errorf("invalid request")
}

if ticketRequest.Realm() == testRealm && ticketRequest.Ticket() == testTicket {
return auth.NewResponse(ticketRequest.AuthID(), ticketRequest.AuthRole(), 0)
}

return nil, fmt.Errorf("invalid ticket")

case auth.MethodCRA:
if request.Realm() == testRealm {
return auth.NewCRAResponse(request.AuthID(), request.AuthRole(), testSecret, 0), nil
}

return nil, fmt.Errorf("invalid realm")

case auth.MethodCryptoSign:
cryptosignRequest, ok := request.(*auth.RequestCryptoSign)
if !ok {
return nil, fmt.Errorf("invalid request")
}

if cryptosignRequest.Realm() == testRealm && cryptosignRequest.PublicKey() == testPublicKey {
return auth.NewResponse(cryptosignRequest.AuthID(), cryptosignRequest.AuthRole(), 0)
}

return nil, fmt.Errorf("unknown publickey")

default:
return nil, fmt.Errorf("unknown authentication method: %v", request.AuthMethod())
}
}

func main() {
session, err := xconn.Connect(context.Background(), "ws://localhost:8080/ws", "realm1")
if err != nil {
Expand All @@ -31,6 +93,7 @@ func main() {
TopicHandleRemoteCandidates: topicOffererOnCandidate,
TopicPublishLocalCandidate: topicAnswererOnCandidate,
Serializer: &serializers.CBORSerializer{},
Authenticator: NewAuthenticator(),
}
webRtcManager.Setup(cfg)

Expand Down
15 changes: 9 additions & 6 deletions provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
log "github.com/sirupsen/logrus"

"github.com/xconnio/wampproto-go"
"github.com/xconnio/wampproto-go/serializers"
"github.com/xconnio/wampproto-go/util"
"github.com/xconnio/xconn-go"
)
Expand Down Expand Up @@ -94,7 +93,7 @@ func (r *WebRTCProvider) Setup(config *ProviderConfig) {
go func() {
select {
case channel := <-answerer.WaitReady():
r.handleWAMPClient(channel, router, config.Serializer)
r.handleWAMPClient(channel, router, config)
case <-time.After(20 * time.Second):
log.Errorln("webrtc connection didn't establish after 20 seconds")
}
Expand All @@ -103,21 +102,25 @@ func (r *WebRTCProvider) Setup(config *ProviderConfig) {
}

func (r *WebRTCProvider) handleWAMPClient(channel *webrtc.DataChannel, xconnRouter *xconn.Router,
serializer serializers.Serializer) {
config *ProviderConfig) {
rtcPeer := NewWebRTCPeer(channel)

hello, err := xconn.ReadHello(rtcPeer, serializer)
hello, err := xconn.ReadHello(rtcPeer, config.Serializer)
if err != nil {
log.Errorf("failed to read hello: %v", err)
return
}

base, err := xconn.Accept(rtcPeer, hello, serializer, nil)
base, err := xconn.Accept(rtcPeer, hello, config.Serializer, config.Authenticator)
if err != nil {
log.Errorln(err)
return
}

if !config.Routed {
return
}

if err = xconnRouter.AttachClient(base); err != nil {
log.Errorf("failed to attach client %v", err)
return
Expand Down Expand Up @@ -151,7 +154,7 @@ func (r *WebRTCProvider) handleWAMPClient(channel *webrtc.DataChannel, xconnRout
return
}

data, err := serializer.Serialize(msg)
data, err := config.Serializer.Serialize(msg)
if err != nil {
log.Printf("failed to serialize message: %v", err)
return
Expand Down
3 changes: 3 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package wamp_webrtc_go
import (
"github.com/pion/webrtc/v4"

"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/wampproto-go/serializers"
"github.com/xconnio/xconn-go"
)
Expand Down Expand Up @@ -32,6 +33,8 @@ type ProviderConfig struct {
TopicHandleRemoteCandidates string
TopicPublishLocalCandidate string
Serializer serializers.Serializer
Routed bool
Authenticator auth.ServerAuthenticator
}

type WebRTCSession struct {
Expand Down

0 comments on commit 7692d4a

Please sign in to comment.