From 3efe2f75ab432bca09e79d692af8556a3cb02bd9 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Tue, 11 Apr 2023 22:35:36 -0700 Subject: [PATCH] removing sturn implementation --- net/server/internal/sturn/attribute.go | 256 ------------- net/server/internal/sturn/message.go | 480 ------------------------- net/server/internal/sturn/sturn.go | 171 --------- net/server/internal/sturn/types.go | 334 ----------------- 4 files changed, 1241 deletions(-) delete mode 100644 net/server/internal/sturn/attribute.go delete mode 100644 net/server/internal/sturn/message.go delete mode 100644 net/server/internal/sturn/sturn.go delete mode 100644 net/server/internal/sturn/types.go diff --git a/net/server/internal/sturn/attribute.go b/net/server/internal/sturn/attribute.go deleted file mode 100644 index 8b7477b3..00000000 --- a/net/server/internal/sturn/attribute.go +++ /dev/null @@ -1,256 +0,0 @@ -package sturn - -import ( - "crypto/md5" - "crypto/hmac" - "crypto/sha1" - "errors" - "strings" - "strconv" - "fmt" -) - -func readAttribute(buf []byte, pos int) (error, *SturnAttribute, int) { - - if len(buf) - pos < 4 { - return errors.New("invalid attribute length"), nil, 0 - } - atrType := getAttributeType(buf[pos + 0], buf[pos + 1]) - atrLength := int(buf[pos + 2]) * 256 + int(buf[pos + 3]) - padLength := ((atrLength + 3) >> 2) << 2 - if len(buf) - pos < 4 + padLength { - return errors.New("invalid attribute buffer"), nil, 0 - } - - attr := &SturnAttribute{ atrType: atrType } - if atrType == ATRRequestedTransport { - if buf[pos + 5] != 0x00 || buf[pos + 6] != 0x00 || buf[pos + 7] != 0x00 { - return errors.New("invalid attribute"), nil, 0 - } - attr.intValue = int32(buf[pos + 4]) - } else if atrType == ATRLifetime { - attr.intValue = 256 * (256 * (256 * int32(buf[pos + 4]) + int32(buf[pos + 5])) + int32(buf[pos + 6])) + int32(buf[pos + 7]); - } else if atrType == ATRNonce { - attr.strValue = string(buf[pos + 4:pos + 4+atrLength]); - } else if atrType == ATRUsername { - attr.strValue = string(buf[pos + 4:pos + 4+atrLength]); - } else if atrType == ATRRealm { - attr.strValue = string(buf[pos + 4:pos + 4+atrLength]); - } else if atrType == ATRMessageIntegrity { - //fmt.Println("HANDLE: ATRMessageIntegrity"); - } else if atrType == ATRMessageIntegritySha256 { - //fmt.Println("HANDLE: ATRMessageIntegritySha256"); - } else if atrType == ATRFingerprint { - //fmt.Println("HANDLE: ATRFingerprint"); - } else if atrType == ATRXorPeerAddress { - if padLength != 8 { - return errors.New("invalid attribute size"), nil, 0 - } - if buf[pos + 4] != 0 || buf[pos + 5] != FAMIPv4 { - return errors.New("unsupported protocol family"), nil, 0 - } - attr.strValue = "" - attr.strValue += strconv.Itoa(int(buf[pos + 8] ^ 0x21)) - attr.strValue += "." - attr.strValue += strconv.Itoa(int(buf[pos + 9] ^ 0x12)) - attr.strValue += "." - attr.strValue += strconv.Itoa(int(buf[pos + 10] ^ 0xA4)) - attr.strValue += "." - attr.strValue += strconv.Itoa(int(buf[pos + 11] ^ 0x42)) - attr.intValue = int32(buf[pos + 6] ^ 0x21) - attr.intValue *= 256 - attr.intValue += int32(buf[pos + 7] ^ 0x12) - } else if atrType == ATRData { - for i := 0; i < atrLength; i++ { - attr.binValue = append(attr.binValue, buf[pos + 4 + i]) - } - } else { - fmt.Println("UNKNOWN ATTRIBUTE", atrType); - } - - return nil, attr, 4 + padLength -} - -func writeAttribute(attribute *SturnAttribute, buf []byte, pos int) (error, int) { - - if len(buf) - pos < 4 { - return errors.New("invalid buffer size"), 0 - } - - if attribute.atrType == ATRXorMappedAddress { - if len(buf) - pos < 12 { - return errors.New("invalid buffer size"), 0 - } - ip := 0 - parts := strings.Split(attribute.strValue, "."); - for i := 0; i < 4; i++ { - val, _ := strconv.Atoi(parts[i]); - ip = (ip * 256) + val; - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRXorMappedAddress); - buf[pos + 2] = 0x00 - buf[pos + 3] = 0x08 - buf[pos + 4] = 0x00 - buf[pos + 5] = FAMIPv4 - buf[pos + 6] = byte((attribute.intValue >> 8) % 256) ^ 0x21 - buf[pos + 7] = byte((attribute.intValue) % 256) ^ 0x12 - buf[pos + 8] = byte((ip >> 24) % 256) ^ 0x21 - buf[pos + 9] = byte((ip >> 16) % 256) ^ 0x12 - buf[pos + 10] = byte((ip >> 8) % 256) ^ 0xA4 - buf[pos + 11] = byte(ip % 256) ^ 0x42 - return nil, 12 - } else if attribute.atrType == ATRXorRelayedAddress { - if len(buf) - pos < 12 { - return errors.New("invalid buffer size"), 0 - } - ip := 0 - parts := strings.Split(attribute.strValue, "."); - for i := 0; i < 4; i++ { - val, _ := strconv.Atoi(parts[i]); - ip = (ip * 256) + val; - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRXorRelayedAddress); - buf[pos + 2] = 0x00 - buf[pos + 3] = 0x08 - buf[pos + 4] = 0x00 - buf[pos + 5] = FAMIPv4 - buf[pos + 6] = byte((attribute.intValue >> 8) % 256) ^ 0x21 - buf[pos + 7] = byte(attribute.intValue % 256) ^ 0x12 - buf[pos + 8] = byte((ip >> 24) % 256) ^ 0x21 - buf[pos + 9] = byte((ip >> 16) % 256) ^ 0x12 - buf[pos + 10] = byte((ip >> 8) % 256) ^ 0xA4 - buf[pos + 11] = byte(ip % 256) ^ 0x42 - return nil, 12 - } else if attribute.atrType == ATRXorPeerAddress { - if len(buf) - pos < 12 { - return errors.New("invalid buffer size"), 0 - } - ip := 0 - parts := strings.Split(attribute.strValue, "."); - for i := 0; i < 4; i++ { - val, _ := strconv.Atoi(parts[i]); - ip = (ip * 256) + val; - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRXorPeerAddress); - buf[pos + 2] = 0x00 - buf[pos + 3] = 0x08 - buf[pos + 4] = 0x00 - buf[pos + 5] = FAMIPv4 - buf[pos + 6] = byte((attribute.intValue >> 8) % 256) ^ 0x21 - buf[pos + 7] = byte(attribute.intValue % 256) ^ 0x12 - buf[pos + 8] = byte((ip >> 24) % 256) ^ 0x21 - buf[pos + 9] = byte((ip >> 16) % 256) ^ 0x12 - buf[pos + 10] = byte((ip >> 8) % 256) ^ 0xA4 - buf[pos + 11] = byte(ip % 256) ^ 0x42 - return nil, 12 - } else if attribute.atrType == ATRData { - paddedLen := ((len(attribute.binValue) + 3) >> 2) << 2 - if len(buf) - pos < 4 + paddedLen { - return errors.New("invalid buffer size"), 0 - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRData) - buf[pos + 2] = byte((len(attribute.binValue) >> 8) % 256) - buf[pos + 3] = byte(len(attribute.binValue) % 256) - for i := 0; i < len(attribute.binValue); i++ { - buf[pos + 4 + i] = attribute.binValue[i] - } - for i := len(attribute.binValue); i < paddedLen; i++ { - buf[pos + 4 + i] = 0x00 - } - return nil, 4 + paddedLen - } else if attribute.atrType == ATRLifetime { - if len(buf) - pos < 8 { - return errors.New("invalid buffer size"), 0 - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRLifetime); - buf[pos + 2] = 0x00 - buf[pos + 3] = 0x04 - buf[pos + 4] = byte((attribute.intValue >> 24) % 256); - buf[pos + 5] = byte((attribute.intValue >> 16) % 256); - buf[pos + 6] = byte((attribute.intValue >> 8) % 256); - buf[pos + 7] = byte(attribute.intValue % 256); - return nil, 8 - } else if attribute.atrType == ATRNonce { - raw := []byte(attribute.strValue) - rawLen := len(raw); - paddedLen := ((len(raw) + 3) >> 2) << 2 - if paddedLen >= 256 { - return errors.New("invalid attribute size"), 0 - } - if len(buf) - pos < 4 + paddedLen { - return errors.New("invalid buffer size"), 0 - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRNonce); - buf[pos + 2] = 0x00 - buf[pos + 3] = byte(rawLen) - for i := 0; i < len(raw); i++ { - buf[pos + 4 + i] = raw[i]; - } - for i := len(raw); i < paddedLen; i++ { - buf[pos + 4 + i] = 0x00; - } - return nil, 4 + paddedLen - } else if attribute.atrType == ATRRealm { - raw := []byte(attribute.strValue) - rawLen := len(raw); - paddedLen := ((len(raw) + 3) >> 2) << 2 - if paddedLen >= 256 { - return errors.New("invalid attribute size"), 0 - } - if len(buf) - pos < 4 + paddedLen { - return errors.New("invalid buffer size"), 0 - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRRealm); - buf[pos + 2] = 0x00 - buf[pos + 3] = byte(rawLen); - for i := 0; i < len(raw); i++ { - buf[pos + 4 + i] = raw[i]; - } - for i := len(raw); i < paddedLen; i++ { - buf[pos + 4 + i] = 0x00; - } - return nil, 4 + paddedLen - } else if attribute.atrType == ATRErrorCode { - if len(buf) - pos < 8 { - return errors.New("invalid buffer size"), 0 - } - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRErrorCode); - buf[pos + 2] = 0x00 - buf[pos + 3] = 0x04 - buf[pos + 4] = 0x00 - buf[pos + 5] = 0x00 - buf[pos + 6] = byte(attribute.intValue / 100) - buf[pos + 7] = byte(attribute.intValue % 100) - return nil, 8 - } else if attribute.atrType == ATRMessageIntegrity { - buf[pos + 1], buf[pos + 0] = setAttributeType(ATRMessageIntegrity); - buf[pos + 2] = 0; - buf[pos + 3] = 0x14; - key := md5.Sum([]byte("user:databag.dweb:pass")); - - // set hash size - lengthField0 := buf[2] - lengthField1 := buf[3] - hashLength := pos + 4 - buf[2] = byte((hashLength >> 8) % 256); - buf[3] = byte(hashLength % 256); - hash := getHmac(key[:], buf[0:pos]); - buf[2] = lengthField0 - buf[3] = lengthField1 - - for i := 0; i < 20; i++ { - buf[4 + pos + i] = hash[i]; - } - - return nil, 24 - } else { - fmt.Println("UNKNOWN!"); - } - return nil, 8 -} - -func getHmac(key []byte, data []byte) []byte { - mac := hmac.New(sha1.New, key) - mac.Write(data) - return mac.Sum(nil) -} diff --git a/net/server/internal/sturn/message.go b/net/server/internal/sturn/message.go deleted file mode 100644 index 25901a71..00000000 --- a/net/server/internal/sturn/message.go +++ /dev/null @@ -1,480 +0,0 @@ -package sturn - -import ( - "net" - "fmt" - "errors" - "bytes" - "strings" - "strconv" -) - -func readMessage(buf []byte) (error, *SturnMessage) { - if len(buf) < 20 { - return errors.New("invalid header size"), nil - } - if buf[0] & 0xC0 != 0 { - return errors.New("invalid message prefix"), nil - } - magic := []byte{0x21, 0x12, 0xA4, 0x42 } - if !bytes.Equal(magic, buf[4:8]) { - return errors.New("invalid message cookie"), nil - } - atrLength := int(buf[2]) * 256 + int(buf[3]) - if atrLength + 20 != len(buf) { - return errors.New("invalid message length"), nil - } - - class, method := getMessageType(buf[0], buf[1]); - transaction := buf[8:20]; - - var attributes []SturnAttribute - var pos int = 0 - for pos < atrLength { - err, attr, n := readAttribute(buf, pos + 20) - if err != nil { - return err, nil - } - pos += n - attributes = append(attributes, *attr); - } - - return nil, &SturnMessage{ - class: class, - method: method, - transaction: transaction, - attributes: attributes, - } -} - -func writeMessage(msg *SturnMessage, buf []byte) (error, int) { - if len(buf) < 20 { - return errors.New("invalid buffer length"), 0 - } - - // set prefix - buf[0], buf[1] = setMessageType(msg.class, msg.method) - - // init size - buf[2] = 0x00 - buf[3] = 0x00 - - // set cookie - buf[4] = 0x21 - buf[5] = 0x12 - buf[6] = 0xA4 - buf[7] = 0x42 - - // set transaction - for i := 0; i < 12; i++ { - buf[8 + i] = msg.transaction[i]; - } - - // set each attribute - pos := 0 - for _, attribute := range msg.attributes { - err, n := writeAttribute(&attribute, buf, 20 + pos); - if err != nil { - return err, 0 - } - pos += n; - - // set size - buf[2] = byte((pos >> 8) % 256); - buf[3] = byte(pos % 256); - } - - return nil, pos + 20; -} - -func (s *Sturn) handleMessage(buf []byte, addr net.Addr) { - - err, msg := readMessage(buf); - if err != nil { - fmt.Println(err, addr.String(), buf); - return - } - if msg == nil { - return - } - - if msg.class == CLSRequest && msg.method == MEHBinding { - fmt.Println("stun/turn binding request"); - s.handleBindingRequest(msg, addr); - } else if msg.class == CLSRequest && msg.method == MEHAllocate { - fmt.Println("stun/turn allocate request"); - s.handleAllocateRequest(msg, addr); - } else if msg.class == CLSRequest && msg.method == MEHRefresh { - fmt.Println("stun/turn refresh request"); - s.handleRefreshRequest(msg, addr); - } else if msg.class == CLSRequest && msg.method == MEHCreatePermission { - fmt.Println("stun/turn create permission request"); - s.handleCreatePermissionRequest(msg, addr); - } else if msg.class == CLSIndication && msg.method == MEHSend { - fmt.Println("stun/turn send"); - s.handleSendIndication(msg, addr, buf); - } else { - fmt.Println("unsupported message", buf); - } -} - -func (s *Sturn) sendRequestError(msg *SturnMessage, addr net.Addr, code int32) { - var attributes []SturnAttribute - attributes = append(attributes, SturnAttribute{ - atrType: ATRErrorCode, - intValue: code, - }) - attributes = append(attributes, SturnAttribute{ - atrType: ATRNonce, - strValue: "", - }) - attributes = append(attributes, SturnAttribute{ - atrType: ATRRealm, - strValue: "databag.dweb", - }) - response := &SturnMessage{ - class: CLSError, - method: msg.method, - transaction: msg.transaction, - attributes: attributes, - }; - err, n := writeMessage(response, s.buf); - if err != nil { - fmt.Printf("failed to write stun response"); - } else { - (*s.conn).WriteTo(s.buf[:n], addr); - } -} - -func (s *Sturn) handleCreatePermissionRequest(msg *SturnMessage, addr net.Addr) { - - username := getAttribute(msg, ATRUsername) - if username == nil { - fmt.Println("no username", addr.String(), msg.transaction); - s.sendRequestError(msg, addr, 401) - return - } - permission := getAttribute(msg, ATRXorPeerAddress) - if permission == nil { - fmt.Println("no peer"); - s.sendRequestError(msg, addr, 400) - return - } - - s.sync.Lock(); - defer s.sync.Unlock(); - _, set := sturn.sessions[username.strValue] - if !set { - fmt.Println("no session", addr.String()); - s.sendRequestError(msg, addr, 401) - return - } - - source := addr.String() - allocation, found := s.allocations[source] - if !found { - fmt.Println("no allocation"); - s.sendRequestError(msg, addr, 400) - return - } - - allocation.permissions = append(allocation.permissions, permission.strValue); - - var attributes []SturnAttribute - attributes = append(attributes, SturnAttribute{ - atrType: ATRMessageIntegrity, - }); - - response := &SturnMessage{ - class: CLSResponse, - method: MEHCreatePermission, - transaction: msg.transaction, - attributes: attributes, - }; - err, n := writeMessage(response, s.buf); - if err != nil { - fmt.Printf("failed to write stun response"); - } else { - (*s.conn).WriteTo(s.buf[:n], addr); - } - return -} - -func (s *Sturn) handleSendIndication(msg *SturnMessage, addr net.Addr, buf []byte) { - - peer := getAttribute(msg, ATRXorPeerAddress) - if peer == nil { - fmt.Println("no peer"); - return - } - - data := getAttribute(msg, ATRData) - if data == nil { - fmt.Println("no data"); - return - } - - s.sync.Lock(); - defer s.sync.Unlock(); - source := addr.String() - allocation, found := s.allocations[source] - if !found { - fmt.Println("no allocation"); - return - } - - set := false - for _, permission := range allocation.permissions { - if permission == peer.strValue { - address := fmt.Sprintf("%s:%d", peer.strValue, peer.intValue) - dst, err := net.ResolveUDPAddr("udp", address) - if err != nil { - fmt.Println("no resolve"); - return - } - - set = true - fmt.Println("stun/turn data", dst.String()); - _, err = allocation.conn.WriteTo(data.binValue, dst) - if err != nil { - fmt.Println("write error"); - } - } - } - if !set { - fmt.Println("dropped indication"); - } -} - -func (s *Sturn) handleBindingRequest(msg *SturnMessage, addr net.Addr) { - - address := strings.Split(addr.String(), ":") - ip := address[0]; - port, _ := strconv.Atoi(address[1]); - var attributes []SturnAttribute - attributes = append(attributes, SturnAttribute{ - atrType: ATRXorMappedAddress, - byteValue: FAMIPv4, - intValue: int32(port), - strValue: ip, - }); - response := &SturnMessage{ - class: CLSResponse, - method: MEHBinding, - transaction: msg.transaction, - attributes: attributes, - }; - err, n := writeMessage(response, s.buf); - if err != nil { - fmt.Printf("failed to write stun response"); - } else { - (*s.conn).WriteTo(s.buf[:n], addr); - } - return -} - -func (s *Sturn) handleRefreshRequest(msg *SturnMessage, addr net.Addr) { - - response := &SturnMessage{ - class: CLSResponse, - method: MEHRefresh, - transaction: msg.transaction, - attributes: []SturnAttribute{}, - }; - err, n := writeMessage(response, s.buf); - if err != nil { - fmt.Printf("failed to write stun response"); - } else { - (*s.conn).WriteTo(s.buf[:n], addr); - } - return -} - -func (s *Sturn) setAllocation(addr net.Addr, transaction []byte, response []byte, port int, conn net.PacketConn, session *SturnSession) (*SturnAllocation) { - source := addr.String() - allocation := &SturnAllocation{} - allocation.port = port - allocation.conn = conn - allocation.source = source - allocation.addr = addr - allocation.transaction = make([]byte, len(transaction)) - copy(allocation.transaction, transaction) - allocation.response = make([]byte, len(response)) - copy(allocation.response, response) - s.allocations[source] = allocation - return allocation -} - -func (s *Sturn) getAllocation(source string, transaction []byte, session *SturnSession) (*SturnAllocation, error) { - for _, allocation := range s.allocations { - if allocation.source == source { - if len(allocation.transaction) == len(transaction) { - match := true - for i := 0; i < len(transaction); i++ { - if transaction[i] != allocation.transaction[i] { - match = false - } - } - if match { - return allocation, nil - } - } - return nil, errors.New("5-tuple collision") - } - } - return nil, nil -} - -func (s *Sturn) handleAllocateRequest(msg *SturnMessage, addr net.Addr) { - - username := getAttribute(msg, ATRUsername) - if username == nil { - fmt.Println("no username", addr.String(), msg.transaction); - s.sendRequestError(msg, addr, 401) - return - } - - s.sync.Lock(); - defer s.sync.Unlock(); - session, set := sturn.sessions[username.strValue] - if !set { - fmt.Println("no session", addr.String()); - s.sendRequestError(msg, addr, 401) - return - } - - allocation, collision := s.getAllocation(addr.String(), msg.transaction, session) - if collision != nil { - fmt.Println("5tuple collision", addr.String()) - s.sendRequestError(msg, addr, 403) - return - } - if allocation != nil { - fmt.Println("dup request", addr.String()) - (*s.conn).WriteTo(allocation.response, addr) - return - } - - relayPort, err := s.getRelayPort() - if err != nil { - fmt.Println(err); - s.sendRequestError(msg, addr, 508) - return - } - - connAddress := fmt.Sprintf(":%d", relayPort) - conn, connErr := net.ListenPacket("udp", connAddress) - if connErr != nil { - s.sendRequestError(msg, addr, 500) - return - } - - address := strings.Split(addr.String(), ":") - ip := address[0]; - port, _ := strconv.Atoi(address[1]); - var attributes []SturnAttribute - attributes = append(attributes, SturnAttribute{ - atrType: ATRXorRelayedAddress, - byteValue: FAMIPv4, - intValue: int32(relayPort), - //strValue: "192.168.13.233", - strValue: "98.234.232.221", - }); - attributes = append(attributes, SturnAttribute{ - atrType: ATRLifetime, - intValue: int32(600), - }); - attributes = append(attributes, SturnAttribute{ - atrType: ATRXorMappedAddress, - byteValue: FAMIPv4, - intValue: int32(port), - strValue: ip, - }); - attributes = append(attributes, SturnAttribute{ - atrType: ATRMessageIntegrity, - }); - response := &SturnMessage{ - class: CLSResponse, - method: MEHAllocate, - transaction: msg.transaction, - attributes: attributes, - }; - - err, n := writeMessage(response, s.buf) - if err != nil { - fmt.Printf("failed to write stun response") - } else { - allocation := s.setAllocation(addr, msg.transaction, s.buf[:n], relayPort, conn, session) - (*s.conn).WriteTo(s.buf[:n], addr) - fmt.Println("allocated: ", addr.String()) - go s.relay(allocation); - } - return -} - -func getAttribute(msg *SturnMessage, atrType int) (attr *SturnAttribute) { - for i, _ := range msg.attributes { - if msg.attributes[i].atrType == atrType { - attr = &msg.attributes[i]; - } - } - return -} - -func (s *Sturn) relay(allocation *SturnAllocation) { - data := make([]byte, SturnMaxSize) - buf := make([]byte, SturnMaxSize) - for { - n, addr, err := allocation.conn.ReadFrom(data) - if err != nil { - fmt.Println(err) - // CLEANUP ALLOCATION - return - } - - s.sync.Lock(); - split := strings.Split(addr.String(), ":") - ip := split[0] - port, _ := strconv.Atoi(split[1]); - set := false - for _, permission := range allocation.permissions { - if permission == ip { - - var attributes []SturnAttribute - attributes = append(attributes, SturnAttribute{ - atrType: ATRXorPeerAddress, - strValue: ip, - intValue: int32(port), - }) - attributes = append(attributes, SturnAttribute{ - atrType: ATRData, - binValue: data[:n], - }) - - relay := &SturnMessage{ - class: CLSIndication, - method: MEHData, - transaction: []byte{ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, - attributes: attributes, - }; - - err, l := writeMessage(relay, buf) - if err != nil { - fmt.Println("no resolve"); - } else { - fmt.Println("---- stun/turn relay", allocation.addr.String()); - _, err := allocation.conn.WriteTo(buf[:l], allocation.addr); - set = true - if err != nil { - fmt.Println("writeto failed"); - } - } - } - } - if !set { - fmt.Println("dropped relay"); - } - s.sync.Unlock(); - } -} - diff --git a/net/server/internal/sturn/sturn.go b/net/server/internal/sturn/sturn.go deleted file mode 100644 index f3366170..00000000 --- a/net/server/internal/sturn/sturn.go +++ /dev/null @@ -1,171 +0,0 @@ -package sturn - -import ( -// "encoding/json" - "encoding/hex" - "sync" - "github.com/theckman/go-securerandom" -// "time" - "errors" - "fmt" - "net" -) - -var sturn *Sturn -const SturnKeepAlive = 3600 -const SturnMaxSize = 1024 -const SturnMaxBindFail = 16 -const SturnNonceSize = 8 -const SturnPassSize = 8 - -type SturnAllocation struct { - source string - transaction []byte - response []byte - port int - permissions []string - conn net.PacketConn - addr net.Addr -} - -type SturnSession struct { - user string - auth string - relayPorts []int -} - -type Sturn struct { - sync sync.Mutex - sessionId int - sessions map[string]*SturnSession - closing bool - port int - conn *net.PacketConn - closed chan bool - buf []byte - publicIp string - relayStart int - relayCount int - relayPorts map[int]bool - relayIndex int - allocations map[string]*SturnAllocation -} - -func Listen(port int, relayStart int, relayCount int) (error) { - - if (sturn != nil) { - (*sturn.conn).Close() - <-sturn.closed - sturn = nil - } - - address := fmt.Sprintf(":%d", port) - conn, err := net.ListenPacket("udp", address) - if err != nil { - return err - } - - relayPorts := make(map[int]bool) - for i := 0; i < relayCount; i++ { - relayPorts[i] = true - } - - sturn = &Sturn{ - sessionId: 0, - closing: false, - port: port, - relayStart: relayStart, - relayCount: relayCount, - relayPorts: relayPorts, - conn: &conn, - buf: make([]byte, SturnMaxSize), - sessions: make(map[string]*SturnSession), - allocations: make(map[string]*SturnAllocation), - } - - go sturn.serve(conn); - return nil -} - -func Close() { - if (sturn != nil) { - (*sturn.conn).Close() - <-sturn.closed - sturn = nil - } -} - -func (s *Sturn) serve(conn net.PacketConn) { - for { - buf := make([]byte, SturnMaxSize) - n, addr, err := conn.ReadFrom(buf) - if err != nil { - fmt.Println(err) - return - } - s.handleMessage(buf[:n], addr); - } - - s.sync.Lock() - s.closing = true - for _, session := range s.sessions { - // TODO cleanup session - fmt.Println(session) - } - s.sync.Unlock() - - s.closed <- true -} - -func TestSession() { - if sturn != nil { - sturn.sync.Lock() - defer sturn.sync.Unlock() - if sturn.closing { - return - } - session := &SturnSession{ - user: "user", - auth: "pass", - } - sturn.sessions["user"] = session - } -} - -func (s *Sturn) addSession() (*SturnSession, error) { - s.sync.Lock() - defer s.sync.Unlock() - if !s.closing { - return nil, errors.New("closing sturn") - } - s.sessionId += 1 - user := fmt.Sprintf("%08d", s.sessionId) - authBin, authErr := securerandom.Bytes(SturnPassSize) - if authErr != nil { - return nil, authErr - } - session := &SturnSession{ - user: user, - auth: hex.EncodeToString(authBin), - } - s.sessions[user] = session - return session, nil -} - -func (s *Sturn) getRelayPort() (int, error) { - s.relayIndex += 1; - for i := 0; i < s.relayCount; i++ { - key := (i + s.relayIndex) % s.relayCount; - if s.relayPorts[key] { - s.relayPorts[key] = false - return s.relayStart + key, nil - } - } - return 0, errors.New("no available relay port") -} - -func (s *Sturn) setRelayPort(port int) { - key := port - s.relayStart - s.relayPorts[key] = true -} - diff --git a/net/server/internal/sturn/types.go b/net/server/internal/sturn/types.go deleted file mode 100644 index 9a2f2547..00000000 --- a/net/server/internal/sturn/types.go +++ /dev/null @@ -1,334 +0,0 @@ -package sturn - -const CLSUnknown = 0 -const CLSRequest = 1 -const CLSResponse = 2 -const CLSError = 3 -const CLSIndication = 4 - -const ATRUnknown = 0 -const ATRMappedAddress = 1 -const ATRUsername = 2 -const ATRMessageIntegrity = 3 -const ATRErrorCode = 4 -const ATRUnknownAttributes = 5 -const ATRRealm = 6 -const ATRNonce = 7 -const ATRXorMappedAddress = 8 -const ATRSoftware = 9 -const ATRAlternateServer = 10 -const ATRFingerprint = 11 -const ATRMessageIntegritySha256 = 12 -const ATRPasswordAlgorithm = 13 -const ATRUserHash = 14 -const ATRPasswordAlgorithms = 15 -const ATRAlternateDomain = 16 -const ATRChannelNumber = 17 -const ATRLifetime = 18 -const ATRXorPeerAddress = 19 -const ATRData = 20 -const ATRXorRelayedAddress = 21 -const ATREvenPort = 22 -const ATRRequestedTransport = 23 -const ATRDontFragment = 24 -const ATRReservationToken = 25 -const ATRAdditionalAddressFamily = 26 -const ATRAddressErrorCode = 27 -const ATRAddressIcmp = 28 -const ATRRequestedAddressFamily = 29 - -const MEHUnknown = 0 -const MEHBinding = 1 -const MEHAllocate = 2 -const MEHRefresh = 3 -const MEHSend = 4 -const MEHData = 5 -const MEHCreatePermission = 6 -const MEHChannelBind = 7 - -const FAMIPv4 = 1 -const FAMIPv6 = 2 - -type SturnAttribute struct { - atrType int - byteValue byte - strValue string - intValue int32 - binValue []byte -} - -type SturnMessage struct { - class int - method int - transaction []byte - attributes []SturnAttribute -} - -func getMessageType(b0 byte, b1 byte) (int, int) { - - if b0 == 0x00 && b1 == 0x01 { - return CLSRequest, MEHBinding - } - if b0 == 0x01 && b1 == 0x01 { - return CLSResponse, MEHBinding - } - if b0 == 0x01 && b1 == 0x11 { - return CLSError, MEHBinding - } - if b0 == 0x00 && b1 == 0x03 { - return CLSRequest, MEHAllocate - } - if b0 == 0x01 && b1 == 0x03 { - return CLSResponse, MEHAllocate - } - if b0 == 0x01 && b1 == 0x13 { - return CLSError, MEHAllocate - } - if b0 == 0x00 && b1 == 0x04 { - return CLSRequest, MEHRefresh - } - if b0 == 0x01 && b1 == 0x04 { - return CLSResponse, MEHRefresh - } - if b0 == 0x01 && b1 == 0x14 { - return CLSError, MEHRefresh - } - if b0 == 0x00 && b1 == 0x08 { - return CLSRequest, MEHCreatePermission - } - if b0 == 0x01 && b1 == 0x08 { - return CLSResponse, MEHCreatePermission - } - if b0 == 0x01 && b1 == 0x18 { - return CLSError, MEHCreatePermission - } - if b0 == 0x00 && b1 == 0x09 { - return CLSRequest, MEHChannelBind - } - if b0 == 0x01 && b1 == 0x09 { - return CLSResponse, MEHChannelBind - } - if b0 == 0x01 && b1 == 0x19 { - return CLSError, MEHChannelBind - } - if b0 == 0x00 && b1 == 0x16 { - return CLSIndication, MEHSend - } - if b0 == 0x00 && b1 == 0x17 { - return CLSIndication, MEHData - } - return CLSUnknown, MEHUnknown -} - -func setMessageType(class int, method int) (byte, byte) { - if class == CLSRequest && method == MEHBinding { - return 0x00, 0x01 - } - if class == CLSResponse && method == MEHBinding { - return 0x01, 0x01 - } - if class == CLSError && method == MEHBinding { - return 0x01, 0x11 - } - if class == CLSRequest && method == MEHAllocate { - return 0x00, 0x03 - } - if class == CLSResponse && method == MEHAllocate { - return 0x01, 0x03 - } - if class == CLSError && method == MEHAllocate { - return 0x01, 0x13 - } - if class == CLSResponse && method == MEHCreatePermission { - return 0x01, 0x08 - } - if class == CLSError && method == MEHCreatePermission { - return 0x01, 0x18 - } - if class == CLSIndication && method == MEHData { - return 0x00, 0x17 - } - return 0x00, 0x00 -} - -func getAttributeType(b0 byte, b1 byte) (int) { - if b1 == 0x01 && b0 == 0x00 { - return ATRMappedAddress - } - if b1 == 0x06 && b0 == 0x00 { - return ATRUsername - } - if b1 == 0x08 && b0 == 0x00 { - return ATRMessageIntegrity - } - if b1 == 0x09 && b0 == 0x00 { - return ATRErrorCode - } - if b1 == 0x0A && b0 == 0x00 { - return ATRUnknownAttributes - } - if b1 == 0x14 && b0 == 0x00 { - return ATRRealm - } - if b1 == 0x15 && b0 == 0x00 { - return ATRNonce - } - if b1 == 0x20 && b0 == 0x00 { - return ATRXorMappedAddress - } - if b1 == 0x22 && b0 == 0x80 { - return ATRSoftware - } - if b1 == 0x23 && b0 == 0x80 { - return ATRAlternateServer - } - if b1 == 0x28 && b0 == 0x80 { - return ATRFingerprint - } - if b1 == 0x1C && b0 == 0x00 { - return ATRMessageIntegritySha256 - } - if b1 == 0x1D && b0 == 0x00 { - return ATRPasswordAlgorithms - } - if b1 == 0x1E && b0 == 0x00 { - return ATRUserHash - } - if b1 == 0x02 && b0 == 0x80 { - return ATRPasswordAlgorithms - } - if b1 == 0x03 && b0 == 0x80 { - return ATRAlternateDomain - } - if b1 == 0x0C && b0 == 0x00 { - return ATRChannelNumber - } - if b1 == 0x0D && b0 == 0x00 { - return ATRLifetime - } - if b1 == 0x12 && b0 == 0x00 { - return ATRXorPeerAddress - } - if b1 == 0x13 && b0 == 0x00 { - return ATRData - } - if b1 == 0x16 && b0 == 0x00 { - return ATRXorRelayedAddress - } - if b1 == 0x17 && b0 == 0x00 { - return ATRRequestedAddressFamily - } - if b1 == 0x18 && b0 == 0x00 { - return ATREvenPort - } - if b1 == 0x19 && b0 == 0x00 { - return ATRRequestedTransport - } - if b1 == 0x1A && b0 == 0x00 { - return ATRDontFragment - } - if b1 == 0x22 && b0 == 0x00 { - return ATRReservationToken - } - if b1 == 0x00 && b0 == 0x80 { - return ATRAdditionalAddressFamily - } - if b1 == 0x01 && b0 == 0x80 { - return ATRAddressErrorCode - } - if b1 == 0x04 && b0 == 0x80 { - return ATRAddressIcmp - } - return ATRUnknown -} - -func setAttributeType(atrType int) (byte, byte) { - if atrType == ATRMappedAddress { - return 0x01, 0x00 - } - if atrType == ATRUsername { - return 0x06, 0x00 - } - if atrType == ATRMessageIntegrity { - return 0x08, 0x00 - } - if atrType == ATRErrorCode { - return 0x09, 0x00 - } - if atrType == ATRUnknownAttributes { - return 0x0A, 0x00 - } - if atrType == ATRRealm { - return 0x14, 0x00 - } - if atrType == ATRNonce { - return 0x15, 0x00 - } - if atrType == ATRXorMappedAddress { - return 0x20, 0x00 - } - if atrType == ATRSoftware { - return 0x22, 0x80 - } - if atrType == ATRAlternateServer { - return 0x23, 0x80 - } - if atrType == ATRFingerprint { - return 0x28, 0x80 - } - if atrType == ATRMessageIntegritySha256 { - return 0x1C, 0x00 - } - if atrType == ATRPasswordAlgorithms { - return 0x1D, 0x00 - } - if atrType == ATRUserHash { - return 0x1E, 0x00 - } - if atrType == ATRPasswordAlgorithms { - return 0x02, 0x80 - } - if atrType == ATRAlternateDomain { - return 0x03, 0x80 - } - if atrType == ATRChannelNumber { - return 0x0C, 0x00 - } - if atrType == ATRLifetime { - return 0x0D, 0x00 - } - if atrType == ATRXorPeerAddress { - return 0x12, 0x00 - } - if atrType == ATRData { - return 0x13, 0x00 - } - if atrType == ATRXorRelayedAddress { - return 0x16, 0x00 - } - if atrType == ATRRequestedAddressFamily { - return 0x17, 0x00 - } - if atrType == ATREvenPort { - return 0x18, 0x00 - } - if atrType == ATRRequestedTransport { - return 0x19, 0x00 - } - if atrType == ATRDontFragment { - return 0x1A, 0x00 - } - if atrType == ATRReservationToken { - return 0x22, 0x00 - } - if atrType == ATRAdditionalAddressFamily { - return 0x00, 0x80 - } - if atrType == ATRAddressErrorCode { - return 0x01, 0x80 - } - if atrType == ATRAddressIcmp { - return 0x04, 0x80 - } - return 0x00, 0x00 -}