static void cockpit_auth_remote_login_async (CockpitAuth *self, GHashTable *headers, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *task; CockpitCreds *creds = NULL; RemoteLoginData *rl; const gchar *password; GBytes *input; gchar *type = NULL; gchar *user = NULL; task = g_simple_async_result_new (G_OBJECT (self), callback, user_data, cockpit_auth_remote_login_async); input = cockpit_auth_parse_authorization (headers, &type); if (type && input && g_str_equal (type, "basic")) { password = parse_basic_auth_password (input, &user); if (password && user) { creds = cockpit_creds_new (user, COCKPIT_CRED_PASSWORD, password, COCKPIT_CRED_RHOST, remote_peer, NULL); } g_free (user); } if (creds) { rl = g_new0 (RemoteLoginData, 1); rl->creds = creds; rl->transport = g_object_new (COCKPIT_TYPE_SSH_TRANSPORT, "host", "127.0.0.1", "port", cockpit_ws_specific_ssh_port, "command", cockpit_ws_bridge_program, "creds", creds, "ignore-key", TRUE, NULL); g_simple_async_result_set_op_res_gpointer (task, rl, remote_login_data_free); g_signal_connect (rl->transport, "result", G_CALLBACK (on_remote_login_done), g_object_ref (task)); } else { g_simple_async_result_set_error (task, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED, "Basic authentication required"); g_simple_async_result_complete_in_idle (task); } g_free (type); g_object_unref (task); }
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_spawn_login_async (CockpitAuth *self, const gchar *application, const gchar *type, gboolean decode_header, GHashTable *headers, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *result; GBytes *input = NULL; AuthData *ad = NULL; const gchar *command; const gchar *argv[] = { "command", type, remote_peer ? remote_peer : "", NULL, }; result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, cockpit_auth_spawn_login_async); command = type_option (type, "command", cockpit_ws_session_program); input = cockpit_auth_parse_authorization (headers, decode_header); if (!input && !gssapi_not_avail && g_strcmp0 (type, "negotiate") == 0) input = g_bytes_new_static ("", 0); if (input && application) { argv[0] = command; ad = create_auth_data (self, "localhost", application, type, remote_peer, command, input); start_auth_process (self, ad, input, result, cockpit_auth_spawn_login_async, argv); } else { g_simple_async_result_set_error (result, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED, "Authentication required"); g_simple_async_result_complete_in_idle (result); } if (input) g_bytes_unref (input); if (ad) auth_data_unref (ad); g_object_unref (result); }
static void cockpit_auth_remote_login_async (CockpitAuth *self, const gchar *application, const gchar *type, GHashTable *headers, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *task; AuthData *ad = NULL; GBytes *input = NULL; GBytes *auth_bytes = NULL; gchar *user = NULL; gchar *password = NULL; /* owned by input */ const gchar *data = NULL; const gchar *command; const gchar *host; const gchar *host_arg; gint next_arg = 1; const gchar *argv[] = { cockpit_ws_ssh_program, NULL, NULL, NULL, NULL, NULL, NULL, }; task = g_simple_async_result_new (G_OBJECT (self), callback, user_data, cockpit_auth_remote_login_async); if (g_strcmp0 (type, "basic") == 0) { input = cockpit_auth_parse_authorization (headers, TRUE); data = g_bytes_get_data (input, NULL); password = strchr (data, ':'); if (password != NULL) { user = g_strndup (data, password - data); password++; auth_bytes = g_bytes_new_static (password, strlen(password)); } } else { input = cockpit_auth_parse_authorization (headers, FALSE); if (input) auth_bytes = g_bytes_ref (input); } if (application && auth_bytes && input) { command = type_option (SSH_SECTION, "command", cockpit_ws_ssh_program); argv[0] = command; host = application_parse_host (application); if (host) { host_arg = host; if (g_strcmp0 (remote_peer, "127.0.0.1") == 0 || g_strcmp0 (remote_peer, "::1") == 0 || cockpit_conf_bool (SSH_SECTION, "allowUnknown", FALSE)) { argv[next_arg++] = "--prompt-unknown-hostkey"; } } else { argv[next_arg++] = "--ignore-hostkey"; if (cockpit_conf_string (SSH_SECTION, "host")) host_arg = cockpit_conf_string (SSH_SECTION, "host"); else host_arg = "localhost"; } argv[next_arg++] = host_arg; argv[next_arg++] = user; ad = create_auth_data (self, host_arg, application, SSH_SECTION, remote_peer, command, input); start_auth_process (self, ad, auth_bytes, task, cockpit_auth_remote_login_async, argv); } else { g_simple_async_result_set_error (task, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED, "Basic authentication required"); g_simple_async_result_complete_in_idle (task); } if (auth_bytes) g_bytes_unref (auth_bytes); if (input) g_bytes_unref (input); if (ad) auth_data_unref (ad); if (user) g_free (user); g_object_unref (task); }