CockpitCreds * cockpit_auth_login_finish (CockpitAuth *self, GAsyncResult *result, gboolean force_secure, GHashTable *out_headers, GError **error) { CockpitAuthClass *klass = COCKPIT_AUTH_GET_CLASS (self); CockpitCreds *creds; gs_free char *cookie = NULL; gs_free gchar *cookie_b64 = NULL; gchar *header; g_return_val_if_fail (klass->login_finish != NULL, FALSE); creds = klass->login_finish (self, result, error); if (creds && out_headers) { cookie = creds_to_cookie (self, creds); cookie_b64 = g_base64_encode ((guint8 *)cookie, strlen (cookie)); header = g_strdup_printf ("CockpitAuth=%s; Path=/; Expires=Wed, 13-Jan-2021 22:23:01 GMT;%s HttpOnly", cookie_b64, force_secure ? " Secure;" : ""); g_hash_table_insert (out_headers, g_strdup ("Set-Cookie"), header); } return creds; }
void cockpit_auth_login_async (CockpitAuth *self, const gchar *path, GHashTable *headers, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { CockpitAuthClass *klass = COCKPIT_AUTH_GET_CLASS (self); GSimpleAsyncResult *result = NULL; g_return_if_fail (klass->login_async != NULL); self->startups++; if (can_start_auth (self)) { klass->login_async (self, path, headers, remote_peer, callback, user_data); } else { g_message ("Request dropped; too many startup connections: %u", self->startups); result = g_simple_async_result_new_error (G_OBJECT (self), callback, user_data, COCKPIT_ERROR, COCKPIT_ERROR_FAILED, "Connection closed by host"); g_simple_async_result_complete_in_idle (result); } if (result) g_object_unref (result); }
gboolean cockpit_auth_verify_password (CockpitAuth *auth, const gchar *user, const gchar *password, GError **error) { CockpitAuthClass *klass = COCKPIT_AUTH_GET_CLASS (auth); g_return_val_if_fail (klass->verify_password != NULL, FALSE); return klass->verify_password (auth, user, password, error); }
void cockpit_auth_login_async (CockpitAuth *self, GHashTable *headers, const gchar *remote_peer, GAsyncReadyCallback callback, gpointer user_data) { CockpitAuthClass *klass = COCKPIT_AUTH_GET_CLASS (self); g_return_if_fail (klass->login_async != NULL); klass->login_async (self, headers, remote_peer, callback, user_data); }
CockpitWebService * cockpit_auth_login_finish (CockpitAuth *self, GAsyncResult *result, CockpitAuthFlags flags, GHashTable *out_headers, GError **error) { CockpitAuthClass *klass = COCKPIT_AUTH_GET_CLASS (self); CockpitAuthenticated *authenticated; CockpitTransport *transport = NULL; CockpitCreds *creds; gchar *cookie_b64 = NULL; gchar *header; guint64 seed; gchar *id; g_return_val_if_fail (klass->login_finish != NULL, FALSE); creds = klass->login_finish (self, result, out_headers, &transport, error); if (creds == NULL) return NULL; seed = self->nonce_seed++; id = g_compute_hmac_for_data (G_CHECKSUM_SHA256, self->key->data, self->key->len, (guchar *)&seed, sizeof (seed)); authenticated = g_new0 (CockpitAuthenticated, 1); authenticated->cookie = g_strdup_printf ("v=2;k=%s", id); authenticated->creds = creds; authenticated->service = cockpit_web_service_new (creds, transport); authenticated->auth = self; authenticated->idling_sig = g_signal_connect (authenticated->service, "idling", G_CALLBACK (on_web_service_idling), authenticated); authenticated->destroy_sig = g_signal_connect (authenticated->service, "destroy", G_CALLBACK (on_web_service_destroy), authenticated); if (transport) g_object_unref (transport); g_object_weak_ref (G_OBJECT (authenticated->service), on_web_service_gone, authenticated); /* Start off in the idling state, and begin a timeout during which caller must do something else */ on_web_service_idling (authenticated->service, authenticated); g_hash_table_insert (self->authenticated, authenticated->cookie, authenticated); g_debug ("sending credential id '%s' for user '%s'", id, cockpit_creds_get_user (creds)); g_free (id); if (out_headers) { gboolean force_secure = !(flags & COCKPIT_AUTH_COOKIE_INSECURE); cookie_b64 = g_base64_encode ((guint8 *)authenticated->cookie, strlen (authenticated->cookie)); header = g_strdup_printf ("cockpit=%s; Path=/; %s HttpOnly", cookie_b64, force_secure ? " Secure;" : ""); g_free (cookie_b64); g_hash_table_insert (out_headers, g_strdup ("Set-Cookie"), header); } g_info ("logged in user: %s", cockpit_creds_get_user (authenticated->creds)); return g_object_ref (authenticated->service); }