# vim: ft=apparmor
#    Copyright (C) 2024 Canonical Ltd.
#
#    Author: sudhackar <sudhakar.verma@canonical.com>
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#------------------------------------------------------------------

abi <abi/4.0>,

include <tunables/global>

profile wpa_supplicant /usr/sbin/wpa_supplicant {
  include <abstractions/base>
  include <abstractions/dbus-strict>

  capability chown,
  capability net_admin,
  capability net_raw,

  # Most of these are extracted from wpa-2.10/wpa_supplicant/dbus/dbus_new.c
  dbus (bind) bus=system name=fi.w1.wpa_supplicant1,
  # fi.w1.wpasupplicant1 methods
  dbus (receive) 
       bus=system
       path=/fi/w1/wpa_supplicant1
       interface=fi.w1.wpa_supplicant1
       member={CreateInterface,RemoveInterface,GetInterface,ExpectDisconnect},
  # fi.w1.wpasupplicant1 signals
  dbus (send)
       bus=system
       path=/fi/w1/wpa_supplicant1
       interface=fi.w1.wpa_supplicant1
       member={InterfaceAdded,InterfaceRemoved},

  # fi.w1.wpasupplicant1.Interface methods
  dbus (receive)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface
        member={Scan,SignalPoll,Disconnect,AddNetwork,Reassociate,Reattach,Reconnect,RemoveNetwork,RemoveAllNetworks,SelectNetwork,NetworkReply,Roam,AddBlob,GetBlob,RemoveBlob,SetPKCS11EngineAndModulePath,FlushBSS,SubscribeProbeReq,UnsubscribeProbeReq,EAPLogoff,EAPLogon,Autoscan,TDLSDiscover,TDLSSetup,TDLSStatus,TDLSTeardown,TDLSChannelSwitch,TDLSCancelChannelSwitch,VendorElemAdd,VenderElemGet,VenderElemRem,SaveConfig,AbortScan,AddCred,RemoveCred,RemoveAllCreds,InterworkingSelect},
  # fi.w1.wpasupplicant.Interface signals
  dbus (send)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface
        member={ScanDone,BSSAdded,BSSRemoved,BlobAdded,BlobRemoved,NetworkAdded,NetworkRemoved,NetworkSelected,ProbeRequest,Certification,EAP,StaAuthorized,StaDeauthorized,StationAdded,StationRemoved,NetworkRequest,InterworkingAPAdded,InterworkingSelectDone,},

  # fi.w1.wpasupplicant.Interface.WPS methods
  dbus (receive)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface.WPS
        member={Start,Cancel},
  # fi.w1.wpasupplicant.WPS signals
  dbus (send)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface.WPS
        member={Event,Credentials},

  # fi.w1.wpasupplicant.Interface.P2PDevice methods
  dbus (receive)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface.P2PDevice
        member={Find,StopFind,Listen,ExtendedListen,PresenceRequest,ProvisionDiscoveryRequest,Connect,GroupAdd,Cancel,Invite,Disconnect,RejectPeer,RemoveClient,Flush,AddService,DeleteService,FlushService,ServiceDiscoveryRequest,ServiceDiscoveryResponse,ServiceDiscoveryCancelRequest,ServiceUpdate,ServiceDiscoveryExternal,AddPersistentGroup,RemovePersistentGroup,RemoveAllPersistentGroups},
  # fi.w1.wpasupplicant.Interface.P2PDevice signals
  dbus (send)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface.P2PDevice
        member={DeviceFound,DeviceFoundProperties,DeviceLost,FindStopped,ProvisionDiscoveryRequestDisplayPin,ProvisionDiscoveryRepsonseDisplayPin,ProvisionDiscoveryRequestEnterPin,ProvisionDiscoveryResponseEnterPin,ProvisionDiscoveryPBCResponse,ProvisionDiscoveryFailure,GroupStarted,GroupFormationFailure,GONegotiaionSuccess,GONegotiationFailure,GONegotiationRequest,InvitationResult,GroupFinished,ServiceDiscoveryRequest,ServiceDiscoveryResponse,PersistentGroupAdded,PersistentGroupRemoved,WpsFailed,InvitationReceived},

  # fi.w1.wpasupplicant.Interface.Mesh signals
  dbus (send)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=fi.w1.wpa_supplicant1.Interface.Mesh
        member={MeshGroupStarted,MeshGroupRemovevd,MeshPeerConnected,MeshPeerDisconnected},

  # fi.w1.wpasupplicant.Group signals (unknown path)
  audit dbus (send)
        bus=system
        path=/fi/w1/wpa_supplicant1/**
        interface=fi.w1.wpa_supplicant1.Group
        member={PeerJoined,PeerDisconnected},

  # Covers all DBus Properties
  dbus (receive)
        bus=system
        path=/fi/w1/wpa_supplicant1{,/**}
        interface=org.freedesktop.DBus.Properties
        member={Get,GetAll,Set},
  dbus (receive)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface=org.freedesktop.DBus.Introspectable
        member=Introspect,
  dbus (send)
        bus=system
        path=/fi/w1/wpa_supplicant1/Interfaces/**
        interface={fi.w1.wpa_supplicant1.Interface,org.freedesktop.DBus.Properties}
        member=PropertiesChanged,

  # Enable wpa_supplicant to request additional names for its bus
  dbus (send)
        bus=system
        path=/org/freedesktop/DBus
        interface=org.freedesktop.DBus
        member={ReleaseName,RequestName}
        peer=(name=org.freedesktop.DBus),

  @{exec_path} mr,

  owner /dev/rfkill r,
  owner /etc/group r,
  owner /etc/nsswitch.conf r,

  owner @{PROC}/sys/net/ipv{4,6}/conf/** rw,

  owner @{run}/wpa_supplicant/ w,
  owner @{run}/wpa_supplicant/** rw,

  owner @{run}/netplan/* r,

  network inet dgram,
  network inet6 dgram,
  network netlink raw,
  network packet dgram,

  @{sys}/devices/pci[0-9]*:[0-9]*/**/ieee80211/phy[0-9]*/name r,
  # Might also need @{sys}/class/ieee80211/ r,
  # phy* files inside are symlinks to the pci directory but directory
  # listing might be needed to enumerate and resolve symlinks

  include if exists <local/wpa_supplicant>
}
