/** * Read the authorized_keys file of the initrd, and put its lines in a json * array. * @return json array of authorized_keys */ json_t * readAuthorizedKeysToJson() { json_t * keys = json_object(); // Open file. FILE * authorized_keys = fopen(AUTHORIZED_KEYS_PATH, "r"); // Check if that succeeded. if (authorized_keys == NULL) { return NULL; } // Read file line by line. int index = 1; char * field; char * line = NULL; size_t line_length = 0; ssize_t read; while ((read = getline(&line, &line_length, authorized_keys)) != -1) { // Ignore empty lines, they do have IDs though. if (strlen(line) > 1) { asprintf(&field, "%d", index); // Remove trailing newline. line[strcspn(line, "\n")] = 0; json_object_set(keys, field, json_string(line)); } index++; } // Close file and clean up. fclose(authorized_keys); if (line) { free(line); } return keys; } /** * Callback function that lists the current ssh keys authorised for access * to the initrd. * * Example output: * {"ssh-keys":{"1":"ssh-rsa AAAAB3... example@example.com", * "2":"ssh-rsa AAAAB3...","5":"command=\"/usr/bin/cryptops-client\" ssh-rsa * AAAAB3... cryptops-test@greenhost"}} * * The indices correspond to line numbers of the authorized_keys file. * Missing indices (like 3 and 4 in the example) arise from empty lines in the * file; those are creted when keys are deleted. * * @param[in] request incoming HTTP request * @param[out] response HTTP response to the request * @param[in] user_data extra data to pass between main thread and callbacks * @return internal status code */ int callback_ssh_keys_get(const struct _u_request * request, struct _u_response * response, void * user_data) { // Read lines of authorized_keys file into json array. json_t * keys = readAuthorizedKeysToJson(); if (keys == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "Could not open authorized_keys file"); return send_simple_response(response, 500, "error", "error reading authorized_keys"); } // Create json response. json_t * json_body = NULL; json_body = json_object(); json_object_set_new(json_body, "ssh-keys", keys); // Send response. ulfius_set_json_body_response(response, 200, json_body); json_decref(json_body); return U_CALLBACK_CONTINUE; }