123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- package packet
- import (
- "bytes"
- "crypto/md5"
- "encoding/base64"
- "encoding/binary"
- "errors"
- "fmt"
- "log"
- "net"
- "time"
- "github.com/gravitl/netmaker/nm-proxy/common"
- "golang.org/x/crypto/blake2s"
- "golang.org/x/crypto/chacha20poly1305"
- "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
- )
- func ConsumeHandshakeInitiationMsg(initiator bool, buf []byte, src *net.UDPAddr, devicePubKey NoisePublicKey, devicePrivKey NoisePrivateKey) error {
- var (
- hash [blake2s.Size]byte
- chainKey [blake2s.Size]byte
- )
- var err error
- var msg MessageInitiation
- reader := bytes.NewReader(buf[:])
- err = binary.Read(reader, binary.LittleEndian, &msg)
- if err != nil {
- log.Println("Failed to decode initiation message")
- return err
- }
- if msg.Type != MessageInitiationType {
- return errors.New("not handshake initiation message")
- }
- log.Println("-----> ConsumeHandshakeInitiationMsg, Intitator: ", initiator)
- mixHash(&hash, &InitialHash, devicePubKey[:])
- mixHash(&hash, &hash, msg.Ephemeral[:])
- mixKey(&chainKey, &InitialChainKey, msg.Ephemeral[:])
- // decrypt static key
- var peerPK NoisePublicKey
- var key [chacha20poly1305.KeySize]byte
- ss := sharedSecret(&devicePrivKey, msg.Ephemeral)
- if isZero(ss[:]) {
- return errors.New("no secret")
- }
- KDF2(&chainKey, &key, chainKey[:], ss[:])
- aead, _ := chacha20poly1305.New(key[:])
- _, err = aead.Open(peerPK[:0], ZeroNonce[:], msg.Static[:], hash[:])
- if err != nil {
- return err
- }
- log.Println("--------> Got HandShake from peer: ", base64.StdEncoding.EncodeToString(peerPK[:]), src)
- if val, ok := common.ExtClientsWaitTh[base64.StdEncoding.EncodeToString(peerPK[:])]; ok {
- val.CommChan <- src
- time.Sleep(time.Second * 3)
- }
- setZero(hash[:])
- setZero(chainKey[:])
- return nil
- }
- func CreateProxyUpdatePacket(msg *ProxyUpdateMessage) ([]byte, error) {
- var buff [MessageProxyUpdateSize]byte
- writer := bytes.NewBuffer(buff[:0])
- err := binary.Write(writer, binary.LittleEndian, msg)
- if err != nil {
- return nil, err
- }
- packet := writer.Bytes()
- return packet, nil
- }
- func ConsumeProxyUpdateMsg(buf []byte) (*ProxyUpdateMessage, error) {
- var msg ProxyUpdateMessage
- reader := bytes.NewReader(buf[:])
- err := binary.Read(reader, binary.LittleEndian, &msg)
- if err != nil {
- log.Println("Failed to decode proxy update message")
- return nil, err
- }
- if msg.Type != MessageProxyUpdateType {
- return nil, errors.New("not proxy update message")
- }
- return &msg, nil
- }
- func CreateMetricPacket(id uint32, sender, reciever wgtypes.Key) ([]byte, error) {
- msg := MetricMessage{
- Type: MessageMetricsType,
- ID: id,
- Sender: sender,
- Reciever: reciever,
- TimeStamp: time.Now().UnixMilli(),
- }
- log.Printf("----------> $$$$$$ CREATED PACKET: %+v\n", msg)
- var buff [MessageMetricSize]byte
- writer := bytes.NewBuffer(buff[:0])
- err := binary.Write(writer, binary.LittleEndian, msg)
- if err != nil {
- return nil, err
- }
- packet := writer.Bytes()
- return packet, nil
- }
- func ConsumeMetricPacket(buf []byte) (*MetricMessage, error) {
- var msg MetricMessage
- var err error
- reader := bytes.NewReader(buf[:])
- err = binary.Read(reader, binary.LittleEndian, &msg)
- if err != nil {
- log.Println("Failed to decode metric message")
- return nil, err
- }
- if msg.Type != MessageMetricsType {
- return nil, errors.New("not metric message")
- }
- return &msg, nil
- }
- func ProcessPacketBeforeSending(buf []byte, n int, srckey, dstKey string) ([]byte, int, string, string) {
- srcKeymd5 := md5.Sum([]byte(srckey))
- dstKeymd5 := md5.Sum([]byte(dstKey))
- m := ProxyMessage{
- Type: MessageProxyType,
- Sender: srcKeymd5,
- Reciever: dstKeymd5,
- }
- var msgBuffer [MessageProxySize]byte
- writer := bytes.NewBuffer(msgBuffer[:0])
- err := binary.Write(writer, binary.LittleEndian, m)
- if err != nil {
- log.Println(err)
- }
- if n > len(buf)-MessageProxySize {
- buf = append(buf, msgBuffer[:]...)
- } else {
- copy(buf[n:n+MessageProxySize], msgBuffer[:])
- }
- n += MessageProxySize
- return buf, n, fmt.Sprintf("%x", srcKeymd5), fmt.Sprintf("%x", dstKeymd5)
- }
- func ExtractInfo(buffer []byte, n int) (int, string, string, error) {
- data := buffer[:n]
- if len(data) < MessageProxySize {
- return n, "", "", errors.New("proxy message not found")
- }
- var msg ProxyMessage
- var err error
- reader := bytes.NewReader(buffer[n-MessageProxySize:])
- err = binary.Read(reader, binary.LittleEndian, &msg)
- if err != nil {
- log.Println("Failed to decode proxy message")
- return n, "", "", err
- }
- if msg.Type != MessageProxyType {
- return n, "", "", errors.New("not a proxy message")
- }
- n -= MessageProxySize
- return n, fmt.Sprintf("%x", msg.Sender), fmt.Sprintf("%x", msg.Reciever), nil
- }
|