50 lines
1.4 KiB
Go
50 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// RequestConfig запрашивает WireGuard конфиг через DTLS-соединение.
|
|
func RequestConfig(conn net.Conn, localPort, deviceID, password string) (string, error) {
|
|
payload := fmt.Sprintf("GETCONF:%s|%s|%s", localPort, deviceID, password)
|
|
if _, err := conn.Write([]byte(payload)); err != nil {
|
|
return "", fmt.Errorf("отправка GETCONF: %w", err)
|
|
}
|
|
|
|
b := make([]byte, 4096)
|
|
if err := conn.SetReadDeadline(time.Now().Add(15 * time.Second)); err != nil {
|
|
return "", fmt.Errorf("установка дедлайна: %w", err)
|
|
}
|
|
n, err := conn.Read(b)
|
|
_ = conn.SetReadDeadline(time.Time{})
|
|
if err != nil {
|
|
return "", fmt.Errorf("чтение ответа конфига: %w", err)
|
|
}
|
|
|
|
resp := string(b[:n])
|
|
if resp == "NOCONF" {
|
|
return "", nil
|
|
}
|
|
|
|
if strings.HasPrefix(resp, "DENIED:") {
|
|
reason := strings.TrimPrefix(resp, "DENIED:")
|
|
switch reason {
|
|
case "wrong_password":
|
|
return "", fmt.Errorf("FATAL_AUTH: неверный пароль подключения")
|
|
case "expired":
|
|
return "", fmt.Errorf("FATAL_AUTH: срок действия пароля истёк")
|
|
case "device_mismatch":
|
|
return "", fmt.Errorf("FATAL_AUTH: пароль привязан к другому устройству")
|
|
default:
|
|
return "", fmt.Errorf("FATAL_AUTH: доступ запрещён (%s)", reason)
|
|
}
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
|