1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

vpn: update pksc11 handling

This commit is contained in:
bbedward
2025-12-31 15:42:19 -05:00
parent 7d8de6e6f0
commit 37f972d075
2 changed files with 34 additions and 90 deletions

View File

@@ -233,6 +233,9 @@ func (a *SecretAgent) GetSecrets(
if a.manager != nil && connType == "802-11-wireless" && a.manager.WasRecentlyFailed(ssid) {
reason = "wrong-password"
}
if settingName == "vpn" && isPKCS11Auth(conn, vpnSvc) {
reason = "pkcs11"
}
var connId, connUuid string
if c, ok := conn["connection"]; ok {
@@ -579,6 +582,15 @@ func inferVPNFields(conn map[string]nmVariantMap, vpnService string) []string {
connType := dataMap["connection-type"]
switch {
case strings.Contains(vpnService, "openconnect"):
authType := dataMap["authtype"]
userCert := dataMap["usercert"]
if authType == "cert" && strings.HasPrefix(userCert, "pkcs11:") {
return []string{"key_pass"}
}
if dataMap["username"] == "" {
fields = []string{"username", "password"}
}
case strings.Contains(vpnService, "openvpn"):
if connType == "password" || connType == "password-tls" {
if dataMap["username"] == "" {
@@ -586,7 +598,7 @@ func inferVPNFields(conn map[string]nmVariantMap, vpnService string) []string {
}
}
case strings.Contains(vpnService, "vpnc"), strings.Contains(vpnService, "l2tp"),
strings.Contains(vpnService, "pptp"), strings.Contains(vpnService, "openconnect"):
strings.Contains(vpnService, "pptp"):
if dataMap["username"] == "" {
fields = []string{"username", "password"}
}
@@ -597,6 +609,8 @@ func inferVPNFields(conn map[string]nmVariantMap, vpnService string) []string {
func vpnFieldMeta(field, vpnService string) (label string, isSecret bool) {
switch field {
case "key_pass":
return "PIN", true
case "password":
return "Password", true
case "Xauth password":
@@ -624,6 +638,25 @@ func vpnFieldMeta(field, vpnService string) (label string, isSecret bool) {
return titleCaser.String(strings.ReplaceAll(field, "-", " ")), false
}
func isPKCS11Auth(conn map[string]nmVariantMap, vpnService string) bool {
if !strings.Contains(vpnService, "openconnect") {
return false
}
vpnSettings, ok := conn["vpn"]
if !ok {
return false
}
dataVariant, ok := vpnSettings["data"]
if !ok {
return false
}
dataMap, ok := dataVariant.Value().(map[string]string)
if !ok {
return false
}
return dataMap["authtype"] == "cert" && strings.HasPrefix(dataMap["usercert"], "pkcs11:")
}
func readVPNPasswordFlags(conn map[string]nmVariantMap, settingName string) uint32 {
if settingName != "vpn" {
return 0xFFFF

View File

@@ -296,13 +296,6 @@ func (b *NetworkManagerBackend) ConnectVPN(uuidOrName string, singleActive bool)
authAction := detectVPNAuthAction(vpnServiceType, vpnData)
switch authAction {
case "pkcs11_pin":
if b.promptBroker == nil {
return fmt.Errorf("PKCS11 authentication requires interactive prompt")
}
if err := b.handlePKCS11Auth(targetConn, connName, targetUUID, vpnServiceType); err != nil {
return err
}
case "openvpn_username":
if b.promptBroker == nil {
return fmt.Errorf("OpenVPN password authentication requires interactive prompt")
@@ -345,12 +338,6 @@ func detectVPNAuthAction(serviceType string, data map[string]string) string {
}
switch {
case strings.Contains(serviceType, "openconnect"):
authType := data["authtype"]
userCert := data["usercert"]
if authType == "cert" && strings.HasPrefix(userCert, "pkcs11:") {
return "pkcs11_pin"
}
case strings.Contains(serviceType, "openvpn"):
connType := data["connection-type"]
username := data["username"]
@@ -361,82 +348,6 @@ func detectVPNAuthAction(serviceType string, data map[string]string) string {
return ""
}
func (b *NetworkManagerBackend) handlePKCS11Auth(targetConn gonetworkmanager.Connection, connName, targetUUID, vpnServiceType string) error {
log.Infof("[ConnectVPN] PKCS11 authentication detected - prompting for PIN")
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
token, err := b.promptBroker.Ask(ctx, PromptRequest{
Name: connName,
ConnType: "vpn",
VpnService: vpnServiceType,
SettingName: "vpn",
Fields: []string{"key_pass"},
FieldsInfo: []FieldInfo{{Name: "key_pass", Label: "PIN", IsSecret: true}},
Reason: "pkcs11",
ConnectionId: connName,
ConnectionUuid: targetUUID,
ConnectionPath: string(targetConn.GetPath()),
})
if err != nil {
return fmt.Errorf("failed to request PIN: %w", err)
}
reply, err := b.promptBroker.Wait(ctx, token)
if err != nil {
return fmt.Errorf("PIN prompt failed: %w", err)
}
if reply.Cancel {
return fmt.Errorf("user cancelled PIN entry")
}
pin := reply.Secrets["key_pass"]
if pin == "" {
return fmt.Errorf("PIN required for PKCS11 authentication")
}
connObj := b.dbusConn.Object("org.freedesktop.NetworkManager", targetConn.GetPath())
var existingSettings map[string]map[string]dbus.Variant
if err := connObj.Call("org.freedesktop.NetworkManager.Settings.Connection.GetSettings", 0).Store(&existingSettings); err != nil {
return fmt.Errorf("failed to get settings: %w", err)
}
settings := make(map[string]map[string]dbus.Variant)
if connSection, ok := existingSettings["connection"]; ok {
settings["connection"] = connSection
}
vpn := existingSettings["vpn"]
var data map[string]string
if dataVariant, ok := vpn["data"]; ok {
if dm, ok := dataVariant.Value().(map[string]string); ok {
data = make(map[string]string)
for k, v := range dm {
data[k] = v
}
} else {
data = make(map[string]string)
}
} else {
data = make(map[string]string)
}
data["key_pass"] = pin
vpn["data"] = dbus.MakeVariant(data)
settings["vpn"] = vpn
var result map[string]dbus.Variant
if err := connObj.Call("org.freedesktop.NetworkManager.Settings.Connection.Update2", 0,
settings, uint32(0x2), map[string]dbus.Variant{}).Store(&result); err != nil {
return fmt.Errorf("failed to set PIN: %w", err)
}
log.Infof("[ConnectVPN] PIN set (in-memory only)")
return nil
}
func (b *NetworkManagerBackend) handleOpenVPNUsernameAuth(targetConn gonetworkmanager.Connection, connName, targetUUID, vpnServiceType string) error {
log.Infof("[ConnectVPN] OpenVPN requires username in vpn.data - prompting before activation")