From b6bf05e83bdc7ca9c431c57558c39bc61fc85011 Mon Sep 17 00:00:00 2001 From: cel Date: Wed, 11 Oct 2017 15:13:46 -1000 Subject: [PATCH] Hash added blob --- base64.c | 43 +++++++++++++++++++++++++++++++++++++++++ base64.h | 1 + sbotc.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/base64.c b/base64.c index 32e26c9..1ee0395 100644 --- a/base64.c +++ b/base64.c @@ -73,3 +73,46 @@ int base64_decode(const char* s, size_t str_len, void *data, size_t data_len) return 0; } + +int base64_encode(const void* buf, size_t size, char *str, size_t out_size) { + static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + char* p = str; + const unsigned char* q = (const unsigned char*) buf; + size_t i = 0; + + if ((size+3)*4/3 + 1 > out_size) { + errno = EMSGSIZE; + return -1; + } + + while (i < size) { + int c = q[i++]; + c *= 256; + if (i < size) + c += q[i]; + i++; + + c *= 256; + if (i < size) + c += q[i]; + i++; + + *p++ = base64[(c & 0x00fc0000) >> 18]; + *p++ = base64[(c & 0x0003f000) >> 12]; + + if (i > size + 1) + *p++ = '='; + else + *p++ = base64[(c & 0x00000fc0) >> 6]; + + if (i > size) + *p++ = '='; + else + *p++ = base64[c & 0x0000003f]; + } + + *p = 0; + + return 0; +} diff --git a/base64.h b/base64.h index 65c77c1..8ca4652 100644 --- a/base64.h +++ b/base64.h @@ -2,4 +2,5 @@ #include +int base64_encode(const void* buf, size_t size, char *str, size_t out_size); int base64_decode(const char *s, size_t str_len, void *data, size_t data_len); diff --git a/sbotc.c b/sbotc.c index 57bd097..a5be292 100644 --- a/sbotc.c +++ b/sbotc.c @@ -653,6 +653,22 @@ static enum stream_state muxrpc_write_sink_1(struct boxs *bs, int infd, return stream_state_open; } +static enum stream_state muxrpc_write_sink_1_hashed(struct boxs *bs, int infd, + crypto_hash_sha256_state *hash_state, int req_id) { + int rc; + char buf[4096]; + ssize_t sz = read(infd, buf, sizeof(buf)); + if (sz < 0) err(1, "read"); + if (sz == 0) { + ps_write(bs, "true", 4, pkt_type_json, req_id, true, true); + return stream_state_ended_ok; + } + rc = crypto_hash_sha256_update(hash_state, buf, sz); + if (rc < 0) errx(1, "hash update failed"); + ps_write(bs, buf, sz, pkt_type_buffer, req_id, true, false); + return stream_state_open; +} + static int muxrpc_write_sink(struct boxs *bs, int infd, enum pkt_type ptype, int req_id) { int rc; fd_set rd; @@ -675,6 +691,43 @@ static int muxrpc_write_sink(struct boxs *bs, int infd, enum pkt_type ptype, int in == stream_state_ended_error || out == stream_state_ended_error ? 2 : 1; } +static int muxrpc_write_blob_add(struct boxs *bs, int infd, int outfd, int req_id) { + int rc; + fd_set rd; + int sfd = bs->s; + int maxfd = infd > sfd ? infd : sfd; + enum stream_state in = stream_state_open; + enum stream_state out = stream_state_open; + crypto_hash_sha256_state hash_state; + unsigned char hash[32]; + char id[54] = "&"; + + rc = crypto_hash_sha256_init(&hash_state); + if (rc < 0) { errno = EINVAL; return -1; } + + while (out == stream_state_open) { + FD_ZERO(&rd); + if (in == stream_state_open) FD_SET(infd, &rd); + if (out == stream_state_open) FD_SET(sfd, &rd); + rc = select(maxfd + 1, &rd, 0, 0, NULL); + if (rc < 0) err(1, "select"); + if (FD_ISSET(infd, &rd)) in = muxrpc_write_sink_1_hashed(bs, infd, &hash_state, req_id); + if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, -1, req_id); + } + + rc = crypto_hash_sha256_final(&hash_state, hash); + if (rc < 0) errx(1, "hash finalize failed"); + + rc = base64_encode(hash, 32, id+1, sizeof(id)-1); + if (rc < 0) err(1, "encoding hash failed"); + strcpy(id + 45, ".sha256\n"); + rc = write_all(outfd, id, sizeof(id)-1); + if (rc < 0) err(1, "writing hash failed"); + + return in == stream_state_ended_ok && out == stream_state_ended_ok ? 0 : + in == stream_state_ended_error || out == stream_state_ended_error ? 2 : 1; +} + static int muxrpc_duplex(struct boxs *bs, int infd, int outfd, enum pkt_type in_ptype, int req_id) { int rc; fd_set rd; @@ -860,7 +913,11 @@ int main(int argc, char *argv[]) { rc = muxrpc_read_source(&bs, STDOUT_FILENO, 1); break; case muxrpc_type_sink: - rc = muxrpc_write_sink(&bs, STDIN_FILENO, ptype, 1); + if (!strcmp(methodstr, "blobs.add")) { + rc = muxrpc_write_blob_add(&bs, STDIN_FILENO, STDOUT_FILENO, 1); + } else { + rc = muxrpc_write_sink(&bs, STDIN_FILENO, ptype, 1); + } break; case muxrpc_type_duplex: rc = muxrpc_duplex(&bs, STDIN_FILENO, STDOUT_FILENO, ptype, 1);