Skip to content

Commit

Permalink
aghnet: imp permissions logic
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Feb 6, 2023
1 parent da1b53a commit 3918789
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 6 deletions.
5 changes: 5 additions & 0 deletions internal/aghnet/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ func CanBindPrivilegedPorts() (can bool, err error) {
return canBindPrivilegedPorts()
}

// AcquirePermissions tries to acquire permissions to bind to privileged ports.
func AcquirePermissions() (err error) {
return acquirePermissions()
}

// NetInterface represents an entry of network interfaces map.
type NetInterface struct {
// Addresses are the network interface addresses.
Expand Down
4 changes: 4 additions & 0 deletions internal/aghnet/net_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ import "github.com/AdguardTeam/AdGuardHome/internal/aghos"
func canBindPrivilegedPorts() (can bool, err error) {
return aghos.HaveAdminRights()
}

func acquirePermissions() (err error) {
return nil
}
21 changes: 18 additions & 3 deletions internal/aghnet/net_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ const dhcpcdConf = "etc/dhcpcd.conf"

func canBindPrivilegedPorts() (can bool, err error) {
res, err := unix.PrctlRetInt(
unix.PR_CAP_AMBIENT,
unix.PR_CAP_AMBIENT_RAISE,
unix.PR_CAPBSET_READ,
unix.CAP_NET_BIND_SERVICE,
0,
0,
0,
)
if err != nil {
if errors.Is(err, unix.EINVAL) {
// Older versions of Linux kernel do not support this. Print a
// warning and check admin rights.
log.Info("warning: cannot check capability cap_net_bind_service: %s", err)
log.Info("warning: cannot check cap_net_bind_service: %s", err)
} else {
return false, err
}
Expand All @@ -45,6 +45,21 @@ func canBindPrivilegedPorts() (can bool, err error) {
return res == 1 || adm, nil
}

func acquirePermissions() (err error) {
_, err = unix.PrctlRetInt(
unix.PR_CAP_AMBIENT,
unix.PR_CAP_AMBIENT_RAISE,
unix.CAP_NET_BIND_SERVICE,
0,
0,
)
if err != nil {
return fmt.Errorf("raising cap_net_bind_service: %w", err)
}

return nil
}

// dhcpcdStaticConfig checks if interface is configured by /etc/dhcpcd.conf to
// have a static IP.
func (n interfaceName) dhcpcdStaticConfig(r io.Reader) (subsources []string, cont bool, err error) {
Expand Down
4 changes: 4 additions & 0 deletions internal/aghnet/net_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ func closePortChecker(c io.Closer) (err error) {
func isAddrInUse(err syscall.Errno) (ok bool) {
return errors.Is(err, windows.WSAEADDRINUSE)
}

func acquirePermissions() (err error) {
return nil
}
13 changes: 10 additions & 3 deletions internal/home/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,14 +570,21 @@ func startMods() (err error) {
func checkPermissions() {
log.Info("Checking if AdGuard Home has necessary permissions")

if ok, err := aghnet.CanBindPrivilegedPorts(); !ok || err != nil {
log.Fatal("This is the first launch of AdGuard Home. You must run it as Administrator.")
err := aghnet.AcquirePermissions()
if err != nil {
log.Debug("acquiring necessary permissions: %s", err)

var ok bool
if ok, err = aghnet.CanBindPrivilegedPorts(); !ok || err != nil {
log.Fatal("This is the first launch of AdGuard Home. You must run it as Administrator.")
}
}

// We should check if AdGuard Home is able to bind to port 53
err := aghnet.CheckPort("tcp", netip.AddrPortFrom(netutil.IPv4Localhost(), defaultPortDNS))
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(netutil.IPv4Localhost(), defaultPortDNS))
if err != nil {
if errors.Is(err, os.ErrPermission) {
log.Debug("checking permissions via binding: %v", err)
log.Fatal(`Permission check failed.
AdGuard Home is not allowed to bind to privileged ports (for instance, port 53).
Expand Down

0 comments on commit 3918789

Please sign in to comment.