From: Antoine Jacoutot Date: Fri, 27 May 2011 13:51:08 +0000 (+0200) Subject: Add glib credentials support to OpenBSD. X-Git-Tag: 2.29.6~88 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=77f4f5aa02458e6c7f909dc6087a39d9b75d0ba6;p=platform%2Fupstream%2Fglib.git Add glib credentials support to OpenBSD. https://bugzilla.gnome.org/show_bug.cgi?id=650885 --- diff --git a/gio/gcredentials.c b/gio/gcredentials.c index f54ea24..3a98333 100644 --- a/gio/gcredentials.c +++ b/gio/gcredentials.c @@ -27,6 +27,11 @@ #include #include #endif +#ifdef __OpenBSD__ +#include +#include +#include +#endif #include #include @@ -63,6 +68,9 @@ * * On FreeBSD, the native credential type is a struct cmsgcred. * This corresponds to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED. + * + * On OpenBSD, the native credential type is a struct sockpeercred. + * This corresponds to %G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED. */ /** @@ -82,6 +90,8 @@ struct _GCredentials struct ucred native; #elif defined(__FreeBSD__) struct cmsgcred native; +#elif defined(__OpenBSD__) + struct sockpeercred native; #else #ifdef __GNUC__ #warning Please add GCredentials support for your OS @@ -135,6 +145,10 @@ g_credentials_init (GCredentials *credentials) credentials->native.cmcred_pid = getpid (); credentials->native.cmcred_euid = geteuid (); credentials->native.cmcred_gid = getegid (); +#elif defined(__OpenBSD__) + credentials->native.pid = getpid (); + credentials->native.uid = geteuid (); + credentials->native.gid = getegid (); #endif } @@ -196,6 +210,16 @@ g_credentials_to_string (GCredentials *credentials) g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid); if (credentials->native.cmcred_gid != -1) g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid); +#elif defined(__OpenBSD__) + g_string_append (ret, "openbsd-sockpeercred:"); + if (credentials->native.pid != -1) + g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid); + if (credentials->native.uid != -1) + g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid); + if (credentials->native.gid != -1) + g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid); + if (ret->str[ret->len - 1] == ',') + ret->str[ret->len - 1] = '\0'; #else g_string_append (ret, "unknown"); #endif @@ -239,6 +263,9 @@ g_credentials_is_same_user (GCredentials *credentials, #elif defined(__FreeBSD__) if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid) ret = TRUE; +#elif defined(__OpenBSD__) + if (credentials->native.uid == other_credentials->native.uid) + ret = TRUE; #else g_set_error_literal (error, G_IO_ERROR, @@ -300,6 +327,17 @@ g_credentials_get_native (GCredentials *credentials, { ret = &credentials->native; } +#elif defined(__OpenBSD__) + if (native_type != G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED) + { + g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only " + "G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED is supported.", + native_type); + } + else + { + ret = &credentials->native; + } #else g_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support " "for the native credentials type. Please add support."); @@ -350,6 +388,17 @@ g_credentials_set_native (GCredentials *credentials, { memcpy (&credentials->native, native, sizeof (struct cmsgcred)); } +#elif defined(__OpenBSD__) + if (native_type != G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED) + { + g_warning ("g_credentials_set_native: Trying to set credentials of type %d " + "but only G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED is supported.", + native_type); + } + else + { + memcpy (&credentials->native, native, sizeof (struct sockpeercred)); + } #else g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support " "for the native credentials type. Please add support."); @@ -388,6 +437,8 @@ g_credentials_get_unix_user (GCredentials *credentials, ret = credentials->native.uid; #elif defined(__FreeBSD__) ret = credentials->native.cmcred_euid; +#elif defined(__OpenBSD__) + ret = credentials->native.uid; #else ret = -1; g_set_error_literal (error, @@ -434,6 +485,9 @@ g_credentials_set_unix_user (GCredentials *credentials, #elif defined(__FreeBSD__) credentials->native.cmcred_euid = uid; ret = TRUE; +#elif defined(__OpenBSD__) + credentials->native.uid = uid; + ret = TRUE; #else g_set_error_literal (error, G_IO_ERROR, diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c index 29e229a..7033f29 100644 --- a/gio/gdbusauth.c +++ b/gio/gdbusauth.c @@ -612,7 +612,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); #ifdef G_OS_UNIX - if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ()) + if (G_IS_UNIX_CONNECTION (auth->priv->stream)) { credentials = g_credentials_new (); if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (auth->priv->stream), @@ -989,13 +989,13 @@ _g_dbus_auth_run_server (GDBusAuth *auth, /* first read the NUL-byte (TODO: read credentials if using a unix domain socket) */ #ifdef G_OS_UNIX - if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ()) + if (G_IS_UNIX_CONNECTION (auth->priv->stream)) { local_error = NULL; credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream), cancellable, &local_error); - if (credentials == NULL) + if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { g_propagate_error (error, local_error); goto out; diff --git a/gio/gioenums.h b/gio/gioenums.h index 87eb2fa..b707745 100644 --- a/gio/gioenums.h +++ b/gio/gioenums.h @@ -1214,6 +1214,7 @@ typedef enum * @G_CREDENTIALS_TYPE_INVALID: Indicates an invalid native credential type. * @G_CREDENTIALS_TYPE_LINUX_UCRED: The native credentials type is a struct ucred. * @G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED: The native credentials type is a struct cmsgcred. + * @G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED: The native credentials type is a struct sockpeercred. Added in 2.30. * * Enumeration describing different kinds of native credential types. * @@ -1223,7 +1224,8 @@ typedef enum { G_CREDENTIALS_TYPE_INVALID, G_CREDENTIALS_TYPE_LINUX_UCRED, - G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED + G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, + G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED } GCredentialsType; /** diff --git a/gio/gsocket.c b/gio/gsocket.c index 97120a6..e447a2b 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -3531,11 +3531,16 @@ g_socket_get_credentials (GSocket *socket, ret = NULL; -#ifdef __linux__ +#if defined(__linux__) || defined(__OpenBSD__) { - struct ucred native_creds; socklen_t optlen; +#if defined(__linux__) + struct ucred native_creds; optlen = sizeof (struct ucred); +#elif defined(__OpenBSD__) + struct sockpeercred native_creds; + optlen = sizeof (struct sockpeercred); +#endif if (getsockopt (socket->priv->fd, SOL_SOCKET, SO_PEERCRED, @@ -3553,7 +3558,11 @@ g_socket_get_credentials (GSocket *socket, { ret = g_credentials_new (); g_credentials_set_native (ret, +#if defined(__linux__) G_CREDENTIALS_TYPE_LINUX_UCRED, +#elif defined(__OpenBSD__) + G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED, +#endif &native_creds); } } diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c index 0617bb9..c21353e 100644 --- a/gio/gunixconnection.c +++ b/gio/gunixconnection.c @@ -334,6 +334,7 @@ g_unix_connection_send_credentials (GUnixConnection *connection, gboolean ret; GOutputVector vector; guchar nul_byte[1] = {'\0'}; + gint num_messages; g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -344,14 +345,25 @@ g_unix_connection_send_credentials (GUnixConnection *connection, vector.buffer = &nul_byte; vector.size = 1; - scm = g_unix_credentials_message_new_with_credentials (credentials); + + if (g_unix_credentials_message_is_supported ()) + { + scm = g_unix_credentials_message_new_with_credentials (credentials); + num_messages = 1; + } + else + { + scm = NULL; + num_messages = 0; + } + g_object_get (connection, "socket", &socket, NULL); if (g_socket_send_message (socket, NULL, /* address */ &vector, 1, &scm, - 1, + num_messages, G_SOCKET_MSG_NONE, cancellable, error) != 1) @@ -364,7 +376,8 @@ g_unix_connection_send_credentials (GUnixConnection *connection, out: g_object_unref (socket); - g_object_unref (scm); + if (scm != NULL) + g_object_unref (scm); g_object_unref (credentials); return ret; } @@ -498,28 +511,47 @@ g_unix_connection_receive_credentials (GUnixConnection *connection, goto out; } - if (nscm != 1) + if (g_unix_credentials_message_is_supported ()) { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - _("Expecting 1 control message, got %d"), - nscm); - goto out; - } + if (nscm != 1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Expecting 1 control message, got %d"), + nscm); + goto out; + } + + if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0])) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unexpected type of ancillary data")); + goto out; + } - if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0])) + ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0])); + g_object_ref (ret); + } + else { - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - _("Unexpected type of ancillary data")); - goto out; + if (nscm != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Not expecting control message, but got %d"), + nscm); + goto out; + } + else + { + ret = g_socket_get_credentials (socket, error); + } } - ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0])); - g_object_ref (ret); - out: #ifdef __linux__