Skip to content
This repository has been archived by the owner on May 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #254 from findy-network/grpcenclave-client-args
Browse files Browse the repository at this point in the history
gRPC-enclave args & translator full multi-tenancy
  • Loading branch information
lainio authored Apr 16, 2024
2 parents 4b6e36e + db2d75c commit b18353c
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 55 deletions.
10 changes: 6 additions & 4 deletions acator/authn/authncmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,13 @@ type execCmd struct {

func newExecCmd(cmd *Cmd) (ec *execCmd) {
assert.NotEmpty(cmd.Origin)
assert.NotEmpty(cmd.AAGUID)

ec = new(execCmd)
ec.Cmd = *cmd
ec.Instance = &acator.Instance{
Counter: 0,
AAGUID: uuid.Must(uuid.Parse("12c85a48-4baf-47bd-b51f-f192871a1511")),
AAGUID: uuid.Must(uuid.Parse(cmd.AAGUID)),
Origin: try.To1(url.Parse(cmd.Origin)),
}
ec.Client = setupClient()
Expand Down Expand Up @@ -430,7 +432,7 @@ func (ec *execCmd) tryHTTPRequest(method, addr string, msg io.Reader) (reader io

func (ec *execCmd) addToCookieJar(URL *url.URL, cookies []*http.Cookie) {
for _, c := range cookies {
glog.V(1).Infoln("--- adding cookie:", c.String())
glog.V(3).Infoln("--- adding cookie:", c.String())
}
jarCookies := ec.Jar.Cookies(URL)
cookies = append(cookies, jarCookies...)
Expand Down Expand Up @@ -489,12 +491,12 @@ func (ec *execCmd) checkCookiePath() {
} else if ec.CookiePath != "" { // just load page
// assert.NotEmpty(cookieFile)
// make the http request to load the page AND cookies
glog.V(1).Infof("cookie path: '%s'", ec.CookiePath)
glog.V(3).Infof("cookie path: '%s'", ec.CookiePath)
if ec.CookiePath == "-" {
ec.CookiePath = ""
}
cookiePageURL := ec.URL + ec.CookiePath
glog.V(1).Infoln("loading cookie page:", cookiePageURL)
glog.V(3).Infoln("loading cookie page:", cookiePageURL)
r := ec.tryHTTPRequest("GET", cookiePageURL, &bytes.Buffer{})
// we don't know how the server behaves, we don't want it to abort
_ = try.To1(io.ReadAll(r))
Expand Down
7 changes: 5 additions & 2 deletions acator/grpcenclave/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ var (
cmd = flag.String("cmd", "login", "FIDO2 cmd: login/register")
user = flag.String("user", "elli", "test user name")
serverAddr = flag.String("addr", "localhost", "agency host gRPC address")
url = flag.String("url", "http://localhost:8090", "FIDO2 server URL")
origin = flag.String("origin", "", "FIDO2 server needs origin if not in HTTPS")
hexKey = flag.String("key",
"289239187d7c395044976416280b6a283bf65562a06b0bdc3a75a4db4adfe7c7",
"soft cipher master key in HEX")
Expand Down Expand Up @@ -60,15 +62,16 @@ func main() {
conn = try.To1(rpcclient.New(*cert, *serverAddr, *port))
defer conn.Close()

glog.V(3).Infoln("Origin:", *origin)
statusCh := try.To1(rpcclient.DoEnter(conn, ctx, &pb.Cmd{
Type: pb.Cmd_Type(pb.Cmd_Type_value[strings.ToUpper(*cmd)]),
UserName: *user,
PublicDIDSeed: "",
URL: "http://localhost:8090",
URL: *url,
AAGUID: "12c85a48-4baf-47bd-b51f-f192871a1511",
Counter: 0,
JWT: "",
Origin: "",
Origin: *origin,
}))

secEnc := enclave.New(*hexKey)
Expand Down
28 changes: 19 additions & 9 deletions acator/grpcenclave/rpcclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ func New(cert, addr string, port int) (conn *grpc.ClientConn, err error) {
return rpc.ClientConn(*cfg)
}

// ChCloser return error handler that closes all given channels.
func ChCloser[C ~chan T, T any](chs ...C) err2.Handler {
return func(err error) error {
for _, c := range chs {
close(c)
}
return err
}
}

func DoEnter(
conn *grpc.ClientConn,
ctx context.Context, //nolint: revive
Expand All @@ -35,25 +45,24 @@ func DoEnter(
) {
defer err2.Handle(&err)

c := authn.NewAuthnServiceClient(conn)
authnClient := authn.NewAuthnServiceClient(conn)
statusCh := make(chan *authn.CmdStatus)

stream := try.To1(c.Enter(ctx, cmd))
stream := try.To1(authnClient.Enter(ctx, cmd))
glog.V(3).Infoln("successful start of:", cmd.GetType())
go func() {
defer err2.Catch(err2.Err(func(err error) {
glog.V(3).Infoln("err when reading response", err)
close(statusCh)
}))
defer err2.Catch(ChCloser(statusCh), err2.Log)

for {
status, err := stream.Recv()
if try.IsEOF(err) {
glog.V(3).Infoln("status stream end")
close(statusCh)
break
}
glog.V(4).Infoln("--> cmd status:",
glog.V(4).Infof("--> cmd ID:%v, status: %v, (secType: %v)",
status.GetCmdID(),
status.GetType(),
status.GetSecType(),
)
statusCh <- status
Expand All @@ -71,12 +80,13 @@ func DoEnterSecret(
) {
defer err2.Handle(&err)

c := authn.NewAuthnServiceClient(conn)
authnClient := authn.NewAuthnServiceClient(conn)

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

glog.V(3).Infoln("going to send SecretMsg:", smsg.Type)
res = try.To1(c.EnterSecret(ctx, smsg))
res = try.To1(authnClient.EnterSecret(ctx, smsg))

glog.V(3).Infoln("successful sent of SecretMsg:", smsg.Type)
return res, nil
Expand Down
115 changes: 77 additions & 38 deletions acator/grpcenclave/rpcserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package rpcserver
import (
"context"
"fmt"
"math"
"strings"
"sync/atomic"
"sync"

"github.com/findy-network/findy-agent-auth/acator/authn"
"github.com/findy-network/findy-agent-auth/acator/grpcenclave"
Expand All @@ -19,8 +20,9 @@ import (
)

func RegisterAuthnServer(s *grpc.Server) error {
pb.RegisterAuthnServiceServer(s, &authnServer{})
glog.V(1).Infoln("GRPC registration for authnServer")
authnServ := &authnServer{}
pb.RegisterAuthnServiceServer(s, authnServ)
glog.V(0).Infoln("GRPC registration for authnServer")
return nil
}

Expand All @@ -35,11 +37,13 @@ func Serve(port int) {

type authnServer struct {
pb.UnimplementedAuthnServiceServer
atomic.Int64

root string

authnCmd *authn.Cmd
id uint8
mu sync.Mutex

authnCmd [math.MaxUint8 + 1]*authn.Cmd
}

func (a *authnServer) AuthFuncOverride(
Expand Down Expand Up @@ -73,43 +77,58 @@ func (a *authnServer) Enter(
// NOTE. Authentication is done by mutual TLS or must be done for this
// service!

glog.V(3).Infoln("=== authn Enter cmd:", cmd.Type)
cmdID := a.Add(1)

a.authnCmd = &authn.Cmd{
SubCmd: strings.ToLower(cmd.GetType().String()),
UserName: cmd.GetUserName(),
PublicDIDSeed: cmd.GetPublicDIDSeed(),
URL: cmd.GetURL(),
AAGUID: cmd.GetAAGUID(),
Counter: cmd.GetCounter(),
Token: cmd.GetJWT(),
}
secEnc := &grpcenclave.Enclave{
Cmd: cmd,
CmdID: cmdID,
OutChan: make(chan *pb.CmdStatus),
InChan: make(chan *pb.SecretMsg),
}
a.authnCmd.SecEnclave = secEnc
var (
secEnc *grpcenclave.Enclave
cmdID uint8
)
a.tx(func() {
cmdID = a.id
a.id++
glog.V(3).Infof("=== authn Enter cmd:%v, cmdID: %v", cmd.Type, cmdID)

secEnc = &grpcenclave.Enclave{
Cmd: cmd,
CmdID: int64(cmdID),
OutChan: make(chan *pb.CmdStatus),
InChan: make(chan *pb.SecretMsg),
}
a.authnCmd[cmdID] = &authn.Cmd{
SubCmd: strings.ToLower(cmd.GetType().String()),
UserName: cmd.GetUserName(),
PublicDIDSeed: cmd.GetPublicDIDSeed(),
URL: cmd.GetURL(),
AAGUID: cmd.GetAAGUID(),
Counter: cmd.GetCounter(),
Token: cmd.GetJWT(),
Origin: cmd.GetOrigin(),
SecEnclave: secEnc,
}
})

go func() {
defer err2.Catch(err2.Err(func(err error) {
errStr := fmt.Sprintf("error: grpc server main: %v", err)
glog.Error(errStr)
status := &pb.CmdStatus{
CmdID: cmdID,
CmdID: int64(cmdID),
Info: &pb.CmdStatus_Err{Err: errStr},
Type: pb.CmdStatus_READY_ERR,
}
if err := server.Send(status); err != nil {
glog.Error("error sending response")
}
close(secEnc.OutChan)
try.Out(server.Send(status)).Logf("error sending response")
// NOTE: we don't close channel here, context handles them
}))
r := try.To1(a.authnCmd.Exec(nil))

var (
r authn.Result
aCmd *authn.Cmd
)
a.tx(func() {
aCmd = a.authnCmd[cmdID]
})
r = try.To1(aCmd.Exec(nil))

secEnc.OutChan <- &pb.CmdStatus{
CmdID: cmdID,
CmdID: int64(cmdID),
Type: pb.CmdStatus_READY_OK,
CmdType: cmd.GetType(),
Info: &pb.CmdStatus_Ok{
Expand All @@ -118,14 +137,25 @@ func (a *authnServer) Enter(
},
},
}
close(secEnc.OutChan)
//close(secEnc.OutChan)
}()

for status := range secEnc.OutChan {
glog.V(1).Infoln("<== status:", status.CmdType, status.CmdID)
try.To(server.Send(status))
loop:
for {
select {
case <-server.Context().Done():
break loop

case status, ok := <-secEnc.OutChan:
if !ok || status.GetType() == pb.CmdStatus_READY_OK {
glog.V(1).Infoln("channel closed")
break loop
}
glog.V(3).Infoln("<== status:", status.CmdType, status.CmdID)
try.To(server.Send(status))
continue loop
}
}
glog.V(1).Infoln("end Enter\n===============\n\n")
return nil
}

Expand All @@ -144,8 +174,11 @@ func (a *authnServer) EnterSecret(
return err
})

glog.V(1).Infoln("secret:", smsg.GetType(), smsg.GetCmdID())
secEnc, ok := a.authnCmd.SecEnclave.(*grpcenclave.Enclave)
assert.NotNil(smsg)
assert.NotEqual(smsg.GetCmdID(), math.MaxUint8+1)

glog.V(3).Infof("secret type: %v, ID: %v", smsg.GetType(), smsg.GetCmdID())
secEnc, ok := a.authnCmd[smsg.GetCmdID()].SecEnclave.(*grpcenclave.Enclave)
assert.That(ok)
assert.NotNil(secEnc)
assert.CNotNil(secEnc.InChan)
Expand All @@ -154,3 +187,9 @@ func (a *authnServer) EnterSecret(

return
}

func (a *authnServer) tx(fn func()) {
a.mu.Lock()
defer a.mu.Unlock()
fn()
}
3 changes: 1 addition & 2 deletions acator/grpcenclave/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import (
)

var (
// TODO: for Dart we start playing without tls or other security
// TODO: we need to build gzip packging to these golang stacks
// TODO: bring next line when we need to test with certs the server.
//cert = flag.String("cert", "../../../scripts/test-cert/", "TLS cert path")
port = flag.Int("port", 50053, "agency host gRPC port")
)
Expand Down

0 comments on commit b18353c

Please sign in to comment.