From 5abe175e908c21d468b5fcf2428eeef32c60a0b0 Mon Sep 17 00:00:00 2001 From: fumiama Date: Sat, 11 Dec 2021 23:50:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E4=BD=BF=E7=94=A8=E6=96=B0?= =?UTF-8?q?=E5=B0=81=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 15 ++- client.c | 120 +++++++++++++++++++--- crypto.c | 128 ++++++++++++++++++++++++ crypto.h | 15 +++ server.c | 265 +++++++++++++++++++++++++------------------------ server.h | 13 +++ 6 files changed, 405 insertions(+), 151 deletions(-) create mode 100644 crypto.c create mode 100644 crypto.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e604df2..5266b1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,19 +9,16 @@ ELSE() add_definitions("-DCPUBIT32") ENDIF() -# include_directories("/usr/local/include") -# link_directories("/usr/local/lib") +include_directories("/usr/local/include") +link_directories("/usr/local/lib") -add_library(dict STATIC dict.c) - -add_executable(simple-dict-server server.c) -add_executable(simple-dict-client client.c) +add_executable(simple-dict-server server.c dict.c crypto.c) +add_executable(simple-dict-client client.c crypto.c) add_executable(migrate migrate.c) add_executable(cfgwriter cfgwriter.c) -target_link_libraries(dict smd5) -target_link_libraries(simple-dict-server dict spb pthread) -target_link_libraries(simple-dict-client pthread) +target_link_libraries(simple-dict-server scrypto spb pthread) +target_link_libraries(simple-dict-client scrypto pthread) target_link_libraries(migrate spb) target_link_libraries(cfgwriter spb) diff --git a/client.c b/client.c index 8a9a985..12daf8c 100644 --- a/client.c +++ b/client.c @@ -1,3 +1,5 @@ +/* See feature_test_macros(7) */ +#define _GNU_SOURCE 1 #include #include #include @@ -9,6 +11,7 @@ #include #include #include +#include "crypto.h" #if !__APPLE__ #include @@ -25,15 +28,60 @@ uint32_t file_size; int recv_bin = 0; void getMessage(void *p) { - int c = 0; - while((c = recv(sockfd, bufr, BUFSIZ, 0)) > 0) { + int c = 0, offset = 0; + CMDPACKET* cp = bufr; + while((c = recv(sockfd, bufr+offset, CMDPACKET_HEAD_LEN-offset, MSG_WAITALL)) > 0) { printf("Recv %d bytes: ", c); if(recv_bin) { - FILE* fp = fopen("dump.bin", "w+"); - fwrite(bufr, c, 1, fp); - fclose(fp); - } else for(int i = 0; i < c; i++) putchar(bufr[i]); - putchar('\n'); + recv_bin = 0; + int i = 0; + bufr[0] = 0; + while(bufr[i] != '$') recv(sockfd, bufr+i, 1, MSG_WAITALL); + bufr[i] = 0; + off_t datalen; + sscanf(bufr, "%d", &datalen); + printf("raw data len: %d\n", datalen); + char* data = malloc(datalen); + if(datalen == recv(sockfd, data, datalen, MSG_WAITALL)) { + raw_decrypt(data, &datalen, 0, "testpwd"); + printf("raw data len after decode: %d\n", datalen); + FILE* fp = fopen("rawdata.bin", "w+"); + fwrite(data, datalen, 1, fp); + fclose(fp); + free(data); + puts("recv raw data succeed."); + } else { + puts("recv raw data error."); + free(data); + break; + } + } else { + offset += c; + if(offset < CMDPACKET_HEAD_LEN) { + puts("recv head error."); + break; + } + c = recv(sockfd, bufr+offset, CMDPACKET_HEAD_LEN+cp->datalen-offset, MSG_WAITALL); + if(c <= 0) { + puts("on recv body error."); + break; + } else offset += c; + if(offset < CMDPACKET_HEAD_LEN+cp->datalen) { + puts("after recv body error."); + break; + } + if(cmdpacket_decrypt(cp, index, "testpwd")) { + cp->data[cp->datalen] = 0; + printf("[normal] Get %u bytes data: %s\n", offset, cp->data); + switch(cp->cmd) { + case CMDACK: + printf("recv ack: %s\n", cp->data); + break; + case CMDEND: + default: return; break; + } + } + } } } @@ -43,6 +91,12 @@ off_t file_size_of(const char* fname) { else return -1; } +void send_cmd(int accept_fd, CMDPACKET* p) { + printf("send %d bytes encrypted data with %d bytes head.\n", p->datalen, CMDPACKET_HEAD_LEN); + if(!~send(accept_fd, (void*)p, CMDPACKET_HEAD_LEN+p->datalen, 0)) puts("Send data error"); + else puts("Send data succeed."); +} + int main(int argc,char *argv[]) { //usage: ./client host port ssize_t numbytes; puts("break!"); @@ -55,11 +109,10 @@ int main(int argc,char *argv[]) { //usage: ./client host port while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1); puts("Connected to server"); - numbytes = recv(sockfd, buf, BUFSIZ,0); - buf[numbytes]='\0'; - puts(buf); if(!pthread_create(&thread, NULL, (void*)&getMessage, NULL)) { puts("Thread create succeeded"); + init_crypto(); + reset_seq(0); while(1) { printf("Enter command:"); scanf("%s",buf); @@ -102,12 +155,53 @@ int main(int argc,char *argv[]) { //usage: ./client host port send(sockfd, md5_vals, 16, 0); } else { - send(sockfd, buf, strlen(buf), 0); - if(!strcmp(buf, "quit")) exit(EXIT_SUCCESS); + buf[3] = 0; + if(!strcmp(buf, "set")) { + CMDPACKET* p = malloc(CMDPACKET_HEAD_LEN+strlen(buf+4)); + p->cmd = CMDSET; + p->datalen = strlen(buf+4); + memcpy(p->data, buf+4, p->datalen); + cmdpacket_encrypt(p, 0, "testsps"); + send_cmd(sockfd, p); + free(p); + } else if(!strcmp(buf, "get")) { + CMDPACKET* p = malloc(CMDPACKET_HEAD_LEN+strlen(buf+4)); + p->cmd = CMDGET; + p->datalen = strlen(buf+4); + memcpy(p->data, buf+4, p->datalen); + cmdpacket_encrypt(p, 0, "testpwd"); + send_cmd(sockfd, p); + free(p); + } else if(!strcmp(buf, "cat")) { + CMDPACKET* p = malloc(CMDPACKET_HEAD_LEN+strlen(buf+4)); + p->cmd = CMDCAT; + p->datalen = 4; + memcpy(p->data, "fill", p->datalen); + cmdpacket_encrypt(p, 0, "testpwd"); + send_cmd(sockfd, p); + free(p); + } else if(!strcmp(buf, "del")) { + CMDPACKET* p = malloc(CMDPACKET_HEAD_LEN+strlen(buf+4)); + p->cmd = CMDDEL; + p->datalen = strlen(buf+4); + memcpy(p->data, buf+4, p->datalen); + cmdpacket_encrypt(p, 0, "testsps"); + send_cmd(sockfd, p); + free(p); + } else if(!strcmp(buf, "end")) { + CMDPACKET* p = malloc(CMDPACKET_HEAD_LEN+strlen(buf+4)); + p->cmd = CMDEND; + p->datalen = 4; + memcpy(p->data, "fill", p->datalen); + cmdpacket_encrypt(p, 0, "testpwd"); + send_cmd(sockfd, p); + free(p); + exit(EXIT_SUCCESS); + } else puts("no such cmd"); } sleep(1); } } else perror("Create msg thread failed"); close(sockfd); return 0; -} \ No newline at end of file +} diff --git a/crypto.c b/crypto.c new file mode 100644 index 0000000..b4d413e --- /dev/null +++ b/crypto.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include "crypto.h" + +// TEA encoding sumtable +static const uint32_t sumtable[0x10] = { + 0x9e3579b9, + 0x3c6ef172, + 0xd2a66d2b, + 0x78dd36e4, + 0x17e5609d, + 0xb54fda56, + 0x5384560f, + 0xf1bb77c8, + 0x8ff24781, + 0x2e4ac13a, + 0xcc653af3, + 0x6a9964ac, + 0x08d12965, + 0xa708081e, + 0x451221d7, + 0xe37793d0, +}; + +static uint8_t seqs[THREADCNT]; // 消息序号 + +static inline int is_md5_equal(uint8_t* digest, uint8_t* digest2) { + #ifdef CPUBIT64 + return (digest[0] == digest2[0]) && + (digest[1] == digest2[1]); + #else + return (digest[0] == digest2[0]) && + (digest[1] == digest2[1]) && + (digest[2] == digest2[2]) && + (digest[3] == digest2[3]); + #endif +} + +void init_crypto() { + srand(time(NULL)); +} + +void reset_seq(int index) { + seqs[index] = 0; +} + +char* raw_encrypt(const char* buf, off_t* len, int index, const char pwd[64]) { + TEADAT tin = {*len, (uint8_t*)buf}; + TEA tea[4]; + + ((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0]; + ((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1]; + ((uint8_t*)tea)[15] = seqs[index]++; + TEADAT* tout = tea_encrypt_native_endian(tea, sumtable, &tin); + + *len = tout->len; + char* encbuf = (char*)malloc(*len); + memcpy(encbuf, tout->data, *len); + free(tout->ptr); + free(tout); + + return encbuf; +} + +char* raw_decrypt(const char* buf, off_t* len, int index, const char pwd[64]) { + TEADAT tin = {*len, (uint8_t*)buf}; + TEA tea[4]; + + ((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0]; + ((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1]; + ((uint8_t*)tea)[15] = seqs[index]++; + TEADAT* tout = tea_decrypt_native_endian(tea, sumtable, &tin); + + *len = tout->len; + char* decbuf = (char*)malloc(*len); + memcpy(decbuf, tout->data, *len); + free(tout->ptr); + free(tout); + + return decbuf; +} + +void cmdpacket_encrypt(CMDPACKET* p, int index, const char pwd[64]) { + TEADAT tin = {p->datalen, p->data}; + TEA tea[4]; + + ((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0]; + ((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1]; + ((uint8_t*)tea)[15] = seqs[index]++; + TEADAT* tout = tea_encrypt_native_endian(tea, sumtable, &tin); + + uint8_t* datamd5 = md5(p->data, p->datalen); + memcpy(p->md5, datamd5, 16); + free(datamd5); + + p->datalen = tout->len; + memcpy(p->data, tout->data, p->datalen); + free(tout->ptr); + free(tout); + + return; +} + +int cmdpacket_decrypt(CMDPACKET* p, int index, const char pwd[64]) { + TEADAT tin = {p->datalen, p->data}; + TEA tea[4]; + + ((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0]; + ((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1]; + ((uint8_t*)tea)[15] = seqs[index]; + TEADAT* tout = tea_decrypt_native_endian(tea, sumtable, &tin); + + uint8_t* datamd5 = md5(tout->data, tout->len); + if(is_md5_equal(datamd5, p->md5)) { + seqs[index]++; + p->datalen = tout->len; + memcpy(p->data, tout->data, p->datalen); + free(datamd5); + free(tout->ptr); + free(tout); + return 1; + } + free(datamd5); + free(tout->ptr); + free(tout); + return 0; +} diff --git a/crypto.h b/crypto.h new file mode 100644 index 0000000..77369ea --- /dev/null +++ b/crypto.h @@ -0,0 +1,15 @@ +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +#include +#include +#include "server.h" + +void init_crypto(); +void reset_seq(int index); +char* raw_encrypt(const char* buf, off_t* len, int index, const char pwd[64]); +char* raw_decrypt(const char* buf, off_t* len, int index, const char pwd[64]); +void cmdpacket_encrypt(CMDPACKET* p, int index, const char pwd[64]); +int cmdpacket_decrypt(CMDPACKET* p, int index, const char pwd[64]); + +#endif /* _CRYPTO_H_ */ diff --git a/server.c b/server.c index 03a344e..506f086 100644 --- a/server.c +++ b/server.c @@ -1,23 +1,25 @@ -#include -#include -#include -#include +/* See feature_test_macros(7) */ +#define _GNU_SOURCE 1 #include -#include +#include +#include +#include +#include #include #include #include -#include -#include -#include +#include +#include +#include #include -#include +#include #include "server.h" #include "dict.h" +#include "crypto.h" #include "config.h" #if !__APPLE__ - #include + #include #endif #ifdef LISTEN_ON_IPV6 @@ -35,8 +37,8 @@ struct THREADTIMER { time_t touch; int accept_fd; ssize_t numbytes; - char *data; - char status, lock_type; + char *dat, *ptr; + char lock_type; }; typedef struct THREADTIMER THREADTIMER; @@ -45,7 +47,6 @@ static pthread_t accept_threads[THREADCNT]; static DICT d; static uint32_t* items_len; static CONFIG* cfg; -static char *setpass, *delpass; static pthread_attr_t attr; #define showUsage(program) printf("Usage: %s [-d] listen_port try_times dict_file config_file\n\t-d: As daemon\n", program) @@ -53,9 +54,7 @@ static pthread_attr_t attr; static void accept_client(); static void accept_timer(void *p); static int bind_server(uint16_t port, int try_times); -static int check_buffer(THREADTIMER *timer); static int close_and_send(THREADTIMER* timer, char *data, size_t numbytes); -static int free_after_send(int accept_fd, char *data, size_t length); static void handle_accept(void *accept_fd_p); static void handle_pipe(int signo); static void handle_quit(int signo); @@ -63,9 +62,7 @@ static void kill_thread(THREADTIMER* timer); static uint32_t last_nonnull(char* p, uint32_t max_size); static int listen_socket(int try_times); static int send_all(THREADTIMER *timer); -static int send_data(int accept_fd, char *data, size_t length); -static int sm1_pwd(THREADTIMER *timer); -static int s0_init(THREADTIMER *timer); +static int send_data(int accept_fd, int index, char *data, size_t length); static int s1_get(THREADTIMER *timer); static int s2_set(THREADTIMER *timer); static int s3_set_data(THREADTIMER *timer); @@ -115,8 +112,14 @@ static uint32_t last_nonnull(char* p, uint32_t max_size) { return max_size; } -static int send_data(int accept_fd, char *data, size_t length) { - if(!~send(accept_fd, data, length, 0)) { +static int send_data(int accept_fd, int index, char *data, size_t length) { + char buf[CMDPACKET_LEN_MAX]; + CMDPACKET* p = (CMDPACKET*)buf; + p->cmd = CMDACK; + p->datalen = length; + memcpy(p->data, data, p->datalen); + cmdpacket_encrypt(p, index, cfg->pwd); + if(!~send(accept_fd, buf, CMDPACKET_HEAD_LEN+p->datalen, 0)) { puts("Send data error"); return 0; } else { @@ -126,68 +129,43 @@ static int send_data(int accept_fd, char *data, size_t length) { } } -static int free_after_send(int accept_fd, char *data, size_t length) { - int re = send_data(accept_fd, data, length); - free(data); - return re; -} - static int send_all(THREADTIMER *timer) { int re = 1; FILE *fp = open_dict(DICT_LOCK_SH, timer->index); if(fp) { timer->lock_type = DICT_LOCK_SH; off_t len = 0, file_size = get_dict_size(); - sprintf(timer->data, "%u$", file_size); - printf("Get file size: %s bytes.\n", timer->data); - uint32_t head_len = strlen(timer->data); - #if __APPLE__ - struct sf_hdtr hdtr; - struct iovec headers; - headers.iov_base = timer->data; - headers.iov_len = head_len; - hdtr.headers = &headers; - hdtr.hdr_cnt = 1; - hdtr.trailers = NULL; - hdtr.trl_cnt = 0; - re = !sendfile(fileno(fp), timer->accept_fd, 0, &len, &hdtr, 0); - #else - send_data(timer->accept_fd, timer->data, head_len); - re = sendfile(timer->accept_fd, fileno(fp), &len, file_size) >= 0; - #endif - printf("Send %u bytes.\n", len); - close_dict(DICT_LOCK_SH, timer->index); + char* buf = (char*)malloc(file_size); + if(buf) { + if(fread(buf, file_size, 1, fp) == 1) { + char* encbuf = raw_encrypt(buf, &file_size, timer->index, cfg->pwd); + sprintf(timer->dat, "%zu$", file_size); + printf("Get encrypted file size: %s\n", timer->dat); + if(send(timer->accept_fd, timer->dat, strlen(timer->dat), 0) > 0) { + re = send(timer->accept_fd, encbuf, file_size, 0) > 0; + printf("Send %u bytes.\n", re); + close_dict(DICT_LOCK_SH, timer->index); + } else re = 0; + free(encbuf); + } + free(buf); + } } return re; } -static int sm1_pwd(THREADTIMER *timer) { - if(!strcmp(cfg->pwd, timer->data)) timer->status = 0; - return !timer->status; -} - -static int s0_init(THREADTIMER *timer) { - if(!strcmp("get", timer->data)) timer->status = 1; - else if(!strcmp(setpass, timer->data)) timer->status = 2; - else if(!strcmp(delpass, timer->data)) timer->status = 4; - else if(!strcmp("md5", timer->data)) timer->status = 5; - else if(!strcmp("cat", timer->data)) return send_all(timer); - else if(!strcmp("quit", timer->data)) return 0; - return send_data(timer->accept_fd, timer->data, timer->numbytes); -} - #define has_next(fp, ch) ((ch=getc(fp)),(feof(fp)?0:(ungetc(ch,fp),1))) static int s1_get(THREADTIMER *timer) { FILE *fp = open_dict(DICT_LOCK_SH, timer->index); - timer->status = 0; + //timer->status = 0; if(fp) { int ch; timer->lock_type = DICT_LOCK_SH; while(has_next(fp, ch)) { SIMPLE_PB* spb = get_pb(fp); DICT* d = (DICT*)spb->target; - if(!strcmp(timer->data, d->key)) { + if(!strcmp(timer->dat, d->key)) { int r = close_and_send(timer, d->data, last_nonnull(d->data, DICTDATSZ)); free(spb); return r; @@ -201,42 +179,43 @@ static int s2_set(THREADTIMER *timer) { FILE *fp = open_dict(DICT_LOCK_EX, timer->index); if(fp) { timer->lock_type = DICT_LOCK_EX; - timer->status = 3; + //timer->status = 3; memset(&d, 0, sizeof(DICT)); - strncpy(d.key, timer->data, DICTKEYSZ-1); + strncpy(d.key, timer->dat, DICTKEYSZ-1); fseek(fp, 0, SEEK_END); - return send_data(timer->accept_fd, "data", 4); + return send_data(timer->accept_fd, timer->index, "data", 4); } else { - timer->status = 0; - return send_data(timer->accept_fd, "erro", 4); + timer->lock_type = DICT_LOCK_UN; + //timer->status = 0; + return send_data(timer->accept_fd, timer->index, "erro", 4); } } static int s3_set_data(THREADTIMER *timer) { - timer->status = 0; + //timer->status = 0; uint32_t datasize = (timer->numbytes > (DICTDATSZ-1))?(DICTDATSZ-1):timer->numbytes; printf("Set data size: %u\n", datasize); - memcpy(d.data, timer->data, datasize); + memcpy(d.data, timer->dat, datasize); puts("Data copy to dict succ"); if(!set_pb(get_dict_fp(timer->index), items_len, sizeof(DICT), &d)) { - printf("Error set data: dict[%s]=%s\n", d.key, timer->data); + printf("Error set data: dict[%s]=%s\n", d.key, timer->dat); return close_and_send(timer, "erro", 4); } else { - printf("Set data: dict[%s]=%s\n", d.key, timer->data); + printf("Set data: dict[%s]=%s\n", d.key, timer->dat); return close_and_send(timer, "succ", 4); } } static int s4_del(THREADTIMER *timer) { FILE *fp = open_dict(DICT_LOCK_EX, timer->index); - timer->status = 0; + //timer->status = 0; if(fp) { int ch; timer->lock_type = DICT_LOCK_EX; while(has_next(fp, ch)) { SIMPLE_PB* spb = get_pb(fp); DICT* d = (DICT*)spb->target; - if(!memcmp(timer->data, d->key, timer->numbytes+1)) { + if(!memcmp(timer->dat, d->key, timer->numbytes+1)) { uint32_t next = ftell(fp); uint32_t this = next - spb->real_len; fseek(fp, 0, SEEK_END); @@ -277,24 +256,10 @@ static int s4_del(THREADTIMER *timer) { } static int s5_md5(THREADTIMER *timer) { - timer->status = 0; + //timer->status = 0; fill_md5(); - if(is_md5_equal(timer->data)) return send_data(timer->accept_fd, "null", 4); - else return send_data(timer->accept_fd, "nequ", 4); -} - -static int check_buffer(THREADTIMER *timer) { - printf("Status: %d\n", timer->status); - switch(timer->status) { - case -1: return sm1_pwd(timer); break; - case 0: return s0_init(timer); break; - case 1: return s1_get(timer); break; - case 2: return s2_set(timer); break; - case 3: return s3_set_data(timer); break; - case 4: return s4_del(timer); break; - case 5: return s5_md5(timer); break; - default: return -1; break; - } + if(is_md5_equal((uint8_t*)timer->dat)) return send_data(timer->accept_fd, timer->index, "null", 4); + else return send_data(timer->accept_fd, timer->index, "nequ", 4); } static void handle_quit(int signo) { @@ -334,9 +299,9 @@ static void kill_thread(THREADTIMER* timer) { timer->accept_fd = 0; puts("Close accept."); } - if(timer->data) { - free(timer->data); - timer->data = NULL; + if(timer->ptr) { + free(timer->ptr); + timer->ptr = NULL; puts("Free data."); } if(timer->lock_type) close_dict(timer->lock_type, timer->index); @@ -348,21 +313,6 @@ static void handle_pipe(int signo) { pthread_exit(NULL); } -#define chkbuf(p) if(!check_buffer(timer_pointer_of(p))) break -#define take_word(p, w) if(timer_pointer_of(p)->numbytes > strlen(w) && strstr(buff, w) == buff) {\ - int l = strlen(w);\ - char store = buff[l];\ - buff[l] = 0;\ - ssize_t n = timer_pointer_of(p)->numbytes - l;\ - timer_pointer_of(p)->numbytes = l;\ - chkbuf(p);\ - buff[0] = store;\ - memmove(buff + 1, buff + l + 1, n - 1);\ - buff[n] = 0;\ - timer_pointer_of(p)->numbytes = n;\ - printf("Split cmd: %s\n", w);\ - } - static void handle_accept(void *p) { int accept_fd = timer_pointer_of(p)->accept_fd; if(accept_fd > 0) { @@ -370,22 +320,79 @@ static void handle_accept(void *p) { pthread_t thread; if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) puts("Error creating timer thread"); else puts("Creating timer thread succeeded"); - send_data(accept_fd, "Welcome to simple dict server.", 31); - timer_pointer_of(p)->status = -1; + //send_data(accept_fd, "Welcome to simple dict server.", 31); + //timer_pointer_of(p)->status = -1; uint32_t index = timer_pointer_of(p)->index; char *buff = calloc(BUFSIZ, sizeof(char)); if(buff) { - timer_pointer_of(p)->data = buff; - while(accept_threads[index] && (timer_pointer_of(p)->numbytes = recv(accept_fd, buff, BUFSIZ, 0)) > 0) { + timer_pointer_of(p)->ptr = buff; + CMDPACKET* cp = (CMDPACKET*)buff; + ssize_t numbytes = 0, offset = 0; + while(accept_threads[index] && (numbytes = recv(accept_fd, buff+offset, CMDPACKET_HEAD_LEN-offset, MSG_WAITALL)) > 0) { touch_timer(p); - buff[timer_pointer_of(p)->numbytes] = 0; - printf("Get %u bytes: %s\n", timer_pointer_of(p)->numbytes, buff); - puts("Check buffer"); - take_word(p, cfg->pwd); - take_word(p, setpass) take_word(p, delpass) else take_word(p, "cat") else take_word(p, "md5"); - if(timer_pointer_of(p)->numbytes > 0) chkbuf(p); + offset += numbytes; + printf("[normal] Get %zd bytes head.\n", numbytes); + if(offset < CMDPACKET_HEAD_LEN) break; + if(offset < CMDPACKET_HEAD_LEN+cp->datalen) { + numbytes = recv(accept_fd, buff+offset, CMDPACKET_HEAD_LEN+cp->datalen-offset, MSG_WAITALL); + printf("[normal] Get %zd bytes body.\n", numbytes); + } + if(numbytes <= 0) break; + else offset += numbytes; + if(offset < CMDPACKET_HEAD_LEN+cp->datalen) break; + printf("[normal] Decrypt %zd bytes data...\n", cp->datalen); + if(cmdpacket_decrypt(cp, index, cfg->pwd)) { + cp->data[cp->datalen] = 0; + timer_pointer_of(p)->dat = (char*)cp->data; + timer_pointer_of(p)->numbytes = cp->datalen; + printf("[normal] Get %zd bytes data: %s\n", offset, cp->data); + switch(cp->cmd) { + case CMDGET: + //timer_pointer_of(p)->status = 1; + if(!s1_get(timer_pointer_of(p))) goto CONV_END; + break; + case CMDCAT: + if(!send_all(timer_pointer_of(p))) goto CONV_END; + break; + case CMDMD5: + //timer_pointer_of(p)->status = 5; + if(!s5_md5(timer_pointer_of(p))) goto CONV_END; + break; + case CMDACK: break; + case CMDEND: + default: goto CONV_END; break; + } + } else if(cmdpacket_decrypt(cp, index, cfg->sps)) { + cp->data[cp->datalen] = 0; + timer_pointer_of(p)->dat = (char*)cp->data; + timer_pointer_of(p)->numbytes = cp->datalen; + printf("[super] Get %zd bytes data: %s\n", offset, cp->data); + switch(cp->cmd) { + case CMDSET: + //timer_pointer_of(p)->status = 2; + if(!s2_set(timer_pointer_of(p))) goto CONV_END; + break; + case CMDDEL: + //timer_pointer_of(p)->status = 4; + if(!s4_del(timer_pointer_of(p))) goto CONV_END; + break; + case CMDDAT: + if(timer_pointer_of(p)->lock_type == DICT_LOCK_EX) { + if(!s3_set_data(timer_pointer_of(p))) goto CONV_END; + } + break; + default: goto CONV_END; break; + } + } else { + puts("decrypt data failed."); + break; + } + if(offset > CMDPACKET_HEAD_LEN+cp->datalen) { + offset -= CMDPACKET_HEAD_LEN+cp->datalen; + memmove(buff, buff+CMDPACKET_HEAD_LEN+cp->datalen, offset); + } else offset = 0; } - printf("Break: recv %u bytes\n", timer_pointer_of(p)->numbytes); + CONV_END: puts("Conversation end\n"); } else puts("Error allocating buffer"); accept_threads[index] = 0; kill_thread(timer_pointer_of(p)); @@ -404,6 +411,7 @@ static void accept_client() { signal(SIGPIPE, handle_pipe); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, 1); + init_crypto(); if(pid < 0) puts("Error when forking a subprocess."); else while(1) { puts("Ready for accept, waitting..."); @@ -432,7 +440,10 @@ static void accept_client() { printf("Accept client %s:%u\n", str, port); timer->index = p; timer->touch = time(NULL); - timer->data = NULL; + timer->ptr = NULL; + puts("reset seq..."); + reset_seq(p); + puts("reset seq succeed"); if (pthread_create(accept_threads + p, &attr, (void *)&handle_accept, timer)) puts("Error creating thread"); else puts("Creating thread succeeded"); } @@ -446,10 +457,9 @@ static void accept_client() { static int close_and_send(THREADTIMER* timer, char *data, size_t numbytes) { close_dict(timer->lock_type, timer->index); - return send_data(timer->accept_fd, data, numbytes); + return send_data(timer->accept_fd, timer->index, data, numbytes); } -#define set_pass(pass, sps, slen, cmd) (pass=malloc(strlen(cmd)+slen+1),((pass)?(strcpy(pass,cmd),strcpy(pass+strlen(cmd),sps),1):0)) #define argequ(i, arg) (*(uint16_t*)argv[i] == *(uint16_t*)(arg)) int main(int argc, char *argv[]) { if(argc != 5 && argc != 6) showUsage(argv[0]); @@ -474,13 +484,10 @@ int main(int argc, char *argv[]) { SIMPLE_PB* spb = get_pb(fp); cfg = (CONFIG*)spb->target; fclose(fp); - int slen = strlen(cfg->sps); - if(set_pass(setpass, cfg->sps, slen, "set") && set_pass(delpass, cfg->sps, slen, "del")) { - items_len = align_struct(sizeof(DICT), 2, d.key, d.data); - if(items_len) { - if(bind_server(port, times)) if(listen_socket(times)) accept_client(); - } else puts("Align struct error."); - } else puts("Allocate memory error."); + items_len = align_struct(sizeof(DICT), 2, d.key, d.data); + if(items_len) { + if(bind_server(port, times)) if(listen_socket(times)) accept_client(); + } else puts("Align struct error."); } else printf("Error opening config file: %s\n", argv[as_daemon?5:4]); } else printf("Error opening dict file: %s\n", argv[as_daemon?4:3]); } else puts("Start daemon error"); diff --git a/server.h b/server.h index e95d200..7d0d488 100644 --- a/server.h +++ b/server.h @@ -4,4 +4,17 @@ #define THREADCNT 16 #define MAXWAITSEC 10 +enum SERVERCMD {CMDGET, CMDSET, CMDDEL, CMDCAT, CMDMD5, CMDDAT, CMDACK, CMDEND}; + +struct CMDPACKET { + uint8_t cmd; + uint8_t datalen; // data len is less than 255 + uint8_t md5[16]; // md5 digest of data below + uint8_t data[]; // with TEA encoding, 64 bytes will be 160 bytes +}; +typedef struct CMDPACKET CMDPACKET; + +#define CMDPACKET_HEAD_LEN (1+1+16) +#define CMDPACKET_LEN_MAX (CMDPACKET_HEAD_LEN+255) + #endif /* _SERVER_H_ */