static JsonObject * parse_login_data (const gchar *json_str) { JsonObject *results = NULL; JsonObject *login_data = NULL; GError *error = NULL; results = cockpit_json_parse_object (json_str, strlen(json_str), &error); if (!results) { g_warning ("received bad json data: %s", error->message); g_error_free (error); goto out; } if (!cockpit_json_get_object (results, "login-data", NULL, &login_data)) { g_warning ("received bad login-data: %s", json_str); login_data = NULL; goto out; } if (login_data) login_data = json_object_ref (login_data); out: if (results) json_object_unref (results); return login_data; }
static CockpitCreds * parse_auth_results (LoginData *login, GError **error) { CockpitCreds *creds = NULL; GByteArray *buffer; GError *json_error = NULL; const gchar *pam_user; JsonObject *results; gconstpointer data; gint64 code = -1; gchar *password; gsize length; buffer = cockpit_pipe_get_buffer (login->auth_pipe); results = cockpit_json_parse_object ((const gchar *)buffer->data, buffer->len, &json_error); if (g_error_matches (json_error, JSON_PARSER_ERROR, JSON_PARSER_ERROR_INVALID_DATA)) { g_message ("got non-utf8 user name from cockpit-session"); g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Login user name is not UTF8 encoded"); g_error_free (json_error); return NULL; } if (!results) { g_warning ("couldn't parse session auth output: %s", json_error->message); g_error_free (json_error); return NULL; } if (!cockpit_json_get_int (results, "pam-result", -1, &code) || code < 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid data from session process: bad PAM result"); } else if (code == PAM_SUCCESS) { if (!cockpit_json_get_string (results, "user", NULL, &pam_user) || !pam_user) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid data from session process: missing user"); } else { g_debug ("user authenticated as %s", pam_user); /* TODO: Try to avoid copying password */ data = g_bytes_get_data (login->password, &length); password = g_strndup (data, length); creds = cockpit_creds_new (pam_user, COCKPIT_CRED_PASSWORD, password, COCKPIT_CRED_RHOST, login->remote_peer, NULL); g_free (password); } } else if (code == PAM_AUTH_ERR || code == PAM_USER_UNKNOWN) { g_debug ("authentication failed: %d", (int)code); g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED, "Authentication failed"); } else { g_debug ("pam error: %d", (int)code); g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED, "%s", pam_strerror (NULL, code)); } json_object_unref (results); return creds; }
static CockpitCreds * parse_auth_results (SessionLoginData *sl, GHashTable *headers, GError **error) { CockpitCreds *creds = NULL; GByteArray *buffer; GError *json_error = NULL; const gchar *pam_user; JsonObject *results; gint64 code = -1; buffer = cockpit_pipe_get_buffer (sl->auth_pipe); g_debug ("cockpit-session says: %.*s", (int)buffer->len, (const gchar *)buffer->data); results = cockpit_json_parse_object ((const gchar *)buffer->data, buffer->len, &json_error); if (g_error_matches (json_error, JSON_PARSER_ERROR, JSON_PARSER_ERROR_INVALID_DATA)) { g_message ("got non-utf8 user name from cockpit-session"); g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Login user name is not UTF8 encoded"); g_error_free (json_error); } else if (!results) { g_warning ("couldn't parse session auth output: %s", json_error ? json_error->message : NULL); g_error_free (json_error); g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid data from session process: no results"); } else if (!cockpit_json_get_int (results, "result-code", -1, &code) || code < 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid data from session process: bad PAM result"); } else if (code == PAM_SUCCESS) { if (!cockpit_json_get_string (results, "user", NULL, &pam_user) || !pam_user) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid data from session process: missing user"); } else { g_debug ("user authenticated as %s", pam_user); creds = create_creds_for_authenticated (pam_user, sl, results); } } else if (code == PAM_AUTH_ERR || code == PAM_USER_UNKNOWN) { g_debug ("authentication failed: %d", (int)code); g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED, "Authentication failed"); } else if (code == PAM_PERM_DENIED) { g_debug ("permission denied: %d", (int)code); g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_PERMISSION_DENIED, "Permission denied"); } else { g_debug ("pam error: %d", (int)code); g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED, "%s", pam_strerror (NULL, code)); } build_gssapi_output_header (headers, results); if (results) json_object_unref (results); return creds; }