Token has been stripped; Headers are encrypted
This commit is contained in:
		| @@ -8,6 +8,14 @@ import ( | |||||||
| 	"io" | 	"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 | // Encrypt encrypts data and returns the encrypted data | ||||||
| func Encrypt(data []byte, key string) ([]byte, error) { | func Encrypt(data []byte, key string) ([]byte, error) { | ||||||
| 	// generate a new AES cipher using our 32 byte key | 	// 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 | 	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) |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ type tun struct { | |||||||
| 	// the unique id for this tunnel | 	// the unique id for this tunnel | ||||||
| 	id string | 	id string | ||||||
|  |  | ||||||
| 	// tunnel token for authentication | 	// tunnel token for session encryption | ||||||
| 	token string | 	token string | ||||||
|  |  | ||||||
| 	// to indicate if we're connected or not | 	// to indicate if we're connected or not | ||||||
| @@ -119,6 +119,7 @@ func (t *tun) newSession(channel, sessionId string) (*session, bool) { | |||||||
| 		tunnel:  t.id, | 		tunnel:  t.id, | ||||||
| 		channel: channel, | 		channel: channel, | ||||||
| 		session: sessionId, | 		session: sessionId, | ||||||
|  | 		token:   t.token, | ||||||
| 		closed:  make(chan bool), | 		closed:  make(chan bool), | ||||||
| 		recv:    make(chan *message, 128), | 		recv:    make(chan *message, 128), | ||||||
| 		send:    t.send, | 		send:    t.send, | ||||||
| @@ -159,7 +160,6 @@ func (t *tun) announce(channel, session string, link *link) { | |||||||
| 			"Micro-Tunnel-Channel": channel, | 			"Micro-Tunnel-Channel": channel, | ||||||
| 			"Micro-Tunnel-Session": session, | 			"Micro-Tunnel-Session": session, | ||||||
| 			"Micro-Tunnel-Link":    link.id, | 			"Micro-Tunnel-Link":    link.id, | ||||||
| 			"Micro-Tunnel-Token":   t.token, |  | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -292,9 +292,6 @@ func (t *tun) process() { | |||||||
| 			// set the session id | 			// set the session id | ||||||
| 			newMsg.Header["Micro-Tunnel-Session"] = msg.session | 			newMsg.Header["Micro-Tunnel-Session"] = msg.session | ||||||
|  |  | ||||||
| 			// set the tunnel token |  | ||||||
| 			newMsg.Header["Micro-Tunnel-Token"] = t.token |  | ||||||
|  |  | ||||||
| 			// send the message via the interface | 			// send the message via the interface | ||||||
| 			t.RLock() | 			t.RLock() | ||||||
|  |  | ||||||
| @@ -447,14 +444,11 @@ func (t *tun) listen(link *link) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// always ensure we have the correct auth token | 		// TODO: figure out network authentication | ||||||
| 		// TODO: segment the tunnel based on token | 		// for now we use tunnel token to encrypt/decrypt | ||||||
| 		// e.g use it as the basis | 		// session communication, but we will probably need | ||||||
| 		token := msg.Header["Micro-Tunnel-Token"] | 		// some sort of network authentication (token) to avoid | ||||||
| 		if token != t.token { | 		// having rogue actors spamming the network | ||||||
| 			log.Debugf("Tunnel link %s received invalid token %s", token) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// message type | 		// message type | ||||||
| 		mtype := msg.Header["Micro-Tunnel"] | 		mtype := msg.Header["Micro-Tunnel"] | ||||||
| @@ -702,9 +696,8 @@ func (t *tun) discover(link *link) { | |||||||
| 			// send a discovery message to all links | 			// send a discovery message to all links | ||||||
| 			if err := link.Send(&transport.Message{ | 			if err := link.Send(&transport.Message{ | ||||||
| 				Header: map[string]string{ | 				Header: map[string]string{ | ||||||
| 					"Micro-Tunnel":       "discover", | 					"Micro-Tunnel":    "discover", | ||||||
| 					"Micro-Tunnel-Id":    t.id, | 					"Micro-Tunnel-Id": t.id, | ||||||
| 					"Micro-Tunnel-Token": t.token, |  | ||||||
| 				}, | 				}, | ||||||
| 			}); err != nil { | 			}); err != nil { | ||||||
| 				log.Debugf("Tunnel failed to send discover to link %s: %v", link.id, err) | 				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()) | 			log.Debugf("Tunnel sending keepalive to link: %v", link.Remote()) | ||||||
| 			if err := link.Send(&transport.Message{ | 			if err := link.Send(&transport.Message{ | ||||||
| 				Header: map[string]string{ | 				Header: map[string]string{ | ||||||
| 					"Micro-Tunnel":       "keepalive", | 					"Micro-Tunnel":    "keepalive", | ||||||
| 					"Micro-Tunnel-Id":    t.id, | 					"Micro-Tunnel-Id": t.id, | ||||||
| 					"Micro-Tunnel-Token": t.token, |  | ||||||
| 				}, | 				}, | ||||||
| 			}); err != nil { | 			}); err != nil { | ||||||
| 				log.Debugf("Error sending keepalive to link %v: %v", link.Remote(), err) | 				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 | 	// send the first connect message | ||||||
| 	if err := link.Send(&transport.Message{ | 	if err := link.Send(&transport.Message{ | ||||||
| 		Header: map[string]string{ | 		Header: map[string]string{ | ||||||
| 			"Micro-Tunnel":       "connect", | 			"Micro-Tunnel":    "connect", | ||||||
| 			"Micro-Tunnel-Id":    t.id, | 			"Micro-Tunnel-Id": t.id, | ||||||
| 			"Micro-Tunnel-Token": t.token, |  | ||||||
| 		}, | 		}, | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -901,9 +892,8 @@ func (t *tun) close() error { | |||||||
| 	for node, link := range t.links { | 	for node, link := range t.links { | ||||||
| 		link.Send(&transport.Message{ | 		link.Send(&transport.Message{ | ||||||
| 			Header: map[string]string{ | 			Header: map[string]string{ | ||||||
| 				"Micro-Tunnel":       "close", | 				"Micro-Tunnel":    "close", | ||||||
| 				"Micro-Tunnel-Id":    t.id, | 				"Micro-Tunnel-Id": t.id, | ||||||
| 				"Micro-Tunnel-Token": t.token, |  | ||||||
| 			}, | 			}, | ||||||
| 		}) | 		}) | ||||||
| 		link.Close() | 		link.Close() | ||||||
| @@ -1157,6 +1147,8 @@ func (t *tun) Listen(channel string, opts ...ListenOption) (Listener, error) { | |||||||
|  |  | ||||||
| 	tl := &tunListener{ | 	tl := &tunListener{ | ||||||
| 		channel: channel, | 		channel: channel, | ||||||
|  | 		// tunnel token | ||||||
|  | 		token: t.token, | ||||||
| 		// the accept channel | 		// the accept channel | ||||||
| 		accept: make(chan *session, 128), | 		accept: make(chan *session, 128), | ||||||
| 		// the channel to close | 		// the channel to close | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ import ( | |||||||
| type tunListener struct { | type tunListener struct { | ||||||
| 	// address of the listener | 	// address of the listener | ||||||
| 	channel string | 	channel string | ||||||
|  | 	// token is the tunnel token | ||||||
|  | 	token string | ||||||
| 	// the accept channel | 	// the accept channel | ||||||
| 	accept chan *session | 	accept chan *session | ||||||
| 	// the channel to close | 	// the channel to close | ||||||
| @@ -78,6 +80,8 @@ func (t *tunListener) process() { | |||||||
| 					channel: m.channel, | 					channel: m.channel, | ||||||
| 					// the session id | 					// the session id | ||||||
| 					session: m.session, | 					session: m.session, | ||||||
|  | 					// tunnel token | ||||||
|  | 					token: t.token, | ||||||
| 					// is loopback conn | 					// is loopback conn | ||||||
| 					loopback: m.loopback, | 					loopback: m.loopback, | ||||||
| 					// the link the message was received on | 					// the link the message was received on | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| package tunnel | package tunnel | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"encoding/hex" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io" | 	"io" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -17,6 +18,8 @@ type session struct { | |||||||
| 	channel string | 	channel string | ||||||
| 	// the session id based on Micro.Tunnel-Session | 	// the session id based on Micro.Tunnel-Session | ||||||
| 	session string | 	session string | ||||||
|  | 	// token is the session token | ||||||
|  | 	token string | ||||||
| 	// closed | 	// closed | ||||||
| 	closed chan bool | 	closed chan bool | ||||||
| 	// remote addr | 	// remote addr | ||||||
| @@ -301,16 +304,10 @@ func (s *session) Send(m *transport.Message) error { | |||||||
| 		// no op | 		// 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 | 	// 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 { | 	if err != nil { | ||||||
|  | 		log.Debugf("failed to encrypt message body: %v", err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -320,9 +317,16 @@ func (s *session) Send(m *transport.Message) error { | |||||||
| 		Body:   body, | 		Body:   body, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// encrypt all the headers | ||||||
| 	for k, v := range m.Header { | 	for k, v := range m.Header { | ||||||
| 		// TODO: should we also encrypt headers? | 		// encrypt the transport message payload | ||||||
| 		data.Header[k] = v | 		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 | 	// create a new message | ||||||
| @@ -366,22 +370,35 @@ func (s *session) Recv(m *transport.Message) error { | |||||||
| 	default: | 	default: | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// TODO: if we encrypt headers we will have to decrypt them here | 	//log.Tracef("Received %+v from recv backlog", msg) | ||||||
| 	token, ok := msg.data.Header["Micro-Tunnel-Token"] | 	log.Debugf("Received %+v from recv backlog", msg) | ||||||
| 	if !ok { |  | ||||||
| 		// TODO: should we continue or return error |  | ||||||
| 		log.Debugf("no token found, insecure channel") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	log.Tracef("Received %+v from recv backlog", msg) |  | ||||||
|  |  | ||||||
| 	// decrypt the received payload using the token | 	// 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 { | 	if err != nil { | ||||||
|  | 		log.Debugf("failed to decrypt message body: %v", err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	msg.data.Body = body | 	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 | 	// set message | ||||||
| 	*m = *msg.data | 	*m = *msg.data | ||||||
| 	// return nil | 	// return nil | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user