feat: add support for EXTERNAL auth without uid (#193)

This commit is contained in:
mvn23 2023-01-07 20:46:55 +01:00 committed by GitHub
parent 4c9a8fe15a
commit 4939ef80e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 1 deletions

View File

@ -4,6 +4,8 @@ from typing import List, Optional, Tuple
from .errors import AuthError
UID_NOT_SPECIFIED = -1
# The auth interface here is unstable. I would like to eventually open this up
# for people to define their own custom authentication protocols, but I'm not
# familiar with what's needed for that exactly. To work with any message bus
@ -57,6 +59,9 @@ class AuthExternal(Authenticator):
"""An authenticator class for the external auth protocol for use with the
:class:`MessageBus <dbus_fast.message_bus.BaseMessageBus>`.
:param uid: The uid to use when connecting to the message bus. Use UID_NOT_SPECIFIED to use the uid known to the kernel.
:vartype uid: int
:sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
"""
@ -68,6 +73,8 @@ class AuthExternal(Authenticator):
def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
self.negotiate_unix_fd = negotiate_unix_fd
uid = self.uid
if uid == UID_NOT_SPECIFIED:
return "AUTH EXTERNAL"
if uid is None:
uid = os.getuid()
hex_uid = str(uid).encode().hex()
@ -86,6 +93,9 @@ class AuthExternal(Authenticator):
if response is _AuthResponse.AGREE_UNIX_FD:
return "BEGIN"
if response is _AuthResponse.DATA and self.uid == UID_NOT_SPECIFIED:
return "DATA"
raise AuthError(f"authentication failed: {response.value}: {args}")

View File

@ -3,9 +3,19 @@ import os
import pytest
from dbus_fast.auth import AuthExternal
from dbus_fast.auth import UID_NOT_SPECIFIED, AuthExternal
from dbus_fast.errors import AuthError
def test_uid_is_set():
auth = AuthExternal(uid=999)
assert auth._authentication_start() == "AUTH EXTERNAL 393939"
def test_auth_external_no_uid():
"""Test AuthExternal with UID_NOT_SPECIFIED"""
auth = AuthExternal(uid=UID_NOT_SPECIFIED)
assert auth._authentication_start() == "AUTH EXTERNAL"
assert auth._receive_line("DATA") == "DATA"
with pytest.raises(AuthError):
auth._receive_line("REJECTED")