From da7ca5e387cf4bb820ca48d13a5fc4376c2474b4 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 27 Jul 2020 13:04:46 +0300 Subject: [PATCH] hacking the server --- server/src/main.c | 9 +++- server/src/md5.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ server/src/md5.h | 55 +++++++++++++++++++ server/src/repo.c | 76 ++++++++++++++++++++------ server/src/repo.h | 12 ++++- 5 files changed, 290 insertions(+), 18 deletions(-) create mode 100644 server/src/md5.c create mode 100644 server/src/md5.h diff --git a/server/src/main.c b/server/src/main.c index c4e0846..a3174d1 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -2,8 +2,11 @@ #include #include #include +#include #include "repo.h" +#include "md5.h" + static const char *guess_repo_name(const char *path); static int parse_args(int argc, char **argv); @@ -30,9 +33,13 @@ int main(int argc, char **argv) /* DBG */ { + struct md5_state sum; int i, count = repo_num_files(); for(i=0; ichksum, sizeof sum.sum); + printf("%s\tmd5:%s size:%lu mtime:%s", file->path, md5_sumstr(&sum), + (unsigned long)file->size, ctime(&file->mtime)); } } diff --git a/server/src/md5.c b/server/src/md5.c new file mode 100644 index 0000000..6b45070 --- /dev/null +++ b/server/src/md5.c @@ -0,0 +1,156 @@ +/* MD5 message digest + * Author: John Tsiombikas + * + * This software is public domain. Feel free to use it any way you like. + * + * If public domain is not applicable in your part of the world, you may use + * this under the terms of the Creative Commons CC-0 license: + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +#include +#include +#include "md5.h" + +#define BLOCKSZ 64 + +static const int shifttab[] = { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 +}; + +static const uint32_t sintab[] = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 +}; + +static void sum_block(uint32_t *blk, uint32_t *sum); +static uint32_t rol(uint32_t x, int s); + +void md5_begin(struct md5_state *md) +{ + md->sum[0] = 0x67452301; + md->sum[1] = 0xefcdab89; + md->sum[2] = 0x98badcfe; + md->sum[3] = 0x10325476; + md->len = 0; + md->bblen = 0; +} + +void md5_msg(struct md5_state *md, void *msg, int msg_size) +{ + int pending, sz; + + while(msg_size) { + pending = BLOCKSZ - md->bblen; + sz = msg_size > pending ? pending : msg_size; + + memcpy(md->blockbuf + md->bblen, msg, sz); + msg = (char*)msg + sz; + md->bblen += sz; + msg_size -= sz; + + if(md->bblen >= BLOCKSZ) { + sum_block((uint32_t*)md->blockbuf, md->sum); + md->bblen = 0; + md->len += BLOCKSZ * 8; + } + } +} + +static void sum_block(uint32_t *blk, uint32_t *sum) +{ + int i, f, g; + int a = sum[0]; + int b = sum[1]; + int c = sum[2]; + int d = sum[3]; + + for(i=0; i<64; i++) { + switch(i >> 4) { + case 0: + f = d ^ (b & (c ^ d)); + g = i; + break; + + case 1: + f = c ^ (d & (b ^ c)); + g = (i * 5 + 1) & 0xf; + break; + + case 2: + f = b ^ c ^ d; + g = (i * 3 + 5) & 0xf; + break; + + case 3: + f = c ^ (b | ~d); + g = (i * 7) & 0xf; + } + + f += a + sintab[i] + blk[g]; + a = d; + d = c; + c = b; + b += rol(f, shifttab[i]); + } + + sum[0] += a; + sum[1] += b; + sum[2] += c; + sum[3] += d; +} + +static uint32_t rol(uint32_t x, int s) +{ + return (x << s) | (x >> (32 - s)); +} + +void md5_end(struct md5_state *md) +{ + md->len += md->bblen * 8; + md->blockbuf[md->bblen++] = 0x80; /* append 1-bit plus 8 zeros padding */ + + if(md->bblen > BLOCKSZ - 8) { + /* pad to BLOCKSZ, sum, then continue with further padding */ + memset(md->blockbuf + md->bblen, 0, BLOCKSZ - md->bblen); + sum_block((uint32_t*)md->blockbuf, md->sum); + md->bblen = 0; + } + + /* pad to BLOCKSZ - 8 */ + memset(md->blockbuf + md->bblen, 0, BLOCKSZ - 8 - md->bblen); + + /* add the length */ + *(uint64_t*)(md->blockbuf + BLOCKSZ - 8) = md->len; + + /* then sum for the last time */ + sum_block((uint32_t*)md->blockbuf, md->sum); +} + +const char *md5_sumstr(struct md5_state *md) +{ + int i; + unsigned char *sum = (unsigned char*)md->sum; + char *s = (char*)md->blockbuf; + + for(i=0; i<16; i++) { + s += sprintf(s, "%02x", sum[i]); + } + return (char*)md->blockbuf; +} diff --git a/server/src/md5.h b/server/src/md5.h new file mode 100644 index 0000000..8f6ef38 --- /dev/null +++ b/server/src/md5.h @@ -0,0 +1,55 @@ +/* MD5 message digest + * Author: John Tsiombikas + * + * This software is public domain. Feel free to use it any way you like. + * + * If public domain is not applicable in your part of the world, you may use + * this under the terms of the Creative Commons CC-0 license: + * http://creativecommons.org/publicdomain/zero/1.0/ + * + * + * usage example 1: compute the md5 sum of the string "hello world" + * + * struct md5_state md; + * md5_begin(&md); + * md5_msg(&md, "hello world", 11); + * md5_end(&md); + * + * md5 sum in: md5_state.sum[0..4] + * To print it you may use the helper function md5_sumstr: + * printf("%s\n", md5_sumstr(&md)); + * + * usage example 2: comput the md5 sum of whatever comes through stdin + * + * int sz; + * struct md5_state md; + * char buf[1024]; + * + * md5_begin(&md); + * while((sz = fread(buf, 1, sizeof buf, stdin)) > 0) { + * md5_msg(&md, buf, sz); + * } + * md5_end(&md); + */ +#ifndef NUCLEAR_DROPCODE_MD5_H_ +#define NUCLEAR_DROPCODE_MD5_H_ + +#include + +struct md5_state { + uint32_t sum[4]; + uint64_t len; + unsigned char blockbuf[64]; + int bblen; +}; + +void md5_begin(struct md5_state *md); +void md5_msg(struct md5_state *md, void *msg, int msg_size); +void md5_end(struct md5_state *md); + +/* after computing the md5 sum, you may use this function to get a pointer + * to a canonical string representation of the sum (identical to GNU md5sum) + */ +const char *md5_sumstr(struct md5_state *md); + +#endif /* NUCLEAR_DROPCODE_MD5_H_ */ diff --git a/server/src/repo.c b/server/src/repo.c index fee52e8..6f81d90 100644 --- a/server/src/repo.c +++ b/server/src/repo.c @@ -1,22 +1,25 @@ #include #include #include +#include +#include #include +#include "repo.h" +#include "md5.h" -struct repofile { - char *path; -}; - +static int add_file(const char *name, const char *path); +static void calc_chksum(FILE *fp, uint32_t *sum); static int proc_tree(git_repository *repo, git_tree *tree, const char *path); -static struct repofile *files; +static struct repo_file *files; static int num_files, max_files; +static const char *repo_path; int repo_init(const char *path) { int res = -1; git_repository *repo = 0; - git_tree *tree; + git_object *tree; git_libgit2_init(); @@ -28,14 +31,16 @@ int repo_init(const char *path) files = 0; num_files = max_files = 0; + repo_path = path; - if(git_revparse_single((git_object**)&tree, repo, "HEAD^{tree}") != 0) { + if(git_revparse_single(&tree, repo, "HEAD^{tree}") != 0) { fprintf(stderr, "repo_init: %s\n", git_error_last()->message); goto end; } - if(proc_tree(repo, tree, 0) == -1) { + if(proc_tree(repo, (git_tree*)tree, 0) == -1) { goto end; } + git_object_free(tree); res = 0; end: @@ -51,6 +56,10 @@ end: void repo_cleanup(void) { + int i; + for(i=0; i= num_files) return 0; - return files[idx].path; + return files + idx; } static int add_file(const char *name, const char *path) { - struct repofile *file; + struct repo_file *file; int pathlen; + struct stat st; + FILE *fp; if(num_files >= max_files) { int newmax = max_files ? max_files * 2 : 16; @@ -83,26 +94,59 @@ static int add_file(const char *name, const char *path) max_files = newmax; } - pathlen = strlen(name); + pathlen = strlen(repo_path) + strlen(name) + 1; if(path) { pathlen += strlen(path) + 1; } file = files + num_files; - if(!(file->path = malloc(pathlen + 1))) { + if(!(file->fullpath = malloc(pathlen + 1))) { fprintf(stderr, "repo_init: failed to allocate file path buffer\n"); return -1; } if(path) { - sprintf(file->path, "%s/%s", path, name); + sprintf(file->fullpath, "%s/%s/%s", repo_path, path, name); } else { - strcpy(file->path, name); + sprintf(file->fullpath, "%s/%s", repo_path, name); } + file->path = file->fullpath + strlen(repo_path) + 1; + + /* attempt to open the file */ + if(!(fp = fopen(file->fullpath, "rb"))) { + fprintf(stderr, "repo_init: failed to open file: %s: %s\n", file->fullpath, strerror(errno)); + free(file->fullpath); + return -1; + } + + /* get size & modification time */ + fstat(fileno(fp), &st); + file->size = st.st_size; + file->mtime = st.st_mtime; + + /* calculate md5 checksum */ + calc_chksum(fp, file->chksum); + + fclose(fp); num_files++; return 0; } +static void calc_chksum(FILE *fp, uint32_t *sum) +{ + static char buf[4096]; + int sz; + struct md5_state md; + + md5_begin(&md); + while((sz = fread(buf, 1, sizeof buf, fp)) > 0) { + md5_msg(&md, buf, sz); + } + md5_end(&md); + + memcpy(sum, md.sum, sizeof md.sum); +} + static int proc_tree(git_repository *repo, git_tree *tree, const char *path) { int i, count = git_tree_entrycount(tree); @@ -126,7 +170,7 @@ static int proc_tree(git_repository *repo, git_tree *tree, const char *path) case GIT_OBJECT_TREE: git_tree_entry_to_object(&obj, repo, ent); if(path) { - char *pathbuf = malloc(strlen(path) + strlen(name) + 1); + char *pathbuf = malloc(strlen(path) + strlen(name) + 2); if(!pathbuf) { fprintf(stderr, "repo_init: failed to allocate memory\n"); return -1; diff --git a/server/src/repo.h b/server/src/repo.h index 3e8643d..fb2c977 100644 --- a/server/src/repo.h +++ b/server/src/repo.h @@ -1,10 +1,20 @@ #ifndef REPO_H_ #define REPO_H_ +#include + +struct repo_file { + char *path; + char *fullpath; + size_t size; + time_t mtime; + uint32_t chksum[4]; +}; + int repo_init(const char *path); void repo_cleanup(void); int repo_num_files(void); -const char *repo_file(int idx); +struct repo_file *repo_file(int idx); #endif /* REPO_H_ */ -- 1.7.10.4