Skip to content

Commit

Permalink
begin sign-in with ssb
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptix committed Mar 22, 2021
1 parent dde6549 commit 880e560
Show file tree
Hide file tree
Showing 18 changed files with 569 additions and 34 deletions.
1 change: 1 addition & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ func runroomsrv() error {
RoomID: roomsrv.Whoami(),
},
roomsrv.StateManager,
roomsrv.Network,
handlers.Databases{
Aliases: db.Aliases,
AuthFallback: db.AuthFallback,
Expand Down
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.16
require (
github.com/BurntSushi/toml v0.3.1
github.com/PuerkitoBio/goquery v1.5.0
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/dustin/go-humanize v1.0.0
github.com/friendsofgo/errors v0.9.2
github.com/go-kit/kit v0.10.0
github.com/gofrs/uuid v4.0.0+incompatible // indirect
Expand All @@ -15,7 +15,6 @@ require (
github.com/gorilla/sessions v1.2.1
github.com/gorilla/websocket v1.4.2
github.com/keks/nocomment v0.0.0-20181007001506-30c6dcb4a472
github.com/kevinburke/go-bindata v3.21.0+incompatible // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/nicksnyder/go-i18n/v2 v2.1.2
github.com/pkg/errors v0.9.1
Expand All @@ -27,10 +26,10 @@ require (
github.com/volatiletech/sqlboiler-sqlite3 v0.0.0-20210314195744-a1c697a68aef // indirect
github.com/volatiletech/sqlboiler/v4 v4.5.0
github.com/volatiletech/strmangle v0.0.1
go.cryptoscope.co/muxrpc/v2 v2.0.0-20210202162901-fe642d405dc6
go.cryptoscope.co/muxrpc/v2 v2.0.0-beta.1.0.20210308090127-5f1f5f9cbb59
go.cryptoscope.co/netwrap v0.1.1
go.cryptoscope.co/secretstream v1.2.2
go.mindeco.de v1.8.0
go.mindeco.de v1.9.0
go.mindeco.de/ssb-refs v0.1.1-0.20210108133850-cf1f44fea870
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
Expand Down
15 changes: 5 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ github.com/keks/nocomment v0.0.0-20181007001506-30c6dcb4a472 h1:6nrO82kszcc+rcKP
github.com/keks/nocomment v0.0.0-20181007001506-30c6dcb4a472/go.mod h1:oLLUlGld/axGHThR36o8bADQUHG+TKSUdoKqCvnoQB4=
github.com/keks/persist v0.0.0-20180731151133-9546f7b3f97e/go.mod h1:KMIOJFEE+0E/mYfYExA9vOpCFDz4TQfzk6mCOtCXR9k=
github.com/keks/persist v0.0.0-20181029214439-3af502dad70b/go.mod h1:KMIOJFEE+0E/mYfYExA9vOpCFDz4TQfzk6mCOtCXR9k=
github.com/kevinburke/go-bindata v3.21.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -427,18 +426,14 @@ github.com/vcraescu/go-paginator/v2 v2.0.0 h1:m9If0wF7pSjYfocrJZcyWNiWn7OfIeLFVQ
github.com/vcraescu/go-paginator/v2 v2.0.0/go.mod h1:qsrC8+/YgRL0LfurxeY3gCAtsN7oOthkIbmBdqpMX9U=
github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU=
github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA=
github.com/volatiletech/null/v8 v8.1.0 h1:eAO3I31A5R04usY5SKMMfDcOCnEGyT/T4wRI0JVGp4U=
github.com/volatiletech/null/v8 v8.1.0/go.mod h1:98DbwNoKEpRrYtGjWFctievIfm4n4MxG0A6EBUcoS5g=
github.com/volatiletech/null/v8 v8.1.2 h1:kiTiX1PpwvuugKwfvUNX/SU/5A2KGZMXfGD0DUHdKEI=
github.com/volatiletech/null/v8 v8.1.2/go.mod h1:98DbwNoKEpRrYtGjWFctievIfm4n4MxG0A6EBUcoS5g=
github.com/volatiletech/randomize v0.0.1 h1:eE5yajattWqTB2/eN8df4dw+8jwAzBtbdo5sbWC4nMk=
github.com/volatiletech/randomize v0.0.1/go.mod h1:GN3U0QYqfZ9FOJ67bzax1cqZ5q2xuj2mXrXBjWaRTlY=
github.com/volatiletech/sqlboiler-sqlite3 v0.0.0-20200618013359-a93887c09a14 h1:2PCMsnM/GVptZVyB8s0vTIFCPjl6f5rhz5Ry5MNShMQ=
github.com/volatiletech/sqlboiler-sqlite3 v0.0.0-20200618013359-a93887c09a14/go.mod h1:fmZQG/eGdD2vdjWZjrVq4v2sTQ+Alz/I09chjYWWUVw=
github.com/volatiletech/sqlboiler-sqlite3 v0.0.0-20210314195744-a1c697a68aef h1:XjoYLjR/XToxGQY9O6WKA8l6t0hIWjPwazVQcQEctFM=
github.com/volatiletech/sqlboiler-sqlite3 v0.0.0-20210314195744-a1c697a68aef/go.mod h1:fmZQG/eGdD2vdjWZjrVq4v2sTQ+Alz/I09chjYWWUVw=
github.com/volatiletech/sqlboiler/v4 v4.0.0/go.mod h1:U0Z5K4y+twWgHxh364G45QyzyNssSbBqNWtXGHVTlgM=
github.com/volatiletech/sqlboiler/v4 v4.4.0 h1:aSlvHidRBuxHHQZNX3ZLGgzNVPVPzWqsC3lhcLbV/b0=
github.com/volatiletech/sqlboiler/v4 v4.4.0/go.mod h1:h4RBAO6QbwMP3ezGmtfGljRms7S27cFIgF3rKgPKstE=
github.com/volatiletech/sqlboiler/v4 v4.5.0 h1:oJ3YXEvv0c48S9W/3TuPLxJxefIkewpub2qZioXXlUY=
github.com/volatiletech/sqlboiler/v4 v4.5.0/go.mod h1:tQgF5zxwqrjR6Wydc5rRylI6puDOO1WvBC70/5up+Hg=
github.com/volatiletech/strmangle v0.0.1 h1:UKQoHmY6be/R3tSvD2nQYrH41k43OJkidwEiC74KIzk=
Expand All @@ -461,8 +456,8 @@ go.cryptoscope.co/margaret v0.0.5/go.mod h1:W+Q6lvzHIrF8+Yt3dItHHsx2R9/Xvj/NkJGM
go.cryptoscope.co/margaret v0.0.8/go.mod h1:VbP0bqavqW5osTmdNvgukrqtmqvZC5sXyPSBUW5rzv8=
go.cryptoscope.co/margaret v0.0.12-0.20190912103626-34323ad497f4 h1:gLSldWRujtUOfdnpA1XKD71xcCp3Wz1URMnT6xpUPV4=
go.cryptoscope.co/margaret v0.0.12-0.20190912103626-34323ad497f4/go.mod h1:3rt+RmZTFZEgfvFxz0ZPDBIWtLJOouWtzV6YbBl6sek=
go.cryptoscope.co/muxrpc/v2 v2.0.0-20210202162901-fe642d405dc6 h1:p135TwijE3DbmklGygc7++MMRRVlujmjqed8kEOmwLs=
go.cryptoscope.co/muxrpc/v2 v2.0.0-20210202162901-fe642d405dc6/go.mod h1:MgaeojIkWY3lLuoNw1mlMT3b3jiZwOj/fgsoGZp/VNA=
go.cryptoscope.co/muxrpc/v2 v2.0.0-beta.1.0.20210308090127-5f1f5f9cbb59 h1:Gv5pKkvHYJNc12uRZ/jMCsR17G7v6oFLLCrGAUVxhvo=
go.cryptoscope.co/muxrpc/v2 v2.0.0-beta.1.0.20210308090127-5f1f5f9cbb59/go.mod h1:MgaeojIkWY3lLuoNw1mlMT3b3jiZwOj/fgsoGZp/VNA=
go.cryptoscope.co/netwrap v0.1.0/go.mod h1:7zcYswCa4CT+ct54e9uH9+IIbYYETEMHKDNpzl8Ukew=
go.cryptoscope.co/netwrap v0.1.1 h1:JLzzGKEvrUrkKzu3iM0DhpHmt+L/gYqmpcf1lJMUyFs=
go.cryptoscope.co/netwrap v0.1.1/go.mod h1:7zcYswCa4CT+ct54e9uH9+IIbYYETEMHKDNpzl8Ukew=
Expand All @@ -471,8 +466,8 @@ go.cryptoscope.co/secretstream v1.2.2/go.mod h1:7nRGZ7fTqSgQAnv2Y4m8xQsS3MFxvB7I
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mindeco.de v1.8.0 h1:Vxob3XaDz85aD4wq8VbQxtradpHbmjciG2eSJLGaFV0=
go.mindeco.de v1.8.0/go.mod h1:ePOcyktbpqzhMPRBDv2gUaDd3h8QtT+DUU1DK+VbQZE=
go.mindeco.de v1.9.0 h1:/xli02DkzpIUZxp/rp1nj8z/OZ9MHvkMIr9TfDVcmBg=
go.mindeco.de v1.9.0/go.mod h1:ePOcyktbpqzhMPRBDv2gUaDd3h8QtT+DUU1DK+VbQZE=
go.mindeco.de/ssb-refs v0.1.1-0.20210108133850-cf1f44fea870 h1:TCI3AefMAaOYECvppn30+CfEB0Fn8IES1SKvvacc3/c=
go.mindeco.de/ssb-refs v0.1.1-0.20210108133850-cf1f44fea870/go.mod h1:OnBnV02ux4lLsZ39LID6yYLqSDp+dqTHb/3miYPkQFs=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
Expand Down
8 changes: 7 additions & 1 deletion internal/network/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ type EndpointStat struct {
Endpoint muxrpc.Endpoint
}

//go:generate counterfeiter -o mocked/endpoints.go . Endpoints

type Endpoints interface {
GetEndpointFor(refs.FeedRef) (muxrpc.Endpoint, bool)
}

type Network interface {
Connect(ctx context.Context, addr net.Addr) error
Serve(context.Context, ...muxrpc.HandlerWrapper) error
GetListenAddr() net.Addr

GetAllEndpoints() []EndpointStat
GetEndpointFor(refs.FeedRef) (muxrpc.Endpoint, bool)
Endpoints

GetConnTracker() ConnTracker

Expand Down
118 changes: 118 additions & 0 deletions internal/network/mocked/endpoints.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions internal/signinwithssb/challenges.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package signinwithssb

import (
"bytes"
"crypto/rand"
"encoding/base64"
"fmt"

"golang.org/x/crypto/ed25519"

refs "go.mindeco.de/ssb-refs"
)

// sign-in with ssb uses 256-bit nonces
const challengeLength = 32

func DecodeChallengeString(c string) ([]byte, error) {
challangeBytes, err := base64.URLEncoding.DecodeString(c)
if err != nil {
return nil, fmt.Errorf("invalid challenge encoding: %w", err)
}

if n := len(challangeBytes); n != challengeLength {
return nil, fmt.Errorf("invalid challenge length: expected %d but got %d", challengeLength, n)
}

return challangeBytes, nil
}

func GenerateChallenge() string {
buf := make([]byte, challengeLength)
rand.Read(buf)
return base64.URLEncoding.EncodeToString(buf)
}

// this structure is used to verify an incoming client response
type ClientRequest struct {
ClientID, ServerID refs.FeedRef

ClientChallange string
ServerChallange string
}

// recreate the signed message
func (cr ClientRequest) createMessage() []byte {
var msg bytes.Buffer
msg.WriteString("=http-auth-sign-in:")
msg.WriteString(cr.ServerID.Ref())
msg.WriteString(":")
msg.WriteString(cr.ClientID.Ref())
msg.WriteString(":")
msg.WriteString(cr.ServerChallange)
msg.WriteString(":")
msg.WriteString(cr.ClientChallange)
return msg.Bytes()
}

func (cr ClientRequest) Sign(privateKey ed25519.PrivateKey) []byte {
msg := cr.createMessage()
return ed25519.Sign(privateKey, msg)
}

func (cr ClientRequest) Validate(signature []byte) bool {
msg := cr.createMessage()
return ed25519.Verify(cr.ClientID.PubKey(), msg, signature)
}
29 changes: 29 additions & 0 deletions internal/signinwithssb/simple_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package signinwithssb

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
refs "go.mindeco.de/ssb-refs"
)

func TestClientRequestString(t *testing.T) {

server := refs.FeedRef{ID: bytes.Repeat([]byte{1}, 32), Algo: "test"}

client := refs.FeedRef{ID: bytes.Repeat([]byte{2}, 32), Algo: "test"}

var req ClientRequest

req.ServerID = server
req.ClientID = client

req.ServerChallange = "fooo"
req.ClientChallange = "barr"

want := "=http-auth-sign-in:@AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=.test:@AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=.test:fooo:barr"

got := req.createMessage()
assert.Equal(t, want, string(got))
}
8 changes: 8 additions & 0 deletions web/errors/badrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,11 @@ type ErrBadRequest struct {
func (br ErrBadRequest) Error() string {
return fmt.Sprintf("rooms/web: bad request error: %s", br.Details)
}

type ErrForbidden struct {
Details error
}

func (f ErrForbidden) Error() string {
return fmt.Sprintf("rooms/web: access denied: %s", f.Details)
}
28 changes: 25 additions & 3 deletions web/handlers/auth/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,49 @@ import (
"go.mindeco.de/http/auth"
"go.mindeco.de/http/render"

"github.com/ssb-ngi-pointer/go-ssb-room/internal/network"
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
refs "go.mindeco.de/ssb-refs"
)

var HTMLTemplates = []string{
"auth/fallback_sign_in.tmpl",
"auth/withssb_sign_in.tmpl",
}

func Handler(m *mux.Router, r *render.Renderer, a *auth.Handler) http.Handler {
func Handler(
m *mux.Router,
r *render.Renderer,
ah *auth.Handler,
roomID refs.FeedRef,
endpoints network.Endpoints,
aliasDB roomdb.AliasesService,
membersDB roomdb.MembersService,
) http.Handler {
if m == nil {
m = router.Auth(nil)
}

// just the form
m.Get(router.AuthFallbackSignInForm).Handler(r.HTML("auth/fallback_sign_in.tmpl", func(w http.ResponseWriter, req *http.Request) (interface{}, error) {
return map[string]interface{}{
csrf.TemplateTag: csrf.TemplateField(req),
}, nil
}))

// hook up the auth handler to the router
m.Get(router.AuthFallbackSignIn).HandlerFunc(a.Authorize)
m.Get(router.AuthFallbackSignOut).HandlerFunc(a.Logout)
m.Get(router.AuthFallbackSignIn).HandlerFunc(ah.Authorize)

m.Get(router.AuthSignOut).HandlerFunc(ah.Logout)

var ssb withssbHandler
ssb.roomID = roomID
ssb.aliases = aliasDB
ssb.members = membersDB
ssb.endpoints = endpoints
ssb.cookieAuth = ah
m.Get(router.AuthWithSSBSignIn).HandlerFunc(r.HTML("auth/withssb_sign_in.tmpl", ssb.login))

return m
}
Loading

0 comments on commit 880e560

Please sign in to comment.