From fe09438921e45127cf4aae19621f135b20c098fb Mon Sep 17 00:00:00 2001 From: Damien Stuart Date: Thu, 24 Jun 2010 02:31:36 +0000 Subject: [PATCH] Start of cleanup for beta release candidate. Removed locale-related code (for now) as it was breaking some things like logging. removed some unimplemented and/or unused parameters and config directives (as well as thier respective documentation references. Added a --rotate-digest-cache command-line arg to force a rename of the digest cache file and start a new one. git-svn-id: file:///home/mbr/svn/fwknop/trunk@224 510a4753-2344-4c79-9c09-4d669213fbeb --- client/fwknop.8 | 161 +++++++++++++++++---------------------- client/spa_comm.c | 4 +- doc/fwknopd.man.asciidoc | 29 ++----- server/access.c | 22 +++--- server/config_init.c | 48 ++---------- server/config_init.h | 12 +-- server/fw_util.c | 22 +++--- server/fwknopd.8 | 47 +++--------- server/fwknopd.c | 84 +++++++++----------- server/fwknopd.conf | 9 --- server/fwknopd_common.h | 7 +- server/incoming_spa.c | 38 ++++----- server/pcap_capture.c | 26 +++---- server/replay_dbm.c | 48 ++++++++++-- server/sig_handler.c | 12 +-- server/tcp_server.c | 10 +-- 16 files changed, 244 insertions(+), 335 deletions(-) diff --git a/client/fwknop.8 b/client/fwknop.8 index 90f5fe5a..ecdfb028 100644 --- a/client/fwknop.8 +++ b/client/fwknop.8 @@ -1,13 +1,13 @@ '\" t .\" Title: fwknop .\" Author: [see the "AUTHOR" section] -.\" Generator: DocBook XSL Stylesheets v1.74.3 -.\" Date: 09/05/2009 -.\" Manual: -.\" Source: +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 06/17/2010 +.\" Manual: +.\" Source: .\" Language: English .\" -.TH "FWKNOP" "8" "09/05/2009" "" "" +.TH "FWKNOP" "8" "06/17/2010" "" "" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -50,9 +50,9 @@ Authorization packets are either encrypted with the \fIRijndael\fR block cipher .RE .\} .sp -Each of the above fields are separated by a \(lq:\(rq character due to the variable length of several of the fields, and those that might contain \(lq:\(rq characters are base64 encoded\&. The message digest (\fBSHA256\fR by default in all versions of \fBfwknop\fR greater than 1\&.9\&.1) allows the server to check message integrity after decryption, and the 16 bytes of random data ensures (with high probability) that no two messages are identical\&. This ensures that replay attacks are not possible against \fBfwknop\fR\&. +Each of the above fields are separated by a \(oq`+:+\'\' character due to the variable length of several of the fields, and those that might contain ``:\(cq\' characters are base64 encoded\&. The message digest (\fBSHA256\fR by default in all versions of \fBfwknop\fR greater than 1\&.9\&.1) allows the server to check message integrity after decryption, and the 16 bytes of random data ensures (with high probability) that no two messages are identical\&. This ensures that replay attacks are not possible against \fBfwknop\fR\&. .sp -For each packet coming from an \fBfwknop\fR client, the \fBfwknopd\fR server caches the \fBSHA256\fR digest calculated over the entire packet and compares against previous packet digests in order to detect attempted replay attacks\&. The digest cache file is located at \fI/var/log/fwknop/digest\&.cache\fR and is not rotated so that the detection of duplicate SPA messages is maximized\&. Both syslog and email alerts are generated if a replay is detected (although this can be tuned via the \fBALERTING_METHODS\fR variable in the \fI/etc/fwknop/fwknop\&.conf\fR file)\&. By default, the \fBfwknop\fR client sends authorization packets over UDP port 62201, but this can be altered with the \fB\-\-Server\-port\fR argument\&. The server must first be configured to acquire the SPA data on the changed protocol\-port\&. Also, \fBfwknop\fR can send the SPA packet over a random port via the \fB\-\-rand\-port\fR argument\&. See \fIfwknopd(8)\fR for further details\&. See the \fBEXAMPLES\fR section for example invocations of the \fBfwknop\fR client\&. +For each packet coming from an \fBfwknop\fR client, the \fBfwknopd\fR server caches the \fBSHA256\fR digest calculated over the entire packet and compares against previous packet digests in order to detect attempted replay attacks\&. The digest cache file is located at \fI/var/log/fwknop/digest\&.cache\fR and is not rotated so that the detection of duplicate SPA messages is maximized\&. Both syslog and email alerts are generated if a replay is detected (although this can be tuned via the \fBALERTING_METHODS\fR variable in the \fI/etc/fwknop/fwknop\&.conf\fR file)\&. By default, the \fBfwknop\fR client sends authorization packets over UDP port 62201, but this can be altered with the \fB\-\-server\-port\fR argument\&. The server must first be configured to acquire the SPA data on the changed protocol\-port\&. Also, \fBfwknop\fR can send the SPA packet over a random port via the \fB\-\-rand\-port\fR argument\&. See \fIfwknopd(8)\fR for further details\&. See the \fBEXAMPLES\fR section for example invocations of the \fBfwknop\fR client\&. .SH "REQUIRED ARGUMENTS" .PP \fB\-D, \-\-destination\fR=\fI\fR @@ -76,7 +76,7 @@ The vast majority of usages for require the \fB\-A\fR argument, but sending full commands with the -\fB\-\-Server\-cmd\fR +\fB\-\-server\-cmd\fR argument via an SPA packet to be executed by \fBfwknopd\fR does not require this argument\&. @@ -113,13 +113,13 @@ client to write a newly created SPA packet out to the specified file so that it Load an encryption key/password from the specified file\&. .RE .PP -\fB\-\-no\-save\-args\fR +\fB\-l, \-\-last\-cmd\fR .RS 4 -Instruct the +Execute \fBfwknop\fR -client to not save its command line arguments to the \fI$HOME/fwknop.run\fR file\&. -This file is used by the \fB\-\-show\-last\fR argument to display the last command -line args that \fBfwknop\fR was invoked with\&. +with the command\-line arguments from the previous invocation (if any)\&. The previous arguments are parsed out of the +\fI~/\&.fwknop\&.run\fR +file\&. .RE .PP \fB\-q, \-\-quiet\fR @@ -176,6 +176,17 @@ client to automatically resolve the externally routable IP address the local sys website\&. .RE .PP +\fB\-C, \-\-server\-cmd\fR=\fI\fR +.RS 4 +Instead of requesting access to a service with an SPA packet, the +\fB\-\-server\-cmd\fR +argument specifies a command that will be executed by the +\fBfwknopd\fR +server\&. The command is encrypted within the SPA packet and sniffed off the wire (as usual) by the +\fBfwknopd\fR +server\&. +.RE +.PP \fB\-g, \-\-gpg\-encryption\fR .RS 4 Use GPG encryption on the SPA packet (default if not specified is Rijndael)\&. @@ -185,13 +196,13 @@ Use of this option will require the specification of a GPG recipient (see along with other GPG\-related options below)\&. .RE .PP -\fB\-H, \-\-http-proxy\fR=\fI\fR +\fB\-H, \-\-http\-proxy\fR=\fI\fR .RS 4 -Specify an HTTP proxy URL that the +Specify an HTTP proxy that the \fBfwknop\fR -client will use to send the SPA packet through\&. Using this option will -automatically set the SPA packet transmission mode (usually set via the -\fB\-\-server\-proto\fR argument) to "http"\&. +client will use to send the SPA packet through\&. Using this option will automatically set the SPA packet transmission mode (usually set via the +\fB\-\-server\-proto\fR +argument) to \(lqhttp\(rq\&. .RE .PP \fB\-m, \-\-digest\-type\fR=\fI\fR @@ -215,7 +226,8 @@ server is protecting an internal network on an RFC\-1918 address space, an exter \fBfwknop\fR client can request that the server port forward an external port to an internal IP, i\&.e\&. \(lq\-\-NAT\-access 192\&.168\&.10\&.2:55000\(rq\&. In this case, access will be granted to 192\&.168\&.10\&.2 via port 55000 to whatever service is requested via the \fB\-\-access\fR -argument (usually tcp/22)\&. Hence, after sending such an SPA packet, one would then do \(lqssh \-p 55000 user@host\(rq and the connection would be forwarded on through to the internal 192\&.168\&.10\&.2 system automatically\&. Note that the port \(lq55000\(rq can be randomly generated via the +argument (usually tcp/22)\&. Hence, after sending such an SPA packet, one would then do \(lqssh \-p 55000 +user@host\(rq and the connection would be forwarded on through to the internal 192\&.168\&.10\&.2 system automatically\&. Note that the port \(lq55000\(rq can be randomly generated via the \fB\-\-nat\-rand\-port\fR argument (described later)\&. .RE @@ -386,14 +398,14 @@ client\&. This is useful when a \(lqroot\(rq user wishes to log into a remote ma .PP \fB\-\-gpg\-recipient\fR=\fI\fR .RS 4 -Specify the GnuPG key ID, e\&.g\&. \(lq1234ABCD\(rq (see the output of "gpg \-\-list\-keys") or the key name (associated email address) of the recipient of the Single Packet Authorization message\&. This key is imported by the +Specify the GnuPG key ID, e\&.g\&. \(lq1234ABCD\(rq (see the output of "gpg\(emlist\-keys") or the key name (associated email address) of the recipient of the Single Packet Authorization message\&. This key is imported by the \fBfwknopd\fR server and the associated private key is used to decrypt the SPA packet\&. The recipient\(cqs key must first be imported into the client GnuPG key ring\&. .RE .PP \fB\-\-gpg\-signer\-key\fR=\fI\fR .RS 4 -Specify the GnuPG key ID, e\&.g\&. \(lqABCD1234\(rq (see the output of \(lqgpg \-\-list\-keys\(rq) or the key name to use when signing the SPA message\&. The user is prompted for the associated GnuPG password to create the signature\&. This adds a cryptographically strong mechanism to allow the +Specify the GnuPG key ID, e\&.g\&. \(oq`+ABCD1234+\'\' (see the output of ``gpg \-\-list\-keys\(cq\') or the key name to use when signing the SPA message\&. The user is prompted for the associated GnuPG password to create the signature\&. This adds a cryptographically strong mechanism to allow the \fBfwknopd\fR daemon on the remote server to authenticate who created the SPA message\&. .RE @@ -407,13 +419,10 @@ The following examples illustrate the command line arguments that could be suppl .sp Packet contents printed to stdout at the fwknop client when creating an \(lqaccess mode\(rq SPA packet: .sp -.\" .if n \{\ -.\" .RS 4 -.\" .\} -.\" .nf -.ft CW +.if n \{\ +.RS 4 +.\} .nf -.ne 1 Random data: 6565240948266426 Username: mbr Timestamp: 1203863233 @@ -421,99 +430,72 @@ Packet contents printed to stdout at the fwknop client when creating an \(lqacce Type: 1 (access mode) Access: 127\&.0\&.0\&.2,tcp/22 SHA256 sum: gngquSL8AuM7r27XsR4qPmJhuBo9pG2PYwII06AaJHw -.ft R .fi -.\" .fi -.\" .if n \{\ -.\" .RE -.\" .\} +.if n \{\ +.RE +.\} .sp Use the Single Packet Authorization mode to gain access to tcp/22 (ssh) and udp/53 running on the system 10\&.0\&.0\&.123 from the IP 192\&.168\&.10\&.4: .sp -.\" .if n \{\ -.\" .RS 4 -.\" .\} -.\" .nf -.ft CW +.if n \{\ +.RS 4 +.\} .nf -.ne 1 $ fwknop \-A "tcp/22,udp/53" \-a 192\&.168\&.10\&.4 \-D 10\&.0\&.0\&.123 -.ft R .fi -.\" .fi -.\" .if n \{\ -.\" .RE -.\" .\} +.if n \{\ +.RE +.\} .sp Same as above example, but gain access from whatever source IP is seen by the fwknop server (useful if the fwknop client is behind a NAT device): .sp -.\" .if n \{\ -.\" .RS 4 -.\" .\} -.\" .nf -.ft CW +.if n \{\ +.RS 4 +.\} .nf -.ne 1 $ fwknop \-A "tcp/22,udp/53" \-s \-D 10\&.0\&.0\&.123 -.ft R .fi -.\" .fi -.\" .if n \{\ -.\" .RE -.\" .\} +.if n \{\ +.RE +.\} .sp Same as above example, but use the IP identification website \fIhttp://www\&.whatismyip\&.com\fR to derive the client IP address\&. This is a safer method of acquiring the client IP address than using the \fB\-s\fR option because the source IP is put within the encrypted packet instead of having the \fBfwknopd\fR daemon grant the requested access from whatever IP address the SPA packet originates: .sp -.\" .if n \{\ -.\" .RS 4 -.\" .\} -.\" .nf -.ft CW +.if n \{\ +.RS 4 +.\} .nf -.ne 1 $ fwknop \-A "tcp/22,udp/53" \-R \-D 10\&.0\&.0\&.123 -.ft R .fi -.\" .fi -.\" .if n \{\ -.\" .RE -.\" .\} +.if n \{\ +.RE +.\} .sp Use the Single Packet Authorization mode to gain access to tcp/22 (ssh) and udp/53 running on the system 10\&.0\&.0\&.123, and use GnuPG keys to encrypt and decrypt: .sp -.\" .if n \{\ -.\" .RS 4 -.\" .\} -.\" .nf -.ft CW +.if n \{\ +.RS 4 +.\} .nf -.ne 1 $ fwknop \-A "tcp/22,udp/53" \-\-gpg\-sign ABCD1234 \-\-gpg\-\-recipient 1234ABCD \-R \-D 10\&.0\&.0\&.123 -.ft R .fi -.\" .fi -.\" .if n \{\ -.\" .RE -.\" .\} +.if n \{\ +.RE +.\} .sp Instruct the fwknop server running at 10\&.0\&.0\&.123 to allow 172\&.16\&.5\&.4 to connect to TCP/22, but spoof the authorization packet from an IP associated with www\&.yahoo\&.com: .sp -.\" .if n \{\ -.\" .RS 4 -.\" .\} -.\" .nf -.ft CW +.if n \{\ +.RS 4 +.\} .nf -.ne 1 # fwknop \-\-Spoof\-src \(cqwww\&.yahoo\&.com\(cq \-A tcp/22 \-a 172\&.16\&.5\&.4 \-D 10\&.0\&.0\&.123 -.ft R .fi -.\" .fi -.\" .if n \{\ -.\" .RE -.\" .\} +.if n \{\ +.RE +.\} .SH "DEPENDENCIES" .sp \fBfwknop\fR requires \fIlibfko\fR (which is normally included with both source and binary distributions\&. @@ -523,7 +505,7 @@ For GPG functionality, GnuPG must also be correctly installed and configured\&. To take advantage of all of the authentication and access management features of the \fBfwknopd\fR daemon/service a functioning iptables firewall is required on the underlying operating system\&. .SH "DIAGNOSTICS" .sp -fwknop can be run with the \fB\-T\fR (or \fB\-\-test\fR) command line option\&. This will have \fBfwkop\fR simply create and print the SPA packet information, then run it through a decrypt/decode cycle and print it again\&. +fwknop can be run with the \fB\-T\fR (or \fB\-\-test\fR) command line option\&. This will have \fBfwknop\fR simply create and print the SPA packet information, then run it through a decrypt/decode cycle and print it again\&. .SH "SEE ALSO" .sp fwknopd(8), iptables(8), gpg(1), gpg\-agent(1), libfko documentation\&. @@ -532,9 +514,8 @@ More information on Single Packet Authorization can be found in the paper \(lqSi .SH "AUTHOR" .sp Damien Stuart -.br -Michael Rash .sp +Michael Rash .SH "CONTRIBUTORS" .sp This \(lqC\(rq version of fwknop was derived from the original Perl\-based version on which many people who are active in the open source community have contributed\&. See the CREDITS file in the fwknop sources, or visit \fIhttp://www\&.cipherdyne\&.org/fwknop/docs/contributors\&.html\fR to view the online list of contributors\&. diff --git a/client/spa_comm.c b/client/spa_comm.c index 06ec5e48..1df3a24c 100644 --- a/client/spa_comm.c +++ b/client/spa_comm.c @@ -259,7 +259,7 @@ send_spa_packet_tcp_raw(char *spa_data, int sd_len, struct sockaddr_in *saddr, { perror("[*] send_spa_packet_tcp_raw: sendto error: "); } - else if(res != sd_len) + else if(res != sd_len + hdrlen) /* account for the header ?*/ { fprintf(stderr, "[#] Warning: bytes sent (%i) not spa data length (%i).\n", @@ -357,7 +357,7 @@ send_spa_packet_icmp(char *spa_data, int sd_len, struct sockaddr_in *saddr, { perror("[*] send_spa_packet_icmp: sendto error: "); } - else if(res != sd_len) + else if(res != sd_len + hdrlen) /* account for icmp header */ { fprintf(stderr, "[#] Warning: bytes sent (%i) not spa data length (%i).\n", res, sd_len); diff --git a/doc/fwknopd.man.asciidoc b/doc/fwknopd.man.asciidoc index 68a02a76..95fba218 100644 --- a/doc/fwknopd.man.asciidoc +++ b/doc/fwknopd.man.asciidoc @@ -49,12 +49,6 @@ COMMAND-LINE OPTIONS option is not usually needed because the ``PCAP_INTF'' keyword in the 'fwknopd.conf' file defines the sniffing interface. -*--fw-list*:: - List all active rules in the ``FWKNOP'' Netfilter chain(s). - -*--fw-flush*:: - Flush all active rules in the ``FWKNOP'' Netfilter chain(s). - *-O, --Override-config*='':: Override config variable values that are normally read from the 'fwknop.conf' file with values from the specified file. Multiple @@ -75,17 +69,14 @@ COMMAND-LINE OPTIONS 'fwknopd.conf' and 'access.conf' files. This will also force a flush of the current ``FWKNOP'' Netfilter chain(s). +*--rotate-digest-cache*:: + Rotate the digest cache file by renaming it to ``-old'', and + starting a new one. + *-S, --Status*:: Display the status of any *fwknopd* processes that may or not be running. -*-l, --locale*='':: - Provide a locale setting other than the default ``C'' locale. - -*--no-locale*:: - Do not set the locale at all so that the default system locale - will apply. - *-v, --verbose*:: Run *fwknopd* in verbose mode. @@ -236,7 +227,6 @@ the full list and corresponding details. *PCAP_CMD_TIMEOUT* '':: Define the timeout for running a command. - *GPG_HOME_DIR* '':: If GPG keys are used instead of a Rijndael symmetric key, this is the default GPG keys directory. Note that each access block in @@ -276,10 +266,6 @@ the full list and corresponding details. listens on. This server is only spawned when ``ENABLE_TCP_SERVER'' is set to ``Y''. -*LOCALE* '':: - Set the locale (via the LC_ALL variable). This can be unset or set to - ``NONE'' to have *fwknopd* honor the default system locale. - *SYSLOG_IDENTITY* '':: Override syslog identity on message logged by *fwknopd*. The defaults are usually ok. @@ -345,11 +331,6 @@ directive starts a new stanza. contained within an authorization packet. Any such command will be executed as root by the *fwknopd* server. -*CMD_REGEX*: '' '(NOT IMPLEMENTED)':: - If ``ENABLE_CMD_EXEC'' is specified, the - ``CMD_REGEX'' keyword instructs *fwknopd* to restrict command execution - to only those command that match the given regular expression. - *REQUIRE_USERNAME*: '':: Require a specific username from the client system as encoded in the SPA data. This variable is optional and if not specified, the username data @@ -421,7 +402,7 @@ to the screen on STDERR as packets are received. SEE ALSO -------- -fwknop(8), iptables(8), gpg(1), gpg-agent(1), libfko docmentation. +fwknop(8), iptables(8), libfko docmentation. AUTHOR diff --git a/server/access.c b/server/access.c index 495de7b4..8b62cd9e 100644 --- a/server/access.c +++ b/server/access.c @@ -43,7 +43,7 @@ add_acc_string(char **var, char *val) { if((*var = strdup(val)) == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Fatal memory allocation error adding access list entry: %s", var ); exit(EXIT_FAILURE); @@ -82,7 +82,7 @@ add_source_mask(acc_stanza_t *acc, char *ip) if((new_sle = calloc(1, sizeof(acc_int_list_t))) == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Fatal memory allocation error adding stanza source_list entry" ); exit(EXIT_FAILURE); @@ -131,7 +131,7 @@ add_source_mask(acc_stanza_t *acc, char *ip) if(inet_aton(ip_str, &in) == 0) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Error parsing IP to int for: %s", ip_str ); @@ -186,7 +186,7 @@ parse_proto_and_port(char *pstr, int *proto, int *port) */ if((ndx = strchr(pstr, '/')) == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Parse error on access port entry: %s", pstr); return(-1); @@ -202,7 +202,7 @@ parse_proto_and_port(char *pstr, int *proto, int *port) *proto = PROTO_UDP; else { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Invalid protocol in access port entry: %s", pstr); return(-1); @@ -231,7 +231,7 @@ add_port_list_ent(acc_port_list_t **plist, char *port_str) if((new_plist = calloc(1, sizeof(acc_port_list_t))) == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Fatal memory allocation error adding stanza source_list entry" ); exit(EXIT_FAILURE); @@ -270,7 +270,7 @@ add_string_list_ent(acc_string_list_t **stlist, char *str_str) if((new_stlist = calloc(1, sizeof(acc_string_list_t))) == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Fatal memory allocation error creating string list entry" ); exit(EXIT_FAILURE); @@ -298,7 +298,7 @@ add_string_list_ent(acc_string_list_t **stlist, char *str_str) if(new_stlist->str == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Fatal memory allocation error adding string list entry item" ); exit(EXIT_FAILURE); @@ -527,7 +527,7 @@ acc_stanza_add(fko_srv_options_t *opts) if(new_acc == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Fatal memory allocation error adding access stanza" ); exit(EXIT_FAILURE); @@ -828,7 +828,7 @@ acc_check_source(fko_srv_options_t *opts, uint32_t ip) if(acc == NULL) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "Check access source called with no access stanzas defined." ); return(NULL); @@ -917,7 +917,7 @@ acc_check_port_access(acc_stanza_t *acc, char *port_str) if(in_pl == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Unable to create acc_port_list from incoming data: %s", port_str ); return(0); diff --git a/server/config_init.c b/server/config_init.c index 15b20791..a65ae83d 100644 --- a/server/config_init.c +++ b/server/config_init.c @@ -313,18 +313,6 @@ set_preconfig_entries(fko_srv_options_t *opts) set_config_entry(opts, CONF_HOSTNAME, opts->hostname); /* Setup the local executables based on build-time info. -#ifdef GPG_EXE - set_config_entry(opts, CONF_EXE_GPG, GPG_EXE); -#endif -#ifdef MAIL_EXE - set_config_entry(opts, CONF_EXE_MAIL, MAIL_EXE); -#endif -#ifdef SENDMAIL_EXE - set_config_entry(opts, CONF_EXE_SENDMAIL, SENDMAIL_EXE); -#endif -#ifdef SH_EXE - set_config_entry(opts, CONF_EXE_SH, SH_EXE); -#endif */ #ifdef IPTABLES_EXE set_config_entry(opts, CONF_EXE_IPTABLES, IPTABLES_EXE); @@ -471,18 +459,6 @@ config_init(fko_srv_options_t *opts, int argc, char **argv) case 'f': opts->foreground = 1; break; - case FIREWALL_LIST: - fprintf(stderr, "*NOT IMPLEMENTED YET*\n"); - // TODO: Add this... - //list_firewall_rules(); - exit(EXIT_SUCCESS); - break; - case FIREWALL_FLUSH: - fprintf(stderr, "*NOT IMPLEMENTED YET*\n"); - // TODO: Add this... - //flush_firewall_rules(); - exit(EXIT_SUCCESS); - break; case GPG_HOME_DIR: set_config_entry(opts, CONF_GPG_HOME_DIR, optarg); break; @@ -495,18 +471,12 @@ config_init(fko_srv_options_t *opts, int argc, char **argv) case 'K': opts->kill = 1; break; - case 'l': - if(opts->no_locale) - fprintf(stderr, "Local option ignored due to no-locale flag.\n"); - else - set_config_entry(opts, CONF_LOCALE, optarg); - break; - case NO_LOCALE: - set_config_entry(opts, CONF_LOCALE, NULL); - break; case 'O': /* This was handled earlier */ break; + case ROTATE_DIGEST_CACHE: + opts->rotate_digest_cache = 1; + break; case 'R': opts->restart = 1; break; @@ -568,21 +538,19 @@ usage(void) " -C, --packet-limit - Limit the number of candidate SPA packets to\n" " process and exit when this limit is reached.\n" " -D, --dump-config - Dump the current fwknop configuration values.\n" - " -f, --foreground - Run fwknopd in the foreground so that it never\n" - " forks off into the background.\n" - " --fw-list - List all active rules in the FWKNOP Netfilter chain.\n" - " --fw-flush - Flush all rules in the FWKNOP Netfilter chain.\n" + " -f, --foreground - Run fwknopd in the foreground (do not become\n" + " a background daemon).\n" " -i, --interface - Specify interface to listen for incoming SPA\n" " packets.\n" " -K, --kill - Kill the currently running fwknopd.\n" " --gpg-home-dir - Specify the GPG home directory.\n" " --gpg-key - Specify the GPG key ID used for decryption.\n" - " -l, --locale - Provide a locale setting other than the default\n" - " of \"C\".\n" - " --no-locale - Do not set any locale. Allow the system default\n" " -O, --override-config - Specify a file with configuration entries that will\n" " overide those in fwknopd.conf\n" " -R, --restart - Force the currently running fwknopd to restart.\n" + " --rotate-digest-cache\n" + " - Rotate the digest cache file by renaming it to\n" + " '-old', and starting a new one.\n" " -S, --status - Display the status of any running fwknopd process.\n" " -v, --verbose - Set verbose mode.\n" " -V, --version - Print version number.\n" diff --git a/server/config_init.h b/server/config_init.h index 64c6a9ea..2c7d454a 100644 --- a/server/config_init.h +++ b/server/config_init.h @@ -55,16 +55,13 @@ enum { GPG_HOME_DIR = 0x200, GPG_KEY, - FIREWALL_LIST, - FIREWALL_FLUSH, - FIREWALL_LOG, - NO_LOCALE, + ROTATE_DIGEST_CACHE, NOOP /* Just to be a marker for the end */ }; /* Our getopt_long options string. */ -#define GETOPTS_OPTION_STRING "a:c:C:Dfhi:Kl:O:RSvV" +#define GETOPTS_OPTION_STRING "a:c:C:Dfhi:KO:RSvV" /* Our program command-line options... */ @@ -75,15 +72,12 @@ static struct option cmd_opts[] = {"packet-limit", 1, NULL, 'C'}, {"dump-config", 0, NULL, 'D'}, {"foreground", 0, NULL, 'f'}, - {"fw-list", 0, NULL, FIREWALL_LIST }, - {"fw-flush", 0, NULL, FIREWALL_FLUSH }, {"help", 0, NULL, 'h'}, {"interface", 1, NULL, 'i'}, {"kill", 0, NULL, 'K'}, {"gpg-home-dir", 1, NULL, GPG_HOME_DIR }, {"gpg-key", 1, NULL, GPG_KEY }, - {"locale", 1, NULL, 'l' }, - {"no-locale", 0, NULL, NO_LOCALE }, + {"rotate-digest-cache", 0, NULL, ROTATE_DIGEST_CACHE }, {"override-config", 1, NULL, 'O' }, {"restart", 0, NULL, 'R'}, {"status", 0, NULL, 'S'}, diff --git a/server/fw_util.c b/server/fw_util.c index 1c0f187b..368b5a84 100644 --- a/server/fw_util.c +++ b/server/fw_util.c @@ -40,7 +40,7 @@ parse_extcmd_error(int retval, int status, char *se_buf) if(retval < 0) { - log_msg(LOG_ERR|LOG_STDERR, "Extcmd fork error: %s", strerror(errno)); + log_msg(LOG_ERR, "Extcmd fork error: %s", strerror(errno)); return; } @@ -77,7 +77,7 @@ parse_extcmd_error(int retval, int status, char *se_buf) emptr += strlen(emptr); } - log_msg(LOG_WARNING|LOG_STDERR, errmsg); + log_msg(LOG_WARNING, errmsg); } static int @@ -99,7 +99,7 @@ jump_rule_exists(int chain_num) if(ipt == NULL) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Got error %i trying to get rules list.\n", errno); return(-1); } @@ -691,8 +691,6 @@ process_spa_request(fko_srv_options_t *opts, spa_data_t *spadat) snat_target ); -//--DSS tmp -fprintf(stderr, "ADD SNAT CMD: %s\n", cmd_buf); res = run_extcmd(cmd_buf, NULL, err, 0, CMD_BUFSIZE, &status); if(EXTCMD_IS_SUCCESS(res)) { @@ -756,13 +754,10 @@ check_firewall_rules(fko_srv_options_t *opts) rn_offset = 0; -//fprintf(stderr, "CHAIN: %i, active_rules: %i, next_exp: %u, Now: %u\n", -// i, ch[i].active_rules, ch[i].next_expire, now); - /* There should be a rule to delete. Get the current list of * rules for this chain and delete the ones that are expired. */ - snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_LIST_RULES_ARGS "\n", + snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_LIST_RULES_ARGS, opts->fw_config->fw_command, ch[i].table, ch[i].to_chain @@ -779,14 +774,15 @@ check_firewall_rules(fko_srv_options_t *opts) continue; } - //fprintf(stderr, "RULES LIST:\n%s\n", cmd_out); + if(opts->verbose > 1) + log_msg(LOG_INFO, "RES=%i, CMD_BUF: %s\nRULES LIST: %s", res, cmd_buf, cmd_out); ndx = strstr(cmd_out, "_exp_"); if(ndx == NULL) { /* we did not find an expected rule. */ - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Did not find expire comment in rules list %i.\n", i); ch[i].active_rules--; @@ -825,7 +821,7 @@ check_firewall_rules(fko_srv_options_t *opts) /* This should not happen. But if it does, complain, * decrement the active rule value, and go on. */ - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Rule parse error while finding rule line start in chain %i", i); ch[i].active_rules--; @@ -839,7 +835,7 @@ check_firewall_rules(fko_srv_options_t *opts) /* This should not happen. But if it does, complain, * decrement the active rule value, and go on. */ - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Rule parse error while finding rule number in chain %i", i); ch[i].active_rules--; diff --git a/server/fwknopd.8 b/server/fwknopd.8 index dd1e2888..cf84d92d 100644 --- a/server/fwknopd.8 +++ b/server/fwknopd.8 @@ -2,12 +2,12 @@ .\" Title: fwknopd .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 02/09/2010 +.\" Date: 06/23/2010 .\" Manual: .\" Source: .\" Language: English .\" -.TH "FWKNOPD" "8" "02/09/2010" "" +.TH "FWKNOPD" "8" "06/23/2010" "" "" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -62,16 +62,6 @@ Manually specify interface on which to sniff, e\&.g\&. \(lq\-i eth0\(rq\&. This file defines the sniffing interface\&. .RE .PP -\fB\-\-fw\-list\fR -.RS 4 -List all active rules in the \(lqFWKNOP\(rq Netfilter chain(s)\&. -.RE -.PP -\fB\-\-fw\-flush\fR -.RS 4 -Flush all active rules in the \(lqFWKNOP\(rq Netfilter chain(s)\&. -.RE -.PP \fB\-O, \-\-Override\-config\fR=\fI\fR .RS 4 Override config variable values that are normally read from the @@ -114,6 +104,11 @@ and files\&. This will also force a flush of the current \(lqFWKNOP\(rq Netfilter chain(s)\&. .RE .PP +\fB\-\-rotate\-digest\-cache\fR +.RS 4 +Rotate the digest cache file by renaming it to \(lq\-old\(rq, and starting a new one\&. +.RE +.PP \fB\-S, \-\-Status\fR .RS 4 Display the status of any @@ -121,16 +116,6 @@ Display the status of any processes that may or not be running\&. .RE .PP -\fB\-l, \-\-locale\fR=\fI\fR -.RS 4 -Provide a locale setting other than the default \(lqC\(rq locale\&. -.RE -.PP -\fB\-\-no\-locale\fR -.RS 4 -Do not set the locale at all so that the default system locale will apply\&. -.RE -.PP \fB\-v, \-\-verbose\fR .RS 4 Run @@ -394,13 +379,6 @@ Set the default port number that the \(lqdummy\(rq TCP server listens on\&. This server is only spawned when \(lqENABLE_TCP_SERVER\(rq is set to \(lqY\(rq\&. .RE .PP -\fBLOCALE\fR \fI\fR -.RS 4 -Set the locale (via the LC_ALL variable)\&. This can be unset or set to \(lqNONE\(rq to have -\fBfwknopd\fR -honor the default system locale\&. -.RE -.PP \fBSYSLOG_IDENTITY\fR \fI\fR .RS 4 Override syslog identity on message logged by @@ -466,13 +444,6 @@ to accept complete commands that are contained within an authorization packet\&. server\&. .RE .PP -\fBCMD_REGEX\fR: \fI\fR \fI(NOT IMPLEMENTED)\fR -.RS 4 -If \(lqENABLE_CMD_EXEC\(rq is specified, the \(lqCMD_REGEX\(rq keyword instructs -\fBfwknopd\fR -to restrict command execution to only those command that match the given regular expression\&. -.RE -.PP \fBREQUIRE_USERNAME\fR: \fI\fR .RS 4 Require a specific username from the client system as encoded in the SPA data\&. This variable is optional and if not specified, the username data in the SPA data is ignored\&. @@ -549,11 +520,11 @@ The \fBfwknopd\fR daemon requires a functioning Netfilter firewall on the underl \fBfwknopd\fR can be run in debug mode with the \fB\-\-debug\fR command line option\&. This will disable daemon mode execution, and print verbose information to the screen on STDERR as packets are received\&. .SH "SEE ALSO" .sp -fwknop(8), iptables(8), gpg(1), gpg\-agent(1), libfko docmentation\&. +fwknop(8), iptables(8), libfko docmentation\&. .SH "AUTHOR" .sp Damien Stuart -.br +.sp Michael Rash .SH "CREDITS" .sp diff --git a/server/fwknopd.c b/server/fwknopd.c index 2c4c099f..72b119d6 100644 --- a/server/fwknopd.c +++ b/server/fwknopd.c @@ -47,7 +47,6 @@ main(int argc, char **argv) fko_ctx_t ctx; int res, last_sig, rpdb_count; char *spa_data, *version; - char *locale; char access_buf[MAX_LINE_LEN]; pid_t old_pid; @@ -88,9 +87,24 @@ main(int argc, char **argv) } } + /* Status of the currently running fwknopd? + */ + if(opts.status == 1) + { + //old_pid = get_running_pid(&opts); + old_pid = write_pid_file(&opts); + + if(old_pid > 0) + fprintf(stderr, "Detected fwknopd is running (pid=%i).\n", old_pid); + else + fprintf(stderr, "No running fwknopd detected.\n", old_pid); + + exit(EXIT_SUCCESS); + } + /* Restart the currently running fwknopd? */ - if(opts.restart == 1) + if(opts.restart == 1 || opts.status == 1) { old_pid = get_running_pid(&opts); @@ -115,42 +129,10 @@ main(int argc, char **argv) } } - /* Status of the currently running fwknopd? - */ - if(opts.status == 1) - { - fprintf(stderr, "Status option not implemented yet.\n"); - exit(EXIT_SUCCESS); - } - /* Initialize logging. */ init_logging(&opts); -#if HAVE_LOCALE_H - /* Set the locale if specified. - */ - if(opts.config[CONF_LOCALE] != NULL && !opts.no_locale) - { - locale = setlocale(LC_ALL, opts.config[CONF_LOCALE]); - - if(locale == NULL) - { - log_msg(LOG_ERR|LOG_STDERR, - "WARNING: Unable to set locale to %s.", - opts.config[CONF_LOCALE] - ); - } - else - { - if(opts.verbose) - log_msg(LOG_ERR|LOG_STDERR, - "Locale set to %s.", opts.config[CONF_LOCALE] - ); - } - } -#endif - /* Make sure we have a valid run dir and path leading to digest file * in case it configured to be somewhere other than the run dir. */ @@ -212,7 +194,7 @@ main(int argc, char **argv) */ if((strncasecmp(opts.config[CONF_AUTH_MODE], "pcap", 4)) != 0) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Capture/auth mode other than 'PCAP' is not supported." ); exit(EXIT_FAILURE); @@ -231,8 +213,16 @@ main(int argc, char **argv) { rpdb_count = replay_db_init(&opts); + if(rpdb_count < 0) + { + log_msg(LOG_WARNING, + "Error opening digest cache file. Incoming digests will not be remembered." + ); + strcpy(opts.config[CONF_ENABLE_DIGEST_PERSISTENCE], "N"); + } + if(opts.verbose) - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Using Digest Cache: '%s' (entry count = %i)", opts.config[CONF_DIGEST_FILE], rpdb_count ); @@ -297,14 +287,14 @@ main(int argc, char **argv) else if (opts.packet_ctr_limit > 0 && opts.packet_ctr >= opts.packet_ctr_limit) { - log_msg(LOG_INFO|LOG_STDERR, + log_msg(LOG_INFO, "Packet count limit (%d) reached. Exiting...", opts.packet_ctr_limit); break; } else /* got_signal was not set (should be if we are here) */ { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "Capture ended without signal. Exiting..."); break; } @@ -355,7 +345,7 @@ check_dir_path(const char *filepath, const char *fp_desc, unsigned char use_base */ if(*filepath != '/') { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Configured %s directory (%s) is not an absolute path.", fp_desc, filepath ); exit(EXIT_FAILURE); @@ -382,7 +372,7 @@ check_dir_path(const char *filepath, const char *fp_desc, unsigned char use_base { if(errno == ENOENT) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "%s directory: %s does not exist. Attempting to create it.", fp_desc, tmp_path ); @@ -392,20 +382,20 @@ check_dir_path(const char *filepath, const char *fp_desc, unsigned char use_base res = make_dir_path(tmp_path); if(res != 0) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Unable to create %s directory: %s (error: %i)", fp_desc, tmp_path, errno ); exit(EXIT_FAILURE); } - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Successfully created %s directory: %s", fp_desc, tmp_path ); } else { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Stat of %s returned error %i", tmp_path, errno ); exit(EXIT_FAILURE); @@ -417,7 +407,7 @@ check_dir_path(const char *filepath, const char *fp_desc, unsigned char use_base */ if(! S_ISDIR(st.st_mode)) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Specified %s directory: %s is NOT a directory\n\n", fp_desc, tmp_path ); exit(EXIT_FAILURE); @@ -464,7 +454,7 @@ make_dir_path(const char *run_dir) if(! S_ISDIR(st.st_mode)) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Component: %s of %s is NOT a directory\n\n", tmp_path, run_dir ); return(ENOTDIR); @@ -594,8 +584,8 @@ write_pid_file(fko_srv_options_t *opts) my_pid = getpid(); snprintf(buf, 6, "%i\n", my_pid); - if(opts->verbose) - fprintf(stderr, "[+] Writing my PID (%i) to the lock file: %s\n", + if(opts->verbose > 1) + log_msg(LOG_INFO, "[+] Writing my PID (%i) to the lock file: %s\n", my_pid, opts->config[CONF_FWKNOP_PID_FILE]); num_bytes = write(op_fd, buf, strlen(buf)); diff --git a/server/fwknopd.conf b/server/fwknopd.conf index 3ec91c40..446edb25 100644 --- a/server/fwknopd.conf +++ b/server/fwknopd.conf @@ -198,11 +198,6 @@ ENABLE_TCP_SERVER N; # TCPSERV_PORT 62201; -# Set the locale (via the LC_ALL variable). This can be set to NONE to -# have fwknopd honor the default system locale. -# -LOCALE C; - # Override syslog identity and facility (the defaults are usually ok). # The SYSLOG_FACILITY variable can be set to one of LOG_LOCAL{0-7} # or LOG_DAEMON (the default). @@ -332,11 +327,7 @@ IPT_MASQUERADE_ACCESS MASQUERADE, src, nat, POSTROUTING, 1, FWKNOP_POSTROUTING # System binaries # -#EXE_GPG /usr/bin/gpg; -#EXE_MAIL /bin/mail; -#EXE_SENDMAIL /usr/sbin/sendmail; #EXE_SH /bin/sh; -#EXE_MKNOD /bin/mknod; #EXE_IPTABLES /sbin/iptables; #EXE_IPFW /sbin/ipfw; ### BSD and Mac OS X only diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index 0c87bce7..fad1330e 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -153,7 +153,7 @@ enum { CONF_ENABLE_SPA_OVER_HTTP, CONF_ENABLE_TCP_SERVER, CONF_TCPSERV_PORT, - CONF_LOCALE, + //CONF_LOCALE, CONF_SYSLOG_IDENTITY, CONF_SYSLOG_FACILITY, CONF_IPT_EXEC_TRIES, @@ -234,7 +234,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = { "ENABLE_SPA_OVER_HTTP", "ENABLE_TCP_SERVER", "TCPSERV_PORT", - "LOCALE", + //"LOCALE", "SYSLOG_IDENTITY", "SYSLOG_FACILITY", "IPT_EXEC_TRIES", @@ -422,7 +422,8 @@ typedef struct fko_srv_options unsigned char dump_config; /* Dump current configuration flag */ unsigned char foreground; /* Run in foreground flag */ unsigned char kill; /* flag to initiate kill of fwknopd */ - unsigned char no_locale; /* Flag to not allow setting locale */ + unsigned char rotate_digest_cache;/* flag to force rotation of digest */ + //unsigned char no_locale; /* Flag to not allow setting locale */ unsigned char restart; /* Restart fwknopd flag */ unsigned char status; /* Get fwknopd status flag */ unsigned char test; /* Test mode flag */ diff --git a/server/incoming_spa.c b/server/incoming_spa.c index 373856c6..76215847 100644 --- a/server/incoming_spa.c +++ b/server/incoming_spa.c @@ -198,7 +198,7 @@ incoming_spa(fko_srv_options_t *opts) if(acc == NULL) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "No access data found for source IP: %s", spadat.pkt_source_ip ); @@ -206,7 +206,7 @@ incoming_spa(fko_srv_options_t *opts) } if(opts->verbose > 1) - log_msg(LOG_DEBUG, "SPA Packet: '%s'\n", spa_pkt->packet_data); + log_msg(LOG_INFO, "SPA Packet: '%s'\n", spa_pkt->packet_data); /* Get encryption type and try its decoding routine first (if the key * for that type is set) @@ -219,7 +219,7 @@ incoming_spa(fko_srv_options_t *opts) res = fko_new_with_data(&ctx, spa_pkt->packet_data, acc->key); else { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "No KEY for RIJNDAEL encrypted messages"); return(SPA_MSG_FKO_CTX_ERROR); } @@ -234,7 +234,7 @@ incoming_spa(fko_srv_options_t *opts) res = fko_new_with_data(&ctx, spa_pkt->packet_data, NULL); if(res != FKO_SUCCESS) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "Error creating fko context (before decryption): %s", fko_errstr(res) ); @@ -276,14 +276,14 @@ incoming_spa(fko_srv_options_t *opts) } else { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "No GPG_DECRYPT_PW for GPG encrypted messages"); return(SPA_MSG_FKO_CTX_ERROR); } } else { - log_msg(LOG_ERR|LOG_STDERR, "Unable to determing encryption type. Got type=%i.", + log_msg(LOG_ERR, "Unable to determing encryption type. Got type=%i.", enc_type); return(SPA_MSG_FKO_CTX_ERROR); } @@ -292,11 +292,11 @@ incoming_spa(fko_srv_options_t *opts) */ if(res != FKO_SUCCESS) { - log_msg(LOG_WARNING|LOG_STDERR, "Error creating fko context: %s", + log_msg(LOG_WARNING, "Error creating fko context: %s", fko_errstr(res)); if(IS_GPG_ERROR(res)) - log_msg(LOG_WARNING|LOG_STDERR, " - GPG ERROR: %s", + log_msg(LOG_WARNING, " - GPG ERROR: %s", fko_gpg_errstr(ctx)); goto clean_and_bail; @@ -306,7 +306,7 @@ incoming_spa(fko_srv_options_t *opts) * if it meets our access criteria. */ if(opts->verbose > 2) - log_msg(LOG_DEBUG, "SPA Decode (res=%i):\n%s", res, dump_ctx(ctx)); + log_msg(LOG_INFO, "SPA Decode (res=%i):\n%s", res, dump_ctx(ctx)); /* Check for replays if so configured. */ @@ -334,7 +334,7 @@ incoming_spa(fko_srv_options_t *opts) if(res != FKO_SUCCESS) { - log_msg(LOG_ERR|LOG_STDERR, "Unexpected error pulling SPA data from the context: %s", + log_msg(LOG_ERR, "Unexpected error pulling SPA data from the context: %s", fko_errstr(res)); res = SPA_MSG_ERROR; goto clean_and_bail; @@ -350,7 +350,7 @@ incoming_spa(fko_srv_options_t *opts) if(ts_diff > atoi(opts->config[CONF_MAX_SPA_PACKET_AGE])) { - log_msg(LOG_WARNING|LOG_STDERR, "SPA data is too old (%i seconds).", + log_msg(LOG_WARNING, "SPA data is too old (%i seconds).", ts_diff); res = SPA_MSG_TOO_OLD; goto clean_and_bail; @@ -364,7 +364,7 @@ incoming_spa(fko_srv_options_t *opts) spa_ip_demark = strchr(spadat.spa_message, ','); if(spa_ip_demark == NULL) { - log_msg(LOG_WARNING|LOG_STDERR, "Error parsing SPA message string: %s", + log_msg(LOG_WARNING, "Error parsing SPA message string: %s", fko_errstr(res)); res = SPA_MSG_ERROR; goto clean_and_bail; @@ -380,7 +380,7 @@ incoming_spa(fko_srv_options_t *opts) { if(acc->require_source_address) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "Got 0.0.0.0 when valid source IP was required." ); res = SPA_MSG_ACCESS_DENIED; @@ -399,7 +399,7 @@ incoming_spa(fko_srv_options_t *opts) { if(strcmp(spadat.username, acc->require_username) != 0) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "Username in SPA data (%s) does not match required username: %s", spadat.username, acc->require_username ); @@ -416,7 +416,7 @@ incoming_spa(fko_srv_options_t *opts) { if(!acc->enable_cmd_exec) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "SPA Command message are not allowed in the current configuration." ); res = SPA_MSG_ACCESS_DENIED; @@ -424,7 +424,7 @@ incoming_spa(fko_srv_options_t *opts) else { /* --DSS TODO: Finish Me */ - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "SPA Command message are not yet supported." ); res = SPA_MSG_NOT_SUPPORTED; @@ -441,7 +441,7 @@ incoming_spa(fko_srv_options_t *opts) */ if(! acc_check_port_access(acc, spadat.spa_message_remain)) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "One or more requested protocol/ports was denied per access.conf." ); @@ -464,7 +464,7 @@ incoming_spa(fko_srv_options_t *opts) if(spadat.message_type == FKO_LOCAL_NAT_ACCESS_MSG || spadat.message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "SPA Local NAT access messages are not yet supported." ); @@ -479,7 +479,7 @@ incoming_spa(fko_srv_options_t *opts) if(spadat.message_type == FKO_NAT_ACCESS_MSG || spadat.message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "SPA NAT access messages are not yet supported." ); diff --git a/server/pcap_capture.c b/server/pcap_capture.c index 097743c5..fe76e76d 100644 --- a/server/pcap_capture.c +++ b/server/pcap_capture.c @@ -68,18 +68,18 @@ pcap_capture(fko_srv_options_t *opts) if(pcap == NULL) { - log_msg(LOG_ERR|LOG_STDERR, "* pcap_open_live error: %s\n", errstr); + log_msg(LOG_ERR, "* pcap_open_live error: %s\n", errstr); exit(EXIT_FAILURE); } /* We are only interested on seeing packets coming into the interface. */ if (pcap_setdirection(pcap, PCAP_D_IN) < 0) - log_msg(LOG_WARNING|LOG_STDERR, "* Warning: pcap error on setdirection"); + log_msg(LOG_WARNING, "* Warning: pcap error on setdirection"); if (pcap == NULL) { - log_msg(LOG_ERR|LOG_STDERR, "[*] pcap error: %s", errstr); + log_msg(LOG_ERR, "[*] pcap error: %s", errstr); exit(EXIT_FAILURE); } @@ -90,7 +90,7 @@ pcap_capture(fko_srv_options_t *opts) { if(pcap_compile(pcap, &fp, opts->config[CONF_PCAP_FILTER], 1, 0) == -1) { - log_msg(LOG_ERR|LOG_STDERR, "[*] Error compiling pcap filter: %s", + log_msg(LOG_ERR, "[*] Error compiling pcap filter: %s", pcap_geterr(pcap) ); exit(EXIT_FAILURE); @@ -98,13 +98,13 @@ pcap_capture(fko_srv_options_t *opts) if(pcap_setfilter(pcap, &fp) == -1) { - log_msg(LOG_ERR|LOG_STDERR, "[*] Error setting pcap filter: %s", + log_msg(LOG_ERR, "[*] Error setting pcap filter: %s", pcap_geterr(pcap) ); exit(EXIT_FAILURE); } - log_msg(LOG_INFO|LOG_STDERR, "PCAP filter is: %s", opts->config[CONF_PCAP_FILTER]); + log_msg(LOG_INFO, "PCAP filter is: %s", opts->config[CONF_PCAP_FILTER]); pcap_freecode(&fp); } @@ -130,7 +130,7 @@ pcap_capture(fko_srv_options_t *opts) */ if((pcap_setnonblock(pcap, 1, errstr)) == -1) { - log_msg(LOG_ERR|LOG_STDERR, "[*] Error setting pcap to non-blocking: %s", + log_msg(LOG_ERR, "[*] Error setting pcap to non-blocking: %s", errstr ); exit(EXIT_FAILURE); @@ -142,7 +142,7 @@ pcap_capture(fko_srv_options_t *opts) */ set_sig_handlers(); - log_msg(LOG_INFO|LOG_STDERR, "Starting fwknopd main event loop."); + log_msg(LOG_INFO, "Starting fwknopd main event loop."); /* Jump into our home-grown packet cature loop. */ @@ -220,7 +220,7 @@ pcap_capture(fko_srv_options_t *opts) else strcpy(errstr, "Undefined Error"); - log_msg(LOG_DEBUG, "Got error %i: '%s' on incoming packet.", res, errstr); + log_msg(LOG_INFO, "Got error %i: '%s' on incoming packet.", res, errstr); } /* Count this packet since it has at least one byte of payload @@ -230,7 +230,7 @@ pcap_capture(fko_srv_options_t *opts) opts->packet_ctr++; if (opts->packet_ctr_limit && opts->packet_ctr >= opts->packet_ctr_limit) { - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "* Incoming packet count limit of %i reached", opts->packet_ctr_limit ); @@ -244,13 +244,13 @@ pcap_capture(fko_srv_options_t *opts) */ else if(res == -1) { - log_msg(LOG_ERR|LOG_STDERR, "[*] Error from pcap_dispatch: %s", + log_msg(LOG_ERR, "[*] Error from pcap_dispatch: %s", pcap_geterr(pcap) ); if(pcap_errcnt++ > MAX_PCAP_ERRORS_BEFORE_BAIL) { - log_msg(LOG_ERR|LOG_STDERR, "[*] %i consecutive pcap errors. Giving up", + log_msg(LOG_ERR, "[*] %i consecutive pcap errors. Giving up", pcap_errcnt ); exit(EXIT_FAILURE); @@ -259,7 +259,7 @@ pcap_capture(fko_srv_options_t *opts) else if(pending_break == 1 || res == -2) { /* pcap_breakloop was called, so we bail. */ - log_msg(LOG_INFO|LOG_STDERR, "Gracefully leaving the fwknopd event loop."); + log_msg(LOG_INFO, "Gracefully leaving the fwknopd event loop."); break; } else diff --git a/server/replay_dbm.c b/server/replay_dbm.c index 7f421288..d7598a34 100644 --- a/server/replay_dbm.c +++ b/server/replay_dbm.c @@ -58,6 +58,37 @@ #define MAX_DIGEST_SIZE 64 +/* Rotate the digest file by simply renaming it. +*/ +static void +rotate_digest_cache_file(fko_srv_options_t *opts) +{ + int res; + char *new_file = NULL; + + log_msg(LOG_INFO, "Rotating digest cache file."); + + new_file = malloc(strlen(opts->config[CONF_DIGEST_FILE])+5); + + if(new_file == NULL) + { + log_msg(LOG_ERR, "rotate_digest_cache_file: Memory allocation error."); + exit(EXIT_FAILURE); + } + + /* The new filename is just the original with a trailing '-old'. + */ + strcpy(new_file, opts->config[CONF_DIGEST_FILE]); + strcat(new_file, "-old"); + + res = rename(opts->config[CONF_DIGEST_FILE], new_file); + + if(res < 0) + log_msg(LOG_ERR, "Unable to rename digest file: %s to %s: %s", + opts->config[CONF_DIGEST_FILE], new_file, strerror(errno) + ); +} + /* Check for the existence of the replay dbm file, and create it if it does * not exist. Returns the number of db entries or -1 on error. */ @@ -73,6 +104,11 @@ replay_db_init(fko_srv_options_t *opts) datum db_key, db_next_key; int db_count = 0; + /* If rotation was specified, do it. + */ + if(opts->rotate_digest_cache) + rotate_digest_cache_file(opts); + #ifdef HAVE_LIBGDBM rpdb = gdbm_open( opts->config[CONF_DIGEST_FILE], 512, GDBM_WRCREAT, S_IRUSR|S_IWUSR, 0 @@ -85,7 +121,7 @@ replay_db_init(fko_srv_options_t *opts) if(!rpdb) { - log_msg(LOG_ERR|LOG_STDERR, + log_msg(LOG_ERR, "Unable to open digest cache file: '%s': %s", opts->config[CONF_DIGEST_FILE], MY_DBM_STRERROR(errno) @@ -143,7 +179,7 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx) res = fko_get_spa_digest(ctx, &digest); if(res != FKO_SUCCESS) { - log_msg(LOG_WARNING|LOG_STDERR, "Error getting digest from SPA data: %s", + log_msg(LOG_WARNING, "Error getting digest from SPA data: %s", fko_errstr(res)); return(SPA_MSG_DIGEST_ERROR); @@ -166,7 +202,7 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx) if(!rpdb) { - log_msg(LOG_WARNING|LOG_STDERR, "Error opening digest_cache: '%s': %s", + log_msg(LOG_WARNING, "Error opening digest_cache: '%s': %s", opts->config[CONF_DIGEST_FILE], MY_DBM_STRERROR(errno) ); @@ -206,7 +242,7 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx) strftime(first, 18, "%D %H:%M:%S", localtime(&(dci_p->first_replay))); strftime(last, 18, "%D %H:%M:%S", localtime(&(dci_p->last_replay))); - log_msg(LOG_WARNING|LOG_STDERR, + log_msg(LOG_WARNING, "Replay detected from source IP: %s\n" " Original source IP: %s\n" " Entry created: %s\n" @@ -223,7 +259,7 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx) /* Save it back to the digest cache */ if(MY_DBM_STORE(rpdb, db_key, db_ent, GDBM_REPLACE) != 0) - log_msg(LOG_WARNING|LOG_STDERR, "Error updating entry in digest_cache: '%s': %s", + log_msg(LOG_WARNING, "Error updating entry in digest_cache: '%s': %s", opts->config[CONF_DIGEST_FILE], MY_DBM_STRERROR(errno) ); @@ -245,7 +281,7 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx) if(MY_DBM_STORE(rpdb, db_key, db_ent, GDBM_INSERT) != 0) { - log_msg(LOG_WARNING|LOG_STDERR, "Error adding entry digest_cache: %s", + log_msg(LOG_WARNING, "Error adding entry digest_cache: %s", MY_DBM_STRERROR(errno) ); diff --git a/server/sig_handler.c b/server/sig_handler.c index b98c5349..0d6de3f1 100644 --- a/server/sig_handler.c +++ b/server/sig_handler.c @@ -85,37 +85,37 @@ set_sig_handlers(void) if(signal(SIGHUP, sig_handler) == SIG_ERR) { - log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGHUP handler"); + log_msg(LOG_ERR, "* Error setting SIGHUP handler"); err++; } if(signal(SIGINT, sig_handler) == SIG_ERR) { - log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGINT handler"); + log_msg(LOG_ERR, "* Error setting SIGINT handler"); err++; } if(signal(SIGTERM, sig_handler) == SIG_ERR) { - log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGTERM handler"); + log_msg(LOG_ERR, "* Error setting SIGTERM handler"); err++; } if(signal(SIGUSR1, sig_handler) == SIG_ERR) { - log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGUSR1 handler"); + log_msg(LOG_ERR, "* Error setting SIGUSR1 handler"); err++; } if(signal(SIGUSR2, sig_handler) == SIG_ERR) { - log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGUSR2 handler"); + log_msg(LOG_ERR, "* Error setting SIGUSR2 handler"); err++; } if(signal(SIGCHLD, sig_handler) == SIG_ERR) { - log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGUSR2 handler"); + log_msg(LOG_ERR, "* Error setting SIGUSR2 handler"); err++; } diff --git a/server/tcp_server.c b/server/tcp_server.c index 34017afc..5cb898ae 100644 --- a/server/tcp_server.c +++ b/server/tcp_server.c @@ -50,7 +50,7 @@ run_tcp_server(fko_srv_options_t *opts) unsigned short port = atoi(opts->config[CONF_TCPSERV_PORT]); - log_msg(LOG_INFO, "Kicking off TCP server for port %i)", port); + log_msg(LOG_INFO, "Kicking off TCP server to listen on port %i.", port); /* Fork off a child process to run the command and provide its outputs. */ @@ -69,7 +69,7 @@ run_tcp_server(fko_srv_options_t *opts) if ((s_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - log_msg(LOG_ERR|LOG_STDERR, "run_tcp_server: socket() failed: %s", + log_msg(LOG_ERR, "run_tcp_server: socket() failed: %s", strerror(errno)); exit(EXIT_FAILURE); } @@ -83,7 +83,7 @@ run_tcp_server(fko_srv_options_t *opts) /* Bind to the local address */ if (bind(s_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { - log_msg(LOG_ERR|LOG_STDERR, "run_tcp_server: bind() failed: %s", + log_msg(LOG_ERR, "run_tcp_server: bind() failed: %s", strerror(errno)); exit(EXIT_FAILURE); } @@ -93,7 +93,7 @@ run_tcp_server(fko_srv_options_t *opts) */ if (listen(s_sock, 1) < 0) { - log_msg(LOG_ERR|LOG_STDERR, "run_tcp_server: listen() failed: %s", + log_msg(LOG_ERR, "run_tcp_server: listen() failed: %s", strerror(errno)); exit(EXIT_FAILURE); } @@ -109,7 +109,7 @@ run_tcp_server(fko_srv_options_t *opts) */ if((c_sock = accept(s_sock, (struct sockaddr *) &caddr, &clen)) < 0) { - log_msg(LOG_ERR|LOG_STDERR, "run_tcp_server: accept() failed: %s", + log_msg(LOG_ERR, "run_tcp_server: accept() failed: %s", strerror(errno)); exit(EXIT_FAILURE); /* Should this be fatal? */ }