Skip to content
Snippets Groups Projects
Commit d61e0219 authored by Arie Peterson's avatar Arie Peterson
Browse files

Clean up syntax and comments

parent 0c9687cc
No related branches found
No related tags found
No related merge requests found
TARGETS=cryptops-api
CFLAGS=-O0 -g -Wall -D_GNU_SOURCE -Iincludes
LDLIBS=-L/test/libraries -lcryptsetup -lc -lulfius -lyder -lorcania -ljansson
LDLIBS=-L./libraries -lcryptsetup -lc -lulfius -lyder -lorcania -ljansson
CC=gcc
all: $(TARGETS)
......
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#define U_DISABLE_CURL
#define U_DISABLE_WEBSOCKET
......@@ -9,55 +8,92 @@
#include <jansson.h>
#include <libcryptsetup.h>
#define PORT 8000
#define PORT 8537
#define PREFIX "/cryptops/v0"
#define CONTAINER_DEVICE "/dev/xvda1"
#define MAPPED_DEVICE_NAME "rootdisk"
#define MAPPED_DEVICE_NAME "xvda1_crypt"
#define FIFO_PATH "/tmp/cryptops-api-stop"
/**
* helper functions declaration
*/
char * read_file(const char * filename);
void stop_server();
int send_simple_response
(
struct _u_response * response,
int http_status,
const char *field,
const char *value
);
/**
* callback functions declaration
*/
int callback_encryption_unlock (const struct _u_request * request, struct _u_response * response, void * user_data);
int callback_default (const struct _u_request * request, struct _u_response * response, void * user_data);
static int encryption_unlock(const char *path, const char *device_name, const char *password);
int callback_encryption_unlock
(
const struct _u_request * request,
struct _u_response * response,
void * user_data
);
int callback_default
(
const struct _u_request * request,
struct _u_response * response,
void * user_data
);
static int encryption_unlock
(
const char *path,
const char *device_name,
const char *password
);
int main (int argc, char **argv)
int main(int argc, char **argv)
{
int ret;
// Set the framework port number
y_init_logs
(
"cryptops-api",
Y_LOG_MODE_CONSOLE,
Y_LOG_LEVEL_DEBUG,
NULL,
"Starting cryptops-api"
);
struct _u_instance instance;
y_init_logs("cryptops-api", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting cryptops-api");
if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK)
{
y_log_message(Y_LOG_LEVEL_ERROR, "Error ulfius_init_instance, abort");
return(1);
}
u_map_put(instance.default_headers, "Access-Control-Allow-Origin", "*");
// Maximum body size sent by the client is 1 Kb
// Maximum body size sent by the client is 1 Kb.
instance.max_post_body_size = 1024;
// Endpoint list declaration
ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, "/encryption/unlock", 0, &callback_encryption_unlock, NULL);
// default_endpoint declaration
// Add api endpoints.
ulfius_add_endpoint_by_val
(
&instance,
"POST",
PREFIX,
"/encryption/unlock",
0,
&callback_encryption_unlock,
NULL
);
// Add default endpoint.
ulfius_set_default_endpoint(&instance, &callback_default, NULL);
// Start the framework
// Start the framework.
int ret;
if (argc == 4 && strcmp("-secure", argv[1]) == 0)
{
// If command-line options are -secure <key_file> <cert_file>, then open an https connection
// If command-line options are -secure <key_file> <cert_file>,
// then listen for https connections.
char * key_pem = read_file(argv[2]), * cert_pem = read_file(argv[3]);
ret = ulfius_start_secure_framework(&instance, key_pem, cert_pem);
o_free(key_pem);
......@@ -65,16 +101,36 @@ int main (int argc, char **argv)
}
else
{
// Open an http connection
// Listen for http connections.
ret = ulfius_start_framework(&instance);
}
if (ret == U_OK)
{
y_log_message(Y_LOG_LEVEL_DEBUG, "Start %sframework on port %d", ((argc == 4 && strcmp("-secure", argv[1]) == 0)?"secure ":""), instance.port);
y_log_message
(
Y_LOG_LEVEL_DEBUG,
"Start %sframework on port %d",
((argc == 4 && strcmp("-secure", argv[1]) == 0)?"secure ":""),
instance.port
);
// Wait for the user to press <enter> on the console to quit the application
getchar();
// Wait for signal from fifo to quit.
y_init_logs
(
"cryptops-api",
Y_LOG_MODE_CONSOLE,
Y_LOG_LEVEL_DEBUG,
NULL,
"Waiting for fifo signal to quit"
);
int fifo = 0;
char buf[4];
char fifo_path[] = FIFO_PATH;
mkfifo(fifo_path, 0600);
fifo = open(fifo_path, O_RDONLY);
// This will block until the fifo is written to.
read(fifo, &buf, 4);
}
else
{
......@@ -91,67 +147,86 @@ int main (int argc, char **argv)
}
/**
* Callback function that uses the given password to open the luks volume.
* Callback function that uses the password passed in the request to open the
* luks volume.
*/
int callback_encryption_unlock(const struct _u_request * request, struct _u_response * response, void * user_data)
int callback_encryption_unlock
(
const struct _u_request * request,
struct _u_response * response,
void * user_data
)
{
json_t * json_input = ulfius_get_json_body_request(request, NULL);
// json_t * password = json_object_get(json_input, "password");
const char * password = json_string_value(json_object_get(json_input, "password"));
const char * password;
password = json_string_value(json_object_get(json_input, "password"));
if (password == NULL)
{
json_t * json_body = NULL;
json_body = json_object();
json_object_set_new(json_body, "error", json_string("missing password"));
ulfius_set_json_body_response(response, 400, json_body);
json_decref(json_body);
return U_CALLBACK_CONTINUE;
return send_simple_response(response, 400, "error", "missing password");
}
int unlock_status = encryption_unlock(CONTAINER_DEVICE, MAPPED_DEVICE_NAME, password);
int unlock_status = encryption_unlock
(
CONTAINER_DEVICE,
MAPPED_DEVICE_NAME,
password
);
if (unlock_status == -1)
{
// Experience learns that -1 is returned when the password is wrong.
json_t * json_body = NULL;
json_body = json_object();
json_object_set_new(json_body, "error", json_string("incorrect password"));
ulfius_set_json_body_response(response, 403, json_body);
json_decref(json_body);
return U_CALLBACK_CONTINUE;
return send_simple_response
(
response,
403,
"error",
"incorrect password"
);
}
if (unlock_status != 0)
{
// Something else went wrong with unlocking.
printf("encryption_unlock failed with status %d\n", unlock_status);
json_t * json_body = NULL;
json_body = json_object();
json_object_set_new(json_body, "error", json_string("error during unlocking"));
ulfius_set_json_body_response(response, 500, json_body);
json_decref(json_body);
return U_CALLBACK_CONTINUE;
return send_simple_response(response, 500, "error", "error during unlocking");
}
// If we reach this point, apparently everything went well.
json_t * json_body = NULL;
json_body = json_object();
json_object_set_new(json_body, "status", json_string("ok"));
ulfius_set_json_body_response(response, 200, json_body);
json_decref(json_body);
return U_CALLBACK_CONTINUE;
stop_server();
return send_simple_response(response, 200, "status", "ok");
}
/**
* Default callback function called if no endpoint has a match
* Default callback function called if no other endpoint matches.
*/
int callback_default(const struct _u_request * request, struct _u_response * response, void * user_data)
int callback_default
(
const struct _u_request * request,
struct _u_response * response,
void * user_data
)
{
ulfius_set_string_body_response(response, 404, "Unknown endpoint");
return U_CALLBACK_CONTINUE;
}
/**
* Use a fifo to signal that we want to stop the api server.
*/
void stop_server()
{
printf("Stopping cryptops-api server...\n");
int fifo;
char fifo_path[] = FIFO_PATH;
fifo = open(fifo_path, O_WRONLY);
char * msg = "stop";
write(fifo, msg, strlen(msg) + 1);
}
/**
* Read a file completely into a string.
*/
char * read_file(const char * filename)
{
char * buffer = NULL;
......@@ -180,17 +255,39 @@ char * read_file(const char * filename)
}
}
static int encryption_unlock(const char *path, const char *device_name, const char *password)
/**
* Respond to the request with a simple json structure '{$field: $value}'.
*/
int send_simple_response
(
struct _u_response * response, /* response struct to use */
int http_status, /* HTTP status code to return */
const char *field, /* name of the json field to return */
const char *value /* json value to return */
)
{
json_t * json_body = NULL;
json_body = json_object();
json_object_set_new(json_body, field, json_string(value));
ulfius_set_json_body_response(response, http_status, json_body);
json_decref(json_body);
return U_CALLBACK_CONTINUE;
}
/**
* Use cryptsetup to unlock the luks container.
* This will create `/dev/mapper/$device_name`.
*/
static int encryption_unlock
(
const char *path, /* path to the encrypted container */
const char *device_name, /* name of the mapping */
const char *password /* encryption password of the container */
)
{
// Let LUKS initialise the encrypted device.
struct crypt_device *cd;
int r;
/*
* LUKS device activation example.
* It's sequence of sub-steps: device initialization, LUKS header load
* and the device activation itself.
*/
r = crypt_init(&cd, path);
int r = crypt_init(&cd, path);
if (r < 0)
{
printf("crypt_init() failed for %s.\n", path);
......@@ -198,27 +295,29 @@ static int encryption_unlock(const char *path, const char *device_name, const ch
return r;
}
/*
* crypt_load() is used to load the LUKS header from block device
* into crypt_device context.
*/
r = crypt_load(
cd, /* crypt context */
CRYPT_LUKS1, /* requested type */
// Load the LUKS header from the block device into the crypt device context.
r = crypt_load
(
cd, /* crypt device context */
CRYPT_LUKS1, /* requested encryption type */
NULL /* additional parameters (not used) */
);
if (r < 0)
{
printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
printf
(
"crypt_load() failed on device %s.\n",
crypt_get_device_name(cd)
);
crypt_free(cd);
return r;
}
/*
* Device activation creates device-mapper devie mapping with name device_name.
*/
r = crypt_activate_by_passphrase(
// Device activation creates device-mapper devie mapping with namei
// device_name.
r = crypt_activate_by_passphrase
(
cd, /* crypt context */
device_name, /* device name to activate */
CRYPT_ANY_SLOT, /* which slot use (ANY - try all) */
......
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