about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2024-12-31 02:18:40 -0600
committerRen Kararou <[email protected]>2024-12-31 02:18:40 -0600
commitf6b4ac41eec72a25c703c63f43bd1104049a405c (patch)
tree6fc60798944ac010c22ede4e2e9e33d6b97d39e0 /src
parent810de0a90148d5dc7fe5919949220a00d14f6447 (diff)
downloadnbtpd-f6b4ac41eec72a25c703c63f43bd1104049a405c.tar.gz
nbtpd-f6b4ac41eec72a25c703c63f43bd1104049a405c.tar.bz2
nbtpd-f6b4ac41eec72a25c703c63f43bd1104049a405c.zip
complete setup code; complete initial packet handling
Diffstat (limited to 'src')
-rw-r--r--src/handlers.c25
-rw-r--r--src/main.c105
-rw-r--r--src/netascii.c4
-rw-r--r--src/packet.c2
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";