]> git.eshelyaron.com Git - emacs.git/commitdiff
Support interactive D-Bus authorization
authorSteven Allen <steven@stebalien.com>
Tue, 9 Jul 2024 11:16:43 +0000 (13:16 +0200)
committerEshel Yaron <me@eshelyaron.com>
Tue, 9 Jul 2024 17:50:56 +0000 (19:50 +0200)
When invoking D-Bus methods, let the user enable interactive
authorization by passing an :authorizable t parameter.  This makes
it possible to D-Bus methods that require polkit authorization.

* configure.ac (HAVE_DBUS_MESSAGE_SET_ALLOW_INTERACTIVE_AUTHORIZATION):
Set a new variable if `dbus_message_set_allow_interactive_authorization'
is available.

* src/dbusbind.c (dbus-message-internal): Allow interactive
authorization by passing :authorizable t.

* doc/misc/dbus.texi (Synchronous Methods, Asynchronous Methods):
* etc/NEWS:
* lisp/net/dbus.el (dbus-call-method-asynchronously): Document the
new parameter.

(cherry picked from commit 551a71c313be26d067e59fa11c79e4ef5c550e92)

configure.ac
doc/misc/dbus.texi
etc/NEWS
lisp/net/dbus.el
src/dbusbind.c

index 15deb1f89aceff99489e2113b90c891499bb027e..905a0e525368050099d1a24878659cc57ac6b157 100644 (file)
@@ -3976,6 +3976,8 @@ if test "${with_dbus}" = "yes"; then
      dnl dbus_watch_get_unix_fd has been introduced in D-Bus 1.1.1.
      dnl dbus_type_is_valid and dbus_validate_* have been introduced in
      dnl D-Bus 1.5.12.
+     dnl dbus_message_set_allow_interactive_authorization was introduced
+     dnl in D-Bus 1.8.10.
      OLD_LIBS=$LIBS
      LIBS="$LIBS $DBUS_LIBS"
      AC_CHECK_FUNCS([dbus_watch_get_unix_fd \
@@ -3983,7 +3985,8 @@ if test "${with_dbus}" = "yes"; then
                    dbus_validate_bus_name \
                     dbus_validate_path \
                    dbus_validate_interface \
-                   dbus_validate_member])
+                   dbus_validate_member \
+                    dbus_message_set_allow_interactive_authorization])
      LIBS=$OLD_LIBS
      DBUS_OBJ=dbusbind.o
    fi
index e5d867acd407498097ee0ee35fa07793a610934b..20d26c80d38fc499adadb1e999d34504a93cb7bd 100644 (file)
@@ -1208,7 +1208,7 @@ which carries the input parameters to the object owning the method to
 be called, and a reply message returning the resulting output
 parameters from the object.
 
-@defun dbus-call-method bus service path interface method &optional :timeout timeout &rest args
+@defun dbus-call-method bus service path interface method &optional :timeout timeout :authorizable auth &rest args
 @anchor{dbus-call-method}
 This function calls @var{method} on the D-Bus @var{bus}.  @var{bus} is
 either the keyword @code{:system} or the keyword @code{:session}.
@@ -1223,6 +1223,10 @@ method call must return.  The default value is 25,000.  If the method
 call doesn't return in time, a D-Bus error is raised (@pxref{Errors
 and Events}).
 
+If the parameter @code{:authorizable} is given and the following
+@var{auth} is non-@code{nil}, the invoked method may interactively
+prompt the user for authorization.  The default is @code{nil}.
+
 The remaining arguments @var{args} are passed to @var{method} as
 arguments.  They are converted into D-Bus types as described in
 @ref{Type Conversion}.
@@ -1302,7 +1306,7 @@ emulate the @code{lshal} command on GNU/Linux systems:
 @cindex method calls, asynchronous
 @cindex asynchronous method calls
 
-@defun dbus-call-method-asynchronously bus service path interface method handler &optional :timeout timeout &rest args
+@defun dbus-call-method-asynchronously bus service path interface method handler &optional :timeout timeout :authorizable auth &rest args
 This function calls @var{method} on the D-Bus @var{bus}
 asynchronously.  @var{bus} is either the keyword @code{:system} or the
 keyword @code{:session}.
@@ -1321,6 +1325,10 @@ reply message must arrive.  The default value is 25,000.  If there is
 no reply message in time, a D-Bus error is raised (@pxref{Errors and
 Events}).
 
+If the parameter @code{:authorizable} is given and the following
+@var{auth} is non-@code{nil}, the invoked method may interactively
+prompt the user for authorization.  The default is @code{nil}.
+
 The remaining arguments @var{args} are passed to @var{method} as
 arguments.  They are converted into D-Bus types as described in
 @ref{Type Conversion}.
index 2718765fe169dbafed044cacccb61ea6d26bed7c..8c49d4b24f63a268cd24c8b42d83c098e74f5752 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -109,6 +109,12 @@ positives.
 \f
 * Lisp Changes in Emacs 31.1
 
++++
+*** Support interactive D-Bus authorization.
+A new ':authorizable t' parameter has been added to 'dbus-call-method'
+and 'dbus-call-method-asynchronously' to allow the user to interactively
+authorize the invoked D-Bus method (e.g., via polkit).
+
 \f
 * Changes in Emacs 31.1 on Non-Free Operating Systems
 
index dd5f0e888596b1137221f23992931f34996da8d3..a50f3a939386687abf3df375372aa54c1ebbcbf0 100644 (file)
@@ -297,6 +297,10 @@ TIMEOUT specifies the maximum number of milliseconds before the
 method call must return.  The default value is 25,000.  If the
 method call doesn't return in time, a D-Bus error is raised.
 
+If the parameter `:authorizable' is given and the following AUTH
+is non-nil, the invoked method may interactively prompt the user
+for authorization.  The default is nil.
+
 All other arguments ARGS are passed to METHOD as arguments.  They are
 converted into D-Bus types via the following rules:
 
@@ -427,6 +431,10 @@ TIMEOUT specifies the maximum number of milliseconds before the
 method call must return.  The default value is 25,000.  If the
 method call doesn't return in time, a D-Bus error is raised.
 
+If the parameter `:authorizable' is given and the following AUTH
+is non-nil, the invoked method may interactively prompt the user
+for authorization.  The default is nil.
+
 All other arguments ARGS are passed to METHOD as arguments.  They are
 converted into D-Bus types via the following rules:
 
index 35ce03c791130357cb6e59e2d7a4edde941369bd..27b9c190793780a2e96799995d00146c1e7187f6 100644 (file)
@@ -1314,7 +1314,7 @@ The following usages are expected:
 `dbus-call-method', `dbus-call-method-asynchronously':
   (dbus-message-internal
     dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER
-    &optional :timeout TIMEOUT &rest ARGS)
+    &optional :timeout TIMEOUT :authorizable AUTH &rest ARGS)
 
 `dbus-send-signal':
   (dbus-message-internal
@@ -1512,12 +1512,38 @@ usage: (dbus-message-internal &rest REST)  */)
        XD_SIGNAL1 (build_string ("Unable to create an error message"));
     }
 
-  /* Check for timeout parameter.  */
-  if ((count + 2 <= nargs) && EQ (args[count], QCtimeout))
+  while ((count + 2 <= nargs))
     {
-      CHECK_FIXNAT (args[count+1]);
-      timeout = min (XFIXNAT (args[count+1]), INT_MAX);
-      count = count+2;
+      /* Check for timeout parameter.  */
+      if (EQ (args[count], QCtimeout))
+        {
+         if (mtype != DBUS_MESSAGE_TYPE_METHOD_CALL)
+           XD_SIGNAL1
+             (build_string (":timeout is only supported on method calls"));
+
+          CHECK_FIXNAT (args[count+1]);
+          timeout = min (XFIXNAT (args[count+1]), INT_MAX);
+          count = count+2;
+       }
+      /* Check for authorizable parameter.  */
+      else if (EQ (args[count], QCauthorizable))
+        {
+         if (mtype != DBUS_MESSAGE_TYPE_METHOD_CALL)
+           XD_SIGNAL1
+             (build_string (":authorizable is only supported on method calls"));
+
+         /* Ignore this keyword if unsupported.  */
+#ifdef HAVE_DBUS_MESSAGE_SET_ALLOW_INTERACTIVE_AUTHORIZATION
+         dbus_message_set_allow_interactive_authorization
+           (dmessage, NILP (args[count+1]) ? FALSE : TRUE);
+#else
+         XD_DEBUG_MESSAGE (":authorizable not supported");
+#endif
+
+          count = count+2;
+       }
+      else break;
+
     }
 
   /* Initialize parameter list of message.  */
@@ -1895,6 +1921,9 @@ syms_of_dbusbind (void)
   /* Lisp symbol for method call timeout.  */
   DEFSYM (QCtimeout, ":timeout");
 
+  /* Lisp symbol for method interactive authorization.  */
+  DEFSYM (QCauthorizable, ":authorizable");
+
   /* Lisp symbols of D-Bus types.  */
   DEFSYM (QCbyte, ":byte");
   DEFSYM (QCboolean, ":boolean");