Token has been stripped; Headers are encrypted

This commit is contained in:
Milos Gajdos 2019-11-25 18:56:00 +00:00
parent f82c267d81
commit 9095b99f6b
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F
4 changed files with 65 additions and 52 deletions

View File

@ -8,6 +8,14 @@ import (
"io"
)
// hash hahes the data into 32 bytes key and returns it
// hash uses sha256 underneath to hash the supplied key
func hash(key string) []byte {
hasher := sha256.New()
hasher.Write([]byte(key))
return hasher.Sum(nil)
}
// Encrypt encrypts data and returns the encrypted data
func Encrypt(data []byte, key string) ([]byte, error) {
// generate a new AES cipher using our 32 byte key
@ -62,11 +70,3 @@ func Decrypt(data []byte, key string) ([]byte, error) {
return plaintext, nil
}
// hash hahes the data into 32 bytes key and returns it
// hash uses sha256 underneath to hash the supplied key
func hash(key string) []byte {
hasher := sha256.New()
hasher.Write([]byte(key))
return hasher.Sum(nil)
}

View File

@ -30,7 +30,7 @@ type tun struct {
// the unique id for this tunnel
id string
// tunnel token for authentication
// tunnel token for session encryption
token string
// to indicate if we're connected or not
@ -119,6 +119,7 @@ func (t *tun) newSession(channel, sessionId string) (*session, bool) {
tunnel: t.id,
channel: channel,
session: sessionId,
token: t.token,
closed: make(chan bool),
recv: make(chan *message, 128),
send: t.send,
@ -159,7 +160,6 @@ func (t *tun) announce(channel, session string, link *link) {
"Micro-Tunnel-Channel": channel,
"Micro-Tunnel-Session": session,
"Micro-Tunnel-Link": link.id,
"Micro-Tunnel-Token": t.token,
},
}
@ -292,9 +292,6 @@ func (t *tun) process() {
// set the session id
newMsg.Header["Micro-Tunnel-Session"] = msg.session
// set the tunnel token
newMsg.Header["Micro-Tunnel-Token"] = t.token
// send the message via the interface
t.RLock()
@ -447,14 +444,11 @@ func (t *tun) listen(link *link) {
return
}
// always ensure we have the correct auth token
// TODO: segment the tunnel based on token
// e.g use it as the basis
token := msg.Header["Micro-Tunnel-Token"]
if token != t.token {
log.Debugf("Tunnel link %s received invalid token %s", token)
return
}
// TODO: figure out network authentication
// for now we use tunnel token to encrypt/decrypt
// session communication, but we will probably need
// some sort of network authentication (token) to avoid
// having rogue actors spamming the network
// message type
mtype := msg.Header["Micro-Tunnel"]
@ -702,9 +696,8 @@ func (t *tun) discover(link *link) {
// send a discovery message to all links
if err := link.Send(&transport.Message{
Header: map[string]string{
"Micro-Tunnel": "discover",
"Micro-Tunnel-Id": t.id,
"Micro-Tunnel-Token": t.token,
"Micro-Tunnel": "discover",
"Micro-Tunnel-Id": t.id,
},
}); err != nil {
log.Debugf("Tunnel failed to send discover to link %s: %v", link.id, err)
@ -733,9 +726,8 @@ func (t *tun) keepalive(link *link) {
log.Debugf("Tunnel sending keepalive to link: %v", link.Remote())
if err := link.Send(&transport.Message{
Header: map[string]string{
"Micro-Tunnel": "keepalive",
"Micro-Tunnel-Id": t.id,
"Micro-Tunnel-Token": t.token,
"Micro-Tunnel": "keepalive",
"Micro-Tunnel-Id": t.id,
},
}); err != nil {
log.Debugf("Error sending keepalive to link %v: %v", link.Remote(), err)
@ -765,9 +757,8 @@ func (t *tun) setupLink(node string) (*link, error) {
// send the first connect message
if err := link.Send(&transport.Message{
Header: map[string]string{
"Micro-Tunnel": "connect",
"Micro-Tunnel-Id": t.id,
"Micro-Tunnel-Token": t.token,
"Micro-Tunnel": "connect",
"Micro-Tunnel-Id": t.id,
},
}); err != nil {
return nil, err
@ -901,9 +892,8 @@ func (t *tun) close() error {
for node, link := range t.links {
link.Send(&transport.Message{
Header: map[string]string{
"Micro-Tunnel": "close",
"Micro-Tunnel-Id": t.id,
"Micro-Tunnel-Token": t.token,
"Micro-Tunnel": "close",
"Micro-Tunnel-Id": t.id,
},
})
link.Close()
@ -1157,6 +1147,8 @@ func (t *tun) Listen(channel string, opts ...ListenOption) (Listener, error) {
tl := &tunListener{
channel: channel,
// tunnel token
token: t.token,
// the accept channel
accept: make(chan *session, 128),
// the channel to close

View File

@ -10,6 +10,8 @@ import (
type tunListener struct {
// address of the listener
channel string
// token is the tunnel token
token string
// the accept channel
accept chan *session
// the channel to close
@ -78,6 +80,8 @@ func (t *tunListener) process() {
channel: m.channel,
// the session id
session: m.session,
// tunnel token
token: t.token,
// is loopback conn
loopback: m.loopback,
// the link the message was received on

View File

@ -1,6 +1,7 @@
package tunnel
import (
"encoding/hex"
"errors"
"io"
"time"
@ -17,6 +18,8 @@ type session struct {
channel string
// the session id based on Micro.Tunnel-Session
session string
// token is the session token
token string
// closed
closed chan bool
// remote addr
@ -301,16 +304,10 @@ func (s *session) Send(m *transport.Message) error {
// no op
}
// get the token
token, ok := m.Header["Micro-Tunnel-Token"]
if !ok {
// TODO: should we continue or return error
log.Debugf("no token found, insecure channel")
}
// encrypt the transport message payload
body, err := Encrypt(m.Body, token+s.channel+s.session)
body, err := Encrypt(m.Body, s.token+s.channel+s.session)
if err != nil {
log.Debugf("failed to encrypt message body: %v", err)
return err
}
@ -320,9 +317,16 @@ func (s *session) Send(m *transport.Message) error {
Body: body,
}
// encrypt all the headers
for k, v := range m.Header {
// TODO: should we also encrypt headers?
data.Header[k] = v
// encrypt the transport message payload
val, err := Encrypt([]byte(v), s.token+s.channel+s.session)
if err != nil {
log.Debugf("failed to encrypt message header %s: %v", k, err)
return err
}
// hex encode the encrypted header value
data.Header[k] = hex.EncodeToString(val)
}
// create a new message
@ -366,22 +370,35 @@ func (s *session) Recv(m *transport.Message) error {
default:
}
// TODO: if we encrypt headers we will have to decrypt them here
token, ok := msg.data.Header["Micro-Tunnel-Token"]
if !ok {
// TODO: should we continue or return error
log.Debugf("no token found, insecure channel")
}
log.Tracef("Received %+v from recv backlog", msg)
//log.Tracef("Received %+v from recv backlog", msg)
log.Debugf("Received %+v from recv backlog", msg)
// decrypt the received payload using the token
body, err := Decrypt(msg.data.Body, token+s.channel+s.session)
body, err := Decrypt(msg.data.Body, s.token+s.channel+s.session)
if err != nil {
log.Debugf("failed to decrypt message body: %v", err)
return err
}
msg.data.Body = body
// encrypt all the headers
for k, v := range msg.data.Header {
// hex decode the header values
h, err := hex.DecodeString(v)
if err != nil {
log.Debugf("failed to decode message header %s: %v", k, err)
return err
}
// encrypt the transport message payload
val, err := Decrypt([]byte(h), s.token+s.channel+s.session)
if err != nil {
log.Debugf("failed to decrypt message header %s: %v", k, err)
return err
}
// hex encode the encrypted header value
msg.data.Header[k] = string(val)
}
// set message
*m = *msg.data
// return nil