2017-05-02 23:33:51 +00:00
|
|
|
package connection
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rsa"
|
|
|
|
"github.com/s-rah/go-ricochet/channels"
|
|
|
|
"github.com/s-rah/go-ricochet/policies"
|
|
|
|
"github.com/s-rah/go-ricochet/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
// InboundConnectionHandler is a convieniance wrapper for handling inbound
|
|
|
|
// connections
|
|
|
|
type InboundConnectionHandler struct {
|
|
|
|
connection *Connection
|
|
|
|
}
|
|
|
|
|
|
|
|
// HandleInboundConnection returns an InboundConnectionHandler given a connection
|
|
|
|
func HandleInboundConnection(c *Connection) *InboundConnectionHandler {
|
|
|
|
ich := new(InboundConnectionHandler)
|
|
|
|
ich.connection = c
|
|
|
|
return ich
|
|
|
|
}
|
|
|
|
|
|
|
|
// ProcessAuthAsServer blocks until authentication has succeeded, failed, or the
|
|
|
|
// connection is closed. A non-nil error is returned in all cases other than successful
|
|
|
|
// and accepted authentication.
|
|
|
|
//
|
|
|
|
// ProcessAuthAsServer cannot be called at the same time as any other call to a Process
|
|
|
|
// function. Another Process function must be called after this function successfully
|
|
|
|
// returns to continue handling connection events.
|
|
|
|
//
|
|
|
|
// The acceptCallback function is called after receiving a valid authentication proof
|
|
|
|
// with the client's authenticated hostname and public key. acceptCallback must return
|
|
|
|
// true to accept authentication and allow the connection to continue, and also returns a
|
|
|
|
// boolean indicating whether the contact is known and recognized. Unknown contacts will
|
|
|
|
// assume they are required to send a contact request before any other activity.
|
|
|
|
func (ich *InboundConnectionHandler) ProcessAuthAsServer(privateKey *rsa.PrivateKey, sach func(hostname string, publicKey rsa.PublicKey) (allowed, known bool)) error {
|
|
|
|
|
2017-07-04 18:29:11 +00:00
|
|
|
if privateKey == nil {
|
|
|
|
return utils.PrivateKeyNotSetError
|
|
|
|
}
|
2017-06-27 17:39:33 +00:00
|
|
|
|
2017-05-02 23:33:51 +00:00
|
|
|
ach := new(AutoConnectionHandler)
|
|
|
|
ach.Init(privateKey, ich.connection.RemoteHostname)
|
|
|
|
ach.SetServerAuthHandler(sach)
|
|
|
|
|
|
|
|
var authResult channels.AuthChannelResult
|
|
|
|
go func() {
|
|
|
|
authResult = ach.WaitForAuthenticationEvent()
|
|
|
|
ich.connection.Break()
|
|
|
|
}()
|
|
|
|
|
|
|
|
policy := policies.UnknownPurposeTimeout
|
|
|
|
err := policy.ExecuteAction(func() error {
|
|
|
|
return ich.connection.Process(ach)
|
|
|
|
})
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
if authResult.Accepted == true {
|
2017-07-04 18:29:11 +00:00
|
|
|
ich.connection.RemoteHostname = authResult.Hostname
|
2017-05-02 23:33:51 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return utils.ClientFailedToAuthenticateError
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|