Implement wpa_supplicant backend

This commit is contained in:
nemunaire 2026-01-01 22:19:57 +07:00
commit 04ada45f44
7 changed files with 874 additions and 2 deletions

View file

@ -0,0 +1,157 @@
package wpasupplicant
import (
"fmt"
"github.com/godbus/dbus/v5"
)
// BSS represents a wpa_supplicant BSS (Basic Service Set) object
type BSS struct {
path dbus.ObjectPath
conn *dbus.Conn
obj dbus.BusObject
}
// BSSProperties holds the properties of a BSS
type BSSProperties struct {
SSID []byte
BSSID []byte
Signal int16 // Signal strength in dBm
Frequency uint32 // Frequency in MHz
Privacy bool // Whether encryption is enabled
RSN map[string]dbus.Variant
WPA map[string]dbus.Variant
}
// NewBSS creates a new BSS instance
func NewBSS(conn *dbus.Conn, path dbus.ObjectPath) *BSS {
return &BSS{
path: path,
conn: conn,
obj: conn.Object(Service, path),
}
}
// GetProperties returns all properties of the BSS
func (b *BSS) GetProperties() (*BSSProperties, error) {
props := &BSSProperties{}
// Get SSID
if ssidProp, err := b.obj.GetProperty(BSSInterface + ".SSID"); err == nil {
if ssid, ok := ssidProp.Value().([]byte); ok {
props.SSID = ssid
}
}
// Get BSSID
if bssidProp, err := b.obj.GetProperty(BSSInterface + ".BSSID"); err == nil {
if bssid, ok := bssidProp.Value().([]byte); ok {
props.BSSID = bssid
}
}
// Get Signal
if signalProp, err := b.obj.GetProperty(BSSInterface + ".Signal"); err == nil {
if signal, ok := signalProp.Value().(int16); ok {
props.Signal = signal
}
}
// Get Frequency
if freqProp, err := b.obj.GetProperty(BSSInterface + ".Frequency"); err == nil {
if freq, ok := freqProp.Value().(uint16); ok {
props.Frequency = uint32(freq)
}
}
// Get Privacy
if privacyProp, err := b.obj.GetProperty(BSSInterface + ".Privacy"); err == nil {
if privacy, ok := privacyProp.Value().(bool); ok {
props.Privacy = privacy
}
}
// Get RSN (WPA2) information
if rsnProp, err := b.obj.GetProperty(BSSInterface + ".RSN"); err == nil {
if rsn, ok := rsnProp.Value().(map[string]dbus.Variant); ok {
props.RSN = rsn
}
}
// Get WPA information
if wpaProp, err := b.obj.GetProperty(BSSInterface + ".WPA"); err == nil {
if wpa, ok := wpaProp.Value().(map[string]dbus.Variant); ok {
props.WPA = wpa
}
}
return props, nil
}
// GetSSIDString returns the SSID as a string
func (b *BSS) GetSSIDString() (string, error) {
prop, err := b.obj.GetProperty(BSSInterface + ".SSID")
if err != nil {
return "", fmt.Errorf("failed to get SSID property: %v", err)
}
ssid, ok := prop.Value().([]byte)
if !ok {
return "", fmt.Errorf("SSID property is not a byte array")
}
return string(ssid), nil
}
// GetBSSIDString returns the BSSID as a formatted MAC address string
func (b *BSS) GetBSSIDString() (string, error) {
prop, err := b.obj.GetProperty(BSSInterface + ".BSSID")
if err != nil {
return "", fmt.Errorf("failed to get BSSID property: %v", err)
}
bssid, ok := prop.Value().([]byte)
if !ok || len(bssid) != 6 {
return "", fmt.Errorf("BSSID property is not a valid MAC address")
}
return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]), nil
}
// GetSignal returns the signal strength in dBm
func (b *BSS) GetSignal() (int16, error) {
prop, err := b.obj.GetProperty(BSSInterface + ".Signal")
if err != nil {
return 0, fmt.Errorf("failed to get Signal property: %v", err)
}
signal, ok := prop.Value().(int16)
if !ok {
return 0, fmt.Errorf("Signal property is not an int16")
}
return signal, nil
}
// DetermineSecurityType determines the security type based on BSS properties
func (p *BSSProperties) DetermineSecurityType() string {
// Check for WPA2 (RSN)
if len(p.RSN) > 0 {
return "psk"
}
// Check for WPA
if len(p.WPA) > 0 {
return "psk"
}
// Check for WEP (privacy but no WPA/RSN)
if p.Privacy {
return "wep"
}
// Open network
return "open"
}