109 lines
2.6 KiB
Go
109 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type Operator struct {
|
|
ID string
|
|
Conn net.Conn
|
|
Authenticated bool
|
|
OperatorIP net.IPAddr
|
|
}
|
|
|
|
// Replace the map and mutex with sync.Map
|
|
var Operators sync.Map
|
|
|
|
func AuthenticateOperator(operatorConn net.Conn, serverHashedPassword string) (string, bool) {
|
|
buffer := make([]byte, 1024)
|
|
n, err := operatorConn.Read(buffer)
|
|
if err != nil {
|
|
log.Printf("Error reading from client: %v", err)
|
|
return "", false
|
|
}
|
|
authMessage := string(buffer[:n])
|
|
|
|
if !strings.HasPrefix(authMessage, "AUTH:") {
|
|
log.Printf("Invalid message format")
|
|
return "", false
|
|
}
|
|
|
|
creds := strings.SplitN(authMessage, ":", 3)
|
|
if len(creds) != 3 {
|
|
log.Printf("Invalid auth message format")
|
|
return "", false
|
|
}
|
|
operatorID := creds[1]
|
|
operatorPass := creds[2]
|
|
|
|
operatorHashedPass := HashPassword(&operatorPass)
|
|
|
|
if operatorHashedPass == serverHashedPassword {
|
|
log.Printf("Operator %s connected", operatorID)
|
|
|
|
// Send success message
|
|
operatorConn.Write([]byte("AUTH_OK"))
|
|
|
|
// Add operator to map
|
|
AddOperator(operatorID, operatorConn)
|
|
return operatorID, true
|
|
} else {
|
|
operatorConn.Write([]byte("AUTH_FAILED"))
|
|
log.Printf("Operator %s failed authentication", operatorID)
|
|
return "", false
|
|
}
|
|
}
|
|
|
|
// Add operator to map
|
|
func AddOperator(operatorID string, operatorConn net.Conn) {
|
|
// Check if operator already exists
|
|
if _, exists := Operators.Load(operatorID); exists {
|
|
log.Printf("Operator %s already connected", operatorID)
|
|
return
|
|
}
|
|
|
|
addr, ok := operatorConn.RemoteAddr().(*net.TCPAddr)
|
|
var operatorIP net.IPAddr
|
|
if ok {
|
|
operatorIP = net.IPAddr{IP: addr.IP}
|
|
} else {
|
|
log.Printf("Failed to parse IP address for operator %s", operatorID)
|
|
}
|
|
|
|
operator := &Operator{
|
|
ID: operatorID,
|
|
Conn: operatorConn,
|
|
Authenticated: true,
|
|
OperatorIP: operatorIP,
|
|
}
|
|
|
|
Operators.Store(operatorID, operator)
|
|
// log.Printf("Operator %s added to the list", operatorID)
|
|
}
|
|
|
|
// Delete operator on disconnect
|
|
func DeleteOperator(operatorID string) {
|
|
// LoadAndDelete checks existence and deletes in one atomic operation
|
|
if _, exists := Operators.LoadAndDelete(operatorID); exists {
|
|
log.Printf("Operator %s removed from the list", operatorID)
|
|
} else {
|
|
log.Printf("Operator %s not found in list", operatorID)
|
|
}
|
|
}
|
|
|
|
// Get operator connection by his ID
|
|
func GetOperatorConn(operatorID string) (net.Conn, bool) {
|
|
value, exists := Operators.Load(operatorID)
|
|
if !exists {
|
|
log.Printf("Operator %s not found", operatorID)
|
|
return nil, false
|
|
}
|
|
|
|
operator := value.(*Operator)
|
|
// log.Printf("Operator found, returning his connection")
|
|
return operator.Conn, true
|
|
}
|