Add L handler among other cursed things

This commit is contained in:
akp 2023-11-11 16:45:42 +00:00
parent e89075bd0d
commit f006ea0470
No known key found for this signature in database
GPG key ID: CF8D58F3DEB20755
3 changed files with 131 additions and 14 deletions

View file

@ -30,7 +30,7 @@ int handle_add_rule(char *data, size_t len) {
add_frame(parse_res);
end:
free_rule(parse_res);
free(parse_res); // this is intentionally NOT free_rule as the optional end IP and port assignments are still used elsewhere.
return retval;
}
@ -50,6 +50,7 @@ int handle_check_rule(char *data, size_t len) {
if (endptr == NULL) {
return HANDLER_ILLEGALARG;
} else if ((endptr - data) != len) {
// TODO: this gets triggered when the port has a trailing zero
return HANDLER_ILLEGALARG;
}
@ -58,4 +59,8 @@ int handle_check_rule(char *data, size_t len) {
}
return HANDLER_OK;
}
int handle_list_rules(int sd) {
return list_rules(sd);
}

View file

@ -4,7 +4,8 @@
#include "../../firewall_types.c"
#include <string.h>
#include "pthread.h"
#include <pthread.h>
#include <sys/socket.h>
struct LogFrame {
struct LogFrame *next;
@ -39,6 +40,9 @@ void append_frame(struct LogFrame **log, struct IP *ip, Port port) {
struct LogFrame *new_log_frame = (struct LogFrame*) malloc(sizeof(struct LogFrame));
memset(new_log_frame, 0, sizeof(struct LogFrame));
new_log_frame->ip = ip;
new_log_frame->port = port;
if (*log == NULL) {
*log = new_log_frame;
} else {
@ -69,7 +73,8 @@ void add_frame(struct Rule* rule) {
int check_ip_and_port(struct IP *ip, Port port) {
// TODO: Something here is broken wrt. ranges of ports and maybe IPs.
// TODO: ip=255.255.255.255??
pthread_rwlock_wrlock(&persist_lock);
struct Frame *cursor = persist_head;
@ -109,4 +114,96 @@ not_found:
found:
pthread_rwlock_unlock(&persist_lock);
return 1;
}
int send_ip(int sd, struct IP *ip) {
char buf[16];
snprintf(buf, 16,"%d.%d.%d.%d", ip->val[0], ip->val[1], ip->val[2], ip->val[3]);
return send(sd, buf, strlen(buf), 0);
}
int send_port(int sd, Port port) {
char buf[6];
snprintf(buf, 6, "%d", port);
return send(sd, buf, strlen(buf), 0);
}
int send_rule(int sd, struct Rule *r) {
if (send_ip(sd, &r->ip.start) == -1) {
return -1;
}
if (r->ip.end != NULL) {
if (send(sd, "-", 1, 0) == -1) {
return -1;
}
if (send_ip(sd, r->ip.end) == -1) {
return -1;
}
}
if (send(sd, " ", 1, 0) == -1) {
return -1;
}
if (send_port(sd, r->port.start) == -1) {
return -1;
}
if (r->port.end != NULL) {
if (send(sd, "-", 1, 0) == -1) {
return -1;
}
if (send_port(sd, *r->port.end) == -1) {
return -1;
}
}
return 0;
}
int list_rules(int sd) {
int status = 0;
pthread_rwlock_rdlock(&persist_lock);
struct Frame *frame_cursor = persist_head;
while (frame_cursor != NULL) {
if (send(sd, "Rule: ", 6, 0) == -1) {
return -1;
}
if (send_rule(sd, &frame_cursor->rule) == -1) {
status = -1;
goto end;
}
if (send(sd, "\n", 1, 0) == -1) {
return -1;
}
struct LogFrame *log_cursor = frame_cursor->log;
while (log_cursor != NULL) {
if (send(sd, "Query: ", 7, 0) == -1) {
return -1;
}
if (send_ip(sd, log_cursor->ip) == -1) {
status = -1;
goto end;
}
if (send(sd, " ", 1, 0) == -1) {
return -1;
}
if (send_port(sd, log_cursor->port) == -1) {
status = -1;
goto end;
}
if (send(sd, "\n", 1, 0) == -1) {
return -1;
}
log_cursor = log_cursor->next;
}
frame_cursor = frame_cursor->next;
}
end:
pthread_rwlock_unlock(&persist_lock);
return status;
}

View file

@ -100,15 +100,19 @@ void handle_connection(int *sdptr) {
fprintf(stderr, "[%d] Operation: %c, message length: %zu\n", sd, operation, message_length);
char *data = (char *) malloc(sizeof(char) * message_length);
char *data;
if (recv_n(sd, data, message_length) != 0) {
if (errno == EPROTO) {
fprintf(stderr, "[%d] too few bytes supplied\n", sd);
} else {
perror("warning: failed to receive from remote host");
if (message_length != 0) {
data = (char *) malloc(sizeof(char) * message_length);
if (recv_n(sd, data, message_length) != 0) {
if (errno == EPROTO) {
fprintf(stderr, "[%d] too few bytes supplied\n", sd);
} else {
perror("warning: failed to receive from remote host");
}
goto data_cleanup;
}
goto data_cleanup;
}
fprintf(stderr, "[%d] Data: %s\n", sd, data);
@ -135,19 +139,30 @@ void handle_connection(int *sdptr) {
}
break;
}
case 'L': {
if (handle_list_rules(sd) != 0) {
perror("warning: failed to send data to remote host");
goto data_cleanup;
}
break;
}
default: {
response = "Illegal request";
break;
}
}
if (send(sd, response, strlen(response), 0) == -1) {
perror("warning: failed to send data to remote host");
goto data_cleanup;
if (response != NULL) {
if (send(sd, response, strlen(response), 0) == -1) {
perror("warning: failed to send data to remote host");
goto data_cleanup;
}
}
data_cleanup:
free(data);
if (data != NULL) {
free(data);
}
cleanup:
free(leader);