Dereference remote replies (#132)

* decided where to put reply dereferencing

* fiddling with dereferencing threads

* further adventures

* tidy up some stuff

* move dereferencing functionality

* a bunch of refactoring

* go fmt

* more refactoring

* bleep bloop

* docs and linting

* start implementing replies collection on gts side

* fiddling around

* allow dereferencing our replies

* lint, fmt
This commit is contained in:
Tobi Smethurst
2021-08-10 13:32:39 +02:00
committed by GitHub
parent 0386a28b5a
commit 0f2de6394a
68 changed files with 2946 additions and 1393 deletions

View File

@@ -147,6 +147,7 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
if strings.EqualFold(requestingHost, f.config.Host) {
// LOCAL ACCOUNT REQUEST
// the request is coming from INSIDE THE HOUSE so skip the remote dereferencing
l.Tracef("proceeding without dereference for local public key %s", requestingPublicKeyID)
if err := f.db.GetWhere([]db.Where{{Key: "public_key_uri", Value: requestingPublicKeyID.String()}}, requestingLocalAccount); err != nil {
return nil, false, fmt.Errorf("couldn't get local account with public key uri %s from the database: %s", requestingPublicKeyID.String(), err)
}
@@ -158,6 +159,7 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
} else if err := f.db.GetWhere([]db.Where{{Key: "public_key_uri", Value: requestingPublicKeyID.String()}}, requestingRemoteAccount); err == nil {
// REMOTE ACCOUNT REQUEST WITH KEY CACHED LOCALLY
// this is a remote account and we already have the public key for it so use that
l.Tracef("proceeding without dereference for cached public key %s", requestingPublicKeyID)
publicKey = requestingRemoteAccount.PublicKey
pkOwnerURI, err = url.Parse(requestingRemoteAccount.URI)
if err != nil {
@@ -167,7 +169,8 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
// REMOTE ACCOUNT REQUEST WITHOUT KEY CACHED LOCALLY
// the request is remote and we don't have the public key yet,
// so we need to authenticate the request properly by dereferencing the remote key
transport, err := f.GetTransportForUser(requestedUsername)
l.Tracef("proceeding with dereference for uncached public key %s", requestingPublicKeyID)
transport, err := f.transportController.NewTransportForUsername(requestedUsername)
if err != nil {
return nil, false, fmt.Errorf("transport err: %s", err)
}
@@ -209,15 +212,28 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
}
pkOwnerURI = pkOwnerProp.GetIRI()
}
// after all that, public key should be defined
if publicKey == nil {
return nil, false, errors.New("returned public key was empty")
}
// do the actual authentication here!
algo := httpsig.RSA_SHA256 // TODO: make this more robust
if err := verifier.Verify(publicKey, algo); err != nil {
return nil, false, nil
algos := []httpsig.Algorithm{
httpsig.RSA_SHA512,
httpsig.RSA_SHA256,
httpsig.ED25519,
}
return pkOwnerURI, true, nil
for _, algo := range algos {
l.Tracef("trying algo: %s", algo)
if err := verifier.Verify(publicKey, algo); err == nil {
l.Tracef("authentication for %s PASSED with algorithm %s", pkOwnerURI, algo)
return pkOwnerURI, true, nil
}
l.Tracef("authentication for %s NOT PASSED with algorithm %s: %s", pkOwnerURI, algo, err)
}
l.Infof("authentication not passed for %s", pkOwnerURI)
return nil, false, nil
}