63 lines
2.0 KiB
Go
63 lines
2.0 KiB
Go
package connection
|
|
|
|
import (
|
|
"crypto/rsa"
|
|
"errors"
|
|
"github.com/s-rah/go-ricochet/channels"
|
|
"github.com/s-rah/go-ricochet/policies"
|
|
"log"
|
|
)
|
|
|
|
// OutboundConnectionHandler is a convieniance wrapper for handling outbound
|
|
// connections
|
|
type OutboundConnectionHandler struct {
|
|
connection *Connection
|
|
}
|
|
|
|
// HandleOutboundConnection returns an OutboundConnectionHandler given a connection
|
|
func HandleOutboundConnection(c *Connection) *OutboundConnectionHandler {
|
|
och := new(OutboundConnectionHandler)
|
|
och.connection = c
|
|
return och
|
|
}
|
|
|
|
// ProcessAuthAsClient blocks until authentication has succeeded or failed with the
|
|
// provided privateKey, or the connection is closed. A non-nil error is returned in all
|
|
// cases other than successful authentication.
|
|
//
|
|
// ProcessAuthAsClient cannot be called at the same time as any other call to a Porcess
|
|
// function. Another Process function must be called after this function successfully
|
|
// returns to continue handling connection events.
|
|
//
|
|
// For successful authentication, the `known` return value indicates whether the peer
|
|
// accepts us as a known contact. Unknown contacts will generally need to send a contact
|
|
// request before any other activity.
|
|
func (och *OutboundConnectionHandler) ProcessAuthAsClient(privateKey *rsa.PrivateKey) (bool, error) {
|
|
ach := new(AutoConnectionHandler)
|
|
ach.Init(privateKey, och.connection.RemoteHostname)
|
|
|
|
var result channels.AuthChannelResult
|
|
go func() {
|
|
err := och.connection.RequestOpenChannel("im.ricochet.auth.hidden-service", ach)
|
|
if err != nil {
|
|
return
|
|
}
|
|
log.Printf("waiting for auth result")
|
|
result = ach.WaitForAuthenticationEvent()
|
|
log.Printf("received auth result")
|
|
och.connection.Break()
|
|
}()
|
|
|
|
policy := policies.UnknownPurposeTimeout
|
|
err := policy.ExecuteAction(func() error {
|
|
return och.connection.Process(ach)
|
|
})
|
|
|
|
if err == nil {
|
|
if result.Accepted == true {
|
|
return result.IsKnownContact, nil
|
|
}
|
|
}
|
|
return false, errors.New("authentication was not accepted by the server")
|
|
}
|