X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdbusauth.c;h=a29f97ea32a97357e04f6c4f7f66b76a4bec357f;hb=25990eb2b6da94e1d03631eab8a952ef84cb9986;hp=eb8ebfd3bf8687fc66869c06563d8d802bd16f2a;hpb=ad363d9aac5a6167121631a1ee8d3cec2784b5c2;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c index eb8ebfd..a29f97e 100644 --- a/gio/gdbusauth.c +++ b/gio/gdbusauth.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: David Zeuthen */ @@ -39,14 +37,14 @@ #include "gdataoutputstream.h" #ifdef G_OS_UNIX -#include -#include +#include "gnetworking.h" #include "gunixconnection.h" #include "gunixcredentialsmessage.h" #endif #include "glibintl.h" +G_GNUC_PRINTF(1, 2) static void debug_print (const gchar *message, ...) { @@ -104,7 +102,7 @@ enum PROP_STREAM }; -G_DEFINE_TYPE (GDBusAuth, _g_dbus_auth, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuth, _g_dbus_auth, G_TYPE_OBJECT) /* ---------------------------------------------------------------------------------------------------- */ @@ -115,8 +113,7 @@ _g_dbus_auth_finalize (GObject *object) if (auth->priv->stream != NULL) g_object_unref (auth->priv->stream); - g_list_foreach (auth->priv->available_mechanisms, (GFunc) mechanism_free, NULL); - g_list_free (auth->priv->available_mechanisms); + g_list_free_full (auth->priv->available_mechanisms, (GDestroyNotify) mechanism_free); if (G_OBJECT_CLASS (_g_dbus_auth_parent_class)->finalize != NULL) G_OBJECT_CLASS (_g_dbus_auth_parent_class)->finalize (object); @@ -167,8 +164,6 @@ _g_dbus_auth_class_init (GDBusAuthClass *klass) { GObjectClass *gobject_class; - g_type_class_add_private (klass, sizeof (GDBusAuthPrivate)); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->get_property = _g_dbus_auth_get_property; gobject_class->set_property = _g_dbus_auth_set_property; @@ -195,17 +190,22 @@ mechanism_free (Mechanism *m) } static void -add_mechanism (GDBusAuth *auth, - GType mechanism_type) +add_mechanism (GDBusAuth *auth, + GDBusAuthObserver *observer, + GType mechanism_type) { - Mechanism *m; - - m = g_new0 (Mechanism, 1); - m->name = _g_dbus_auth_mechanism_get_name (mechanism_type); - m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type); - m->gtype = mechanism_type; + const gchar *name; - auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m); + name = _g_dbus_auth_mechanism_get_name (mechanism_type); + if (observer == NULL || g_dbus_auth_observer_allow_mechanism (observer, name)) + { + Mechanism *m; + m = g_new0 (Mechanism, 1); + m->name = name; + m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type); + m->gtype = mechanism_type; + auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m); + } } static gint @@ -222,12 +222,17 @@ mech_compare_func (Mechanism *a, Mechanism *b) static void _g_dbus_auth_init (GDBusAuth *auth) { - auth->priv = G_TYPE_INSTANCE_GET_PRIVATE (auth, G_TYPE_DBUS_AUTH, GDBusAuthPrivate); + auth->priv = _g_dbus_auth_get_instance_private (auth); +} +static void +_g_dbus_auth_add_mechs (GDBusAuth *auth, + GDBusAuthObserver *observer) +{ /* TODO: trawl extension points */ - add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_ANON); - add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_SHA1); - add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL); + add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_ANON); + add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_SHA1); + add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL); auth->priv->available_mechanisms = g_list_sort (auth->priv->available_mechanisms, (GCompareFunc) mech_compare_func); @@ -391,7 +396,7 @@ hexdecode (const gchar *str, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Error hexdecoding string `%s' around position %d", + "Error hexdecoding string '%s' around position %d", str, n); goto out; } @@ -513,7 +518,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth *auth, "stream", auth->priv->stream, "credentials", credentials_that_were_sent, NULL); - debug_print ("CLIENT: Trying mechanism `%s'", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); + debug_print ("CLIENT: Trying mechanism '%s'", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); g_ptr_array_add (attempted_auth_mechs, (gpointer) _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); /* the auth mechanism may not be supported @@ -521,7 +526,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth *auth, */ if (!_g_dbus_auth_mechanism_is_supported (mech)) { - debug_print ("CLIENT: Mechanism `%s' says it is not supported", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); + debug_print ("CLIENT: Mechanism '%s' says it is not supported", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); g_object_unref (mech); mech = NULL; goto again; @@ -531,14 +536,14 @@ client_choose_mech_and_send_initial_response (GDBusAuth *auth, initial_response = _g_dbus_auth_mechanism_client_initiate (mech, &initial_response_len); #if 0 - g_printerr ("using auth mechanism with name `%s' of type `%s' with initial response `%s'\n", + g_printerr ("using auth mechanism with name '%s' of type '%s' with initial response '%s'\n", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype), g_type_name (G_TYPE_FROM_INSTANCE (mech)), initial_response); #endif if (initial_response != NULL) { - //g_printerr ("initial_response = `%s'\n", initial_response); + //g_printerr ("initial_response = '%s'\n", initial_response); encoded = hexencode (initial_response); s = g_strdup_printf ("AUTH %s %s\r\n", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype), @@ -550,7 +555,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth *auth, { s = g_strdup_printf ("AUTH %s\r\n", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype)); } - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_object_unref (mech); @@ -577,6 +582,7 @@ typedef enum gchar * _g_dbus_auth_run_client (GDBusAuth *auth, + GDBusAuthObserver *observer, GDBusCapabilityFlags offered_capabilities, GDBusCapabilityFlags *out_negotiated_capabilities, GCancellable *cancellable, @@ -597,6 +603,8 @@ _g_dbus_auth_run_client (GDBusAuth *auth, debug_print ("CLIENT: initiating"); + _g_dbus_auth_add_mechs (auth, observer); + ret_guid = NULL; supported_auth_mechs = NULL; attempted_auth_mechs = g_ptr_array_new (); @@ -612,7 +620,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), @@ -635,7 +643,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, if (G_UNLIKELY (_g_dbus_debug_authentication ())) { s = g_credentials_to_string (credentials); - debug_print ("CLIENT: sent credentials `%s'", s); + debug_print ("CLIENT: sent credentials '%s'", s); g_free (s); } } @@ -648,7 +656,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, /* Get list of supported authentication mechanisms */ s = "AUTH\r\n"; - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; state = CLIENT_STATE_WAITING_FOR_REJECT; @@ -663,13 +671,14 @@ _g_dbus_auth_run_client (GDBusAuth *auth, if (line == NULL) goto out; debug_print ("CLIENT: WaitingForReject, read '%s'", line); - foobar: + + choose_mechanism: if (!g_str_has_prefix (line, "REJECTED ")) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "In WaitingForReject: Expected `REJECTED am1 am2 ... amN', got `%s'", + "In WaitingForReject: Expected 'REJECTED am1 am2 ... amN', got '%s'", line); g_free (line); goto out; @@ -679,7 +688,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, supported_auth_mechs = g_strsplit (line + sizeof ("REJECTED ") - 1, " ", 0); #if 0 for (n = 0; supported_auth_mechs != NULL && supported_auth_mechs[n] != NULL; n++) - g_printerr ("supported_auth_mechs[%d] = `%s'\n", n, supported_auth_mechs[n]); + g_printerr ("supported_auth_mechs[%d] = '%s'\n", n, supported_auth_mechs[n]); #endif } g_free (line); @@ -703,7 +712,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; - debug_print ("CLIENT: WaitingForOK, read `%s'", line); + debug_print ("CLIENT: WaitingForOK, read '%s'", line); if (g_str_has_prefix (line, "OK ")) { if (!g_dbus_is_guid (line + 3)) @@ -711,7 +720,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid OK response `%s'", + "Invalid OK response '%s'", line); g_free (line); goto out; @@ -722,7 +731,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { s = "NEGOTIATE_UNIX_FD\r\n"; - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; state = CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD; @@ -730,7 +739,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, else { s = "BEGIN\r\n"; - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ @@ -739,7 +748,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, } else if (g_str_has_prefix (line, "REJECTED ")) { - goto foobar; + goto choose_mechanism; } else { @@ -747,7 +756,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "In WaitingForOk: unexpected response `%s'", + "In WaitingForOk: unexpected response '%s'", line); g_free (line); goto out; @@ -759,13 +768,13 @@ _g_dbus_auth_run_client (GDBusAuth *auth, line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; - debug_print ("CLIENT: WaitingForAgreeUnixFD, read=`%s'", line); + debug_print ("CLIENT: WaitingForAgreeUnixFD, read='%s'", line); if (g_strcmp0 (line, "AGREE_UNIX_FD") == 0) { g_free (line); negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; s = "BEGIN\r\n"; - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ @@ -773,10 +782,10 @@ _g_dbus_auth_run_client (GDBusAuth *auth, } else if (g_str_has_prefix (line, "ERROR") && (line[5] == 0 || g_ascii_isspace (line[5]))) { - //g_strstrip (line + 5); g_debug ("bah, no unix_fd: `%s'", line + 5); + //g_strstrip (line + 5); g_debug ("bah, no unix_fd: '%s'", line + 5); g_free (line); s = "BEGIN\r\n"; - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ @@ -788,7 +797,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "In WaitingForAgreeUnixFd: unexpected response `%s'", + "In WaitingForAgreeUnixFd: unexpected response '%s'", line); g_free (line); goto out; @@ -800,7 +809,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; - debug_print ("CLIENT: WaitingForData, read=`%s'", line); + debug_print ("CLIENT: WaitingForData, read='%s'", line); if (g_str_has_prefix (line, "DATA ")) { gchar *encoded; @@ -831,7 +840,7 @@ _g_dbus_auth_run_client (GDBusAuth *auth, s = g_strdup_printf ("DATA %s\r\n", encoded_data); g_free (encoded_data); g_free (data); - debug_print ("CLIENT: writing `%s'", s); + debug_print ("CLIENT: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); @@ -841,12 +850,19 @@ _g_dbus_auth_run_client (GDBusAuth *auth, } state = CLIENT_STATE_WAITING_FOR_OK; } + else if (g_str_has_prefix (line, "REJECTED ")) + { + /* could be the chosen authentication method just doesn't work. Try + * another one... + */ + goto choose_mechanism; + } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "In WaitingForData: unexpected response `%s'", + "In WaitingForData: unexpected response '%s'", line); g_free (line); goto out; @@ -955,6 +971,8 @@ _g_dbus_auth_run_server (GDBusAuth *auth, debug_print ("SERVER: initiating"); + _g_dbus_auth_add_mechs (auth, observer); + ret = FALSE; dis = NULL; dos = NULL; @@ -967,7 +985,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "The given guid `%s' is not valid", + "The given guid '%s' is not valid", guid); goto out; } @@ -981,13 +999,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; @@ -997,6 +1015,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, { local_error = NULL; byte = g_data_input_stream_read_byte (dis, cancellable, &local_error); + byte = byte; /* To avoid -Wunused-but-set-variable */ if (local_error != NULL) { g_propagate_error (error, local_error); @@ -1006,6 +1025,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, #else local_error = NULL; byte = g_data_input_stream_read_byte (dis, cancellable, &local_error); + byte = byte; /* To avoid -Wunused-but-set-variable */ if (local_error != NULL) { g_propagate_error (error, local_error); @@ -1017,7 +1037,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, if (G_UNLIKELY (_g_dbus_debug_authentication ())) { s = g_credentials_to_string (credentials); - debug_print ("SERVER: received credentials `%s'", s); + debug_print ("SERVER: received credentials '%s'", s); g_free (s); } } @@ -1034,13 +1054,13 @@ _g_dbus_auth_run_server (GDBusAuth *auth, case SERVER_STATE_WAITING_FOR_AUTH: debug_print ("SERVER: WaitingForAuth"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); - debug_print ("SERVER: WaitingForAuth, read `%s'", line); + debug_print ("SERVER: WaitingForAuth, read '%s'", line); if (line == NULL) goto out; if (g_strcmp0 (line, "AUTH") == 0) { s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); @@ -1077,14 +1097,14 @@ _g_dbus_auth_run_server (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unexpected line `%s' while in WaitingForAuth state", + "Unexpected line '%s' while in WaitingForAuth state", line); g_strfreev (tokens); goto out; } /* TODO: record that the client has attempted to use this mechanism */ - //g_debug ("client is trying `%s'", mech_name); + //g_debug ("client is trying '%s'", mech_name); auth_mech_to_use_gtype = find_mech_by_name (auth, mech_name); if ((auth_mech_to_use_gtype == (GType) 0) || @@ -1093,7 +1113,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, /* We don't support this auth mechanism */ g_strfreev (tokens); s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); @@ -1153,7 +1173,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, else { s = g_strdup_printf ("OK %s\r\n", guid); - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); @@ -1166,7 +1186,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, case G_DBUS_AUTH_MECHANISM_STATE_REJECTED: s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); @@ -1190,7 +1210,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, s = g_strdup_printf ("DATA %s\r\n", encoded_data); g_free (encoded_data); g_free (data); - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); @@ -1213,7 +1233,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unexpected line `%s' while in WaitingForAuth state", + "Unexpected line '%s' while in WaitingForAuth state", line); g_free (line); goto out; @@ -1223,7 +1243,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, case SERVER_STATE_WAITING_FOR_DATA: debug_print ("SERVER: WaitingForData"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); - debug_print ("SERVER: WaitingForData, read `%s'", line); + debug_print ("SERVER: WaitingForData, read '%s'", line); if (line == NULL) goto out; if (g_str_has_prefix (line, "DATA ")) @@ -1253,7 +1273,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unexpected line `%s' while in WaitingForData state", + "Unexpected line '%s' while in WaitingForData state", line); g_free (line); } @@ -1272,7 +1292,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, &line_length, cancellable, error); - debug_print ("SERVER: WaitingForBegin, read `%s'", line); + debug_print ("SERVER: WaitingForBegin, read '%s'", line); if (line == NULL) goto out; if (g_strcmp0 (line, "BEGIN") == 0) @@ -1289,24 +1309,24 @@ _g_dbus_auth_run_server (GDBusAuth *auth, { negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; s = "AGREE_UNIX_FD\r\n"; - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } else { s = "ERROR \"fd passing not offered\"\r\n"; - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } } else { - g_debug ("Unexpected line `%s' while in WaitingForBegin state", line); + g_debug ("Unexpected line '%s' while in WaitingForBegin state", line); g_free (line); s = "ERROR \"Unknown Command\"\r\n"; - debug_print ("SERVER: writing `%s'", s); + debug_print ("SERVER: writing '%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; }