Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux: Re-introduce D-Bus API Authorization #7110

Merged
merged 13 commits into from Jul 26, 2023
Merged

Conversation

oskirby
Copy link
Collaborator

@oskirby oskirby commented Jun 7, 2023

Description

We recently found that the use of polkit in our code was incorrect in that it wasn't actually enforcing anything so we decided to simply remove the code around polkit. This PR attempts to restore proper authorization of the D-Bus API used to manipulate the controller and network interface.

The authorization check goes as follows:

  • If the calling process has the CAP_NET_ADMIN capability, then access to the D-Bus API is granted.
  • If calling the activate method and the VPN was previously disconnected, access is granted and the UID that activated the connection is recorded for later.
  • If the caller matches the UID that activated the connection, then access is granted.
  • Otherwise, access is denied.

In other words: Any user can activate the VPN, and once activated only that user can manipulate the VPN connection. However, processes with CAP_NET_ADMIN bypass this check and are always authorized.

Checklist

  • My code follows the style guidelines for this project
  • I have not added any packages that contain high risk or unknown licenses (GPL, LGPL, MPL, etc. consult with DevOps if in question)
  • I have performed a self review of my own code
  • I have commented my code PARTICULARLY in hard to understand areas
  • I have added thorough tests where needed

@oskirby oskirby changed the title Linux: Re-introduce D-Bbus API Aauthentication Linux: Re-introduce D-Bbus API Authorization Jun 7, 2023
@oskirby oskirby requested a review from bakulf June 7, 2023 15:38
@oskirby oskirby changed the title Linux: Re-introduce D-Bbus API Authorization Linux: Re-introduce D-Bus API Authorization Jun 7, 2023
@oskirby oskirby mentioned this pull request Jun 14, 2023
5 tasks
@oskirby oskirby requested review from strseb and Gela July 13, 2023 14:16
@oskirby oskirby marked this pull request as ready for review July 13, 2023 14:16
}

/* Checks to see if the caller has sufficient authorization */
bool DBusService::checkCallerAuthz() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the way this function is being used/called above (if (!checkCallerAuthz) {...}, would a name such as DBusService::callerAuthorized() make the code more intuitive?

@@ -57,6 +61,9 @@ DBusService::DBusService(QObject* parent) : Daemon(parent) {
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this);
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this,
SLOT(userListCompleted(QDBusPendingCallWatcher*)));

// Drop as many root permissions as we are able.
dropRootPermissions();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own understanding, why are we dropping all possible permissions here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is generally good security practice to drop permissions that aren't required. For example, if we had a security bug that allowed an attacker to hijack the process, they would be limited only to the remaining capabilities and would be denied full root permissions.

logger.warning() << "Failed to retrieve process capabilities";
return;
}
auto guard = qScopeGuard([&] { cap_free(caps); });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this being used somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just used for garbage collection. The scopeguard ensures that cap_free() is invoked regardless of how this function exits.

src/apps/vpn/platforms/linux/daemon/dbusservice.cpp Outdated Show resolved Hide resolved
src/apps/vpn/platforms/linux/daemon/dbusservice.cpp Outdated Show resolved Hide resolved
src/apps/vpn/platforms/linux/daemon/dbusservice.cpp Outdated Show resolved Hide resolved
src/apps/vpn/platforms/linux/daemon/dbusservice.cpp Outdated Show resolved Hide resolved
src/apps/vpn/platforms/linux/daemon/dbusservice.cpp Outdated Show resolved Hide resolved
logger.warning() << "Failed to retrieve process capabilities";
return false;
}
auto guard = qScopeGuard([&] { cap_free(caps); });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the lambda expression isn't being called further down, can we remove the guard assignment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope guard is used to ensure that cap_free() is called at function exit, regardless of which path we take to exit the function.

src/apps/vpn/platforms/linux/daemon/dbusservice.cpp Outdated Show resolved Hide resolved
@oskirby oskirby requested a review from Gela July 24, 2023 20:11
Copy link
Collaborator

@strseb strseb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link

@Gela Gela left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@oskirby oskirby merged commit ba14efb into main Jul 26, 2023
94 checks passed
@oskirby oskirby deleted the linux-dbus-api-authz branch July 26, 2023 16:10
lesleyjanenorton pushed a commit that referenced this pull request Aug 4, 2023
* Check for CAP_NET_ADMIN to auth D-Bus calls.
* Add libcap as a build dependency
* Require D-Bus authorization for controller APIs
* Permit API calls originating from the daemon itself.
* Drop daemon permissions after launch.
* Apply auth check to split tunneling APIs too
* Restrict API access by UID
lesleyjanenorton added a commit that referenced this pull request Aug 7, 2023
* Linux: Re-introduce D-Bus API Authorization (#7110)

* Check for CAP_NET_ADMIN to auth D-Bus calls.
* Add libcap as a build dependency
* Require D-Bus authorization for controller APIs
* Permit API calls originating from the daemon itself.
* Drop daemon permissions after launch.
* Apply auth check to split tunneling APIs too
* Restrict API access by UID

---------

Co-authored-by: Naomi Kirby <oskirby@gmail.com>
Gela pushed a commit that referenced this pull request Aug 27, 2023
* Check for CAP_NET_ADMIN to auth D-Bus calls.
* Add libcap as a build dependency
* Require D-Bus authorization for controller APIs
* Permit API calls originating from the daemon itself.
* Drop daemon permissions after launch.
* Apply auth check to split tunneling APIs too
* Restrict API access by UID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants