Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 5 commits
  • 1 file changed
  • 0 commit comments
  • 1 contributor
Showing with 275 additions and 305 deletions.
  1. +275 −305 src/knockd.c
View
580 src/knockd.c
@@ -55,7 +55,7 @@
#include <errno.h>
#include "list.h"
-static char version[] = "0.5";
+static char version[] = "0.6";
#define SEQ_TIMEOUT 25 /* default knock timeout in seconds */
#define CMD_TIMEOUT 10 /* default timeout in seconds between start and stop commands */
@@ -73,6 +73,7 @@ typedef struct opendoor {
unsigned short seqcount;
unsigned short sequence[SEQ_MAX];
unsigned short protocol[SEQ_MAX];
+ char *target;
time_t seq_timeout;
char *start_command;
time_t cmd_timeout;
@@ -510,6 +511,7 @@ int parseconfig(char *configfile)
}
strncpy(door->name, section, sizeof(door->name)-1);
door->name[sizeof(door->name)-1] = '\0';
+ door->target = 0;
door->seqcount = 0;
door->seq_timeout = SEQ_TIMEOUT; /* default sequence timeout (seconds) */
door->start_command = NULL;
@@ -569,7 +571,15 @@ int parseconfig(char *configfile)
linenum, key);
return(1);
}
- if(!strcmp(key, "SEQUENCE")) {
+ if(!strcmp(key, "TARGET")) {
+ door->target = malloc(sizeof(char) * (strlen(ptr)+1));
+ if(door->target == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ strcpy(door->target, ptr);
+ dprint("config: %s: target: %s\n", door->name, door->target);
+ } else if(!strcmp(key, "SEQUENCE")) {
int i;
i = parse_port_sequence(ptr, door);
if (i > 0) {
@@ -804,19 +814,17 @@ long get_current_one_time_sequence_position(opendoor_t *door)
*/
void generate_pcap_filter()
{
- /* NOTE: We're doing string manipulations in a daemon -- use defensive programming! */
-
PMList *lp;
opendoor_t *door;
- char *buffer = NULL; /* temporary buffer to create the individual filter strings */
- size_t bufsize = 0; /* size of buffer */
- char port_str[10]; /* used by snprintf to convert unsigned short --> string */
- short head_set = 0; /* flag indicating if protocol head is set (i.e. "((tcp dst port") */
- short tcp_present = 0; /* flag indicating if TCP is used */
- short udp_present = 0; /* flag indicating if UDP is used */
+ char *buffer = NULL; /* temporary buffer to create the individual filter strings */
+ size_t bufsize = 0; /* size of buffer */
+ char port_str[10]; /* used by snprintf to convert unsigned short --> string */
+ short head_set = 0; /* flag indicating if protocol head is set (i.e. "((tcp dst port") */
+ short tcp_present = 0; /* flag indicating if TCP is used */
+ short udp_present = 0; /* flag indicating if UDP is used */
unsigned int i;
- short modified_filters = 0; /* flag indicating if at least one filter has changed --> recompile the filter */
- struct bpf_program bpf_prog; /* compiled BPF filter program */
+ short modified_filters = 0; /* flag indicating if at least one filter has changed --> recompile the filter */
+ struct bpf_program bpf_prog; /* compiled BPF filter program */
/* generate subfilters for each door having a NULL pcap_filter_exp
*
@@ -851,6 +859,10 @@ void generate_pcap_filter()
buffer[0] = '\0';
}
+ bufsize = realloc_strcat(&buffer, "(dst host ", bufsize); /* accept only incoming packets */
+ bufsize = realloc_strcat(&buffer, door->target ? door->target : myip, bufsize);
+ bufsize = realloc_strcat(&buffer, " and (", bufsize);
+
/* generate filter for all TCP ports (i.e. "((tcp dst port 4000 or 4001 or 4002) and tcp[tcpflags] & tcp-syn != 0)" */
for(i = 0; i < door->seqcount; i++) {
if(door->protocol[i] == IPPROTO_TCP) {
@@ -949,6 +961,8 @@ void generate_pcap_filter()
if(udp_present) {
bufsize = realloc_strcat(&buffer, ")", bufsize); /* close parentheses of UDP ports */
}
+
+ bufsize = realloc_strcat(&buffer, "))", bufsize); /* close parantheses around port filters */
/* test if in any of the precedent calls to realloc_strcat() failed. We can do this safely here because
* realloc_strcat() returns 0 on failure and if a buffer size of 0 is passed to it, the function does
@@ -985,9 +999,6 @@ void generate_pcap_filter()
* )
*/
if(modified_filters) {
- bufsize = realloc_strcat(&buffer, "dst host ", bufsize); /* accept only incoming packets */
- bufsize = realloc_strcat(&buffer, myip, bufsize);
- bufsize = realloc_strcat(&buffer, " and (", bufsize);
/* iterate over all doors */
for(lp = doors; lp; lp = lp->next) {
door = (opendoor_t*)lp->data;
@@ -996,7 +1007,6 @@ void generate_pcap_filter()
bufsize = realloc_strcat(&buffer, " or ", bufsize);
}
}
- bufsize = realloc_strcat(&buffer, ")", bufsize); /* close parantheses around port filters */
/* test if in any of the precedent calls to realloc_strcat() failed. See above why this is ok to do this only
* at this point */
@@ -1063,19 +1073,14 @@ size_t realloc_strcat(char **dest, const char *src, size_t size)
void close_door(opendoor_t *door)
{
doors = list_remove(doors, door);
- if (door) {
- if (door->start_command) {
- free(door->start_command);
- }
- if (door->stop_command) {
- free(door->stop_command);
- }
+ if(door) {
+ free(door->target);
+ free(door->start_command);
+ free(door->stop_command);
if (door->one_time_sequences_fd) {
fclose(door->one_time_sequences_fd);
}
- if (door->pcap_filter_exp) {
- free(door->pcap_filter_exp);
- }
+ free(door->pcap_filter_exp);
free(door);
}
}
@@ -1196,6 +1201,235 @@ int exec_cmd(char* command, char* name){
return ret;
}
+/*
+ * If examining a TCP packet, try to match flags against those in
+ * the door config.
+ */
+#if defined(__FreeBSD__) || defined(__APPLE__)
+int flags_match(opendoor_t* door, struct ip* ip, struct tcphdr* tcp)
+{
+ /* if tcp, check the flags to ignore the packets we don't want
+ * (don't even use it to cancel sequences)
+ */
+ if(ip->ip_p == IPPROTO_TCP) {
+ if(door->flag_fin != DONT_CARE) {
+ if(door->flag_fin == SET && !(tcp->th_flags & TH_FIN)) {
+ dprint("packet is not FIN, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_fin == NOT_SET && (tcp->th_flags & TH_FIN)) {
+ dprint("packet is not !FIN, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_syn != DONT_CARE) {
+ if(door->flag_syn == SET && !(tcp->th_flags & TH_SYN)) {
+ dprint("packet is not SYN, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_syn == NOT_SET && (tcp->th_flags & TH_SYN)) {
+ dprint("packet is not !SYN, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_rst != DONT_CARE) {
+ if(door->flag_rst == SET && !(tcp->th_flags & TH_RST)) {
+ dprint("packet is not RST, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_rst == NOT_SET && (tcp->th_flags & TH_RST)) {
+ dprint("packet is not !RST, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_psh != DONT_CARE) {
+ if(door->flag_psh == SET && !(tcp->th_flags & TH_PUSH)) {
+ dprint("packet is not PSH, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_psh == NOT_SET && (tcp->th_flags & TH_PUSH)) {
+ dprint("packet is not !PSH, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_ack != DONT_CARE) {
+ if(door->flag_ack == SET && !(tcp->th_flags & TH_ACK)) {
+ dprint("packet is not ACK, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_ack == NOT_SET && !(tcp->th_flags & TH_ACK)) {
+ dprint("packet is not !ACK, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_urg != DONT_CARE) {
+ if(door->flag_urg == SET && !(tcp->th_flags & TH_URG)) {
+ dprint("packet is not URG, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_urg == NOT_SET && !(tcp->th_flags & TH_URG)) {
+ dprint("packet is not !URG, ignoring...\n");
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+#else
+int flags_match(opendoor_t* door, struct iphdr* ip, struct tcphdr* tcp)
+{
+ /* if tcp, check the flags to ignore the packets we don't want
+ * (don't even use it to cancel sequences)
+ */
+ if(ip->protocol == IPPROTO_TCP) {
+ if(door->flag_fin != DONT_CARE) {
+ if(door->flag_fin == SET && tcp->fin != 1) {
+ dprint("packet is not FIN, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_fin == NOT_SET && tcp->fin == 1) {
+ dprint("packet is not !FIN, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_syn != DONT_CARE) {
+ if(door->flag_syn == SET && tcp->syn != 1) {
+ dprint("packet is not SYN, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_syn == NOT_SET && tcp->syn == 1) {
+ dprint("packet is not !SYN, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_rst != DONT_CARE) {
+ if(door->flag_rst == SET && tcp->rst != 1) {
+ dprint("packet is not RST, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_rst == NOT_SET && tcp->rst == 1) {
+ dprint("packet is not !RST, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_psh != DONT_CARE) {
+ if(door->flag_psh == SET && tcp->psh != 1) {
+ dprint("packet is not PSH, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_psh == NOT_SET && tcp->psh == 1) {
+ dprint("packet is not !PSH, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_ack != DONT_CARE) {
+ if(door->flag_ack == SET && tcp->ack != 1) {
+ dprint("packet is not ACK, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_ack == NOT_SET && tcp->ack == 1) {
+ dprint("packet is not !ACK, ignoring...\n");
+ return 0;
+ }
+ }
+ if(door->flag_urg != DONT_CARE) {
+ if(door->flag_urg == SET && tcp->urg != 1) {
+ dprint("packet is not URG, ignoring...\n");
+ return 0;
+ }
+ if(door->flag_urg == NOT_SET && tcp->urg == 1) {
+ dprint("packet is not !URG, ignoring...\n");
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+#endif
+
+/**
+ * Process a knock attempt to see if the knocker has graduated to the next
+ * sequence. If they've completed all sequences correctly, then we open the
+ * door.
+ */
+void process_attempt(knocker_t *attempt)
+{
+ /* level up! */
+ attempt->stage++;
+ if(attempt->srchost) {
+ vprint("%s (%s): %s: Stage %d\n", attempt->src, attempt->srchost, attempt->door->name, attempt->stage);
+ logprint("%s (%s): %s: Stage %d", attempt->src, attempt->srchost, attempt->door->name, attempt->stage);
+ } else {
+ vprint("%s: %s: Stage %d\n", attempt->src, attempt->door->name, attempt->stage);
+ logprint("%s: %s: Stage %d", attempt->src, attempt->door->name, attempt->stage);
+ }
+ if(attempt->stage >= attempt->door->seqcount) {
+ if(attempt->srchost) {
+ vprint("%s (%s): %s: OPEN SESAME\n", attempt->src, attempt->srchost, attempt->door->name);
+ logprint("%s (%s): %s: OPEN SESAME", attempt->src, attempt->srchost, attempt->door->name);
+ } else {
+ vprint("%s: %s: OPEN SESAME\n", attempt->src, attempt->door->name);
+ logprint("%s: %s: OPEN SESAME", attempt->src, attempt->door->name);
+ }
+ if(attempt->door->start_command && strlen(attempt->door->start_command)) {
+ /* run the associated command */
+ if(fork() == 0) {
+ /* child */
+ char parsed_start_cmd[PATH_MAX];
+ char parsed_stop_cmd[PATH_MAX];
+ size_t cmd_len = 0;
+
+ setsid();
+
+ /* parse start and stop command and check if the parsed commands fit in the given buffer. Don't
+ * execute any command if one of them has been truncated */
+ cmd_len = parse_cmd(parsed_start_cmd, sizeof(parsed_start_cmd), attempt->door->start_command, attempt->src);
+ if(cmd_len >= sizeof(parsed_start_cmd)) { /* command has been truncated --> do NOT execute it */
+ fprintf(stderr, "error: parsed start command has been truncated! --> won't execute it\n");
+ logprint("error: parsed start command has been truncated! --> won't execute it");
+ exit(0); /* exit child */
+ }
+ if(attempt->door->stop_command) {
+ cmd_len = parse_cmd(parsed_stop_cmd, sizeof(parsed_stop_cmd), attempt->door->stop_command, attempt->src);
+ if(cmd_len >= sizeof(parsed_stop_cmd)) { /* command has been truncated --> do NOT execute it */
+ fprintf(stderr, "error: parsed stop command has been truncated! --> won't execute start command\n");
+ logprint("error: parsed stop command has been truncated! --> won't execute start command");
+ exit(0); /* exit child */
+ }
+ }
+
+ /* all parsing ok --> execute the parsed (%IP% = source IP) command */
+ exec_cmd(parsed_start_cmd, attempt->door->name);
+ /* if stop_command is set, sleep for cmd_timeout and run it*/
+ if(attempt->door->stop_command){
+ sleep(attempt->door->cmd_timeout);
+ if(attempt->srchost) {
+ vprint("%s (%s): %s: command timeout\n", attempt->src, attempt->srchost, attempt->door->name);
+ logprint("%s (%s): %s: command timeout", attempt->src, attempt->srchost, attempt->door->name);
+ } else {
+ vprint("%s: %s: command timeout\n", attempt->src, attempt->door->name);
+ logprint("%s: %s: command timeout", attempt->src, attempt->door->name);
+ }
+ exec_cmd(parsed_stop_cmd, attempt->door->name);
+ }
+
+ exit(0); /* exit child */
+ }
+ }
+ /* change to next sequence if one time sequences are used.
+ * Note that here the door will eventually be closed in
+ * get_new_one_time_sequence() if no more sequences are left */
+ if(attempt->door->one_time_sequences_fd) {
+ disable_used_one_time_sequence(attempt->door);
+ get_new_one_time_sequence(attempt->door);
+
+ /* update pcap filter */
+ free(attempt->door->pcap_filter_exp);
+ attempt->door->pcap_filter_exp = NULL;
+ generate_pcap_filter();
+ }
+ }
+}
/* Sniff an interface, looking for port-knock sequences
*/
@@ -1267,22 +1501,6 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
return;
}
- /* make sure this packet was sent TO us, not FROM us or THROUGH us.
- * Actually the pcap filter will take care of forwarding only packets
- * destined for us, but another check won't hurt... */
- if(inet_aton(myip, &inaddr) == 0) {
- fprintf(stderr, "error: could not understand IP address: %s\n", myip);
- return;
- }
-#if defined(__FreeBSD__) || defined(__APPLE__)
- if(ip->ip_dst.s_addr != inaddr.s_addr) {
-#else
- if(ip->daddr != inaddr.s_addr) {
-#endif
- dprint("packet destined for another host, ignoring...\n");
- return;
- }
-
sport = dport = 0;
#if defined(__FreeBSD__) || defined(__APPLE__)
@@ -1379,224 +1597,24 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
attempt = NULL;
/* look for this guy in our attempts list */
for(lp = attempts; lp; lp = lp->next) {
- if(!strncmp(((knocker_t*)lp->data)->src, srcIP, sizeof(srcIP))) {
- attempt = (knocker_t*)lp->data;
+ knocker_t *att = (knocker_t*)lp->data;
+ if(!strncmp(att->src, srcIP, sizeof(srcIP)) &&
+ !strncmp(att->door->target ? att->door->target : myip, dstIP, sizeof(dstIP))) {
+ attempt = att;
break;
}
}
if(attempt) {
- int flagsmatch = 1;
- /* if tcp, check the flags to ignore the packets we don't want
- * (don't even use it to cancel sequences)
- */
+ int flagsmatch = flags_match(attempt->door, ip, tcp);
#if defined(__FreeBSD__) || defined(__APPLE__)
- if(ip->ip_p == IPPROTO_TCP) {
- if(attempt->door->flag_fin != DONT_CARE) {
- if(attempt->door->flag_fin == SET && !(tcp->th_flags & TH_FIN)) {
- dprint("packet is not FIN, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_fin == NOT_SET && (tcp->th_flags & TH_FIN)) {
- dprint("packet is not !FIN, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_syn != DONT_CARE) {
- if(attempt->door->flag_syn == SET && !(tcp->th_flags & TH_SYN)) {
- dprint("packet is not SYN, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_syn == NOT_SET && (tcp->th_flags & TH_SYN)) {
- dprint("packet is not !SYN, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_rst != DONT_CARE) {
- if(attempt->door->flag_rst == SET && !(tcp->th_flags & TH_RST)) {
- dprint("packet is not RST, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_rst == NOT_SET && (tcp->th_flags & TH_RST)) {
- dprint("packet is not !RST, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_psh != DONT_CARE) {
- if(attempt->door->flag_psh == SET && !(tcp->th_flags & TH_PUSH)) {
- dprint("packet is not PSH, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_psh == NOT_SET && (tcp->th_flags & TH_PUSH)) {
- dprint("packet is not !PSH, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_ack != DONT_CARE) {
- if(attempt->door->flag_ack == SET && !(tcp->th_flags & TH_ACK)) {
- dprint("packet is not ACK, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_ack == NOT_SET && !(tcp->th_flags & TH_ACK)) {
- dprint("packet is not !ACK, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_urg != DONT_CARE) {
- if(attempt->door->flag_urg == SET && !(tcp->th_flags & TH_URG)) {
- dprint("packet is not URG, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_urg == NOT_SET && !(tcp->th_flags & TH_URG)) {
- dprint("packet is not !URG, ignoring...\n");
- flagsmatch = 0;
- }
- }
- }
if(flagsmatch && ip->ip_p == attempt->door->protocol[attempt->stage] &&
dport == attempt->door->sequence[attempt->stage]) {
-
#else
- if(ip->protocol == IPPROTO_TCP) {
- if(attempt->door->flag_fin != DONT_CARE) {
- if(attempt->door->flag_fin == SET && tcp->fin != 1) {
- dprint("packet is not FIN, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_fin == NOT_SET && tcp->fin == 1) {
- dprint("packet is not !FIN, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_syn != DONT_CARE) {
- if(attempt->door->flag_syn == SET && tcp->syn != 1) {
- dprint("packet is not SYN, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_syn == NOT_SET && tcp->syn == 1) {
- dprint("packet is not !SYN, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_rst != DONT_CARE) {
- if(attempt->door->flag_rst == SET && tcp->rst != 1) {
- dprint("packet is not RST, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_rst == NOT_SET && tcp->rst == 1) {
- dprint("packet is not !RST, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_psh != DONT_CARE) {
- if(attempt->door->flag_psh == SET && tcp->psh != 1) {
- dprint("packet is not PSH, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_psh == NOT_SET && tcp->psh == 1) {
- dprint("packet is not !PSH, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_ack != DONT_CARE) {
- if(attempt->door->flag_ack == SET && tcp->ack != 1) {
- dprint("packet is not ACK, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_ack == NOT_SET && tcp->ack == 1) {
- dprint("packet is not !ACK, ignoring...\n");
- flagsmatch = 0;
- }
- }
- if(attempt->door->flag_urg != DONT_CARE) {
- if(attempt->door->flag_urg == SET && tcp->urg != 1) {
- dprint("packet is not URG, ignoring...\n");
- flagsmatch = 0;
- }
- if(attempt->door->flag_urg == NOT_SET && tcp->urg == 1) {
- dprint("packet is not !URG, ignoring...\n");
- flagsmatch = 0;
- }
- }
- }
if(flagsmatch && ip->protocol == attempt->door->protocol[attempt->stage] &&
dport == attempt->door->sequence[attempt->stage]) {
#endif
- /* level up! */
- attempt->stage++;
- if(attempt->srchost) {
- vprint("%s (%s): %s: Stage %d\n", attempt->src, attempt->srchost, attempt->door->name, attempt->stage);
- logprint("%s (%s): %s: Stage %d", attempt->src, attempt->srchost, attempt->door->name, attempt->stage);
- } else {
- vprint("%s: %s: Stage %d\n", attempt->src, attempt->door->name, attempt->stage);
- logprint("%s: %s: Stage %d", attempt->src, attempt->door->name, attempt->stage);
- }
- if(attempt->stage >= attempt->door->seqcount) {
- if(attempt->srchost) {
- vprint("%s (%s): %s: OPEN SESAME\n", attempt->src, attempt->srchost, attempt->door->name);
- logprint("%s (%s): %s: OPEN SESAME", attempt->src, attempt->srchost, attempt->door->name);
- } else {
- vprint("%s: %s: OPEN SESAME\n", attempt->src, attempt->door->name);
- logprint("%s: %s: OPEN SESAME", attempt->src, attempt->door->name);
- }
- if(attempt->door->start_command && strlen(attempt->door->start_command)) {
- /* run the associated command */
- if(fork() == 0) {
- /* child */
- char parsed_start_cmd[PATH_MAX];
- char parsed_stop_cmd[PATH_MAX];
- size_t cmd_len = 0;
-
- setsid();
-
- /* parse start and stop command and check if the parsed commands fit in the given buffer. Don't
- * execute any command if one of them has been truncated */
- cmd_len = parse_cmd(parsed_start_cmd, sizeof(parsed_start_cmd), attempt->door->start_command, attempt->src);
- if(cmd_len >= sizeof(parsed_start_cmd)) { /* command has been truncated --> do NOT execute it */
- fprintf(stderr, "error: parsed start command has been truncated! --> won't execute it\n");
- logprint("error: parsed start command has been truncated! --> won't execute it");
- exit(0); /* exit child */
- }
- if(attempt->door->stop_command) {
- cmd_len = parse_cmd(parsed_stop_cmd, sizeof(parsed_stop_cmd), attempt->door->stop_command, attempt->src);
- if(cmd_len >= sizeof(parsed_stop_cmd)) { /* command has been truncated --> do NOT execute it */
- fprintf(stderr, "error: parsed stop command has been truncated! --> won't execute start command\n");
- logprint("error: parsed stop command has been truncated! --> won't execute start command");
- exit(0); /* exit child */
- }
- }
-
- /* all parsing ok --> execute the parsed (%IP% = source IP) command */
- exec_cmd(parsed_start_cmd, attempt->door->name);
- /* if stop_command is set, sleep for cmd_timeout and run it*/
- if(attempt->door->stop_command){
- sleep(attempt->door->cmd_timeout);
- if(attempt->srchost) {
- vprint("%s (%s): %s: command timeout\n", attempt->src, attempt->srchost, attempt->door->name);
- logprint("%s (%s): %s: command timeout", attempt->src, attempt->srchost, attempt->door->name);
- } else {
- vprint("%s: %s: command timeout\n", attempt->src, attempt->door->name);
- logprint("%s: %s: command timeout", attempt->src, attempt->door->name);
- }
- exec_cmd(parsed_stop_cmd, attempt->door->name);
- }
-
- exit(0); /* exit child */
- }
- }
- /* change to next sequence if one time sequences are used.
- * Note that here the door will eventually be closed in
- * get_new_one_time_sequence() if no more sequences are left */
- if(attempt->door->one_time_sequences_fd) {
- disable_used_one_time_sequence(attempt->door);
- get_new_one_time_sequence(attempt->door);
-
- /* update pcap filter */
- free(attempt->door->pcap_filter_exp);
- attempt->door->pcap_filter_exp = NULL;
- generate_pcap_filter();
- }
- }
+ process_attempt(attempt);
} else if(flagsmatch == 0) {
/* TCP flags didn't match -- just ignore this packet, don't
* invalidate the knock.
@@ -1612,64 +1630,15 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
for(lp = doors; lp; lp = lp->next) {
opendoor_t *door = (opendoor_t*)lp->data;
/* if we're working with TCP, try to match the flags */
-#if defined(__FreeBSD__) || defined(__APPLE__)
- if(ip->ip_p == IPPROTO_TCP){
- if(door->flag_fin != DONT_CARE) {
- if(door->flag_fin == SET && !(tcp->th_flags & TH_FIN)) {dprint("packet is not FIN, ignoring...\n");continue;}
- if(door->flag_fin == NOT_SET && (tcp->th_flags & TH_FIN)) {dprint("packet is not !FIN, ignoring...\n");continue;}
- }
- if(door->flag_syn != DONT_CARE) {
- if(door->flag_syn == SET && !(tcp->th_flags & TH_SYN)) {dprint("packet is not SYN, ignoring...\n");continue;}
- if(door->flag_syn == NOT_SET && (tcp->th_flags & TH_SYN)) {dprint("packet is not !SYN, ignoring...\n");continue;}
- }
- if(door->flag_rst != DONT_CARE) {
- if(door->flag_rst == SET && !(tcp->th_flags & TH_RST)) {dprint("packet is not RST, ignoring...\n");continue;}
- if(door->flag_rst == NOT_SET && (tcp->th_flags & TH_RST)) {dprint("packet is not !RST, ignoring...\n");continue;}
- }
- if(door->flag_psh != DONT_CARE) {
- if(door->flag_psh == SET && !(tcp->th_flags & TH_PUSH)) {dprint("packet is not PSH, ignoring...\n");continue;}
- if(door->flag_psh == NOT_SET && (tcp->th_flags & TH_PUSH)) {dprint("packet is not !PSH, ignoring...\n");continue;}
- }
- if(door->flag_ack != DONT_CARE) {
- if(door->flag_ack == SET && !(tcp->th_flags & TH_ACK)) {dprint("packet is not ACK, ignoring...\n");continue;}
- if(door->flag_ack == NOT_SET && (tcp->th_flags & TH_ACK)) {dprint("packet is not !ACK, ignoring...\n");continue;}
- }
- if(door->flag_urg != DONT_CARE) {
- if(door->flag_urg == SET && !(tcp->th_flags & TH_URG)) {dprint("packet is not URG, ignoring...\n");continue;}
- if(door->flag_urg == NOT_SET && (tcp->th_flags & TH_URG)) {dprint("packet is not !URG, ignoring...\n");continue;}
- }
+ if(!flags_match(door, ip, tcp)) {
+ continue;
}
-
- if(ip->ip_p == door->protocol[0] && dport == door->sequence[0]) {
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ if(ip->ip_p == door->protocol[0] && dport == door->sequence[0] &&
+ !strcmp(dstIP, door->target ? door->target : myip)) {
#else
- if(ip->protocol == IPPROTO_TCP){
- if(door->flag_fin != DONT_CARE) {
- if(door->flag_fin == SET && tcp->fin != 1) {dprint("packet is not FIN, ignoring...\n");continue;}
- if(door->flag_fin == NOT_SET && tcp->fin == 1) {dprint("packet is not !FIN, ignoring...\n");continue;}
- }
- if(door->flag_syn != DONT_CARE) {
- if(door->flag_syn == SET && tcp->syn != 1) {dprint("packet is not SYN, ignoring...\n");continue;}
- if(door->flag_syn == NOT_SET && tcp->syn == 1) {dprint("packet is not !SYN, ignoring...\n");continue;}
- }
- if(door->flag_rst != DONT_CARE) {
- if(door->flag_rst == SET && tcp->rst != 1) {dprint("packet is not RST, ignoring...\n");continue;}
- if(door->flag_rst == NOT_SET && tcp->rst == 1) {dprint("packet is not !RST, ignoring...\n");continue;}
- }
- if(door->flag_psh != DONT_CARE) {
- if(door->flag_psh == SET && tcp->psh != 1) {dprint("packet is not PSH, ignoring...\n");continue;}
- if(door->flag_psh == NOT_SET && tcp->psh == 1) {dprint("packet is not !PSH, ignoring...\n");continue;}
- }
- if(door->flag_ack != DONT_CARE) {
- if(door->flag_ack == SET && tcp->ack != 1) {dprint("packet is not ACK, ignoring...\n");continue;}
- if(door->flag_ack == NOT_SET && tcp->ack == 1) {dprint("packet is not !ACK, ignoring...\n");continue;}
- }
- if(door->flag_urg != DONT_CARE) {
- if(door->flag_urg == SET && tcp->urg != 1) {dprint("packet is not URG, ignoring...\n");continue;}
- if(door->flag_urg == NOT_SET && tcp->urg == 1) {dprint("packet is not !URG, ignoring...\n");continue;}
- }
- }
-
- if(ip->protocol == door->protocol[0] && dport == door->sequence[0]) {
+ if(ip->protocol == door->protocol[0] && dport == door->sequence[0] &&
+ !strcmp(dstIP, door->target ? door->target : myip)) {
#endif
struct hostent *he;
/* create a new entry */
@@ -1693,7 +1662,7 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
}
}
- attempt->stage = 1;
+ attempt->stage = 0;
attempt->seq_start = pkt_secs;
attempt->door = door;
if(attempt->srchost) {
@@ -1704,6 +1673,7 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
logprint("%s: %s: Stage 1", attempt->src, door->name);
}
attempts = list_add(attempts, attempt);
+ process_attempt(attempt);
}
}
}

No commit comments for this range

Something went wrong with that request. Please try again.