Adding Inbound Version Negotiation
+ Error handling for missing private key setting
This commit is contained in:
parent
a2fa40492a
commit
f4ed1c244b
|
@ -75,6 +75,11 @@ func (ah *HiddenServiceAuthChannel) Closed(err error) {
|
|||
// returned, it will be sent as the ChannelResult message.
|
||||
// Remote -> [Open Authentication Channel] -> Local
|
||||
func (ah *HiddenServiceAuthChannel) OpenInbound(channel *Channel, oc *Protocol_Data_Control.OpenChannel) ([]byte, error) {
|
||||
|
||||
if ah.PrivateKey == nil {
|
||||
return nil, utils.PrivateKeyNotSetError
|
||||
}
|
||||
|
||||
ah.channel = channel
|
||||
clientCookie, _ := proto.GetExtension(oc, Protocol_Data_AuthHiddenService.E_ClientCookie)
|
||||
if len(clientCookie.([]byte)[:]) != 16 {
|
||||
|
@ -92,6 +97,12 @@ func (ah *HiddenServiceAuthChannel) OpenInbound(channel *Channel, oc *Protocol_D
|
|||
// returned, it will be sent as the OpenChannel message.
|
||||
// Local -> [Open Authentication Channel] -> Remote
|
||||
func (ah *HiddenServiceAuthChannel) OpenOutbound(channel *Channel) ([]byte, error) {
|
||||
|
||||
if ah.PrivateKey == nil {
|
||||
return nil, utils.PrivateKeyNotSetError
|
||||
}
|
||||
|
||||
|
||||
ah.channel = channel
|
||||
messageBuilder := new(utils.MessageBuilder)
|
||||
return messageBuilder.OpenAuthenticationChannel(ah.channel.ID, ah.GenClientCookie()), nil
|
||||
|
|
|
@ -71,9 +71,10 @@ func GetOpenAuthenticationChannelMessage() *Protocol_Data_Control.OpenChannel {
|
|||
}
|
||||
|
||||
func TestAuthenticationOpenInbound(t *testing.T) {
|
||||
|
||||
privateKey, _ := utils.LoadPrivateKeyFromFile("../testing/private_key")
|
||||
opm := GetOpenAuthenticationChannelMessage()
|
||||
authHandler := new(HiddenServiceAuthChannel)
|
||||
authHandler.PrivateKey = privateKey
|
||||
channel := Channel{ID: 1}
|
||||
response, err := authHandler.OpenInbound(&channel, opm)
|
||||
|
||||
|
@ -90,7 +91,9 @@ func TestAuthenticationOpenInbound(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAuthenticationOpenOutbound(t *testing.T) {
|
||||
privateKey, _ := utils.LoadPrivateKeyFromFile("../testing/private_key")
|
||||
authHandler := new(HiddenServiceAuthChannel)
|
||||
authHandler.PrivateKey = privateKey
|
||||
channel := Channel{ID: 1}
|
||||
response, err := authHandler.OpenOutbound(&channel)
|
||||
|
||||
|
|
|
@ -24,7 +24,9 @@ type AutoConnectionHandler struct {
|
|||
}
|
||||
|
||||
// Init ...
|
||||
// TODO: Split this into client and server init
|
||||
func (ach *AutoConnectionHandler) Init(privateKey *rsa.PrivateKey, serverHostname string) {
|
||||
|
||||
ach.handlerMap = make(map[string]func() channels.Handler)
|
||||
ach.RegisterChannelHandler("im.ricochet.auth.hidden-service", func() channels.Handler {
|
||||
hsau := new(channels.HiddenServiceAuthChannel)
|
||||
|
|
|
@ -35,6 +35,10 @@ func HandleInboundConnection(c *Connection) *InboundConnectionHandler {
|
|||
// 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 {
|
||||
|
||||
if privateKey == nil {
|
||||
return utils.PrivateKeyNotSetError
|
||||
}
|
||||
|
||||
ach := new(AutoConnectionHandler)
|
||||
ach.Init(privateKey, ich.connection.RemoteHostname)
|
||||
ach.SetServerAuthHandler(sach)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/rsa"
|
||||
"errors"
|
||||
"github.com/s-rah/go-ricochet/channels"
|
||||
"github.com/s-rah/go-ricochet/utils"
|
||||
"github.com/s-rah/go-ricochet/policies"
|
||||
"log"
|
||||
)
|
||||
|
@ -33,6 +34,11 @@ func HandleOutboundConnection(c *Connection) *OutboundConnectionHandler {
|
|||
// 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) {
|
||||
|
||||
if privateKey == nil {
|
||||
return false, utils.PrivateKeyNotSetError
|
||||
}
|
||||
|
||||
ach := new(AutoConnectionHandler)
|
||||
ach.Init(privateKey, och.connection.RemoteHostname)
|
||||
|
||||
|
|
43
ricochet.go
43
ricochet.go
|
@ -53,3 +53,46 @@ func negotiateVersion(conn net.Conn, remoteHostname string) (*connection.Connect
|
|||
}
|
||||
|
||||
|
||||
// NegotiateVersionInbound takes in a connection and performs version negotiation
|
||||
// as if that connection was a client. Returns a ricochet connection if successful
|
||||
// error otherwise.
|
||||
func NegotiateVersionInbound(conn net.Conn) (*connection.Connection, error) {
|
||||
versions := []byte{0x49, 0x4D, 0x01, 0x01}
|
||||
// Read version response header
|
||||
header := make([]byte, 3)
|
||||
if _, err := io.ReadAtLeast(conn, header, len(header)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if header[0] != versions[0] || header[1] != versions[1] || header[2] < 1 {
|
||||
return nil, utils.VersionNegotiationError
|
||||
}
|
||||
|
||||
// Read list of supported versions (which is header[2] bytes long)
|
||||
versionList := make([]byte, header[2])
|
||||
if _, err := io.ReadAtLeast(conn, versionList, len(versionList)); err != nil {
|
||||
return nil, utils.VersionNegotiationError
|
||||
}
|
||||
|
||||
selectedVersion := byte(0xff)
|
||||
for _, v := range versionList {
|
||||
if v == 0x01 {
|
||||
selectedVersion = v
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if n, err := conn.Write([]byte{selectedVersion}); err != nil || n < 1 {
|
||||
return nil, utils.VersionNegotiationFailed
|
||||
}
|
||||
|
||||
if selectedVersion == 0xff {
|
||||
return nil, utils.VersionNegotiationFailed
|
||||
}
|
||||
|
||||
rc := connection.NewInboundConnection(conn)
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ const (
|
|||
ActionTimedOutError = Error("ActionTimedOutError")
|
||||
|
||||
ClientFailedToAuthenticateError = Error("ClientFailedToAuthenticateError")
|
||||
|
||||
|
||||
PrivateKeyNotSetError = Error("PrivateKeyNotSetError")
|
||||
)
|
||||
|
||||
// RecoverFromError doesn't really recover from anything....see comment below
|
||||
|
|
Loading…
Reference in New Issue