diff --git a/src/api/ssh_keys_get.c b/src/api/ssh_keys_get.c new file mode 100644 index 0000000000000000000000000000000000000000..255442174be3a3f72fa99ed6eb59b766a4865c42 --- /dev/null +++ b/src/api/ssh_keys_get.c @@ -0,0 +1,82 @@ +/** + * 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) + { + 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) + { + printf("Could not open authorized_keys file\n"); + 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; +} diff --git a/src/cryptops-api.c b/src/cryptops-api.c index 46762612e6aac5ae120316afe84abf93135a0455..bd168686abfafefb94f0cd7a760803e5a7170f09 100644 --- a/src/cryptops-api.c +++ b/src/cryptops-api.c @@ -8,6 +8,7 @@ #include <api/default.c> #include <api/encryption_add.c> #include <api/encryption_unlock.c> +#include <api/ssh_keys_get.c> int main(int argc, char ** argv) { @@ -32,6 +33,8 @@ int main(int argc, char ** argv) 0, &callback_encryption_add, &reboot); ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, "/encryption/unlock", 0, &callback_encryption_unlock, NULL); + ulfius_add_endpoint_by_val(&instance, "GET" , PREFIX, "/ssh/keys", + 0, &callback_ssh_keys_get, NULL); // Add default endpoint. ulfius_set_default_endpoint(&instance, &callback_default, NULL); diff --git a/src/includes/settings.h b/src/includes/settings.h index bb61b7e4b31a6b139d3e5ac8110429afdf32ed44..b9152495e10ec082612699939b1ed435b38383d5 100644 --- a/src/includes/settings.h +++ b/src/includes/settings.h @@ -13,4 +13,4 @@ #define TMP_LOCATION "/tmp/" MAPPED_DEVICE_NAME #define AUTHORIZED_KEYS_DIR "/root/.ssh" #define AUTHORIZED_KEYS_PATH AUTHORIZED_KEYS_DIR "/authorized_keys" -#define SSH_HOST_KEY_DIR "/dropbear" +#define SSH_HOST_KEY_DIR "/dropbear" \ No newline at end of file