diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/handlers.c | 25 | ||||
-rw-r--r-- | src/main.c | 105 | ||||
-rw-r--r-- | src/netascii.c | 4 | ||||
-rw-r--r-- | src/packet.c | 2 |
4 files changed, 98 insertions, 38 deletions
diff --git a/src/handlers.c b/src/handlers.c index 4162926..788934d 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -1,26 +1,27 @@ +#include <stdlib.h> #include <sys/socket.h> #include "handlers.h" -void read_req_resp(nbd_nbtpd_args args) { - if (args.path[0] == 0) { +void *read_req_resp(void *args) { + if ((*(nbd_nbtpd_args *)args).path[0] == 0) { nbd_nbtpd_resp_error(args); - return; + return (void *)NULL; } - return; + return (void *)NULL; } -void write_req_resp(nbd_nbtpd_args args) { - if (args.path[0] == 0) { +void *write_req_resp(void *args) { + if ((*(nbd_nbtpd_args *)args).path[0] == 0) { nbd_nbtpd_resp_error(args); - return; + return (void *)NULL; } - return; + return (void *)NULL; } -void nbd_nbtpd_resp_error(nbd_nbtpd_args args) { - if (args.path[0] == 0) { - return; +void *nbd_nbtpd_resp_error(void *args) { + if ((*(nbd_nbtpd_args *)args).path[0] == 0) { + return (void *)NULL; } - return; + return (void *)NULL; } diff --git a/src/main.c b/src/main.c index 3701c79..0264050 100644 --- a/src/main.c +++ b/src/main.c @@ -17,11 +17,17 @@ #include "packet.h" #include "netascii.h" +#include "handlers.h" -static int stop = 0; +int nbtpd_stop = 0; -void stop_handler() { - stop = 1; +void stop_handler(int i) { + syslog(LOG_ERR, "caught shutdown signal, cleaning up."); + if (i != 0) { + nbtpd_stop = i; + } else { + nbtpd_stop = 1; + } return; } @@ -89,6 +95,8 @@ int main(int argc, char **argv) { setlogmask(LOG_UPTO(LOG_INFO)); openlog(argv[0], LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_FTP); syslog(LOG_INFO, "starting up..."); + signal(SIGTERM, &stop_handler); + signal(SIGINT, &stop_handler); if (daemonize) { if (daemon(1, 0)) { @@ -127,16 +135,18 @@ int main(int argc, char **argv) { } syslog(LOG_INFO, "socket bind success"); - //TODO: use getpwnam_r() and getgrnam_r() - struct passwd *u = getpwnam((const char *)&user); - if (setuid((*u).pw_uid) == -1) { - syslog(LOG_ERR, "failed to drop user privileges"); - return -1; - } - struct group *g = getgrnam((const char *)&group); - if (setgid((*g).gr_gid) == -1) { - syslog(LOG_ERR, "failed to drop group privileges"); - return -1; + if (daemonize) { + //TODO: use getpwnam_r() and getgrnam_r() + struct group *g = getgrnam((const char *)&group); + if (setgid((*g).gr_gid) == -1) { + syslog(LOG_ERR, "failed to drop group privileges"); + return -1; + } + struct passwd *u = getpwnam((const char *)&user); + if (setuid((*u).pw_uid) == -1) { + syslog(LOG_ERR, "failed to drop user privileges"); + return -1; + } } // create persistent buffer @@ -147,21 +157,70 @@ int main(int argc, char **argv) { close(s); return -1; } - while (!stop) { + while (!nbtpd_stop) { struct sockaddr_in caddr; unsigned int clen = sizeof(caddr); memset(buf, '\0', 1024); - if (recvfrom(s, buf, 1024, 0, (struct sockaddr*)&caddr, &clen) < 0) { - syslog(LOG_ERR, - "got a client connection, but unable to receive data!"); - free(buf); + ssize_t recvd_bytes = 0; + if ((recvd_bytes = recvfrom(s, buf, 1024, 0, + (struct sockaddr *)&caddr, &clen)) < 0) { + syslog( + LOG_ERR, + "got a client connection, but unable to receive data!" + ); continue; } - //TODO: process packet - - // we will never actually join on this thread, and don't care to keep it around. - //pthread_t *_thread; // since this hasn't been implemented yet, clang is complaining - + if (recvd_bytes < 4) { + syslog(LOG_ERR, "ignoring invalid packet."); + continue; + } + nbd_nbtpd_args *args = malloc(sizeof(nbd_nbtpd_args)); + if (args == NULL) { + syslog(LOG_CRIT, "unable to allocate memory"); + continue; + } + nbd_tftp_opcode oc = ntohs(((uint16_t)buf[0] << 8) + buf[1]); + (*args).client = caddr; + (*args).err = 0; + memset((*args).path, '\0', 768); + memset((*args).mode, '\0', 32); + int i; + for(i = 2; buf[i] != 0 && i < recvd_bytes && (i - 2) < 768; i++) { + (*args).path[i - 2] = buf[i]; + } + int s = i + 1; + if (s >= recvd_bytes) { + oc = 0; + } else { + for(i = s; buf[i] != 0 && i < recvd_bytes && (i - s) < 32; i++) { + (*args).mode[i - s] = buf[i]; + } + } + pthread_t *_thread = malloc(sizeof(pthread_t)); + if (_thread == NULL) { + syslog(LOG_CRIT, "unable to allocate memory"); + free(args); + continue; + } + void *(*func)(void *); + switch (oc) { + case RRQ: + func = &read_req_resp; + break; + case WRQ: + func = &write_req_resp; + break; + default: + (*args).err = 4; + func = &nbd_nbtpd_resp_error; + } + if (pthread_create(_thread, 0, func, (void *)args) != 0) { + syslog( + LOG_CRIT, + "unable to handle request: cannot create thread!" + ); + free(args); + } } // free our persistent buffer diff --git a/src/netascii.c b/src/netascii.c index 2180093..fb4d7b8 100644 --- a/src/netascii.c +++ b/src/netascii.c @@ -14,7 +14,7 @@ uint8_t is_netascii_char(char c) { /// WARNING! This function is NOT safe. Use only for strings you have already /// verified are NULL terminated! -uint8_t is_netascii_str(char* str) { +uint8_t is_netascii_str(char *str) { for (uint64_t i = 0; str[i] != 0; i++) { if (!is_netascii_char(str[i])) { return 0; @@ -29,7 +29,7 @@ uint8_t is_netascii_str(char* str) { return 1; } -uint8_t is_netascii_buf(char* buf, uint64_t len) { +uint8_t is_netascii_buf(char *buf, uint64_t len) { for (uint64_t i = 0; i < len; i++) { if (!is_netascii_char(buf[i])) { return 0; diff --git a/src/packet.c b/src/packet.c index 8f7a7e6..5bc8be6 100644 --- a/src/packet.c +++ b/src/packet.c @@ -1,6 +1,6 @@ #include "packet.h" -char* nbt_tftp_error_to_message(nbt_tftp_ecode error) { +char *nbd_tftp_error_to_message(nbd_tftp_ecode error) { switch (error) { case 0: return "ERROR"; |