static void cockpit_auth_session_login_async (CockpitAuth *self, const gchar *path, GHashTable *headers, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *result; SessionLoginData *sl; GBytes *input; gchar *application; gchar *type = NULL; result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, cockpit_auth_session_login_async); application = cockpit_auth_parse_application (path); input = cockpit_auth_parse_authorization (headers, &type); if (input && application) { sl = g_new0 (SessionLoginData, 1); sl->remote_peer = g_strdup (remote_peer); sl->auth_type = type; sl->authorization = g_bytes_ref (input); sl->application = application; application = NULL; g_simple_async_result_set_op_res_gpointer (result, sl, session_login_data_free); sl->session_pipe = spawn_session_process (type, input, remote_peer, &sl->auth_pipe); if (sl->session_pipe) { g_signal_connect (sl->auth_pipe, "close", G_CALLBACK (on_session_login_done), g_object_ref (result)); } else { g_simple_async_result_set_error (result, COCKPIT_ERROR, COCKPIT_ERROR_FAILED, "Internal error starting session process"); g_simple_async_result_complete_in_idle (result); } } else { g_free (type); g_simple_async_result_set_error (result, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED, "Authentication required"); g_simple_async_result_complete_in_idle (result); } g_bytes_unref (input); g_free (application); g_object_unref (result); }
static void cockpit_auth_session_login_async (CockpitAuth *self, GHashTable *headers, GBytes *input, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *result; GBytes *password = NULL; gchar *user = NULL; LoginData *login; GError *error = NULL; result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, cockpit_auth_session_login_async); if (!cockpit_auth_parse_input (input, &user, &password, &error)) { g_message ("couldn't parse login input: %s", error->message); g_simple_async_result_take_error (result, error); g_simple_async_result_complete_in_idle (result); } else { login = g_new0 (LoginData, 1); login->password = password; login->remote_peer = g_strdup (remote_peer); g_simple_async_result_set_op_res_gpointer (result, login, login_data_free); g_assert (password != NULL); login->session_pipe = spawn_session_process (user, password, remote_peer, &login->auth_pipe); if (login->session_pipe) { g_signal_connect (login->auth_pipe, "close", G_CALLBACK (on_login_done), g_object_ref (result)); } else { g_simple_async_result_set_error (result, COCKPIT_ERROR, COCKPIT_ERROR_FAILED, "Internal error starting session process"); g_simple_async_result_complete_in_idle (result); } } g_free (user); g_object_unref (result); }
/** * cockpit_auth_start_session: * @self: a CockpitAuth * @creds: credentials for the session * * Start a local session process for the given credentials. It may be * that one is hanging around from prior authentication, in which case * that one is used. * * If launching the session fails, then the pipe will be created in a * failed state, and will close shortly. A CockpitPipe is always returned. * * Returns: (transfer full): the new pipe */ CockpitPipe * cockpit_auth_start_session (CockpitAuth *self, CockpitCreds *creds) { CockpitPipe *pipe; CockpitPipe *auth_pipe = NULL; const gchar *password; GBytes *bytes; g_return_val_if_fail (creds != NULL, NULL); pipe = pop_session_process (self, creds); if (pipe == NULL) { password = cockpit_creds_get_password (creds); if (password == NULL) { bytes = NULL; } else { bytes = g_bytes_new_with_free_func (password, strlen (password), cockpit_creds_unref, creds); } pipe = spawn_session_process (cockpit_creds_get_user (creds), bytes, cockpit_creds_get_rhost (creds), &auth_pipe); if (auth_pipe) { /* * Any failure will come from the pipe exit code, but the session * needs our password (if we have one) so let it get sent. */ g_signal_connect (auth_pipe, "close", G_CALLBACK (g_object_unref), NULL); } } if (!pipe) { pipe = g_object_new (COCKPIT_TYPE_PIPE, "problem", "internal-error", NULL); } return pipe; }