mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-13 00:42:49 -05:00
switch hto monorepo structure
This commit is contained in:
306
backend/internal/server/network/agent_iwd.go
Normal file
306
backend/internal/server/network/agent_iwd.go
Normal file
@@ -0,0 +1,306 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/backend/internal/errdefs"
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
iwdAgentManagerPath = "/net/connman/iwd"
|
||||
iwdAgentManagerIface = "net.connman.iwd.AgentManager"
|
||||
iwdAgentInterface = "net.connman.iwd.Agent"
|
||||
iwdAgentObjectPath = "/com/danklinux/iwdagent"
|
||||
)
|
||||
|
||||
type ConnectionStateChecker interface {
|
||||
IsConnectingTo(ssid string) bool
|
||||
}
|
||||
|
||||
type IWDAgent struct {
|
||||
conn *dbus.Conn
|
||||
objPath dbus.ObjectPath
|
||||
prompts PromptBroker
|
||||
onUserCanceled func()
|
||||
onPromptRetry func(ssid string)
|
||||
lastRequestSSID string
|
||||
stateChecker ConnectionStateChecker
|
||||
}
|
||||
|
||||
const iwdAgentIntrospectXML = `
|
||||
<node>
|
||||
<interface name="net.connman.iwd.Agent">
|
||||
<method name="Release">
|
||||
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||
</method>
|
||||
<method name="RequestPassphrase">
|
||||
<arg type="o" name="network" direction="in"/>
|
||||
<arg type="s" name="passphrase" direction="out"/>
|
||||
</method>
|
||||
<method name="RequestPrivateKeyPassphrase">
|
||||
<arg type="o" name="network" direction="in"/>
|
||||
<arg type="s" name="passphrase" direction="out"/>
|
||||
</method>
|
||||
<method name="RequestUserNameAndPassword">
|
||||
<arg type="o" name="network" direction="in"/>
|
||||
<arg type="s" name="username" direction="out"/>
|
||||
<arg type="s" name="password" direction="out"/>
|
||||
</method>
|
||||
<method name="RequestUserPassword">
|
||||
<arg type="o" name="network" direction="in"/>
|
||||
<arg type="s" name="user" direction="in"/>
|
||||
<arg type="s" name="password" direction="out"/>
|
||||
</method>
|
||||
<method name="Cancel">
|
||||
<arg type="s" name="reason" direction="in"/>
|
||||
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`
|
||||
|
||||
func NewIWDAgent(conn *dbus.Conn, prompts PromptBroker) (*IWDAgent, error) {
|
||||
if conn == nil {
|
||||
return nil, fmt.Errorf("dbus connection is nil")
|
||||
}
|
||||
|
||||
agent := &IWDAgent{
|
||||
conn: conn,
|
||||
objPath: dbus.ObjectPath(iwdAgentObjectPath),
|
||||
prompts: prompts,
|
||||
}
|
||||
|
||||
if err := conn.Export(agent, agent.objPath, iwdAgentInterface); err != nil {
|
||||
return nil, fmt.Errorf("failed to export IWD agent: %w", err)
|
||||
}
|
||||
|
||||
if err := conn.Export(agent, agent.objPath, "org.freedesktop.DBus.Introspectable"); err != nil {
|
||||
return nil, fmt.Errorf("failed to export introspection: %w", err)
|
||||
}
|
||||
|
||||
mgr := conn.Object("net.connman.iwd", dbus.ObjectPath(iwdAgentManagerPath))
|
||||
call := mgr.Call(iwdAgentManagerIface+".RegisterAgent", 0, agent.objPath)
|
||||
if call.Err != nil {
|
||||
return nil, fmt.Errorf("failed to register agent with iwd: %w", call.Err)
|
||||
}
|
||||
|
||||
return agent, nil
|
||||
}
|
||||
|
||||
func (a *IWDAgent) Close() {
|
||||
if a.conn != nil {
|
||||
mgr := a.conn.Object("net.connman.iwd", dbus.ObjectPath(iwdAgentManagerPath))
|
||||
mgr.Call(iwdAgentManagerIface+".UnregisterAgent", 0, a.objPath)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *IWDAgent) SetStateChecker(checker ConnectionStateChecker) {
|
||||
a.stateChecker = checker
|
||||
}
|
||||
|
||||
func (a *IWDAgent) getNetworkName(networkPath dbus.ObjectPath) string {
|
||||
netObj := a.conn.Object("net.connman.iwd", networkPath)
|
||||
nameVar, err := netObj.GetProperty("net.connman.iwd.Network.Name")
|
||||
if err == nil {
|
||||
if name, ok := nameVar.Value().(string); ok {
|
||||
return name
|
||||
}
|
||||
}
|
||||
return string(networkPath)
|
||||
}
|
||||
|
||||
func (a *IWDAgent) RequestPassphrase(network dbus.ObjectPath) (string, *dbus.Error) {
|
||||
ssid := a.getNetworkName(network)
|
||||
|
||||
if a.stateChecker != nil && !a.stateChecker.IsConnectingTo(ssid) {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.prompts == nil {
|
||||
if a.onUserCanceled != nil {
|
||||
a.onUserCanceled()
|
||||
}
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.lastRequestSSID == ssid {
|
||||
if a.onPromptRetry != nil {
|
||||
a.onPromptRetry(ssid)
|
||||
}
|
||||
}
|
||||
a.lastRequestSSID = ssid
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
token, err := a.prompts.Ask(ctx, PromptRequest{
|
||||
SSID: ssid,
|
||||
Fields: []string{"psk"},
|
||||
})
|
||||
if err != nil {
|
||||
if a.onUserCanceled != nil {
|
||||
a.onUserCanceled()
|
||||
}
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
reply, err := a.prompts.Wait(ctx, token)
|
||||
if err != nil {
|
||||
if reply.Cancel || errors.Is(err, errdefs.ErrSecretPromptCancelled) {
|
||||
if a.onUserCanceled != nil {
|
||||
a.onUserCanceled()
|
||||
}
|
||||
}
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if passphrase, ok := reply.Secrets["psk"]; ok {
|
||||
return passphrase, nil
|
||||
}
|
||||
|
||||
if a.onUserCanceled != nil {
|
||||
a.onUserCanceled()
|
||||
}
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
func (a *IWDAgent) RequestPrivateKeyPassphrase(network dbus.ObjectPath) (string, *dbus.Error) {
|
||||
ssid := a.getNetworkName(network)
|
||||
|
||||
if a.stateChecker != nil && !a.stateChecker.IsConnectingTo(ssid) {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.prompts == nil {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.lastRequestSSID == ssid {
|
||||
if a.onPromptRetry != nil {
|
||||
a.onPromptRetry(ssid)
|
||||
}
|
||||
}
|
||||
a.lastRequestSSID = ssid
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
token, err := a.prompts.Ask(ctx, PromptRequest{
|
||||
SSID: ssid,
|
||||
Fields: []string{"private-key-password"},
|
||||
})
|
||||
if err != nil {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
reply, err := a.prompts.Wait(ctx, token)
|
||||
if err != nil || reply.Cancel {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if passphrase, ok := reply.Secrets["private-key-password"]; ok {
|
||||
return passphrase, nil
|
||||
}
|
||||
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
func (a *IWDAgent) RequestUserNameAndPassword(network dbus.ObjectPath) (string, string, *dbus.Error) {
|
||||
ssid := a.getNetworkName(network)
|
||||
|
||||
if a.stateChecker != nil && !a.stateChecker.IsConnectingTo(ssid) {
|
||||
return "", "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.prompts == nil {
|
||||
return "", "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.lastRequestSSID == ssid {
|
||||
if a.onPromptRetry != nil {
|
||||
a.onPromptRetry(ssid)
|
||||
}
|
||||
}
|
||||
a.lastRequestSSID = ssid
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
token, err := a.prompts.Ask(ctx, PromptRequest{
|
||||
SSID: ssid,
|
||||
Fields: []string{"identity", "password"},
|
||||
})
|
||||
if err != nil {
|
||||
return "", "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
reply, err := a.prompts.Wait(ctx, token)
|
||||
if err != nil || reply.Cancel {
|
||||
return "", "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
username, hasUser := reply.Secrets["identity"]
|
||||
password, hasPass := reply.Secrets["password"]
|
||||
|
||||
if hasUser && hasPass {
|
||||
return username, password, nil
|
||||
}
|
||||
|
||||
return "", "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
func (a *IWDAgent) RequestUserPassword(network dbus.ObjectPath, user string) (string, *dbus.Error) {
|
||||
ssid := a.getNetworkName(network)
|
||||
|
||||
if a.stateChecker != nil && !a.stateChecker.IsConnectingTo(ssid) {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.prompts == nil {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if a.lastRequestSSID == ssid {
|
||||
if a.onPromptRetry != nil {
|
||||
a.onPromptRetry(ssid)
|
||||
}
|
||||
}
|
||||
a.lastRequestSSID = ssid
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
token, err := a.prompts.Ask(ctx, PromptRequest{
|
||||
SSID: ssid,
|
||||
Fields: []string{"password"},
|
||||
})
|
||||
if err != nil {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
reply, err := a.prompts.Wait(ctx, token)
|
||||
if err != nil || reply.Cancel {
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
if password, ok := reply.Secrets["password"]; ok {
|
||||
return password, nil
|
||||
}
|
||||
|
||||
return "", dbus.NewError("net.connman.iwd.Agent.Error.Canceled", nil)
|
||||
}
|
||||
|
||||
func (a *IWDAgent) Cancel(reason string) *dbus.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *IWDAgent) Release() *dbus.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *IWDAgent) Introspect() (string, *dbus.Error) {
|
||||
return iwdAgentIntrospectXML, nil
|
||||
}
|
||||
Reference in New Issue
Block a user