aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2018-06-23 20:41:45 -0400
committerFranklin Wei <me@fwei.tk>2018-06-23 20:41:45 -0400
commit54cffee43a62dcb176bbd0fb7525598d275cfde4 (patch)
tree8c60c53ef311fa94b6b0ccfc9c1c046b37b817c3
parent77094976e17f3c1151dc7210815f0d47029ea54b (diff)
downloadcsaa-54cffee43a62dcb176bbd0fb7525598d275cfde4.zip
csaa-54cffee43a62dcb176bbd0fb7525598d275cfde4.tar.gz
csaa-54cffee43a62dcb176bbd0fb7525598d275cfde4.tar.bz2
csaa-54cffee43a62dcb176bbd0fb7525598d275cfde4.tar.xz
Add command-line interface for client
Mostly functional now; file info and content retrieval not fully done yet.
-rw-r--r--client.c367
-rw-r--r--container1/docker-compose.yml6
-rw-r--r--container1/hello-world.tarbin0 -> 12800 bytes
-rw-r--r--crypto.c23
-rw-r--r--helper.c2
-rw-r--r--main.c7
-rw-r--r--service_provider.c90
-rw-r--r--service_provider.h27
-rw-r--r--trusted_module.c6
9 files changed, 455 insertions, 73 deletions
diff --git a/client.c b/client.c
index 27e8a4d..4ee9d99 100644
--- a/client.c
+++ b/client.c
@@ -1,5 +1,17 @@
-/* Taken from
- * https://github.com/troydhanson/network/blob/master/unixdomain/01.basic/cli.c */
+/* Based on:
+ * <https://github.com/troydhanson/network/blob/master/unixdomain/01.basic/cli.c> */
+
+/* Usage:
+ *
+ * $ ./client [-s <SOCKET>] -k KEY -u USERID COMMAND [PARAMS]
+ *
+ * Where COMMAND and PARAMS is one of the following:
+ * create (takes no parameters)
+ * modifyacl fileidx user_1 acc_1 ... user_n acc_n
+ * modifyfile fileidx buildcode_file compose_file image_file [FILE_KEY]
+ * retrieveinfo fileidx version
+ * retrievefile fileidx version buildcode_out compose_out image_out [FILE_KEY]
+ */
#define CLIENT
#include "crypto.h"
@@ -10,19 +22,232 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
-char *socket_path = "socket";
+static const char *socket_path = "socket";
+static const char *parse_args_fail = NULL;
+static const char *userkey = NULL;
+static uint64_t user_id = 0;
+static struct user_request cl_request;
+static struct iomt *new_acl = NULL;
+const char *buildcode_path = NULL, *compose_path = NULL, *image_path = NULL, *file_key = NULL;
+
+int compare_tuple(const void *p1, const void *p2)
+{
+ const uint64_t *a = p1, *b = p2;
+ if(*a < *b)
+ return -1;
+ else if(*a == *b)
+ return 0;
+ else
+ return 1;
+}
+
+static int ilog2(int n)
+{
+ int l = 0;
+ while(n > 1)
+ {
+ n >>= 1;
+ ++l;
+ }
+ return l;
+}
+
+void print_usage(const char *name)
+{
+ printf("Usage: %s [-s <SOCKET>] -k KEY -u USERID COMMAND [PARAMS]\n"
+ "\n"
+ "Where COMMAND and PARAMS are one of the following:\n"
+ " create (takes no parameters)\n"
+ " modifyacl fileidx USER1 ACCESS1 ... USERn ACCESSn\n"
+ " modifyfile fileidx buildcode_file compose_file image_file [FILE_KEY]\n"
+ " retrieveinfo fileidx version\n"
+ " retrievefile fileidx version buildcode_out compose_out image_out [FILE_KEY]\n", name);
+}
+
+bool parse_args(int argc, char *argv[])
+{
+ for(int i = 1; i < argc; ++i)
+ {
+ char *arg = argv[i];
+ if(!strcmp(arg, "-s") || !strcmp(arg, "--socket"))
+ {
+ if(++i < argc)
+ socket_path = argv[i];
+ else
+ {
+ parse_args_fail = "Expected parameter after -s";
+ return false;
+ }
+ }
+ else if(!strcmp(arg, "-k") || !strcmp(arg, "--userkey"))
+ {
+ if(++i < argc)
+ userkey = argv[i];
+ else
+ {
+ parse_args_fail = "Expected user key";
+ return false;
+ }
+ }
+ else if(!strcmp(arg, "-u"))
+ {
+ if(++i < argc)
+ user_id = atol(argv[i]);
+ else
+ {
+ parse_args_fail = "Expected user id";
+ return false;
+ }
+ }
+ else if(!strcmp(arg, "-h") || !strcmp(arg, "--help"))
+ {
+ print_usage(argv[0]);
+ exit(1);
+ }
+ else if(!strcmp(arg, "create"))
+ {
+ if(cl_request.type != USERREQ_NONE)
+ {
+ parse_args_fail = "Multiple commands";
+ return false;
+ }
+ cl_request.type = CREATE_FILE;
+ }
+ else if(!strcmp(arg, "modifyacl"))
+ {
+ if(cl_request.type != USERREQ_NONE)
+ {
+ parse_args_fail = "Multiple commands";
+ return false;
+ }
+ cl_request.type = MODIFY_ACL;
+
+ if(++i < argc)
+ cl_request.modify_acl.file_idx = atol(argv[i]);
+ else
+ {
+ parse_args_fail = "Expected file idx";
+ return false;
+ }
+
+ i++;
+
+ size_t n = argc - i;
+ n &= ~1; /* round down to next even integer */
+
+ uint64_t *acl_tuples = calloc(n, sizeof(uint64_t));
+
+ /* consume (user, access level) tuples */
+ for(int j = 0; i < argc; i += 2, j += 2)
+ {
+ acl_tuples[j] = atol(argv[i]);
+ acl_tuples[j + 1] = atol(argv[i + 1]);
+ }
+
+ /* sort ACL tuples by user id */
+ qsort(acl_tuples, n / 2, 2 * sizeof(uint64_t), compare_tuple);
+
+ size_t logleaves = ilog2(n);
+
+ /* round up if acl size is not an integer power of 2 */
+ if((1 << logleaves) != n)
+ logleaves++;
+
+ new_acl = iomt_new(logleaves);
+ /* now produce IOMT */
+ uint64_t first_idx = acl_tuples[0];
+
+ for(int j = 0; j < n; j += 2)
+ {
+ iomt_update_leaf_full(new_acl, j / 2, acl_tuples[j], first_idx, u64_to_hash(acl_tuples[j + 1]));
+ if(j > 0)
+ iomt_update_leaf_nextidx(new_acl, j / 2 - 1, acl_tuples[j]);
+ }
+ }
+ else if(!strcmp(arg, "modifyfile"))
+ {
+ if(cl_request.type != USERREQ_NONE)
+ {
+ parse_args_fail = "Multiple commands";
+ return false;
+ }
+ cl_request.type = MODIFY_FILE;
+
+ if(++i < argc)
+ cl_request.modify_file.file_idx = atol(argv[i]);
+ else
+ {
+ parse_args_fail = "Expected file idx";
+ return false;
+ }
+
+ buildcode_path = argv[++i];
+ compose_path = argv[++i];
+ image_path = argv[++i];
+ if(i + 1 < argc)
+ file_key = argv[++i];
+ }
+ else if(!strcmp(arg, "retrieveinfo") || !strcmp(arg, "retrievefile"))
+ {
+ if(cl_request.type != USERREQ_NONE)
+ {
+ parse_args_fail = "Multiple commands";
+ return false;
+ }
+ cl_request.type = RETRIEVE_INFO;
+
+ if(++i < argc)
+ cl_request.retrieve.file_idx = atol(argv[i]);
+ else
+ {
+ parse_args_fail = "Expected file idx";
+ return false;
+ }
+
+ if(++i < argc)
+ cl_request.retrieve.version = atol(argv[i]);
+ else
+ {
+ parse_args_fail = "Expected file version";
+ return false;
+ }
+
+ if(!strcmp(arg, "retrievefile"))
+ {
+ buildcode_path = argv[++i];
+ compose_path = argv[++i];
+ image_path = argv[++i];
+ if(i + 1 < argc)
+ file_key = argv[++i];
+ }
+ }
+ else
+ {
+ parse_args_fail = "Unknown parameter";
+ return false;
+ }
+ }
+ if(cl_request.type != USERREQ_NONE && user_id != 0 && userkey != NULL)
+ return true;
+ else
+ {
+ parse_args_fail = "Missing required parameter (either command, user ID, or user key)";
+ return false;
+ }
+}
static struct tm_request verify_and_sign(int fd, const struct user_request *req)
{
struct tm_request tmr = req_null;
- if(read(fd, &tmr, sizeof(tmr)) != sizeof(tmr))
+ if(recv(fd, &tmr, sizeof(tmr), MSG_WAITALL) != sizeof(tmr))
{
- perror("read");
+ perror("short read");
exit(1);
}
@@ -34,12 +259,18 @@ static struct tm_request verify_and_sign(int fd, const struct user_request *req)
{
/* check request values to make sure they actually do what we
* want */
- struct iomt_node acl_node = { req->create.user_id, req->create.user_id, u64_to_hash(3) };
+ struct iomt_node acl_node = { req->user_id, req->user_id, u64_to_hash(3) };
if(tmr.type != ACL_UPDATE ||
tmr.idx == 0 ||
tmr.counter != 0 ||
!hash_equals(hash_node(&acl_node), tmr.val))
+ {
+ printf("Refusing to sign request because %d %d %d %d\n", tmr.type != ACL_UPDATE,
+ tmr.idx == 0,
+ tmr.counter != 0,
+ !hash_equals(hash_node(&acl_node), tmr.val));
return req_null;
+ }
break;
}
case MODIFY_FILE:
@@ -56,7 +287,8 @@ static struct tm_request verify_and_sign(int fd, const struct user_request *req)
break;
}
- hash_t hmac = hmac_sha256(&tmr, sizeof(tmr), "a", 1);
+ printf("Signing request\n");
+ hash_t hmac = hmac_sha256(&tmr, sizeof(tmr), userkey, strlen(userkey));
write(fd, &hmac, sizeof(hmac));
return tmr;
@@ -65,13 +297,13 @@ static struct tm_request verify_and_sign(int fd, const struct user_request *req)
static bool verify_sp_ack(int fd, const struct tm_request *tmr)
{
hash_t hmac = hash_null;
- if(read(fd, &hmac, sizeof(hmac)) != sizeof(hmac))
+ if(recv(fd, &hmac, sizeof(hmac), MSG_WAITALL) != sizeof(hmac))
{
perror("read 2");
exit(2);
}
- return ack_verify(tmr, "a", 1, hmac);
+ return ack_verify(tmr, userkey, strlen(userkey), hmac);
}
/* In case of modifcation or file creation, returns true on successful
@@ -84,6 +316,7 @@ bool exec_request(int fd, const struct user_request *req,
const struct iomt *new_buildcode, /* MODIFY_FILE only */
const struct iomt *new_composefile, /* MODIFY_FILE only */
const void *new_file_contents, size_t len, /* MODIFY_FILE only */
+ struct tm_request *tmreq_out, /* CREATE_FILE, MODIFY_FILE, and MODIFY_ACL only */
struct version_info *verinfo_out, /* RETRIEVE_INFO only */
const void *user_key, size_t keylen, /* RETRIEVE_INFO and RETRIEVE_FILE only */
struct iomt **buildcode, /* RETRIEVE_FILE only */
@@ -125,14 +358,16 @@ bool exec_request(int fd, const struct user_request *req,
{
/* verify module ack */
struct tm_request tmr = verify_and_sign(fd, req);
+ if(tmreq_out)
+ *tmreq_out = tmr;
return verify_sp_ack(fd, &tmr);
}
case RETRIEVE_INFO:
{
hash_t hmac;
struct version_info verinfo;
- read(fd, &verinfo, sizeof(verinfo));
- read(fd, &hmac, sizeof(hmac));
+ recv(fd, &verinfo, sizeof(verinfo), MSG_WAITALL);
+ recv(fd, &hmac, sizeof(hmac), MSG_WAITALL);
if(hash_equals(hmac, hmac_sha256(&verinfo, sizeof(verinfo), user_key, keylen)))
{
@@ -144,7 +379,7 @@ bool exec_request(int fd, const struct user_request *req,
case RETRIEVE_FILE:
{
hash_t encrypted_secret;
- read(fd, &encrypted_secret, sizeof(encrypted_secret));
+ recv(fd, &encrypted_secret, sizeof(encrypted_secret), MSG_WAITALL);
*secret_out = crypt_secret(encrypted_secret,
req->retrieve.file_idx,
@@ -154,10 +389,10 @@ bool exec_request(int fd, const struct user_request *req,
*buildcode = iomt_deserialize(read_from_fd, &fd);
*composefile = iomt_deserialize(read_from_fd, &fd);
- read(fd, file_len, sizeof(*file_len));
+ recv(fd, file_len, sizeof(*file_len), MSG_WAITALL);
*file_contents_out = malloc(*file_len);
- read(fd, file_contents_out, *file_len);
+ recv(fd, file_contents_out, *file_len, MSG_WAITALL);
return true;
}
default:
@@ -177,11 +412,11 @@ int connect_to_service(const char *sockpath)
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- if (*socket_path == '\0') {
+ if (*sockpath == '\0') {
*addr.sun_path = '\0';
- strncpy(addr.sun_path+1, socket_path+1, sizeof(addr.sun_path)-2);
+ strncpy(addr.sun_path+1, sockpath+1, sizeof(addr.sun_path)-2);
} else {
- strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
+ strncpy(addr.sun_path, sockpath, sizeof(addr.sun_path)-1);
}
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
@@ -192,17 +427,108 @@ int connect_to_service(const char *sockpath)
return fd;
}
+void *load_file(const char *path, size_t *len)
+{
+ FILE *f = fopen(path, "r");
+ *len = fseek(f, 0, SEEK_END);
+ fseek(f, 0, SEEK_SET);
+ void *buf = malloc(*len);
+ fread(buf, 1, *len, f);
+ return buf;
+}
+
+bool server_request(const char *sockpath,
+ const char *userkey, uint64_t user_id,
+ struct user_request req,
+ struct iomt *new_acl,
+ const char *buildcode_path,
+ const char *compose_path,
+ const char *image_path,
+ const char *file_key)
+{
+ int fd = connect_to_service(sockpath);
+
+ req.user_id = user_id;
+
+ struct iomt *buildcode = NULL, *composefile = NULL;
+ if(req.type == MODIFY_FILE)
+ {
+ /* these can safely take NULLs */
+ buildcode = iomt_from_lines(buildcode_path);
+ composefile = iomt_from_lines(compose_path);
+ }
+
+ void *file_contents = NULL;
+ size_t file_len = 0;
+ hash_t secret = hash_null;
+ if(image_path && req.type == MODIFY_FILE)
+ file_contents = load_file(image_path, &file_len);
+
+ /* TODO: encrypt file */
+
+ struct version_info verinfo;
+ struct tm_request tmreq;
+
+ bool success = exec_request(fd, &req,
+ req.type == MODIFY_ACL ? new_acl : NULL,
+ req.type == MODIFY_FILE ? buildcode : NULL,
+ req.type == MODIFY_FILE ? composefile : NULL,
+ req.type == MODIFY_FILE ? file_contents : NULL,
+ req.type == MODIFY_FILE ? file_len : 0,
+ req.type <= MODIFY_ACL ? &tmreq : NULL,
+ req.type == RETRIEVE_INFO ? &verinfo : NULL,
+ req.type >= RETRIEVE_INFO ? userkey : NULL,
+ req.type >= RETRIEVE_INFO ? strlen(userkey) : 0,
+ req.type == RETRIEVE_FILE ? &buildcode : NULL,
+ req.type == RETRIEVE_FILE ? &composefile : NULL,
+ req.type == RETRIEVE_FILE ? &secret : NULL,
+ req.type == RETRIEVE_FILE ? &file_contents : NULL,
+ req.type == RETRIEVE_FILE ? &file_len : NULL);
+
+ printf("Request %s\n",
+ success ?
+ "\033[32;1msucceeded\033[0m" :
+ "\033[31;1mfailed\033[0m");
+
+ if(!success)
+ return false;
+
+ switch(req.type)
+ {
+ case CREATE_FILE:
+ printf("Created file with index %lu.\n", tmreq.idx);
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
int main(int argc, char *argv[]) {
char buf[100];
int fd,rc;
- if (argc > 1) socket_path=argv[1];
+ if(!parse_args(argc, argv))
+ {
+ printf("%s\n", parse_args_fail);
+ print_usage(argv[0]);
+ return 1;
+ }
+
+ signal(SIGPIPE, SIG_IGN);
+
+ server_request(socket_path, userkey, user_id,
+ cl_request, new_acl,
+ buildcode_path, compose_path, image_path,
+ file_key);
+#if 0
fd = connect_to_service(socket_path);
struct user_request req;
req.type = CREATE_FILE;
- req.create.user_id = 1;
+ req.user_id = 1;
check("Client file creation", exec_request(fd, &req, NULL, NULL, NULL, NULL, 0,
NULL, NULL, 0,
@@ -211,7 +537,7 @@ int main(int argc, char *argv[]) {
fd = connect_to_service(socket_path);
req.type = MODIFY_FILE;
- req.modify_file.user_id = 1;
+ req.user_id = 1;
req.modify_file.file_idx = 1;
req.modify_file.encrypted_secret = hash_null;
req.modify_file.kf = hash_null;
@@ -220,6 +546,7 @@ int main(int argc, char *argv[]) {
NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL));
close(fd);
+#endif
return 0;
}
diff --git a/container1/docker-compose.yml b/container1/docker-compose.yml
new file mode 100644
index 0000000..a7a8243
--- /dev/null
+++ b/container1/docker-compose.yml
@@ -0,0 +1,6 @@
+test1
+test2
+
+blank
+
+test3
diff --git a/container1/hello-world.tar b/container1/hello-world.tar
new file mode 100644
index 0000000..814ce84
--- /dev/null
+++ b/container1/hello-world.tar
Binary files differ
diff --git a/crypto.c b/crypto.c
index 4125f7b..a7bf68c 100644
--- a/crypto.c
+++ b/crypto.c
@@ -2,6 +2,8 @@
#include "trusted_module.h"
#include "test.h"
+#include <sys/socket.h>
+#include <unistd.h>
#include <string.h>
#include <openssl/hmac.h>
@@ -379,7 +381,11 @@ struct iomt *iomt_dup(const struct iomt *tree)
uint64_t read_u64(int (*read_fn)(void *userdata, void *buf, size_t len), void *userdata)
{
uint64_t n;
- read_fn(userdata, &n, sizeof(n));
+ if(read_fn(userdata, &n, sizeof(n)) != sizeof(n))
+ {
+ printf("short read\n");
+ return 0;
+ }
return n;
}
@@ -389,7 +395,6 @@ void write_u64(void (*write_fn)(void *userdata, const void *data, size_t len),
write_fn(userdata, &n, sizeof(n));
}
-
void iomt_serialize(const struct iomt *tree,
void (*write_fn)(void *userdata, const void *data, size_t len),
void *userdata)
@@ -435,6 +440,9 @@ void iomt_free(struct iomt *tree)
struct iomt *iomt_from_lines(const char *filename)
{
+ if(!filename)
+ return NULL;
+
struct iomt *tree = iomt_new(FILELINES_LOGLEAVES);
FILE *f = fopen(filename, "r");
@@ -445,7 +453,7 @@ struct iomt *iomt_from_lines(const char *filename)
int c;
uint64_t line = 0;
- while(c != EOF)
+ do
{
c = fgetc(f);
@@ -473,7 +481,7 @@ struct iomt *iomt_from_lines(const char *filename)
/* re-initialize for next line */
SHA256_Init(&ctx);
}
- }
+ } while(c != EOF);
fclose(f);
@@ -609,7 +617,12 @@ void write_to_fd(void *userdata, const void *data, size_t len)
int read_from_fd(void *userdata, void *buf, size_t len)
{
int *fdptr = userdata;
- return read(*fdptr, buf, len);
+ int rc = recv(*fdptr, buf, len, MSG_WAITALL);
+ if(rc != len)
+ {
+ printf("short read");
+ }
+ return rc;
}
void crypto_test(void)
diff --git a/helper.c b/helper.c
index e72d39f..7f2abd7 100644
--- a/helper.c
+++ b/helper.c
@@ -106,7 +106,7 @@ struct tm_request req_filecreate(const struct trusted_module *tm,
req.counter = 0;
/* construct ACL with a single element (the user, with full access) */
- struct iomt_node acl_node = (struct iomt_node) { 1, 1, u64_to_hash(3) };
+ struct iomt_node acl_node = (struct iomt_node) { user_id, user_id, u64_to_hash(3) };
req.val = merkle_compute(hash_node(&acl_node), NULL, NULL, 0);
hash_t one = u64_to_hash(1);
diff --git a/main.c b/main.c
index 567a441..4363592 100644
--- a/main.c
+++ b/main.c
@@ -31,7 +31,7 @@ void cleanup(void)
unlink(cleanup_socket);
}
-void sigint(int sig)
+void signal_handler(int sig)
{
cleanup();
exit(1);
@@ -46,7 +46,7 @@ void run_tests(void)
int main()
{
- run_tests();
+ //run_tests();
const char *socket_name = "socket";
int sockfd;
@@ -59,7 +59,8 @@ int main()
cleanup_socket = socket_name;
atexit(cleanup);
- signal(SIGINT, sigint);
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
sp_main(sockfd);
}
diff --git a/service_provider.c b/service_provider.c
index cf1535d..eb47ab3 100644
--- a/service_provider.c
+++ b/service_provider.c
@@ -2,6 +2,7 @@
* module */
#include <assert.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -402,9 +403,9 @@ struct tm_request sp_createfile(struct service_provider *sp,
user_id, user_id, u64_to_hash(3));
struct tm_request req = req_filecreate(sp->tm,
- i + 1,
- sp->iomt->mt_leaves + i,
- file_comp, file_orders, sp->iomt->mt_logleaves);
+ user_id,
+ sp->iomt->mt_leaves + i,
+ file_comp, file_orders, sp->iomt->mt_logleaves);
hash_t req_hmac = sign_request(userdata, &req);
hash_t fr_hmac;
@@ -456,12 +457,12 @@ struct tm_request sp_modifyacl(struct service_provider *sp,
&acl_orders);
struct tm_request req = req_aclmodify(sp->tm,
- &rec->fr_cert, rec->fr_hmac,
- file_node,
- file_comp, file_orders, sp->iomt->mt_logleaves,
- acl_node,
- acl_comp, acl_orders, rec->acl->mt_logleaves,
- new_acl->mt_nodes[0]);
+ &rec->fr_cert, rec->fr_hmac,
+ file_node,
+ file_comp, file_orders, sp->iomt->mt_logleaves,
+ acl_node,
+ acl_comp, acl_orders, rec->acl->mt_logleaves,
+ new_acl->mt_nodes[0]);
free(file_comp);
free(file_orders);
@@ -498,7 +499,10 @@ struct tm_request sp_modifyfile(struct service_provider *sp,
/* modification */
struct file_record *rec = lookup_record(sp, file_idx);
if(!rec)
+ {
+ printf("Could not find file with index %lu\n", file_idx);
return req_null;
+ }
int *file_orders, *acl_orders;
struct iomt_node *file_node = iomt_find_leaf(sp->iomt, file_idx);
@@ -714,10 +718,13 @@ void *sp_retrieve_file(struct service_provider *sp,
static hash_t get_client_signature(void *userdata, const struct tm_request *req)
{
int *fd = userdata;
- write(*fd, req, sizeof(*req));
+ if(write(*fd, req, sizeof(*req)) != sizeof(*req))
+ return hash_null;
hash_t hmac;
- read(*fd, &hmac, sizeof(hmac));
+ if(recv(*fd, &hmac, sizeof(hmac), MSG_WAITALL) != sizeof(hmac))
+ return hash_null;
+
return hmac;
}
@@ -725,7 +732,7 @@ static void sp_handle_client(struct service_provider *sp, int cl)
{
/* We should probably fork() here to avoid blocking */
struct user_request user_req;
- if(read(cl, &user_req, sizeof(user_req)) != sizeof(user_req))
+ if(recv(cl, &user_req, sizeof(user_req), MSG_WAITALL) != sizeof(user_req))
return;
hash_t ack_hmac = hash_null;
@@ -733,44 +740,54 @@ static void sp_handle_client(struct service_provider *sp, int cl)
switch(user_req.type)
{
case CREATE_FILE:
- sp_createfile(sp, user_req.create.user_id, get_client_signature, &cl, &ack_hmac);
- write(cl, &ack_hmac, sizeof(ack_hmac));
+ {
+ printf("Client: create file\n");
+ sp_createfile(sp, user_req.user_id, get_client_signature, &cl, &ack_hmac);
+ if(write(cl, &ack_hmac, sizeof(ack_hmac)) != sizeof(ack_hmac))
+ return;
break;
+ }
case MODIFY_ACL:
{
+ printf("Client: modify ACL\n");
struct iomt *acl = iomt_deserialize(read_from_fd, &cl);
sp_modifyacl(sp,
- user_req.modify_acl.user_id,
+ user_req.user_id,
get_client_signature,
&cl,
user_req.modify_acl.file_idx,
acl,
&ack_hmac);
iomt_free(acl);
- write(cl, &ack_hmac, sizeof(ack_hmac));
+ if(write(cl, &ack_hmac, sizeof(ack_hmac)) != sizeof(ack_hmac))
+ return;
break;
}
case MODIFY_FILE:
{
+ printf("Client: modify file\n");
struct iomt *buildcode = iomt_deserialize(read_from_fd, &cl);
struct iomt *composefile = iomt_deserialize(read_from_fd, &cl);
size_t filelen;
- read(cl, &filelen, sizeof(filelen));
+ recv(cl, &filelen, sizeof(filelen), MSG_WAITALL);
void *filebuf = malloc(filelen);
- read(cl, filebuf, filelen);
-
- sp_modifyfile(sp,
- user_req.modify_file.user_id,
- get_client_signature,
- &cl,
- user_req.modify_file.file_idx,
- user_req.modify_file.encrypted_secret,
- user_req.modify_file.kf,
- buildcode,
- composefile,
- filebuf, filelen,
- &ack_hmac);
+ recv(cl, filebuf, filelen, MSG_WAITALL);
+
+ if(sp_modifyfile(sp,
+ user_req.user_id,
+ get_client_signature,
+ &cl,
+ user_req.modify_file.file_idx,
+ user_req.modify_file.encrypted_secret,
+ user_req.modify_file.kf,
+ buildcode,
+ composefile,
+ filebuf, filelen,
+ &ack_hmac).type == REQ_NONE)
+ {
+ printf("Failed: %s\n", tm_geterror());
+ }
iomt_free(buildcode);
iomt_free(composefile);
write(cl, &ack_hmac, sizeof(ack_hmac));
@@ -778,8 +795,9 @@ static void sp_handle_client(struct service_provider *sp, int cl)
}
case RETRIEVE_INFO:
{
+ printf("Client: retrieve info\n");
struct version_info verinfo = sp_fileinfo(sp,
- user_req.retrieve.user_id,
+ user_req.user_id,
user_req.retrieve.file_idx,
user_req.retrieve.version,
&ack_hmac);
@@ -789,11 +807,12 @@ static void sp_handle_client(struct service_provider *sp, int cl)
}
case RETRIEVE_FILE:
{
+ printf("Client: retrieve file\n");
hash_t encrypted_secret;
size_t len;
struct iomt *buildcode = NULL, *composefile = NULL;
void *contents = sp_retrieve_file(sp,
- user_req.retrieve.user_id,
+ user_req.user_id,
user_req.retrieve.file_idx,
user_req.retrieve.version,
&encrypted_secret,
@@ -811,6 +830,11 @@ static void sp_handle_client(struct service_provider *sp, int cl)
break;
}
+ case USERREQ_NONE:
+ {
+ printf("null request\n");
+ exit(1);
+ }
}
}
@@ -824,6 +848,8 @@ int sp_main(int sockfd)
return 1;
}
+ signal(SIGPIPE, SIG_IGN);
+
int logleaves = 8;
struct service_provider *sp = sp_new("a", 1, logleaves);
diff --git a/service_provider.h b/service_provider.h
index be931a2..f5fd4bc 100644
--- a/service_provider.h
+++ b/service_provider.h
@@ -32,30 +32,33 @@ struct service_provider;
/* request from the client to the service */
struct user_request {
- enum { CREATE_FILE, MODIFY_FILE, MODIFY_ACL, RETRIEVE_INFO, RETRIEVE_FILE } type;
+ enum { USERREQ_NONE = 0, CREATE_FILE, MODIFY_FILE, MODIFY_ACL, RETRIEVE_INFO, RETRIEVE_FILE } type;
+ uint64_t user_id;
union {
struct {
- uint64_t user_id;
- } create;
- struct {
- uint64_t user_id, file_idx;
+ uint64_t file_idx;
/* ACL IOMT will follow */
+
+ /* service will respond with tm_request structure,
+ * requiring a client signature; then the module's HMAC
+ * will follow */
} modify_acl;
struct {
- uint64_t user_id, file_idx;
+ uint64_t file_idx;
hash_t encrypted_secret, kf;
/* file contents, build code IOMT, and compose file IOMT
* will follow */
- /* will respond with module's HMAC of tm_request struct
- * plus a zero byte */
+ /* service will respond with tm_request structure,
+ * requiring a client signature; then the module's HMAC
+ * will follow */
} modify_file;
struct {
/* same structure for retrieve file and retrieve info */
- uint64_t user_id, file_idx, version;
- /* will respond with either version_info struct, plus
- * HMAC, or file contents and key (which the client can
- * verify themselves) */
+ uint64_t file_idx, version;
+ /* service will respond with either version_info struct,
+ * plus HMAC, or file contents and key (which the client
+ * can verify themselves) */
} retrieve;
};
} __attribute__((packed));
diff --git a/trusted_module.c b/trusted_module.c
index 9e310b3..712e7a8 100644
--- a/trusted_module.c
+++ b/trusted_module.c
@@ -653,6 +653,12 @@ struct tm_cert tm_request(struct trusted_module *tm,
}
else if(req->type == ACL_UPDATE)
{
+ if(access < 3)
+ {
+ tm_seterror("user has insufficient permissions");
+ return cert_null;
+ }
+
/* We just need a new FR certificate with the new ACL. */
struct tm_cert cert = cert_null;
cert.type = FR;