mirror of
https://github.com/0x1d/rcond.git
synced 2025-12-14 18:25:21 +01:00
feat: add backend for configuring WiFi STA
This commit is contained in:
@@ -6,15 +6,23 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/0x1d/rcond/pkg/network"
|
||||
network "github.com/0x1d/rcond/pkg/network"
|
||||
"github.com/0x1d/rcond/pkg/user"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type configureAPRequest struct {
|
||||
Interface string `json:"interface"`
|
||||
SSID string `json:"ssid"`
|
||||
Password string `json:"password"`
|
||||
Interface string `json:"interface"`
|
||||
SSID string `json:"ssid"`
|
||||
Password string `json:"password"`
|
||||
Autoconnect bool `json:"autoconnect"`
|
||||
}
|
||||
|
||||
type configureSTARequest struct {
|
||||
Interface string `json:"interface"`
|
||||
SSID string `json:"ssid"`
|
||||
Password string `json:"password"`
|
||||
Autoconnect bool `json:"autoconnect"`
|
||||
}
|
||||
|
||||
type networkUpRequest struct {
|
||||
@@ -40,6 +48,30 @@ func writeError(w http.ResponseWriter, message string, code int) {
|
||||
json.NewEncoder(w).Encode(errorResponse{Error: message})
|
||||
}
|
||||
|
||||
func HandleConfigureSTA(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var req configureSTARequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeError(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Configuring station on interface %s", req.Interface)
|
||||
uuid, err := network.ConfigureSTA(req.Interface, req.SSID, req.Password, req.Autoconnect)
|
||||
if err != nil {
|
||||
log.Printf("Failed to configure station on interface %s: %v", req.Interface, err)
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{"uuid": uuid})
|
||||
}
|
||||
|
||||
func HandleConfigureAP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
@@ -53,7 +85,7 @@ func HandleConfigureAP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
log.Printf("Configuring access point on interface %s", req.Interface)
|
||||
uuid, err := network.ConfigureAP(req.Interface, req.SSID, req.Password)
|
||||
uuid, err := network.ConfigureAP(req.Interface, req.SSID, req.Password, req.Autoconnect)
|
||||
if err != nil {
|
||||
log.Printf("Failed to configure access point on interface %s: %v", req.Interface, err)
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
|
||||
@@ -59,6 +59,7 @@ func (s *Server) verifyToken(next http.HandlerFunc) http.HandlerFunc {
|
||||
func (s *Server) RegisterRoutes() {
|
||||
s.router.HandleFunc("/health", s.healthHandler).Methods(http.MethodGet)
|
||||
s.router.HandleFunc("/network/ap", s.verifyToken(HandleConfigureAP)).Methods(http.MethodPost)
|
||||
s.router.HandleFunc("/network/sta", s.verifyToken(HandleConfigureSTA)).Methods(http.MethodPost)
|
||||
s.router.HandleFunc("/network/interface/{interface}", s.verifyToken(HandleNetworkUp)).Methods(http.MethodPut)
|
||||
s.router.HandleFunc("/network/interface/{interface}", s.verifyToken(HandleNetworkDown)).Methods(http.MethodDelete)
|
||||
s.router.HandleFunc("/network/connection/{uuid}", s.verifyToken(HandleNetworkRemove)).Methods(http.MethodDelete)
|
||||
|
||||
@@ -31,13 +31,28 @@ type ConnectionConfig struct {
|
||||
IPv6Method string
|
||||
}
|
||||
|
||||
// DefaultAPConfig returns a default access point configuration
|
||||
func DefaultAPConfig(uuid uuid.UUID, ssid string, password string) *ConnectionConfig {
|
||||
func DefaultSTAConfig(uuid uuid.UUID, ssid string, password string, autoconnect bool) *ConnectionConfig {
|
||||
return &ConnectionConfig{
|
||||
Type: "802-11-wireless",
|
||||
UUID: uuid.String(),
|
||||
ID: ssid,
|
||||
AutoConnect: true,
|
||||
AutoConnect: autoconnect,
|
||||
SSID: ssid,
|
||||
Mode: "infrastructure",
|
||||
KeyMgmt: "wpa-psk",
|
||||
PSK: password,
|
||||
IPv4Method: "auto",
|
||||
IPv6Method: "ignore",
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultAPConfig returns a default access point configuration
|
||||
func DefaultAPConfig(uuid uuid.UUID, ssid string, password string, autoconnect bool) *ConnectionConfig {
|
||||
return &ConnectionConfig{
|
||||
Type: "802-11-wireless",
|
||||
UUID: uuid.String(),
|
||||
ID: ssid,
|
||||
AutoConnect: autoconnect,
|
||||
SSID: ssid,
|
||||
Mode: "ap",
|
||||
Band: "bg",
|
||||
@@ -219,8 +234,16 @@ func GetConnectionPath(conn *dbus.Conn, connUUID string) (dbus.ObjectPath, error
|
||||
// Takes a D-Bus connection, UUID string, SSID string, and password string as arguments.
|
||||
// Returns the D-Bus object path of the new connection profile.
|
||||
// Returns an error if the connection creation fails.
|
||||
func AddAccessPointConnection(conn *dbus.Conn, uuid uuid.UUID, ssid string, password string) (dbus.ObjectPath, error) {
|
||||
return AddConnectionWithConfig(conn, DefaultAPConfig(uuid, ssid, password))
|
||||
func AddAccessPointConnection(conn *dbus.Conn, uuid uuid.UUID, ssid string, password string, autoconnect bool) (dbus.ObjectPath, error) {
|
||||
return AddConnectionWithConfig(conn, DefaultAPConfig(uuid, ssid, password, autoconnect))
|
||||
}
|
||||
|
||||
// AddStationConnection creates a new NetworkManager connection profile for a WiFi station (client).
|
||||
// Takes a D-Bus connection, UUID string, SSID string, and password string as arguments.
|
||||
// Returns the D-Bus object path of the new connection profile.
|
||||
// Returns an error if the connection creation fails.
|
||||
func AddStationConnection(conn *dbus.Conn, uuid uuid.UUID, ssid string, password string, autoconnect bool) (dbus.ObjectPath, error) {
|
||||
return AddConnectionWithConfig(conn, DefaultSTAConfig(uuid, ssid, password, autoconnect))
|
||||
}
|
||||
|
||||
// AddConnectionWithConfig creates a new NetworkManager connection profile with the given configuration.
|
||||
@@ -233,6 +256,19 @@ func AddConnectionWithConfig(conn *dbus.Conn, cfg *ConnectionConfig) (dbus.Objec
|
||||
"/org/freedesktop/NetworkManager/Settings",
|
||||
)
|
||||
|
||||
var wirelessMap map[string]dbus.Variant
|
||||
if cfg.Mode == "ap" {
|
||||
wirelessMap = map[string]dbus.Variant{
|
||||
"mode": dbus.MakeVariant(cfg.Mode),
|
||||
"band": dbus.MakeVariant(cfg.Band),
|
||||
"channel": dbus.MakeVariant(cfg.Channel),
|
||||
}
|
||||
} else {
|
||||
wirelessMap = map[string]dbus.Variant{
|
||||
"ssid": dbus.MakeVariant([]byte(cfg.SSID)),
|
||||
}
|
||||
}
|
||||
|
||||
settingsMap := map[string]map[string]dbus.Variant{
|
||||
"connection": {
|
||||
"type": dbus.MakeVariant(cfg.Type),
|
||||
@@ -240,12 +276,7 @@ func AddConnectionWithConfig(conn *dbus.Conn, cfg *ConnectionConfig) (dbus.Objec
|
||||
"id": dbus.MakeVariant(cfg.ID),
|
||||
"autoconnect": dbus.MakeVariant(cfg.AutoConnect),
|
||||
},
|
||||
"802-11-wireless": {
|
||||
"ssid": dbus.MakeVariant([]byte(cfg.SSID)),
|
||||
"mode": dbus.MakeVariant(cfg.Mode),
|
||||
"band": dbus.MakeVariant(cfg.Band),
|
||||
"channel": dbus.MakeVariant(cfg.Channel),
|
||||
},
|
||||
"802-11-wireless": wirelessMap,
|
||||
"802-11-wireless-security": {
|
||||
"key-mgmt": dbus.MakeVariant(cfg.KeyMgmt),
|
||||
"psk": dbus.MakeVariant(cfg.PSK),
|
||||
@@ -318,15 +349,37 @@ func SetHostname(newHost string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// ConfigureSTA connects to a WiFi access point with the specified settings.
|
||||
// It takes the interface name, SSID and password as arguments.
|
||||
// A new connection with a generated UUID will be created.
|
||||
// Returns the UUID of the created connection and any error that occurred.
|
||||
func ConfigureSTA(iface string, ssid string, password string, autoconnect bool) (string, error) {
|
||||
uuid := uuid.New()
|
||||
|
||||
err := withDbus(func(conn *dbus.Conn) error {
|
||||
_, err := AddStationConnection(conn, uuid, ssid, password, autoconnect)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create station connection: %v", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return uuid.String(), nil
|
||||
}
|
||||
|
||||
// ConfigureAP creates a WiFi access point connection with the specified settings.
|
||||
// It takes the interface name, SSID and password as arguments.
|
||||
// A new connection with a generated UUID will be created.
|
||||
// Returns the UUID of the created connection and any error that occurred.
|
||||
func ConfigureAP(iface string, ssid string, password string) (string, error) {
|
||||
func ConfigureAP(iface string, ssid string, password string, autoconnect bool) (string, error) {
|
||||
uuid := uuid.New()
|
||||
|
||||
err := withDbus(func(conn *dbus.Conn) error {
|
||||
_, err := AddAccessPointConnection(conn, uuid, ssid, password)
|
||||
_, err := AddAccessPointConnection(conn, uuid, ssid, password, autoconnect)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create access point connection: %v", err)
|
||||
}
|
||||
Reference in New Issue
Block a user