Skip to content
Snippets Groups Projects
Commit 9fb0fd90 authored by Maarten de Waard's avatar Maarten de Waard :angel:
Browse files

basic PUT and DELETE behavior, still does some weird stuff with random unicode...

basic PUT and DELETE behavior, still does some weird stuff with random unicode characters appearing some times
parent cc550fef
No related branches found
No related tags found
No related merge requests found
/**
* Callback function that deletes an SSH key from the list of keys authorised
* for access to the initrd. The line will be left empty, because that keeps
* the ids if SSH keys in tact for ssh_keys_get
*
* 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_delete(const struct _u_request * request,
struct _u_response * response, void * user_data)
{
// Read ssh key id from request URI.
const char * id_string = u_map_get(request->map_url, "id");
if (id_string == NULL)
{
return send_simple_response(response, 400, "error",
"missing url parameter `id`");
}
int id;
int r = parse_int(id_string, &id);
if (r != 0)
{
printf("invalid url parameter `id`: %s\n", id_string);
return send_simple_response(response, 400, "error",
"invalid url parameter `id`");
}
// Replace the key at ID with ""
r = replace_ssh_key(id, "");
if(r < 0)
{
if(r == -1)
return send_simple_response(response, 500, "error",
"error opening authorized_keys");
if(r == -2)
return send_simple_response(response, 500, "error",
"error opening authorized_keys tmp file");
return send_simple_response(response, 500, "error",
"Unknown error while processing ssh keys");
}
return send_simple_response(response, 200, "status", "ok");
}
/**
* Callback function that deletes an SSH key from the list of keys authorised
* for access to the initrd. The line will be left empty, because that keeps
* the ids if SSH keys in tact for ssh_keys_get
*
* 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_put(const struct _u_request * request,
struct _u_response * response, void * user_data)
{
// Read ssh key id from request URI.
const char * id_string = u_map_get(request->map_url, "id");
if (id_string == NULL)
{
return send_simple_response(response, 400, "error",
"missing url parameter `id`");
}
int id;
int r = parse_int(id_string, &id);
if (r != 0)
{
printf("invalid url parameter `id`: %s\n", id_string);
return send_simple_response(response, 400, "error",
"invalid url parameter `id`");
}
// Read in json request body.
json_t * json_input = ulfius_get_json_body_request(request, NULL);
// Read SSH key from request.
const char * ssh_key;
ssh_key = json_string_value(json_object_get(json_input, "ssh-key"));
if (ssh_key == NULL)
{
return send_simple_response(response, 400, "error", "missing ssh-key");
}
r = replace_ssh_key(id, ssh_key);
if(r < 0)
{
if(r == -1)
return send_simple_response(response, 500, "error",
"error opening authorized_keys");
if(r == -2)
return send_simple_response(response, 500, "error",
"error opening authorized_keys tmp file");
return send_simple_response(response, 500, "error",
"Unknown error while processing ssh keys");
}
return send_simple_response(response, 200, "status", "ok");
}
......@@ -191,3 +191,90 @@ int parse_int(const char * input, int * result)
*result = l;
return 0;
}
/**
* Write an ssh_key to a specific rule in the authorized_keys file.
*
* @param[in] id line number/ssh_key id
* @param[in] ssh_key ssh key contents. If this string is empty, this is seen
* as deleting the key. Newline characters are ignored
*/
int replace_ssh_key(int id, const char * ssh_key)
{
// Open file.
FILE * authorized_keys_in = fopen(AUTHORIZED_KEYS_PATH, "r");
// Check if that succeeded.
if (authorized_keys_in == NULL)
{
printf("Could not open authorized_keys file for reading\n");
return -1;
}
// Make tmp outfile for authorized keys
char * authorized_keys_out_name;
asprintf(&authorized_keys_out_name, "%s%s", AUTHORIZED_KEYS_PATH, ".tmp");
// Open file.
FILE * authorized_keys_out = fopen(authorized_keys_out_name, "w");
// Check if that succeeded.
if (authorized_keys_out == NULL)
{
printf("Could not open authorized_keys tmp file for writing\n");
return -2;
}
int line_number = 1;
char ch;
// Loop through all the characters in the input file
do {
ch = getc(authorized_keys_in);
if (ch == '\n')
line_number++;
if (line_number != id)
{
// Copy all lines that don't have id as line number
putc(ch, authorized_keys_out);
}
else
{
// Insert the new line first
putc(ch);
// Copy ssh_key to the line that has id as line number
// Some magic happens here, where *ssh_key++ returns the current
// index and moves the pointer to the next index of ssh_key
// TODO: prepend ssh_key with command= line
while(*ssh_key)
{
printf("inserting %c\n", *ssh_key);
if(*ssh_key != '\n' && *ssh_key != '\r')
{
putc(*ssh_key++, authorized_keys_out);
}
}
printf("inserting new line %c\n", *ssh_key);
putc('\n', authorized_keys_out);
// Read characters until the next newline
do {
printf("not inserting %c\n", ch);
ch = getc(authorized_keys_in);
} while (ch != EOF && ch != '\n');
printf("increasing line number to %d\n", line_number + 1);
// Increment line_number because the next loop will read a new
// character
line_number++;
}
} while (ch != EOF);
fclose(authorized_keys_in);
fclose(authorized_keys_out);
// Remove old authorized_keys file and replace it with the new one
remove(AUTHORIZED_KEYS_PATH);
rename(authorized_keys_out_name, AUTHORIZED_KEYS_PATH);
return 0;
}
......@@ -10,7 +10,9 @@
#include <api/encryption_unlock.c>
#include <api/encryption_keys_put.c>
#include <api/ssh_keys_get.c>
#include <api/ssh_keys_put.c>
#include <api/ssh_keys_post.c>
#include <api/ssh_keys_delete.c>
int main(int argc, char ** argv)
{
......@@ -50,9 +52,15 @@ int main(int argc, char ** argv)
ulfius_add_endpoint_by_val(&instance, "GET" , PREFIX,
"/ssh/keys",
0, &callback_ssh_keys_get, NULL);
ulfius_add_endpoint_by_val(&instance, "PUT" , PREFIX,
"/ssh/keys/:id",
0, &callback_ssh_keys_put, NULL);
ulfius_add_endpoint_by_val(&instance, "POST" , PREFIX,
"/ssh/keys",
0, &callback_ssh_keys_post, NULL);
ulfius_add_endpoint_by_val(&instance, "DELETE" , PREFIX,
"/ssh/keys/:id",
0, &callback_ssh_keys_delete, NULL);
// Add default endpoint.
ulfius_set_default_endpoint(&instance, &callback_default, NULL);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment