Merge branch 'master' into dstuart_refactor_autoconf

This commit is contained in:
Damien Stuart
2015-08-29 12:46:24 -04:00
221 changed files with 7638 additions and 2691 deletions
+4 -1
View File
@@ -39,7 +39,7 @@ install_manifest.txt
*.o
*.lo
#project generated files
# project generated files
autom4te.cache/
*.m4
client/.deps/
@@ -70,6 +70,9 @@ server/fwknopd.8
server/Makefile.in
stamp-h1
# For anyone running on a Mac
.DS_Store
android/project/libs
android/project/obj
android/project/jni/fwknop/fko.h
+17
View File
@@ -1,5 +1,10 @@
Jonathan Bennett
- Contributed OpenWRT support - see the extras/openwrt/ directory.
- Suggested the addition of the --key-gen option to fwknopd.
- Contributed the console-qr.sh script (in extras/console-qr/) to create
QR codes from fwknopd access.conf keys.
- Wrote a new fwknop client for Android called "Fwknop2" - see:
https://f-droid.org/repository/browse/?fdid=org.cipherdyne.fwknop2
Sebastien Jeanquier
- Assisted with getting fwknop included in BackTrack Linux - the choice
@@ -55,6 +60,7 @@ Franck Joncourt
- Added log module support for the client.
- Added the ability to read a passphrase from STDIN and also from a file
descriptor via --fd (closes #74).
- Added libfko unit tests via the CUnit framework.
Jonathan Schulz
- Submitted patches to change HTTP connection type to 'close' for -R mode
@@ -213,3 +219,14 @@ Grant Pannell
Alexander Kozhevnikov
- Reported a bug when fwknop is compiled with --enable-udp-server where
the server was including pcap.h
Dan Brooks
- Contributed a patch for the Android client app to add the definition of
custom server udp port. This is similiar to the --server-port argument
offered by the main fwknop client.
Github user 'sgh7':
- Contributed a patch to have fwknopd exit if the interface it is sniffing
on goes down. If this happens, it is expected that the native process
monitoring feature in things like systemd or upstart will restart
fwknopd.
+63 -1
View File
@@ -1,7 +1,69 @@
fwknop-2.6.6 (02//2015):
fwknop-2.6.7 (08/24/2015):
- [server] When command execution is enabled with ENABLE_CMD_EXEC for an
access.conf stanza, added support for running commands via sudo. This was
suggested by Github user 'freegigi' (issue #159) as a means to provide
command filtering using the powerful sudoers syntax. This feature is
implemented by prefixing any incoming command from a valid SPA packet
with the sudo command along with optional user and group requirements
as defined by the following new access.conf variables:
ENABLE_CMD_SUDO_EXEC, CMD_SUDO_EXEC_USER, and CMD_SUDO_EXEC_GROUP.
- [server] Kevin Layer reported a bug to the fwknop mailing list that
simultaneous NAT access for two different access.conf stanza was not
functioning properly. After some diagnosis, this was a result of
rule_exists() not properly detecting and differentiating existing DNAT
rules from new ones with different port numbers when 'iptables -C'
support is not available. This was against iptables-1.4.7, and has been
fixed in this release of fwknop (tracked as issue #162).
- [server] Added --key-gen to fwknopd. This feature was suggested by
Jonathan Bennett, and will help with ease of use efforts. The first
platform to take advantage of this will likely be OpenWRT thanks to
Jonathan.
- [server] By default, fwknopd will now exit if the interface that it is
sniffing goes down (patch contributed by Github user 'sgh7'). If this
happens, it is expected that the native process monitoring feature in
things like systemd or upstart will restart fwknopd. However, if fwknopd
is not being monitored by systemd, upstart, or anything else, this
behavior can be disabled with the EXIT_AT_INTF_DOWN variable in the
fwknopd.conf file. If disabled, fwknopd will try to recover when a
downed interface comes back up.
- [extras] Added a script from Jonathan Bennett at
extras/console-qr/console-qr.sh to generate QR codes from fwknopd
access.conf keys.
- [build] Added --with-firewalld to the autoconf configure script. This is
a synonym for --with-firewall-cmd to avoid confusion. Some package
maintainers use --with-firewalld to build fwknop.
fwknop-2.6.6 (04/23/2015):
- [server] Add the ability for fwknopd to function as an generic SPA
gateway. This allows scenarios such as the fwknopd system providing DHCP
addresses to client systems, but those systems would be blocking by
default from accessing the broader Internet until a valid SPA packet is
sent to the gateway. Two new access.conf variables support this feature:
DISABLE_DNAT (do not build any DNAT rules for forwarded connections) and
FORWARD_ALL (allow all traffic to be forwarded instead of specfic
services requested within an SPA packet). So far, this feature is only
supported on systems running iptables or firewalld. The idea was
contributed by "spartan1833" to the fwknop mailing list, and this became
issue 131 on github.
- [server] Bug fix when compiled with --enable-udp-server to not include
pcap.h, which is likely not installed whenever libpcap is also not
installed. This bug was reported by Alexander Kozhevnikov.
- [android] (Dan Brooks) Contributed a patch for the Android client app to
add the definition of custom server udp port. This is similiar to the
--server-port argument offered by the main fwknop client.
- [test suite] Handle versions of lcov that don't have the --rc argument
which is normally used to force the creation of branch coverage stats
when code coverage reports are created.
- [build] Add --enable-asan-support to autoconf configure script to enable
Google's Address Sanitizer (ASan) support. This feature is used during
the testing phase for new fwknop releases. Running fwknop under the
complete test suite (and also under AFL) with ASan support compiled in
did not turn up any new bugs.
- [test suite] (Franck Joncourt) Added libfko unit tests with the CUnit
framework.
- [test suite] Set AFL_HARDEN=1 to AFL fuzzing wrapper scripts. This
enables simple memory bug detection in AFL at the cost of a small
performance hit.
fwknop-2.6.5 (12/16/2014):
- [server] (Grant Pannell) Added a new access.conf variable "DESTINATION"
+1581 -692
View File
File diff suppressed because it is too large Load Diff
+65 -32
View File
@@ -71,6 +71,10 @@ EXTRA_DIST = \
extras/fwknop-launcher/fwknop-launcher.conf \
extras/apparmor/usr.sbin.fwknopd \
extras/apparmor/configure_args.sh \
extras/ramdisk/ramdisk-create.sh \
extras/ramdisk/ramdisk-create-osx.sh \
extras/console-qr/console-qr.sh \
extras/sanitizer/asan-build.sh \
fwknop.spec \
iphone/main.m \
iphone/Fwknop.xcodeproj \
@@ -121,20 +125,9 @@ EXTRA_DIST = \
python/setup.py \
python/fkomodule.c \
python/fko.py \
test/conf/gpg_dirs_orig.tar.gz \
test/conf/client-gpg/pubring.gpg \
test/conf/client-gpg/secring.gpg \
test/conf/client-gpg/trustdb.gpg \
test/conf/client-gpg-no-pw/pubring.gpg \
test/conf/client-gpg-no-pw/secring.gpg \
test/conf/client-gpg-no-pw/trustdb.gpg \
test/conf/server-gpg/pubring.gpg \
test/conf/server-gpg/secring.gpg \
test/conf/server-gpg/trustdb.gpg \
test/conf/server-gpg-no-pw/pubring.gpg \
test/conf/server-gpg-no-pw/secring.gpg \
test/conf/server-gpg-no-pw/trustdb.gpg \
test/conf/gpg_dirs.tar.gz \
test/conf/hmac_android_access.conf \
test/conf/hmac_android_fdroid_access.conf \
test/conf/android_access.conf \
test/conf/android_legacy_iv_access.conf \
test/conf/base64_key_access.conf \
@@ -159,6 +152,7 @@ EXTRA_DIST = \
test/conf/expired_epoch_stanza_access.conf \
test/conf/expired_stanza_access.conf \
test/conf/force_nat_access.conf \
test/conf/no_exit_down_intf_fwknopd.conf \
test/conf/future_expired_stanza_access.conf \
test/conf/fuzzing_open_ports_access.conf \
test/conf/fuzzing_restrict_ports_access.conf \
@@ -176,6 +170,9 @@ EXTRA_DIST = \
test/conf/gpg_no_sig_no_fpr_access.conf \
test/conf/gpg_no_sig_verify_access.conf \
test/conf/gpg_invalid_sig_id_access.conf \
test/conf/gpg_large_signing_key_access.conf \
test/conf/gpg_subkey_access.conf \
test/conf/gpg_server_large_key_access.conf \
test/conf/fwknoprc_gpg_invalid_exe \
test/conf/fwknoprc_hmac_defaults \
test/conf/fwknoprc_hmac_time_offset_mins \
@@ -224,7 +221,12 @@ EXTRA_DIST = \
test/conf/hmac_force_nat_access.conf \
test/conf/hmac_force_snat_access.conf \
test/conf/hmac_force_masq_access.conf \
test/conf/hmac_force_nat_forward_all_access.conf \
test/conf/hmac_no_b64_cygwin_access.conf \
test/conf/hmac_forward_all_access.conf \
test/conf/hmac_forward_all_masq_access.conf \
test/conf/hmac_forward_all_and_dnat_access.conf \
test/conf/hmac_force_masq_no_dnat_access.conf \
test/conf/multi_pkts.pcap \
test/conf/fwknoprc_default_hmac_base64_key \
test/conf/fwknoprc_hmac_nat_rand_base64_key \
@@ -266,6 +268,7 @@ EXTRA_DIST = \
test/conf/fwknoprc_stanza_list \
test/conf/icmp_pcap_filter_fwknopd.conf \
test/conf/invalid_expire_access.conf \
test/conf/require_force_nat_access.conf \
test/conf/invalid_source_access.conf \
test/conf/ipt_output_chain_fwknopd.conf \
test/conf/firewd_output_chain_fwknopd.conf \
@@ -303,6 +306,7 @@ EXTRA_DIST = \
test/conf/no_subnet_source_match_access.conf \
test/conf/ofb_mode_access.conf \
test/conf/open_ports_access.conf \
test/conf/open_ports_force_masq_access.conf \
test/conf/override_fwknopd.conf \
test/conf/override2_fwknopd.conf \
test/conf/override_no_digest_tracking_fwknopd.conf \
@@ -320,7 +324,11 @@ EXTRA_DIST = \
test/conf/firewd_snat_fwknopd.conf \
test/conf/ipt_snat_no_translate_ip_fwknopd.conf \
test/conf/firewd_snat_no_translate_ip_fwknopd.conf \
test/conf/ipt_snat_translate_ip_fwknopd.conf \
test/conf/firewd_snat_translate_ip_fwknopd.conf \
test/conf/destination_rule_fwknopd.conf \
test/conf/firewd_spa_dst_snat_fwknopd.conf \
test/conf/ipt_spa_dst_snat_fwknopd.conf \
test/conf/hmac_spa_destination_access.conf \
test/conf/hmac_spa_destination2_access.conf \
test/conf/hmac_spa_destination3_access.conf \
@@ -357,36 +365,59 @@ EXTRA_DIST = \
test/misc/freebsd_rc.conf \
test/misc/pf.rules \
test/misc/pf.sh \
test/asan/use-after-free.c \
test/asan/Makefile \
test/afl/compile/afl-compile-code-coverage.sh \
test/afl/compile/afl-compile-no-enable-arg.sh \
test/afl/compile/afl-compile.sh \
test/afl/compile/afl-gen-code-coverage.sh \
test/afl/compile/fcns \
test/afl/doc/AFL_status_screen.png \
test/afl/README \
test/afl/README.md \
test/afl/fuzzing-wrappers/client-rc.sh \
test/afl/fuzzing-wrappers/fcns \
test/afl/fuzzing-wrappers/helpers/fwknop-rc-hangs.sh \
test/afl/fuzzing-wrappers/helpers/fwknop-rc-test.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-digest-cache.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-access-hangs.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-access.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-conf-hangs.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-conf.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-hangs.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-test.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-access.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-enc-pkt-file.sh \
test/afl/fuzzing-wrappers/server-access.sh \
test/afl/fuzzing-wrappers/server-conf.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-digest-cache.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-test.sh \
test/afl/fuzzing-wrappers/helpers/fwknop-rc-hangs.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-access-hangs.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-hangs.sh \
test/afl/fuzzing-wrappers/helpers/afl-cmin/server-conf-cmin.sh \
test/afl/fuzzing-wrappers/helpers/afl-cmin/README \
test/afl/fuzzing-wrappers/helpers/afl-cmin/spa-pkts-cmin.sh \
test/afl/fuzzing-wrappers/helpers/afl-cmin/server-access-cmin.sh \
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-conf-hangs.sh \
test/afl/fuzzing-wrappers/server-digest-cache.sh \
test/afl/fuzzing-wrappers/spa-pkts.sh \
test/afl/fuzzing-wrappers/server-access.sh \
test/afl/fuzzing-wrappers/server-enc-pkts.sh \
test/afl/fuzzing-wrappers/fcns \
test/afl/fuzzing-wrappers/server-conf.sh \
test/afl/test-cases/client-rc/fwknoprc \
test/afl/test-cases/server-access/access.conf \
test/afl/test-cases/server-conf/fwknopd.conf \
test/afl/test-cases/spa-pkts/spa.start \
test/afl/test-cases/spa-pkts/spa2.start \
test/afl/test-cases/spa-pkts/spa3.start \
test/afl/test-cases/client-rc/fwknoprc2 \
test/afl/test-cases/server-digest-cache/digest.cache \
test/afl/test-cases/spa-pkts.cmin/spa1_sha384.start \
test/afl/test-cases/spa-pkts.cmin/spa1_sha256.start \
test/afl/test-cases/spa-pkts.cmin/spa1_md5.start \
test/afl/test-cases/spa-pkts.cmin/spa2_sha384.start \
test/afl/test-cases/spa-pkts.cmin/spa2_md5.start \
test/afl/test-cases/enc-pkts/spa.enc \
test/afl/test-cases/server-access/access.conf \
test/afl/test-cases/spa-pkts/spa1_sha384.start \
test/afl/test-cases/spa-pkts/spa3_sha384.start \
test/afl/test-cases/spa-pkts/spa3_sha256.start \
test/afl/test-cases/spa-pkts/spa3_sha512.start \
test/afl/test-cases/spa-pkts/spa1_sha256.start \
test/afl/test-cases/spa-pkts/spa1_sha512.start \
test/afl/test-cases/spa-pkts/spa3_md5.start \
test/afl/test-cases/spa-pkts/spa1_md5.start \
test/afl/test-cases/spa-pkts/spa2_sha256.start \
test/afl/test-cases/spa-pkts/spa2_sha512.start \
test/afl/test-cases/spa-pkts/spa2_sha384.start \
test/afl/test-cases/spa-pkts/spa2_md5.start \
test/afl/test-cases/server-conf/firewalld/fwknopd.conf \
test/afl/test-cases/server-conf/iptables/fwknopd.conf \
test/tests/address_sanitizer.pl \
test/tests/build_security.pl \
test/tests/preliminaries.pl \
test/tests/code_structure.pl \
@@ -422,8 +453,10 @@ EXTRA_DIST = \
test/run-test-suite.sh \
test/valgrind_suppressions \
test/configure_max_coverage.sh \
test/rm-coverage-files.sh \
test/gen-coverage-report.sh \
test/init-lcov.sh \
test/rm-coverage-files.sh \
test/lcov.env \
test/configure_max_coverage.sh \
test/README \
VERSION \
+104 -3
View File
@@ -57,13 +57,109 @@ for Rijndael encryption is generated via the standard PBKDF1 key derivation
algorithm, and CBC mode is set. If the GnuPG method is chosen, then the
encryption keys are derived from GnuPG key rings.
## Tutorial
## Use Cases
People who use Single Packet Authorization (SPA) or its security-challenged cousin
Port Knocking (PK) usually access SSHD running on the same system where the SPA/PK
software is deployed. That is, a firewall running on a host has a default-drop
policy against all incoming SSH connections so that SSHD cannot be scanned, but a
SPA daemon reconfigures the firewall to temporarily grant access to a passively
authenticated SPA client:
![alt text][SPA-basic-access-SSHD]
[SPA-basic-access-SSHD]: /doc/images/SPA_basic.png "Basic SPA usage to access SSHD"
fwknop supports the above, but also goes much further and makes robust usage of NAT
(for iptables/firewalld firewalls). After all, *important* firewalls are usually gateways
between networks as opposed to just being deployed on standalone hosts. NAT is commonly
used on such firewalls (at least for IPv4 communications) to provide Internet access to
internal networks that are on RFC 1918 address space, and also to allow external
hosts access to services hosted on internal systems.
Because fwknop integrates with NAT, SPA can be leveraged to access internal services
*through* the firewall by users on the external Internet. Although this has plenty of
applications on modern traditional networks, it also allows fwknop to support cloud
computing environments such as Amazon's AWS:
![alt text][SPA-Amazon-AWS-cloud]
[SPA-Amazon-AWS-cloud]: /doc/images/SPA_AWS_network_setup.png "SPA usage on Amazon AWS cloud environments"
## Tutorial
A comprehensive tutorial on fwknop can be found here:
[http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html](http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html)
## Features
The following is a complete list of features supported by the fwknop project:
* Implements Single Packet Authorization around iptables and firewalld firewalls
on Linux, ipfw firewalls on *BSD and Mac OS X, and PF on OpenBSD.
* The fwknop client runs on Linux, Mac OS X, *BSD, and Windows under Cygwin.
In addition, there is an [Android app](https://github.com/oneru/Fwknop2/releases)
to generate SPA packets.
* Supports both Rijndael and GnuPG methods for the encryption/decryption of
SPA packets.
* Supports HMAC authenticated encryption for both Rijndael and GnuPG. The order
of operation is encrypt-then-authenticate to avoid various cryptanalytic problems.
* Replay attacks are detected and thwarted by SHA-256 digest comparison of valid
incoming SPA packets. Other digest algorithms are also supported, but SHA-256 is
the default.
* SPA packets are passively sniffed from the wire via libpcap. The fwknopd server
can also acquire packet data from a file that is written to by a separate Ethernet
sniffer (such as with `tcpdump -w <file>`), from the iptables ULOG pcap writer, or
directly via a UDP socket in `--udp-server` mode.
* For iptables firewalls, ACCEPT rules added by fwknop are added and deleted (after
a configurable timeout) from custom iptables chains so that fwknop does not
interfere with any existing iptables policy that may already be loaded on the
system.
* Supports inbound NAT connections for authenticated SPA communications (iptables
firewalls only for now). This means fwknop can be configured to create DNAT
rules so that you can reach a service (such as SSH) running on an internal system
on an RFC 1918 IP address from the open Internet. SNAT rules are also supported
which essentially turns fwknopd into a [SPA-authenticating gateway](https://www.cipherdyne.org/blog/2015/04/nat-and-single-packet-authorization.html)
to access the Internet from an internal network.
* Multiple users are supported by the fwknop server, and each user can be assigned
their own symmetric or asymmetric encryption key via the /etc/fwknop/access.conf
file.
* Automatic resolution of external IP address via
[https://www.cipherdyne.org/cgi-bin/myip](https://www.cipherdyne.org/cgi-bin/myip)
(this is useful when the fwknop client is run from behind a NAT device). Because
the external IP address is encrypted within each SPA packet in this mode,
Man-in-the-Middle (MITM) attacks where an inline device intercepts an SPA packet
and only forwards it from a different IP in an effort to gain access are thwarted.
* [Port randomization](https://www.cipherdyne.org/blog/2008/06/single-packet-authorization-with-port-randomization.html)
is supported for the destination port of SPA packets as well
as the port over which the follow-on connection is made via the iptables NAT
capabilities. The later applies to forwarded connections to internal services and
to access granted to local sockets on the system running fwknopd.
* Integration with Tor (as described in this
[DefCon 14](http://www.cipherdyne.org/fwknop/docs/talks/dc14_fwknop_slides.pdf) presentation).
Note that because Tor uses TCP for transport, sending SPA packets through the Tor
network requires that each SPA packet is sent over an established TCP connection,
so technically this breaks the "single" aspect of "Single Packet Authorization".
However, Tor provides anonymity benefits that can outweigh this consideration in
some deployments.
* Implements a versioned protocol for SPA communications, so it is easy to extend
the protocol to offer new SPA message types and maintain backwards compatibility
with older fwknop clients at the same time.
* Supports the execution of shell commands on behalf of valid SPA packets.
* The fwknop server can be configured to place multiple restrictions on inbound SPA
packets beyond those enforced by encryption keys and replay attack detection.
Namely, packet age, source IP address, remote user, access to requested ports,
and more.
* Bundled with fwknop is a comprehensive test suite that issues a series of tests
designed to verify that both the client and server pieces of fwknop work properly.
These tests involve sniffing SPA packets over the local loopback interface,
building temporary firewall rules that are checked for the appropriate access based
on the testing config, and parsing output from both the fwknop client and fwknopd
server for expected markers for each test. Test suite output can easily be
anonymized for communication to third parties for analysis.
* fwknop was the first program to integrate port knocking with passive OS
fingerprinting. However, Single Packet Authorization offers many security benefits
beyond port knocking, so the port knocking mode of operation is generally
deprecated.
## License
The fwknop project is released as open source software under the terms of
the **GNU General Public License (GPL v2)**. The latest release can be found
@@ -84,10 +180,15 @@ and there are python bindings as well in the `python` directory).
## Upgrading
If you are upgrading from an older version of fwknop (and this includes the
original perl implementation as well), then you will want to read the
following link to ensure a smooth transition to fwknop-2.5:
following link to ensure a smooth transition to fwknop-2.5 or later:
[http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility](http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#backwards-compatibility)
## Misc
* Questions or comments about fwknop will be fielded on the
[fwknop mailing list](http://lists.sourceforge.net/lists/listinfo/fwknop-discuss]).
* For static analysis, fwknop uses the CLANG static analyzer and also the powerful
Coverity Scan tool: ![](https://scan.coverity.com/projects/403/badge.svg)
## Building fwknop
This distribution uses GNU autoconf for setting up the build. Please see
@@ -143,7 +244,7 @@ migrate to this version, there are some things to be aware of:
those files.
## For fwknop developers
### For fwknop developers
If you are pulling this distribution from git, you should run the
`autogen.sh` script to generate the autoconf files. If you get errors about
missing directories or files, try running `autogen.sh` again. After that
+1 -1
View File
@@ -1 +1 @@
2.6.5
2.6.7
+8
View File
@@ -1,3 +1,11 @@
***
Please note that this Android client has been deprecated in favor of Jonathan
Bennett's new Android client that is available here:
https://github.com/oneru/Fwknop2/releases/
****
===============================================================================
FWKNOP for Android
+5
View File
@@ -0,0 +1,5 @@
Please note that this Android client has been deprecated in favor of Jonathan
Bennett's new Android client that is available here:
https://github.com/oneru/Fwknop2/releases/
+9 -1
View File
@@ -68,6 +68,10 @@ jstring Java_com_max2idea_android_fwknop_Fwknop_sendSPAPacket(JNIEnv* env,
jstring jdestip = (*env)->GetObjectField(env, thiz, fid);
const char *destip_str = (*env)->GetStringUTFChars(env, jdestip, 0);
fid = (*env)->GetFieldID(env, c, "destport_str", "Ljava/lang/String;");
jstring jdestport = (*env)->GetObjectField(env, thiz, fid);
const char *destport_str = (*env)->GetStringUTFChars(env, jdestport, 0);
fid = (*env)->GetFieldID(env, c, "passwd_str", "Ljava/lang/String;");
jstring jpasswd = (*env)->GetObjectField(env, thiz, fid);
const char *passwd_str = (*env)->GetStringUTFChars(env, jpasswd, 0);
@@ -94,6 +98,10 @@ jstring Java_com_max2idea_android_fwknop_Fwknop_sendSPAPacket(JNIEnv* env,
sprintf(res_msg, "Error: Invalid or missing destination IP");
goto cleanup2;
}
if(destport_str == NULL) {
sprintf(res_msg, "Error: Invalid or missing destination port");
goto cleanup2;
}
if(passwd_str == NULL) {
sprintf(res_msg, "Error: Invalid or missing password");
goto cleanup2;
@@ -112,7 +120,7 @@ jstring Java_com_max2idea_android_fwknop_Fwknop_sendSPAPacket(JNIEnv* env,
/* Set our spa server info
*/
opts.spa_server_str = (char*)destip_str;
opts.spa_dst_port = FKO_DEFAULT_PORT; /* Until we make this settable. */
opts.spa_dst_port = atoi(destport_str);
/* Intialize the context
*/
+21
View File
@@ -88,6 +88,27 @@
android:textSize="20dip"
/>
</LinearLayout>
<LinearLayout android:id="@+id/destPortl"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/destPortStr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Server UDP Port: "
android:textSize="20dip"
/>
<EditText
android:id="@+id/destPort"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="62201"
android:singleLine="true"
android:textSize="20dip"
/>
</LinearLayout>
<LinearLayout android:id="@+id/fwTimeoutl"
android:orientation="horizontal"
android:layout_width="fill_parent"
@@ -98,6 +98,7 @@ public class Fwknop extends Activity {
private EditText mPasswd;
private EditText mHmac;
private EditText mDestip;
private EditText mDestport;
private EditText mTCPAccessPorts;
private EditText mUDPAccessPorts;
private EditText mFwTimeout;
@@ -107,6 +108,7 @@ public class Fwknop extends Activity {
private String passwd_str;
private String hmac_str;
private String destip_str;
private String destport_str;
private String fw_timeout_str;
private CheckBox mCheck;
private String externalIP = "";
@@ -344,6 +346,14 @@ public class Fwknop extends Activity {
return;
}
if (this.mDestport != null && !this.mDestport.getText().toString().trim().equals("")) {
this.destport_str = mDestport.getText().toString();
edit.putString("destport_str", mDestport.getText().toString());
} else {
this.UIAlert("Input error", "Please enter a valid Server port", this);
return;
}
if (this.mFwTimeout != null) {
int fw_timeout;
try {
@@ -381,6 +391,9 @@ public class Fwknop extends Activity {
this.mDestip = (EditText) findViewById(R.id.destIP);
this.mDestip.setText(prefs.getString("destip_str", ""));
this.mDestport = (EditText) findViewById(R.id.destPort);
this.mDestport.setText(prefs.getString("destport_str", "62201"));
this.mFwTimeout = (EditText) findViewById(R.id.fwTimeout);
this.mFwTimeout.setText(prefs.getString("fw_timeout_str", "60"));
+1 -7
View File
@@ -199,7 +199,7 @@ static int critical_var_array[] =
};
/**
* @brief Generate Rijndael + HMAC keys from /dev/random (base64 encoded) and exit.
* @brief Generate Rijndael + HMAC keys from /dev/urandom (base64 encoded).
*
* @param options FKO command line option structure
*/
@@ -1869,12 +1869,6 @@ validate_options(fko_cli_options_t *options)
snprintf(options->http_user_agent, HTTP_MAX_USER_AGENT_LEN,
"%s%s", "Fwknop/", MY_VERSION);
#if AFL_FUZZING
/* Don't issue IP resolution requests in AFL fuzzing mode
*/
options->resolve_ip_http_https = 0;
#endif
if(options->http_proxy[0] != 0x0 && options->spa_proto != FKO_PROTO_HTTP)
{
log_msg(LOG_VERBOSITY_ERROR,
+11 -4
View File
@@ -2,12 +2,12 @@
.\" Title: fwknop
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 11/15/2014
.\" Date: 08/24/2015
.\" Manual: Fwknop Client
.\" Source: Fwknop Client
.\" Language: English
.\"
.TH "FWKNOP" "8" "11/15/2014" "Fwknop Client" "Fwknop Client"
.TH "FWKNOP" "8" "08/24/2015" "Fwknop Client" "Fwknop Client"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -164,10 +164,17 @@ rc file is a more powerful mechanism for specifying not only the HMAC key but ot
.RS 4
Have
\fBfwknop\fR
generate both Rijndael and HMAC keys that can be used for SPA packet encryption\&. These keys are derived from /dev/urandom and then base64 encoded before being printed to stdout, and are meant to be included within the \(lq$HOME/\&.fwknoprc\(rq file (or the file referenced by
generate both Rijndael and HMAC keys that can be used for SPA packet encryption and authentication\&. These keys are derived from /dev/urandom and then base64 encoded before being printed to stdout, and are meant to be included within the \(lq$HOME/\&.fwknoprc\(rq file (or the file referenced by
\fB\-\-get\-key\fR)\&. Such keys are generally more secure than passphrases that are typed in from the command line\&.
.RE
.PP
\fB\-\-key\-gen\-file\fR=\fI<file>\fR
.RS 4
Write generated keys to the specified file\&. Note that the file is overwritten if it already exists\&. If this option is not given, then
\fB\-\-key\-gen\fR
writes the keys to stdout\&.
.RE
.PP
\fB\-\-key\-len\fR=\fI<length>\fR
.RS 4
Specify the number of bytes for a generated Rijndael key\&. The maximum size is currently 128 bytes\&.
@@ -1256,7 +1263,7 @@ Additional commentary on Single Packet Authorization can be found via Michael Ra
Damien Stuart <dstuart@dstuart\&.org>, Michael Rash <mbr@cipherdyne\&.org>
.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\&. A few contributors deserve to be singled out including: Franck Joncourt, Max Kastanas, Vlad Glagolev, Sean Greven, Hank Leininger, Fernando Arnaboldi, and Erik Gomez\&.
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 \fIhttps://github\&.com/mrash/fwknop/blob/master/CREDITS\fR to view the online list of contributors\&. A few contributors deserve to be singled out including: Franck Joncourt, Max Kastanas, Vlad Glagolev, Sean Greven, Hank Leininger, Fernando Arnaboldi, and Erik Gomez\&.
.sp
The phrase \(lqSingle Packet Authorization\(rq was coined by MadHat and Simple Nomad at the BlackHat Briefings of 2005\&.
.SH "BUGS"
+22 -3
View File
@@ -64,6 +64,14 @@ static int is_hostname_str_with_port(const char *str,
static int enable_fault_injections(fko_cli_options_t * const opts);
#endif
#if AFL_FUZZING
/* These are used in AFL fuzzing mode so the fuzzing cycle is not
* interrupted by trying to read from stdin
*/
#define AFL_ENC_KEY "aflenckey"
#define AFL_HMAC_KEY "aflhmackey"
#endif
#define NAT_ACCESS_STR_TEMPLATE "%s,%d" /*!< Template for a nat access string ip,port with sscanf*/
#define HOSTNAME_BUFSIZE 64 /*!< Maximum size of a hostname string */
#define CTX_DUMP_BUFSIZE 4096 /*!< Maximum size allocated to a FKO context dump */
@@ -1126,7 +1134,9 @@ static int
get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
char *key, int *key_len, char *hmac_key, int *hmac_key_len)
{
#if !AFL_FUZZING
char *key_tmp = NULL, *hmac_key_tmp = NULL;
#endif
int use_hmac = 0, res = 0;
memset(key, 0x0, MAX_KEY_LEN+1);
@@ -1173,6 +1183,9 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
"[+] GPG mode set, signing passphrase not required");
else if(strlen(options->gpg_signer_key))
{
#if AFL_FUZZING
strlcpy(key, AFL_ENC_KEY, MAX_KEY_LEN+1);
#else
key_tmp = getpasswd("Enter passphrase for signing: ", options->input_fd);
if(key_tmp == NULL)
{
@@ -1180,19 +1193,23 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
return 0;
}
strlcpy(key, key_tmp, MAX_KEY_LEN+1);
#endif
*key_len = strlen(key);
}
}
else
{
#if AFL_FUZZING
strlcpy(key, AFL_ENC_KEY, MAX_KEY_LEN+1);
#else
key_tmp = getpasswd("Enter encryption key: ", options->input_fd);
if(key_tmp == NULL)
{
log_msg(LOG_VERBOSITY_ERROR, "[*] getpasswd() key error.");
return 0;
}
strlcpy(key, key_tmp, MAX_KEY_LEN+1);
#endif
*key_len = strlen(key);
}
}
@@ -1232,15 +1249,17 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
}
else
{
#if AFL_FUZZING
strlcpy(hmac_key, AFL_HMAC_KEY, MAX_KEY_LEN+1);
#else
hmac_key_tmp = getpasswd("Enter HMAC key: ", options->input_fd);
if(hmac_key_tmp == NULL)
{
log_msg(LOG_VERBOSITY_ERROR, "[*] getpasswd() key error.");
return 0;
}
strlcpy(hmac_key, hmac_key_tmp, MAX_KEY_LEN+1);
#endif
*hmac_key_len = strlen(hmac_key);
use_hmac = 1;
}
+1 -5
View File
@@ -69,8 +69,6 @@
#define MAX_HOSTNAME_LEN 70
#define MAX_URL_HOST_LEN 256
#define MAX_URL_PATH_LEN 1024
#define MAX_KEY_LEN 128
#define MAX_B64_KEY_LEN 180
/* fwknop client configuration parameters and values
*/
@@ -156,10 +154,10 @@ typedef struct fko_cli_options
unsigned char use_gpg;
unsigned char use_gpg_agent;
unsigned char gpg_no_signing_pw;
unsigned char key_gen;
int time_offset_plus;
int time_offset_minus;
int fw_timeout;
int key_gen;
char use_rc_stanza[MAX_LINE_LEN];
unsigned char got_named_stanza;
@@ -173,8 +171,6 @@ typedef struct fko_cli_options
} fko_cli_options_t;
extern fko_cli_options_t options;
void free_configs(fko_cli_options_t *opts);
#endif /* FWKNOP_COMMON_H */
+30
View File
@@ -45,6 +45,10 @@
#include <sys/wait.h>
#endif
#if AFL_FUZZING
#define AFL_SET_RESOLVE_HOST "192.168.12.123" /* force to non-routable IP */
#endif
struct url
{
char port[MAX_PORT_STR_LEN+1];
@@ -95,6 +99,19 @@ try_url(struct url *url, fko_cli_options_t *options)
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
#if AFL_FUZZING
/* Make sure to not generate any resolution requests when compiled
* for AFL fuzzing cycles
*/
strlcpy(options->allow_ip_str, AFL_SET_RESOLVE_HOST,
sizeof(options->allow_ip_str));
log_msg(LOG_VERBOSITY_INFO,
"\n[+] AFL fuzzing cycle, force IP resolution to: %s",
options->allow_ip_str);
return(1);
#endif
error = getaddrinfo(url->host, url->port, &hints, &result);
if (error != 0)
{
@@ -381,6 +398,19 @@ resolve_ip_https(fko_cli_options_t *options)
strlcat(wget_ssl_cmd, WGET_RESOLVE_URL_SSL, sizeof(wget_ssl_cmd));
}
#if AFL_FUZZING
/* Make sure to not generate any resolution requests when compiled
* for AFL fuzzing cycles
*/
strlcpy(options->allow_ip_str, AFL_SET_RESOLVE_HOST,
sizeof(options->allow_ip_str));
log_msg(LOG_VERBOSITY_INFO,
"\n[+] AFL fuzzing cycle, force IP resolution to: %s",
options->allow_ip_str);
return(1);
#endif
#if HAVE_EXECVPE
if(strtoargv(wget_ssl_cmd, wget_argv, &wget_argc, options) != 1)
{
+23 -4
View File
@@ -54,7 +54,7 @@ dump_transmit_options(const fko_cli_options_t *options)
/* Function to generate a header checksum.
*/
unsigned short
static unsigned short
chksum(unsigned short *buf, int nbytes)
{
unsigned int sum;
@@ -119,6 +119,14 @@ send_spa_packet_tcp_or_udp(const char *spa_data, const int sd_len,
snprintf(port_str, MAX_PORT_STR_LEN+1, "%d", options->spa_dst_port);
#if AFL_FUZZING
/* Make sure to never send SPA packets under AFL fuzzing cycles
*/
log_msg(LOG_VERBOSITY_NORMAL,
"AFL fuzzing enabled, SPA packet not actually sent.");
return res;
#endif
error = getaddrinfo(options->spa_server_str, port_str, &hints, &result);
if (error != 0)
@@ -261,7 +269,7 @@ send_spa_packet_tcp_raw(const char *spa_data, const int sd_len,
tcph->check = 0;
tcph->urg_ptr = 0;
/* No we can compute our checksum.
/* Now we can compute our checksum.
*/
iph->check = chksum((unsigned short *)pkt_data, iph->tot_len);
@@ -360,7 +368,7 @@ send_spa_packet_udp_raw(const char *spa_data, const int sd_len,
udph->check = 0;
udph->len = htons(sd_len + sizeof(struct udphdr));
/* No we can compute our checksum.
/* Now we can compute our checksum.
*/
iph->check = chksum((unsigned short *)pkt_data, iph->tot_len);
@@ -464,7 +472,7 @@ send_spa_packet_icmp(const char *spa_data, const int sd_len,
icmph->un.echo.sequence = htons(1);
}
/* No we can compute our checksum.
/* Now we can compute our checksum.
*/
iph->check = chksum((unsigned short *)pkt_data, iph->tot_len);
icmph->checksum = chksum((unsigned short *)icmph, sizeof(struct icmphdr) + sd_len);
@@ -590,6 +598,9 @@ send_spa_packet_http(const char *spa_data, const int sd_len,
return 0;
}
/* In AFL fuzzing mode, the following function will not send
* the SPA packet.
*/
return send_spa_packet_tcp_or_udp(http_buf, strlen(http_buf), options);
}
@@ -684,6 +695,14 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options)
* the ip address */
hints.ai_family = AF_INET;
#if AFL_FUZZING
/* Make sure to never send SPA packets under AFL fuzzing cycles
*/
log_msg(LOG_VERBOSITY_NORMAL,
"AFL fuzzing enabled, SPA packet not actually sent.");
return res;
#endif
if (resolve_dest_adr(options->spa_server_str, &hints, ip_str, sizeof(ip_str)) != 0)
{
log_msg(LOG_VERBOSITY_ERROR, "[*] Unable to resolve %s as an ip address",
+4
View File
@@ -147,6 +147,7 @@ enum {
#define MIN_HIGH_PORT 10000 /* sensible minimum for SPA dest port */
#define ANY_PORT 0 /* used as a wildcard */
#define ANY_PROTO 0 /* used as a wildcard */
#define NAT_ANY_PORT ANY_PORT
#define MAX_SERVER_STR_LEN 50
#define MAX_ICMP_TYPE 40
#define MAX_ICMP_CODE 15
@@ -157,6 +158,9 @@ enum {
#define MAX_GPG_KEY_ID 128
#define MAX_USERNAME_LEN 30
#define MAX_KEY_LEN 128
#define MAX_B64_KEY_LEN 180
/* Command line argument / argv handling
*/
#define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */
+62 -20
View File
@@ -11,7 +11,7 @@ AC_PREREQ(2.62)
dnl Define our name, version and email.
m4_define(my_package, [fwknop])
m4_define(my_version, [2.6.5])
m4_define(my_version, [2.6.7])
m4_define(my_bug_email, [dstuart@dstuart.org])
AC_INIT(my_package, my_version, my_bug_email)
@@ -170,6 +170,32 @@ fi
AM_CONDITIONAL([WANT_C_UNIT_TESTS], [test "$want_c_unit_tests" = yes])
dnl Decide whether or not to enable address sanitizer support
dnl
want_asan_support=no
AC_ARG_ENABLE([asan-support],
[AS_HELP_STRING([--enable-asan-support],
[Build fwknop binaries with address sanitizer support @<:@default is to disable@:>@])],
[want_asan_support=$enableval],
[])
if test "x$want_asan_support" = "xyes"; then
FKO_CHECK_COMPILER_ARG([-fsanitize=address -fno-omit-frame-pointer])
fi
dnl Decide whether or not force 32-bit mode
dnl
want_32bit_mode=no
AC_ARG_ENABLE([32bit-mode],
[AS_HELP_STRING([--enable-32bit-mode],
[Build 32-bit fwknop binaries @<:@default is to disable@:>@])],
[want_32bit_mode=$enableval],
[])
if test "x$want_32bit_mode" = "xyes"; then
FKO_CHECK_COMPILER_ARG([-m32])
fi
dnl Decide whether or not to compile in certain features that enable fuzzing
dnl of fwknop code - this is for testing purposes only.
dnl
@@ -553,6 +579,22 @@ dnl
]
)
AC_ARG_WITH([firewalld],
[AS_HELP_STRING([--with-firewalld=/path/to/firewall-cmd],
[Synonym for --with-firewall-cmd, specify path to the firewall-cmd executable @<:@default=check path@:>@])],
[
AS_IF([ test "x$withval" = xno ], [],
AS_IF([ test "x$withval" = x -o "x$withval" = xyes ],
[AC_MSG_ERROR([--with-firewalld requires an argument specifying a path to firewall-cmd])],
[ FORCE_FIREWALLD_EXE=$withval ]
)
)
],
[
AC_PATH_PROG(FIREWALLD_EXE, [firewalld], [], [$APP_PATH])
]
)
dnl Check for iptables
dnl
AC_ARG_WITH([iptables],
@@ -628,29 +670,29 @@ dnl
dnl If a firewall was forced. set the appropriate _EXE var and clear the others.
dnl
AS_IF([test "x$FORCE_FIREWALLD_EXE" != x], [
FIREWALLD_EXE="$FORCE_FIREWALLD_EXE"
FIREWALLD_EXE="$FORCE_FIREWALLD_EXE"
],[
AS_IF([test "x$FORCE_IPTABLES_EXE" != x], [
IPTABLES_EXE="$FORCE_IPTABLES_EXE"
FIREWALLD_EXE=""
IPTABLES_EXE="$FORCE_IPTABLES_EXE"
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_IPFW_EXE" != x], [
IPFW_EXE="$FORCE_IPFW_EXE"
IPTABLES_EXE=""
FIREWALLD_EXE=""
IPFW_EXE="$FORCE_IPFW_EXE"
IPTABLES_EXE=""
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_PF_EXE" != x], [
PF_EXE="$FORCE_PF_EXE"
IPFW_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
PF_EXE="$FORCE_PF_EXE"
IPFW_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
],[
AS_IF([test "x$FORCE_IPF_EXE" != x], [
IPF_EXE="$FORCE_IPF_EXE"
PF_EXE=""
IPFW_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
IPF_EXE="$FORCE_IPF_EXE"
PF_EXE=""
IPFW_EXE=""
IPTABLES_EXE=""
FIREWALLD_EXE=""
]
]
]
@@ -664,19 +706,19 @@ dnl then ipfw, pf, and otherwise we try ipf.
dnl
AS_IF([test "x$FIREWALLD_EXE" != x], [
FW_DEF="FW_FIREWALLD"
FIREWALL_TYPE="firewalld"
FIREWALL_TYPE="firewalld"
FIREWALL_EXE=$FIREWALLD_EXE
AC_DEFINE_UNQUOTED([FIREWALL_FIREWALLD], [1], [The firewall type: firewalld.])
],[
AS_IF([test "x$IPTABLES_EXE" != x], [
FW_DEF="FW_IPTABLES"
FIREWALL_TYPE="iptables"
FIREWALL_TYPE="iptables"
FIREWALL_EXE=$IPTABLES_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPTABLES], [1], [The firewall type: iptables.])
],[
AS_IF([test "x$IPFW_EXE" != x], [
FW_DEF="FW_IPFW"
FIREWALL_TYPE="ipfw"
FIREWALL_TYPE="ipfw"
FIREWALL_EXE=$IPFW_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPFW], [1], [The firewall type: ipfw.])
],[
@@ -688,7 +730,7 @@ dnl
],[
AS_IF([test "x$IPF_EXE" != x], [
AC_MSG_ERROR([Sorry - ipf was specified or the only one found, however, it is not supported yet.])
FIREWALL_TYPE="ipf"
FIREWALL_TYPE="ipf"
FIREWALL_EXE=$IPF_EXE
AC_DEFINE_UNQUOTED([FIREWALL_IPF], [1], [The firewall type: ipf.])
], [AC_MSG_ERROR([No firewall program was found or specified.]) ]
+10 -5
View File
@@ -190,11 +190,16 @@ GENERAL OPTIONS
*--key-gen*::
Have *fwknop* generate both Rijndael and HMAC keys that can be used for SPA
packet encryption. These keys are derived from /dev/urandom and then base64
encoded before being printed to stdout, and are meant to be included within
the ``$HOME/.fwknoprc'' file (or the file referenced by *--get-key*). Such
keys are generally more secure than passphrases that are typed in from the
command line.
packet encryption and authentication. These keys are derived from
/dev/urandom and then base64 encoded before being printed to stdout, and
are meant to be included within the ``$HOME/.fwknoprc'' file (or the file
referenced by *--get-key*). Such keys are generally more secure than
passphrases that are typed in from the command line.
*--key-gen-file*='<file>'::
Write generated keys to the specified file. Note that the file is
overwritten if it already exists. If this option is not given, then
*--key-gen* writes the keys to stdout.
*--key-len*='<length>'::
Specify the number of bytes for a generated Rijndael key. The maximum size
+98 -12
View File
@@ -68,7 +68,7 @@ COMMAND-LINE OPTIONS
*-d, --digest-file*='<digest-file>'::
Specify the location of the 'digest.cache' file. If this option is
not given, 'fwknopd' will use the compile-time default location (typically
'@localstatedir@/run/fwknop/digest.cache').
'@localstatedir@/fwknop/digest.cache').
*-D, --dump-config*::
Dump the configuration values that *fwknopd* derives from the
@@ -116,7 +116,7 @@ COMMAND-LINE OPTIONS
network traffic.
*-l, --locale*='<locale>'::
Set/override the system default locale setting.
Set/override the system default locale setting.
*--no-ipt-check-support*::
Disable the usage of the iptables '-C' option. This is not normally needed,
@@ -128,10 +128,31 @@ COMMAND-LINE OPTIONS
'@sysconfdir@/fwknop/fwknopd.conf' file with values from the specified file. Multiple
override config files can be given as a comma-separated list.
*--key-gen*::
Have *fwknopd* generate both Rijndael and HMAC keys that can be used for
SPA packet encryption and authentication. These keys are derived from
/dev/urandom and then base64 encoded before being printed to stdout, and
are meant to be manually included in a stanza within the
'@sysconfdir@/fwknop/access.conf' file. Such keys are generally more secure
than passphrases.
*--key-gen-file*='<file>'::
Write generated keys to the specified file. Note that the file is
overwritten if it already exists. If this option is not given, then
*--key-gen* writes the keys to stdout.
*--key-len*='<length>'::
Specify the number of bytes for a generated Rijndael key. The maximum size
is currently 128 bytes.
*--hmac-key-len*='<length>'::
Specify the number of bytes for a generated HMAC key. The maximum size is
currently 128 bytes.
*-p, --pid-file*='<pid-file>'::
Specify the location of the 'fwknopd.pid' file. If this option is
not given, 'fwknopd' will use the compile-time default location (typically
'@localstatedir@/run/fwknop/fwknopd.pid).
'@localstatedir@/fwknop/fwknopd.pid').
*-P, --pcap-filter*='<filter>'::
Specify a Berkeley packet filter statement on the *fwknopd* command
@@ -165,11 +186,11 @@ COMMAND-LINE OPTIONS
*--rotate-digest-cache*::
Rotate the digest cache file by renaming it to ``<name>-old'', and
starting a new one. The digest cache file is typically found in
'@localstatedir@/run/fwknop/digest.cache'.
'@localstatedir@/fwknop/digest.cache'.
*-r, --run-dir*='<path>'::
Specify the directory where *fwknopd* writes run time state files. The
default is '@localstatedir@/run'.
default is '@localstatedir@'.
*-S, --status*::
Display the status of any *fwknopd* processes that may or not be
@@ -220,7 +241,8 @@ This section list the more prominent configuration variables used by
*fwknopd*. It is not a complete list. There are directives for the type
of firewall used by *fwknopd* (i.e. _iptables_, _ipfw_, or _pf_). You will
want to make sure to check these to make sure they have appropriate values.
See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and corresponding details.
See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and
corresponding details.
*PCAP_INTF* '<interface>'::
Specify the ethernet interface on which *fwknopd* will sniff packets.
@@ -255,6 +277,14 @@ See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and correspond
previously save digests. It is a good idea to leave this feature on
to reduce the possibility of being vulnerable to a replay attack.
*RULES_CHECK_THRESHOLD* '<count>'::
Defines the number of times firewall rule expiration times must be checked
before a "deep" check is run. This allows *fwknopd* to remove rules that
contain a proper '_exp_<time>' even if a third party program added them
instead of *fwknopd*. The default value for this variable is 20, and this
typically results in this check being run every two seconds or so. To
disable this type of checking altogether, set this variable to zero.
*ENABLE_IPT_FORWARDING* '<Y/N>'::
Allow SPA clients to request access to services through an iptables
firewall instead of just to it (i.e. access through the FWKNOP_FORWARD
@@ -283,7 +313,10 @@ See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and correspond
built with the MASQUERADE target (since then the internal IP does not
have to be defined here in the '@sysconfdir@/fwknop/fwknopd.conf' file),
but if you want *fwknopd* to use the SNAT target, you must also define an
IP address with the ``SNAT_TRANSLATE_IP'' variable.
IP address with the ``SNAT_TRANSLATE_IP'' variable. Note that this
variable is generally deprecated in favor of the ``FORCE_SNAT'' variable
in the '@sysconfdir@/fwknop/access.conf' file which enables per-stanza
control over the SNAT IP.
*ENABLE_IPT_OUTPUT* '<Y/N>'::
Add ACCEPT rules to the FWKNOP_OUTPUT chain. This is usually only useful
@@ -302,6 +335,15 @@ See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and correspond
Flush all existing rules in the fwknop chains when *fwknopd* is stopped
or otherwise exits cleanly. The default is ``Y''.
*EXIT_AT_INTF_DOWN* '<Y/N>'::
When *fwknopd* is sniffing an interface, if the interface is
administratively downed or unplugged, fwknopd will cleanly exit and an
assumption is made that any process monitoring infrastructure like systemd
or upstart will restart it. However, if fwknopd is not being monitored by
systemd, upstart, or anything else, this behavior can be disabled with the
``EXIT_AT_INTF_DOWN'' variable. If disabled, fwknopd will try to recover
when a downed interface comes back up.
*GPG_HOME_DIR* '<path>'::
If GPG keys are used instead of a Rijndael symmetric key, this is
the default GPG keys directory. Note that each access stanza in
@@ -396,7 +438,7 @@ See the '@sysconfdir@/fwknop/fwknopd.conf' file for the full list and correspond
*FWKNOP_RUN_DIR* '<path>'::
Specify the directory where *fwknopd* writes run time state files. The
default is '@localstatedir@/run'.
default is '@localstatedir@'.
ACCESS.CONF VARIABLES
~~~~~~~~~~~~~~~~~~~~~
@@ -501,11 +543,42 @@ directive starts a new stanza.
the *fwknopd* server as the user specified by the ``CMD_EXEC_USER'' or
as the user that started *fwknopd* if that is not set.
*ENABLE_CMD_SUDO_EXEC* '<Y/N>'::
*sudo* provides a powerful means of restricting the sets of commands that
users can execute via the ``sudoers'' file. By enabling this feature (and
in ``ENABLE_CMD_EXEC'' mode), all incoming commands from valid SPA packets
will be prefixed by ``/path/to/sudo -u <user> -g <group>'' where the path
to sudo is set by the ``SUDO_EXE'' variable, ``<user>'' is set by the
``CMD_SUDO_EXEC_USER'' variable (default is ``root'' if not set), and
``<group>'' is set by ``CMD_SUDO_EXEC_GROUP'' (default is also ``root'' if
not set).
*CMD_EXEC_USER* '<username>'::
This specifies the user that will execute commands contained within a SPA
packet. If not specified, fwknopd will execute it as the user it is
running as (most likely root). Setting this to a non-root user is highly
recommended.
Specify the user (via setuid) that will execute a command contained within
a SPA packet. If this variable is not given, fwknopd will execute the
command as the user it is running as (most likely root). Setting this to a
non-root user such as ``nobody'' is highly recommended if elevated
permissions are not needed.
*CMD_SUDO_EXEC_USER* '<username>'::
Specify the user (via ``sudo -u <user>'') that will execute a command
contained within a SPA packet. If this variable is not given, fwknopd will
assume the command should be executed as root.
*CMD_EXEC_GROUP* '<groupname>'::
Specify the group (via setgid) that will execute a command contained within
a SPA packet. If this variable is not given, fwknopd will execute the
command as the user it is running as (most likely root). Setting this to a
non-root user such as ``nobody'' is highly recommended if elevated
permissions are not needed.
*CMD_SUDO_EXEC_GROUP* '<groupname>'::
Specify the group (via ``sudo -gu <group>'') that will execute a command
contained within a SPA packet. If this variable is not given, fwknopd will
assume the command should be executed as root.
*SUDO_EXE* '<path>'::
Define the path to the sudo binary. Default is ``/usr/bin/sudo''.
*REQUIRE_USERNAME* '<username>'::
Require a specific username from the client system as encoded in the SPA
@@ -546,6 +619,19 @@ directive starts a new stanza.
necessary to also specify an IP address for SNAT rules because the
MASQUERADE target is used instead.
*FORWARD_ALL* '<Y/N>'::
In NAT scenarios, control whether all traffic is forwarded through the
*fwknopd* system as opposed to just forwarding connections to specific
services as requested by the *fwknop* client.
*DISABLE_DNAT* '<Y/N>'::
Control whether DNAT rules are created in FORCE_NAT scenarios. This is
mainly used in conjunction with the FORWARD_ALL variable to allow
*fwknopd* to act essentially as an SPA gateway. I.e., the *fwknop* client
is used to gain access via SPA to the broader Internet after being granted
an IP via DHCP, but prior to sending the SPA packet all traffic is blocked
by default to the Internet.
*GPG_DECRYPT_ID* '<keyID>'::
Define a GnuPG key ID to use for decrypting SPA messages that
have been encrypted by an *fwknop* client. This keyword is
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+240 -59
View File
@@ -550,7 +550,7 @@ parsing, and data extraction.
For building a new fko @acronym{SPA} message, you will use the @code{fko_new}
function:
@deftypefun int fko_new (@w{fko_ctx_t @var{*ctx}})
@deftypefun int fko_new (fko_ctx_t @var{*ctx})
The function @code{fko_new} sets up and initializes a new @code{fko_ctx_t}
object, pre-populates default values and returns a handle for it in @var{ctx}.
The function returns the error code @code{FKO_SUCCESS} if the context was
@@ -577,7 +577,8 @@ if(rc != FKO_SUCCESS)
For a context that will be used for receiving and parsing an existing
@acronym{SPA} message, you will use the @code{fko_new_with_data} function:
@deftypefun int fko_new_with_data (@w{fko_ctx_t @var{*ctx}, const char @var{*data}, const char @var{*key}, const char @var{key_len}, int @var{encryption_mode}, const char @var{hmac_key}, const int @var{hmac_type}})
@deftypefun int fko_new_with_data @
(fko_ctx_t @var{*ctx}, const char @var{*data}, const char @var{*key}, const char @var{key_len}, int @var{encryption_mode}, const char @var{hmac_key}, const int @var{hmac_type})
The function @code{fko_new_with_data} sets up and initializes a new
@code{fko_ctx_t} context, but instead of initializing default values, it
@@ -698,7 +699,7 @@ the memory and resources it was using. This is especially important in
programs that process @acronym{SPA} data repeatedly (i.e. in a loop).
Failure to destroy the context can cause memory leaks in your program.
@deftypefun void fko_destroy (@w{fko_ctx_t @var{ctx}})
@deftypefun void fko_destroy (fko_ctx_t @var{ctx})
The function @code{fko_destroy} destroys the context with the handle
@var{ctx} and releases all associated resources.
@end deftypefun
@@ -845,7 +846,7 @@ return an integer representing the return status of the function. When
succesfull, they will return @code{FKO_SUCCESS}. Otherwise, an error
code value is returned.
@deftypefun int fko_set_spa_digest_type (@w{fko_ctx_t @var{ctx}, short @var{digest_type}});
@deftypefun int fko_set_spa_digest_type (fko_ctx_t @var{ctx}, short @var{digest_type});
Set the message digest type. Valid values can be found in @ref{Digests}
of this manual. If a value other than the those that are supported is given,
the function will return @code{FKO_ERROR_INVALID_DATA}.
@@ -855,7 +856,7 @@ For example:
@end example
@end deftypefun
@deftypefun int fko_set_spa_hmac_type (@w{fko_ctx_t @var{ctx}, short @var{hmac_type}});
@deftypefun int fko_set_spa_hmac_type (fko_ctx_t @var{ctx}, short @var{hmac_type});
Set the message hmac type. Valid values can be found in @ref{HMAC Digests}
of this manual. If a value other than the those that are supported is given,
the function will return @code{FKO_ERROR_INVALID_DATA}.
@@ -865,7 +866,7 @@ For example:
@end example
@end deftypefun
@deftypefun int fko_set_spa_encryption_type (@w{fko_ctx_t @var{ctx}, short @var{encrypt_type}});
@deftypefun int fko_set_spa_encryption_type (fko_ctx_t @var{ctx}, short @var{encrypt_type});
Set the encrytion algorithm to use when ecrypting the final @acronym{SPA}
data. Valid values can be found in @ref{Encryption Algorithms} of this
manual.
@@ -875,7 +876,7 @@ For example:
@end example
@end deftypefun
@deftypefun int fko_set_rand_value (@w{fko_ctx_t @var{ctx}, const char @var{*val}});
@deftypefun int fko_set_rand_value (fko_ctx_t @var{ctx}, const char @var{*val});
Set the random value portion of the spa data to the given value (@var{val}).
The given value must be a pointer to a 16-character decimal numeric string
or NULL. If the value is NULL, the function generate a new random value.
@@ -883,7 +884,7 @@ If a string value is provided, it must be a 16-character decimal string.
Otherwise, the function will return @code{FKO_ERROR_INVALID_DATA}.
@end deftypefun
@deftypefun int fko_set_username (@w{fko_ctx_t @var{ctx}, const char @var{*username}});
@deftypefun int fko_set_username (fko_ctx_t @var{ctx}, const char @var{*username});
Set the username field of the @acronym{SPA} data. If @var{username} is NULL,
libfko will first look for the environment variable @env{SPOOF_USER}
and use its value if found. Otherwise, it will try to determine the username
@@ -892,12 +893,12 @@ then fallback to the environment variables @env{LOGNAME} or @env{USER}. If
none of those work, the function will return @code{FKO_ERROR_USERNAME_UNKNOWN}.
@end deftypefun
@deftypefun int fko_set_timestamp (@w{fko_ctx_t @var{ctx}, int @var{offset}});
@deftypefun int fko_set_timestamp (fko_ctx_t @var{ctx}, int @var{offset});
Sets the timestamp value of the SPA data to the current time plus the offset
value.
@end deftypefun
@deftypefun int fko_set_spa_message_type (@w{fko_ctx_t @var{ctx}, short @var{msg_type}});
@deftypefun int fko_set_spa_message_type (fko_ctx_t @var{ctx}, short @var{msg_type});
Sets the message type for the SPA data. The choices for the
@code{spa_message_type} are listed in @ref{SPA Messages}.
For example:
@@ -906,25 +907,25 @@ For example:
@end example
@end deftypefun
@deftypefun int fko_set_spa_message (@w{fko_ctx_t @var{ctx}, const char @var{*msg_string}});
@deftypefun int fko_set_spa_message (fko_ctx_t @var{ctx}, const char @var{*msg_string});
Set the SPA message string to the given value. If this string does not
conform to the required @code{spa_nat_access} format, the function will
return @code{FKO_ERROR_INVALID_DATA}.
@end deftypefun
@deftypefun int fko_set_spa_nat_access (@w{fko_ctx_t @var{ctx}, const char @var{*nat_access}});
@deftypefun int fko_set_spa_nat_access (fko_ctx_t @var{ctx}, const char @var{*nat_access});
Set the optional SPA nat access string to the given value. If this string
does not conform to the required @code{spa_nat_access} format, the function
will return
@code{FKO_ERROR_INVALID_DATA}.
@end deftypefun
@deftypefun int fko_set_spa_server_auth (@w{fko_ctx_t @var{ctx}, const char @var{*server_auth}});
@deftypefun int fko_set_spa_server_auth (fko_ctx_t @var{ctx}, const char @var{*server_auth});
Set the optional (very seldom used) SPA server auth feature to the given
value. This parameter may become deprecated.
@end deftypefun
@deftypefun int fko_set_spa_client_timeout (@w{fko_ctx_t @var{ctx}, int @var{timeout}});
@deftypefun int fko_set_spa_client_timeout (fko_ctx_t @var{ctx}, int @var{timeout});
Sets the SPA client timeout value. If the timeout is set to a value greater
than 0, it is assumed the @code{spa_message_type} setting should be one of
the ``TIMEOUT'' variants. This function will change the @code{message_type}
@@ -932,7 +933,7 @@ to the appropriate setting if necessary. However, it is recommended you set
the correct @code{message_type} ahead of time.
@end deftypefun
@deftypefun int fko_set_spa_digest (@w{fko_ctx_t @var{ctx}});
@deftypefun int fko_set_spa_digest (fko_ctx_t @var{ctx});
Initiates a calculation (or recalculation) of the message digest hash for the
current @acronym{SPA} data. If the required data fields are not set this
function will return @code{FKO_ERROR_MISSING_ENCODED_DATA}.
@@ -941,7 +942,7 @@ as it will be called automatically by other functions during normal
processing (most notably @code{fko_spa_data_final}).
@end deftypefun
@deftypefun int fko_set_spa_hmac (@w{fko_ctx_t @var{ctx}, const char @var{*hmac_key}, const int @var{hmac_key_len}});
@deftypefun int fko_set_spa_hmac (fko_ctx_t @var{ctx}, const char @var{*hmac_key}, const int @var{hmac_key_len});
Initiates a calculation (or recalculation) of the message HMAC for the
current @acronym{SPA} data.
@strong{Note}: It should not be necessary to call this function directly
@@ -949,7 +950,7 @@ as it will be called automatically by other functions during normal
processing (most notably @code{fko_spa_data_final}).
@end deftypefun
@deftypefun int fko_set_spa_data (@w{fko_ctx_t @var{ctx}, char @var{*enc_data}});
@deftypefun int fko_set_spa_data (fko_ctx_t @var{ctx}, char @var{*enc_data});
This function is used to place encrypted @acronym{SPA} data into a newly
created empty context (i.e. with @code{fko_new}). In most cases, you would
use @code{fko_new_with_data} so you wouldn't have to take the extra step to
@@ -960,37 +961,37 @@ use this function. However, some may find a reason to do it in this way.
@noindent
@emph{GPG-specific functions:}
@deftypefun int fko_set_gpg_recipient (@w{fko_ctx_t @var{ctx}, const char @var{recipient}});
@deftypefun int fko_set_gpg_recipient (fko_ctx_t @var{ctx}, const char @var{recipient});
Sets the @acronym{GPG} key for the recipient. This would be the recipient's
public key used to encyrpt the @acronym{SPA} data. You can use the user name
("recip@@the.dest.com") or the key ID ("5EXXXXCC"). At present, multiple
recipients are not supported.
@end deftypefun
@deftypefun int fko_set_gpg_signer (@w{fko_ctx_t @var{ctx}, const char @var{signer}});
@deftypefun int fko_set_gpg_signer (fko_ctx_t @var{ctx}, const char @var{signer});
Sets the @acronym{GPG} key for signing the data. This would be the sender's
key used to sign the @acronym{SPA} data. You can use the user name or key ID.
@end deftypefun
@deftypefun int fko_set_gpg_home_dir (@w{fko_ctx_t @var{ctx}, const char @var{home_dir}});
@deftypefun int fko_set_gpg_home_dir (fko_ctx_t @var{ctx}, const char @var{home_dir});
Sets the @acronym{GPG} home directory for the current gpgme context. This
allows for using alternate keyrings, gpg configurations, etc.
@end deftypefun
@deftypefun int fko_set_gpg_signature_verify (@w{fko_ctx_t @var{ctx}, unsigned char @var{verify}});
@deftypefun int fko_set_gpg_signature_verify (fko_ctx_t @var{ctx}, unsigned char @var{verify});
Sets the verify @acronym{GPG} signature flag. When set to a true value, the
@acronym{GPG} signature is extracted and checked for validity during the
decryption/decoding phase. When set to false, no attempt is made to access
or check the signature. This flag is set to true by default.
@end deftypefun
@deftypefun int fko_set_gpg_ignore_verify_error (@w{fko_ctx_t @var{ctx}, unsigned char @var{ignore}});
@deftypefun int fko_set_gpg_ignore_verify_error (fko_ctx_t @var{ctx}, unsigned char @var{ignore});
Sets the ignore signature verify error flag. When set to a true value. Any
signature verification errors are ignored (but still captured) and the
decoding process will continue. The default value of this flag is false.
@end deftypefun
@deftypefun int fko_set_gpg_exe (@w{fko_ctx_t @var{ctx}, const char @var{gpg_exe}});
@deftypefun int fko_set_gpg_exe (fko_ctx_t @var{ctx}, const char @var{gpg_exe});
Sets the path to the @acronym{GPG} executable that @emph{gpgme} will use.
By default, @emph{libfko} forces @emph{gpgme} to use @command{gpg} in case
@emph{gpgme} was compiled to use @command{gpg2} as its default engine. You
@@ -1013,32 +1014,32 @@ an FKO error code. The value of the respective field or parmeter that is
being retrieved will placed into the variables whose addresses are passed
to the function.
@deftypefun int fko_get_spa_data (@w{fko_ctx_t @var{ctx}, char @var{**spa_data}});
@deftypefun int fko_get_spa_data (fko_ctx_t @var{ctx}, char @var{**spa_data});
Assigns the pointer to the string holding the final encrypted
@acronym{SPA} data to the address @var{spa_data} is pointing to. This is the
data that would be packaged into a packet and sent to an fwknop server.
The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_rand_value (@w{fko_ctx_t @var{ctx}, char @var{**rand_val}});
@deftypefun int fko_get_rand_value (fko_ctx_t @var{ctx}, char @var{**rand_val});
Assigns the pointer to the string holding the random 16-character decimal
number (@code{rand_val}) associated with the current context to the address
@var{rand_val} is pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_username (@w{fko_ctx_t @var{ctx}, char @var{**username}});
@deftypefun int fko_get_username (fko_ctx_t @var{ctx}, char @var{**username});
Assigns the pointer to the string holding the username associated with the
current context to the address @var{rand_val} is pointing to. The return value
is an FKO error status.
@end deftypefun
@deftypefun int fko_get_timestamp (@w{fko_ctx_t @var{ctx}, time_t @var{*timestamp}});
@deftypefun int fko_get_timestamp (fko_ctx_t @var{ctx}, time_t @var{*timestamp});
Sets the value of the @var{timestamp} variable to the timestamp value
associated with the current context. The return value is an FKO error
status.
@end deftypefun
@deftypefun int fko_get_spa_message_type (@w{fko_ctx_t @var{ctx}, short @var{*msg_type}});
@deftypefun int fko_get_spa_message_type (fko_ctx_t @var{ctx}, short @var{*msg_type});
Sets the value of the @var{msg_type} variable to the @acronym{SPA} message
type value associated with the current context. This value can be checked
against the list of valid message_types listed in @ref{SPA Messages} of this
@@ -1062,64 +1063,64 @@ manual. For example:
The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_message (@w{fko_ctx_t @var{ctx}, char @var{**spa_msg}});
@deftypefun int fko_get_spa_message (fko_ctx_t @var{ctx}, char @var{**spa_msg});
Assigns the pointer to the string holding the the fko @acronym{SPA} request
message associated with the current context to the address @var{spa_msg} is
pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_nat_access (@w{fko_ctx_t @var{ctx}, char @var{**nat_access}});
@deftypefun int fko_get_spa_nat_access (fko_ctx_t @var{ctx}, char @var{**nat_access});
Assigns the pointer to the string holding the the fko @acronym{SPA} nat access
message associated with the current context to the address @var{nat_access} is
pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_server_auth (@w{fko_ctx_t @var{ctx}, char @var{**server_auth}});
@deftypefun int fko_get_spa_server_auth (fko_ctx_t @var{ctx}, char @var{**server_auth});
Assigns the pointer to the string holding the the fko @acronym{SPA} server
auth message associated with the current context to the address
@var{server_auth} is pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_client_timeout (@w{fko_ctx_t @var{ctx}, int @var{*client_timeout}});
@deftypefun int fko_get_spa_client_timeout (fko_ctx_t @var{ctx}, int @var{*client_timeout});
Sets the value of the @var{client_timeout} variable to the client_timeout
value associated with the current context. The return value is an FKO error
status.
@end deftypefun
@deftypefun int fko_get_spa_digest_type (@w{fko_ctx_t @var{ctx}, short @var{*digest_type}});
@deftypefun int fko_get_spa_digest_type (fko_ctx_t @var{ctx}, short @var{*digest_type});
Sets the value of the @var{digest_type} variable to the digest type value
associated with the current context. This value can be checked against the
list of valid digest_types listed in @ref{Digests} of this manual. The
return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_hmac_type (@w{fko_ctx_t @var{ctx}, short @var{*hmac_type}});
@deftypefun int fko_get_spa_hmac_type (fko_ctx_t @var{ctx}, short @var{*hmac_type});
Sets the value of the @var{hmac_type} variable to the HMAC type value
associated with the current context. This value can be checked against the
list of valid hmac_types listed in @ref{HMAC Digests} of this manual. The
return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_digest (@w{fko_ctx_t @var{ctx}, char @var{**spa_digest}});
@deftypefun int fko_get_spa_digest (fko_ctx_t @var{ctx}, char @var{**spa_digest});
Assigns the pointer to the string holding the the fko @acronym{SPA} digest
value associated with the current context to the address @var{spa_digest}
is pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_hmac (@w{fko_ctx_t @var{ctx}, char @var{**spa_hmac}});
@deftypefun int fko_get_spa_hmac (fko_ctx_t @var{ctx}, char @var{**spa_hmac});
Assigns the pointer to the string holding the the fko @acronym{SPA} HMAC
value associated with the current context to the address @var{spa_hmac}
is pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_spa_encryption_type (@w{fko_ctx_t @var{ctx}, short @var{*enc_type}});
@deftypefun int fko_get_spa_encryption_type (fko_ctx_t @var{ctx}, short @var{*enc_type});
Sets the value of the @var{enc_type} variable to the encryption type value
associated with the current context. This value can be checked against the
list of valid digest_types listed in @ref{Encryption Algorithms} of this
manual. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_encoded_data (@w{fko_ctx_t @var{ctx}, char @var{**enc_msg}});
@deftypefun int fko_get_encoded_data (fko_ctx_t @var{ctx}, char @var{**enc_msg});
Assigns the pointer to the string holding the the encoded @acronym{SPA} data
(before encryption) associated with the current context to the address
@var{enc_msg} is pointing to. This is intermediate data that would not
@@ -1127,7 +1128,7 @@ normally be of use unless debugging the library. The return value is an
FKO error status.
@end deftypefun
@deftypefun int fko_get_version (@w{fko_ctx_t @var{ctx}, char @var{**fko_version}});
@deftypefun int fko_get_version (fko_ctx_t @var{ctx}, char @var{**fko_version});
Assigns the pointer to the string holding the the @acronym{SPA} version
value associated with the current context to the address @var{fko_version}
is pointing to. This is a static value for @acronym{SPA} data that is being
@@ -1140,61 +1141,61 @@ value is an FKO error status.
@noindent
@emph{GPG-specific functions:}
@deftypefun int fko_get_gpg_recipient (@w{fko_ctx_t @var{ctx}, char @var{**recipient}});
@deftypefun int fko_get_gpg_recipient (fko_ctx_t @var{ctx}, char @var{**recipient});
Assigns the pointer to the string holding the the @acronym{GPG} recipient ID
associated with the current context to the address @var{recipient} is pointing
to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_gpg_signer (@w{fko_ctx_t @var{ctx}, char @var{**signer}});
@deftypefun int fko_get_gpg_signer (fko_ctx_t @var{ctx}, char @var{**signer});
Assigns the pointer to the string holding the the @acronym{GPG} signer ID
associated with the current context to the address @var{signer} is pointing
to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_gpg_home_dir (@w{fko_ctx_t @var{ctx}, char @var{**gpg_dir}});
@deftypefun int fko_get_gpg_home_dir (fko_ctx_t @var{ctx}, char @var{**gpg_dir});
Assigns the pointer to the string holding the the @acronym{GPG} home directory
associated with the current context to the address @var{gpg_dir} is pointing
to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_gpg_signature_verify (@w{fko_ctx_t @var{ctx}, unsigned char @var{*val}});
@deftypefun int fko_get_gpg_signature_verify (fko_ctx_t @var{ctx}, unsigned char @var{*val});
Sets the value of the @var{val} variable to the current gpg_signature_verify
flag value associated with the current context. The return value is an FKO
error status.
@end deftypefun
@deftypefun int fko_get_gpg_ignore_verify_error (@w{fko_ctx_t @var{ctx}, unsigned char @var{*val}});
@deftypefun int fko_get_gpg_ignore_verify_error (fko_ctx_t @var{ctx}, unsigned char @var{*val});
Sets the value of the @var{val} variable to the current ignore_verify_error
flag value associated with the current context. The return value is an FKO
error status.
@end deftypefun
@deftypefun int fko_get_gpg_signature_id (@w{fko_ctx_t @var{ctx}, char @var{**sig_id}});
@deftypefun int fko_get_gpg_signature_id (fko_ctx_t @var{ctx}, char @var{**sig_id});
Assigns the pointer to the string holding the the @acronym{GPG} signature ID
associated with the current context to the address @var{sig_id} is pointing
to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_gpg_signature_fpr (@w{fko_ctx_t @var{ctx}, char @var{**sig_fpr}});
@deftypefun int fko_get_gpg_signature_fpr (fko_ctx_t @var{ctx}, char @var{**sig_fpr});
Assigns the pointer to the string holding the the @acronym{GPG} signature
fingerprint associated with the current context to the address @var{sig_fpr}
is pointing to. The return value is an FKO error status.
@end deftypefun
@deftypefun int fko_get_gpg_signature_summary (@w{fko_ctx_t @var{ctx}, int @var{*sig_sum}});
@deftypefun int fko_get_gpg_signature_summary (fko_ctx_t @var{ctx}, int @var{*sig_sum});
Sets the value of the @var{sig_sum} variable to the @acronym{GPG} signature
summary value associated with the current context. The return value is an FKO
error status.
@end deftypefun
@deftypefun int fko_get_gpg_signature_status (@w{fko_ctx_t @var{ctx}, int @var{*sig_stat}});
@deftypefun int fko_get_gpg_signature_status (fko_ctx_t @var{ctx}, int @var{*sig_stat});
Sets the value of the @var{sig_stat} variable to the @acronym{GPG} signature
error status value associated with the current context. The return value is an
FKO error status.
@end deftypefun
@deftypefun int fko_get_gpg_exe (@w{fko_ctx_t @var{ctx}, char @var{**gpg_exe}});
@deftypefun int fko_get_gpg_exe (fko_ctx_t @var{ctx}, char @var{**gpg_exe});
Assigns the pointer to the string holding the the @acronym{GPG} executable path
associated with the current context to the address @var{gpg_exe} is pointing
to. The return value is an FKO error status.
@@ -1219,14 +1220,14 @@ All of these functions return an integer representing the return status of
the function. When succesfull, they will return @code{FKO_SUCCESS}.
Otherwise, an error code value is returned.
@deftypefun int fko_spa_data_final (@w{fko_ctx_t @var{ctx}, char @var{*enc_key}, int @var{ken_len}, char @var{*hmac_key}, int @var{hmac_key_len}});
@deftypefun int fko_spa_data_final (fko_ctx_t @var{ctx}, char @var{*enc_key}, int @var{ken_len}, char @var{*hmac_key}, int @var{hmac_key_len});
This function is the final step in creating a complete encrypted
@acronym{SPA} data string suitable for transmission to an fwknop server.
It does require all of the requisite @acronym{SPA} data fields be set,
otherwise it will fail with an appropriate error code.
@end deftypefun
@deftypefun int fko_decrypt_spa_data (@w{fko_ctx_t @var{ctx}, char @var{*dec_key}, int @var{key_len}});
@deftypefun int fko_decrypt_spa_data (fko_ctx_t @var{ctx}, char @var{*dec_key}, int @var{key_len});
When given the correct @var{key} (password), this function decrypts, decodes,
and parses the encrypted @acronym{SPA} data that was supplied to the context
via the @code{fko_new_with_data} function that was also called without the
@@ -1235,20 +1236,20 @@ via the @code{fko_new_with_data} function that was also called without the
fields in the context for later retrieval.
@end deftypefun
@deftypefun int fko_encrypt_spa_data (@w{fko_ctx_t @var{ctx}, char @var{*enc_key}, int @var{key_len}});
@deftypefun int fko_encrypt_spa_data (fko_ctx_t @var{ctx}, char @var{*enc_key}, int @var{key_len});
Encrypts the intermediate encoded @acronym{SPA} data stored in the context.
This function will call @code{fko_encode} if necessary. It is normally not
called directly as it is called from @code{fko_spa_data_final}.
@end deftypefun
@deftypefun int fko_decode_spa_data (@w{fko_ctx_t @var{ctx}});
@deftypefun int fko_decode_spa_data (fko_ctx_t @var{ctx});
This function performs the decoding, parsing, validation of the @acronym{SPA}
data that was just decrypted. It is normally not called directly as it is
called from @code{fko_decrypt_spa_data} (which is in turn called from
@code{fko_new_with_data} if a password is supplied to it).
@end deftypefun
@deftypefun int fko_encode_spa_data (@w{fko_ctx_t @var{ctx}});
@deftypefun int fko_encode_spa_data (fko_ctx_t @var{ctx});
Performs the base64 encoding of those @acronym{SPA} data fields that
need to be encoded, performs some data validation, and calls
@code{fkp_set_spa_digest} to recompute the @acronym{SPA} message
@@ -1261,14 +1262,14 @@ called from @code{fko_encrypt_spa_data} (which is in turn called from
@noindent
@emph{GPG-specific utility functions:}
@deftypefun int fko_gpg_signature_id_match (@w{fko_ctx_t @var{ctx}, const char @var{*id}, unsigned char @var{*id_match}});
@deftypefun int fko_gpg_signature_id_match (fko_ctx_t @var{ctx}, const char @var{*id}, unsigned char @var{*id_match});
Sets the value of the @var{id_match} variable to true (1) if the value of
@var{id} matches the ID of the @acronym{GPG} signature associated with the
current context. Otherwise, @var{id_match} is set to false (0). The return
value is an FKO error status.
@end deftypefun
@deftypefun int fko_gpg_signature_fpr_match (@w{fko_ctx_t @var{ctx}, const char @var{*fpr}, unsigned char @var{*fpr_match}});
@deftypefun int fko_gpg_signature_fpr_match (fko_ctx_t @var{ctx}, const char @var{*fpr}, unsigned char @var{*fpr_match});
Sets the value of the @var{fpr_match} variable to true (1) if the value of
@var{fpr} matches the fingerprint of the @acronym{GPG} signature associated
with the current context. Otherwise, @var{fpr_match} is set to false (0).
@@ -1286,7 +1287,7 @@ success (0), or one of the non-zero values thar corresponds to a number
of possible errors. libfko provides a function to get a descriptive string
for the given error code.
@deftypefun {const char *} fko_errstr (@w{int @var{err_code}})
@deftypefun {const char *} fko_errstr (int @var{err_code})
The function @code{fko_errstr} returns a pointer to a statically
allocated string containing the descripton of the error.
@end deftypefun
@@ -1304,9 +1305,173 @@ FKO Context is not initialized
@item FKO_ERROR_MEMORY_ALLOCATION
Unable to allocate memory
@item FKO_ERROR_FILESYSTEM_OPERATION
Read/write bytes mismiatch
Read/write bytes mismatch
@item FKO_ERROR_INVALID_DATA
Args contain invalid data
@item FKO_ERROR_INVALID_DATA_CLIENT_TIMEOUT_NEGATIVE
Invalid data: negative timeout value
@item FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL
Invalid data: invalid message length
@item FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII
Invalid data: contains non-ascii characters
@item FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS
Invalid data: insufficient number of data fields
@item FKO_ERROR_INVALID_DATA_DECODE_GT_MAX_FIELDS
Invalid data: too many data fields
@item FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS
Invalid data: invalid number of fields
@item FKO_ERROR_INVALID_DATA_DECODE_ENC_MSG_LEN_MT_T_SIZE
Invalid data: decode: encoded message - digest size is not valid
@item FKO_ERROR_INVALID_DATA_DECODE_RAND_MISSING
Invalid data: decode: missing random data
@item FKO_ERROR_INVALID_DATA_DECODE_USERNAME_MISSING
Invalid data: decode: missing username
@item FKO_ERROR_INVALID_DATA_DECODE_USERNAME_TOOBIG
Invalid data: decode: username to large
@item FKO_ERROR_INVALID_DATA_DECODE_USERNAME_DECODEFAIL
Invalid data: decode: failed to decode username
@item FKO_ERROR_INVALID_DATA_DECODE_USERNAME_VALIDFAIL
Invalid data: decode: invalid username
@item FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_MISSING
Invalid data: decode: missing timestamp
@item FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_TOOBIG
Invalid data: decode: timestamp too large
@item FKO_ERROR_INVALID_DATA_DECODE_TIMESTAMP_DECODEFAIL
Invalid data: decode: failed to decode timestamp
@item FKO_ERROR_INVALID_DATA_DECODE_VERSION_MISSING
Invalid data: decode: missing version data
@item FKO_ERROR_INVALID_DATA_DECODE_VERSION_TOOBIG
Invalid data: decode: version data is too large
@item FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING
Invalid data: decode: missing message type
@item FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG
Invalid data: decode: message type is too large
@item FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL
Invalid data: decode: failed to decode message type
@item FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_MISSING
Invalid data: decode: missing message data
@item FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_TOOBIG
Invalid data: decode: message data is too large
@item FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_DECODEFAIL
Invalid data: decode: failed to decode message data
@item FKO_ERROR_INVALID_DATA_DECODE_MESSAGE_VALIDFAIL
Invalid data: decode: invalid message data
@item FKO_ERROR_INVALID_DATA_DECODE_ACCESS_VALIDFAIL
Invalid data: decode: invliad access data
@item FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_MISSING
Invalid data: decode: missing NAT access data
@item FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_TOOBIG
Invalid data: decode: NAT access data is too large
@item FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_DECODEFAIL
Invalid data: decode: failed to decode NAT access data
@item FKO_ERROR_INVALID_DATA_DECODE_NATACCESS_VALIDFAIL
Invalid data: decode: invalid NAT access
@item FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING
Invalid data: decode: missing server auth
@item FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL
Invalid data: decode: server auth decode fail
@item FKO_ERROR_INVALID_DATA_DECODE_SPA_EXTRA_TOOBIG
Invalid data: decode: SPA extra too large
@item FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG
Invalid data: decode: extra too large
@item FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL
Invalid data: decode: extra decode failed
@item FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_MISSING
Invalid data: decode: missing timeout
@item FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_TOOBIG
Invalid data: decode timeout value is too large
@item FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_VALIDFAIL
Invalid data: decode invalid timeout
@item FKO_ERROR_INVALID_DATA_DECODE_TIMEOUT_DECODEFAIL
Invalid data: decode: timeout decode failed
@item FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG
Invalid data: encode: message is too large
@item FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL
Invalid data: encode: invalid message length
@item FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL
Invalid data: encode: invalid digest
@item FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG
Invalid data: encode: digest is too large
@item FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64
Invalid data: encoded data is not Base64
@item FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL
Invalid data: encrypt: invalid message length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL
Invalid data: encrypt: invalid digest length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL
Invalid data: encrypt: invalid plaintext length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL
Invalid data: encrypt: invalid encrypt result message length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL
Invalid data: encrypt: decode cipher length failed
@item FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL
Invalid data: encrypt: invalid cipher length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING
Invalid data: encrypt: missing decrypted message
@item FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL
Invalid data: encrypt: invalid decrypted message length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL
Invalid data: encrypt: invalid encryption type
@item FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL
Invalid data: encrypt: invalid encryption mode
@item FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN
Invalid data: encrypt: unknown encryption type
@item FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING
Invalid data: missing encoded message
@item FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL
Invalid data: invalid message length from new
@item FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL
Invalid data: invalid key length from gen_keylen
@item FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL
Invalid data: gen_hmaclen failure
@item FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL
Invalid data: gen_key: encode failure
@item FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL
Invalid data: gen_hmac: encode failure
@item FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL
Invalid data: set_spa_data: invalid message length
@item FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL
Invalid data: invalid HMAC msglen
@item FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL
Invalid data: invalid length for encrypted message
@item FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL
Invalid data: HMAC comparison failed
@item FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL
Invalid data: invalid HMAC type
@item FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL
Invalid data: invalid HMAC length
@item FKO_ERROR_INVALID_DATA_MESSAGE_PORT_MISSING
Invalid data: missing port
@item FKO_ERROR_INVALID_DATA_MESSAGE_TYPE_VALIDFAIL
Invalid data: invalid message type
@item FKO_ERROR_INVALID_DATA_MESSAGE_EMPTY
Invalid data: empty data message
@item FKO_ERROR_INVALID_DATA_MESSAGE_CMD_MISSING
Invalid data: missing command message
@item FKO_ERROR_INVALID_DATA_MESSAGE_ACCESS_MISSING
Invalid data: missing access message
@item FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING
Invalid data: missing NAT data
@item FKO_ERROR_INVALID_DATA_MESSAGE_PORTPROTO_MISSING
Invalid data: missing proto/port data
@item FKO_ERROR_INVALID_DATA_NAT_EMPTY
Invalid data: empty NAT value
@item FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL
Invalid data: invalid random data length
@item FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING
Invalid data: server auth missing
@item FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL
Invalid data: invalid timestamp value
@item FKO_ERROR_INVALID_DATA_USER_MISSING
Invalid data: missing user data
@item FKO_ERROR_INVALID_DATA_USER_FIRSTCHAR_VALIDFAIL
Invalid data: user first char not valid
@item FKO_ERROR_INVALID_DATA_USER_REMCHAR_VALIDFAIL
Invalid data: user remchar not valid
@item FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN
Invalid data: util conversion to long less than minimum
@item FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX
Invalid data: util conversion to long greater than maximum
@item FKO_ERROR_DATA_TOO_LARGE
Value or Size of the data exceeded the max allowed
@item FKO_ERROR_INVALID_KEY_LEN
@@ -1343,6 +1508,8 @@ Invalid HMAC key length
Unsupported HMAC mode (default: SHA256)
@item FKO_ERROR_UNSUPPORTED_FEATURE
Unsupported or unimplemented feature or function
@item FKO_ERROR_ZERO_OUT_DATA
Could not zero out sensitive data
@item FKO_ERROR_UNKNOWN
Unknown/Unclassified error
@end table
@@ -1406,6 +1573,20 @@ Missing GPG signature
Bad GPG signature
@item FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED
Trying to check signature with verification disabled
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL
Invalid data: encrypt: invalid GPG-encrypt message
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL
Invalid data: encrypt: invalid GPG digest
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL
Invalid data: encrypt: invalid GPG message length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL
Invalid data: encrypt: invalid GPG result message length
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL
Invalid data: encrypt: GPG cipher failed
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSG_NULL
Invalid data: encrypt: GPG-encoded message is NULL
@item FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_ENCODEDMSGLEN_VALIDFAIL
Invalid data: encrypt: invalid GPG-encrypted message length
@end table
@end deftypevar
@@ -1416,7 +1597,7 @@ using the following function:
@cindex gpg-specific functions
@deftypefun {const char *} fko_gpg_errstr (@w{int @var{err_code}})
@deftypefun {const char *} fko_gpg_errstr (int @var{err_code})
The function @code{fko_errstr} returns a pointer to a statically
allocated string containing the descripton of the @acronym{GPGME} error.
@end deftypefun
+1 -1
View File
@@ -7,7 +7,7 @@
#
if [ -x ./configure ]; then
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var $@
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/run $@
else
echo "[*] Execute from the fwknop top level sources directory"
fi
+1 -1
View File
@@ -1,6 +1,6 @@
# Last Modified: Sun Aug 18 22:54:57 2013
# Assumes fwknopd was built with:
# './configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var'
# './configure --prefix=/usr --sysconfdir=/etc --localstatedir=/run'
#include <tunables/global>
/usr/sbin/fwknopd {
+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
while read line; do
line=$(echo "$line" | sed 's:#.*$::g')
if [ "$(echo $line | grep -c 'SOURCE')" -ne "0" ]
then
source=$line
if [ -n "$qr" ]
then
echo $'\n\n'$source
qrencode -o - -t UTF8 "$qr"
qr=""
fi
fi
if [ "$(echo $line | grep -c 'KEY')" -ne "0" ]
then
trline="$(echo $line | sed 's/^[ \t]*//;s/[ \t]*$//' | sed 's/ /:/')"
qr="$qr$trline "
fi
done
if [ -n "$qr" ]
then
echo $'\n\n'$source
qrencode -o - -t UTF8 "$qr"
fi
+2 -1
View File
@@ -1,7 +1,8 @@
#!/bin/sh +x
make clean
export PATH=$PATH:/home/mbr/coverity/cov-analysis-linux64-7.5.0/bin
./extras/apparmor/configure_args.sh
export PATH=$PATH:/home/mbr/coverity/cov-analysis-linux64-7.7.0/bin
cov-build --dir cov-int make
tar cvfz fwknop.tgz cov-int
+13
View File
@@ -0,0 +1,13 @@
diff --git a/configure.ac b/configure.ac
index 8fadbfb..87d5ffb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -150,7 +150,7 @@ AC_ARG_ENABLE([libfiu-support],
if test "x$want_libfiu_support" = "xyes"; then
AC_DEFINE([HAVE_LIBFIU], [1], [Define for fault injection testing support])
FKO_CHECK_COMPILER_ARG([-DFIU_ENABLE])
- FKO_CHECK_COMPILER_ARG_LDFLAGS_ONLY([-lfiu])
+ FKO_CHECK_COMPILER_ARG_LDFLAGS_ONLY([-pthread -lfiu -ldl])
fi
dnl Decide whether or not to enable C unit testing
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh -x
#
# This script creates a ramdisk and clones the fwknop git repository
# into it. This is meant for AFL fuzzing cycles.
#
### 1GB
RSIZE=2097152
LABEL="ramdisk-for-fwknop"
RAMDISK=/Volumes/$LABEL
if [ -d $RAMDISK ]
then
echo "[*] $RAMDISK mount point already exists"
exit 1
fi
if [ -f extras/ramdisk/ramdisk-create-osx.sh ]
then
diskutil erasevolume HFS+ "$LABEL" `hdiutil attach -nomount ram://$RSIZE`
git clone . $RAMDISK/fwknop.git
else
echo "[*] Run this script from the top level fwknop sources directory"
exit 1
fi
exit $?
+26
View File
@@ -0,0 +1,26 @@
#!/bin/sh -x
#
# This script creates a ramdisk and clones the fwknop git repository
# into it. This is meant for AFL fuzzing cycles.
#
RSIZE=768M
RAMDISK=/tmp/afl-ramdisk
if [ -d $RAMDISK ]
then
echo "[*] $RAMDISK directory already exists"
exit 1
fi
if [ -f extras/ramdisk/ramdisk-create.sh ]
then
mkdir $RAMDISK && chmod 777 $RAMDISK
mount -t tmpfs -o size=$RSIZE tmpfs $RAMDISK
git clone . $RAMDISK/fwknop.git
else
echo "[*] Run this script from the top level fwknop sources directory"
exit 1
fi
exit $?
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh -x
#
# In some cases when enabling Google's Address Sanitizer, errors like the
# following can be generated. This script provides a workaround.
#
# fwknop-spa_comm.o: In function `send_spa_packet_http':
# /home/mbr/git/fwknop.git/client/spa_comm.c:516: undefined reference to `rpl_malloc'
# ../lib/.libs/libfko.so: undefined reference to `rpl_realloc'
#
if [ -x ./configure ]; then
export ac_cv_func_malloc_0_nonnull=yes
export ac_cv_func_realloc_0_nonnull=yes
./autogen.sh
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/run --enable-asan-support $@
make clean
make
else
echo "[*] Execute from the fwknop top level sources directory"
fi
+12
View File
@@ -0,0 +1,12 @@
[Unit]
Description=Firewall Knock Operator Daemon
After=network-online.target
[Service]
Type=forking
PIDFile=/run/fwknop/fwknopd.pid
ExecStart=/usr/sbin/fwknopd
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
+1
View File
@@ -0,0 +1 @@
d /run/fwknop 0700 root root -
+11 -5
View File
@@ -8,15 +8,15 @@
%define _libdir /usr/lib
%endif
%define _sysconfdir /etc
%define _localstatedir /var
%define _localstatedir /var/run
%define _infodir /usr/share/info
%define _mandir /usr/share/man
Name: fwknop
Version: 2.6.5
Version: 2.6.7
Epoch: 1
Release: 1%{?dist}
Summary: Firewall Knock Operator client. An implementation of Single Packet Authorization.
Summary: Firewall Knock Operator client. An implementation of Single Packet Authorization.
Group: Applications/Internet
License: GPL
@@ -43,14 +43,14 @@ Group: Development/Libraries
Requires: libfko >= 2.0.3
%package server
Summary: The Firewall Knock Operator server. An implementation of Single Packet Authorization.
Summary: The Firewall Knock Operator server. An implementation of Single Packet Authorization.
Group: System Environment/Daemons
Requires: libfko => 2.0.3, libpcap, iptables
%description
Fwknop implements an authorization scheme known as Single Packet Authorization
(SPA) for Linux systems running firewalld or iptables. This mechanism requires
(SPA) for Linux systems running firewalld or iptables. This mechanism requires
only a single encrypted and non-replayed packet to communicate various pieces of
information including desired access through a firewalld or iptables policy. The
main application of this program is to use firewalld or iptables in a default-drop
@@ -142,6 +142,12 @@ fi
%config(noreplace) %attr(0600,root,root) %{_sysconfdir}/fwknop/access.conf
%changelog
* Mon Aug 24 2015 <mbr@cipherdyne.org> - 2.6.7
- fwknop-2.6.7 release.
* Tue Apr 23 2015 <mbr@cipherdyne.org> - 2.6.6
- fwknop-2.6.6 release.
* Tue Dec 16 2014 <mbr@cipherdyne.org> - 2.6.5
- fwknop-2.6.5 release.
-6
View File
@@ -124,12 +124,6 @@ verify_digest(char *tbuf, int t_size, fko_ctx_t ctx)
static int
is_valid_digest_len(int t_size, fko_ctx_t ctx)
{
#if AFL_FUZZING
ctx->digest_type = FKO_DIGEST_SHA256;
ctx->digest_len = t_size;
return FKO_SUCCESS;
#endif
switch(t_size)
{
case MD5_B64_LEN:
+1 -1
View File
@@ -107,7 +107,7 @@ my_passphrase_cb(
/* Verify gpg signatures in a verify_result set.
*/
int
static int
process_sigs(fko_ctx_t fko_ctx, gpgme_verify_result_t vres)
{
unsigned int sig_cnt = 0;
+129 -39
View File
@@ -76,6 +76,58 @@ add_acc_string(char **var, const char *val)
return SUCCESS;
}
/* Add an access user entry
*/
static int
add_acc_user(char **user_var, uid_t *uid_var, struct passwd *upw,
const char *val, const char *var_name)
{
struct passwd *pw = NULL;
if(add_acc_string(user_var, val) != SUCCESS)
return FATAL_ERR;
errno = 0;
upw = pw = getpwnam(val);
if(upw == NULL || pw == NULL)
{
log_msg(LOG_ERR, "[*] Unable to determine UID for %s: %s.",
var_name, errno ? strerror(errno) : "Not a user on this system");
return FATAL_ERR;
}
*uid_var = pw->pw_uid;
return SUCCESS;
}
/* Add an access group entry
*/
static int
add_acc_group(char **group_var, gid_t *gid_var,
const char *val, const char *var_name)
{
struct passwd *pw = NULL;
if(add_acc_string(group_var, val) != SUCCESS)
return FATAL_ERR;
errno = 0;
pw = getpwnam(val);
if(pw == NULL)
{
log_msg(LOG_ERR, "[*] Unable to determine GID for %s: %s.",
var_name, errno ? strerror(errno) : "Not a group on this system");
return FATAL_ERR;
}
*gid_var = pw->pw_gid;
return SUCCESS;
}
/* Decode base64 encoded string into access entry
*/
static int
@@ -754,7 +806,7 @@ free_acc_stanza_data(acc_stanza_t *acc)
free(acc->source);
free_acc_int_list(acc->source_list);
}
if(acc->destination != NULL)
{
free(acc->destination);
@@ -803,6 +855,12 @@ free_acc_stanza_data(acc_stanza_t *acc)
free(acc->hmac_key_base64);
}
if(acc->cmd_sudo_exec_user != NULL)
free(acc->cmd_sudo_exec_user);
if(acc->cmd_sudo_exec_group != NULL)
free(acc->cmd_sudo_exec_group);
if(acc->cmd_exec_user != NULL)
free(acc->cmd_exec_user);
@@ -1077,7 +1135,9 @@ set_acc_defaults(fko_srv_options_t *opts)
/* Perform some sanity checks on an acc stanza data.
*/
static int
acc_data_is_valid(struct passwd *user_pw, acc_stanza_t * const acc)
acc_data_is_valid(fko_srv_options_t *opts,
struct passwd *user_pw, struct passwd *sudo_user_pw,
acc_stanza_t * const acc)
{
if(acc == NULL)
{
@@ -1139,15 +1199,24 @@ acc_data_is_valid(struct passwd *user_pw, acc_stanza_t * const acc)
}
}
#if defined(FIREWALL_FIREWALLD) || defined(FIREWALL_IPTABLES)
if((acc->force_snat == 1 || acc->force_masquerade == 1)
&& acc->force_nat == 0 && acc->disable_dnat == 0)
&& acc->force_nat == 0)
{
log_msg(LOG_ERR,
"[*] FORCE_SNAT/FORCE_MASQUERADE implies FORCE_NAT or DISABLE_DNAT must also be used for stanza source: '%s'",
acc->source
);
return(0);
if(acc->forward_all == 1)
{
add_acc_force_nat(opts, acc, "0.0.0.0 0");
}
else
{
log_msg(LOG_ERR,
"[*] FORCE_SNAT/FORCE_MASQUERADE requires either FORCE_NAT or FORWARD_ALL: '%s'",
acc->source
);
return(0);
}
}
#endif
if(acc->require_source_address == 0)
{
@@ -1167,6 +1236,17 @@ acc_data_is_valid(struct passwd *user_pw, acc_stanza_t * const acc)
acc->cmd_exec_gid = user_pw->pw_gid;
}
if(sudo_user_pw != NULL
&& acc->cmd_sudo_exec_uid != 0 && acc->cmd_sudo_exec_gid == 0)
{
log_msg(LOG_INFO,
"Setting gid to group associated with CMD_SUDO_EXEC_USER '%s' in stanza source: '%s'",
acc->cmd_exec_user,
acc->source
);
acc->cmd_sudo_exec_gid = sudo_user_pw->pw_gid;
}
return(1);
}
@@ -1184,8 +1264,8 @@ parse_access_file(fko_srv_options_t *opts)
char var[MAX_LINE_LEN] = {0};
char val[MAX_LINE_LEN] = {0};
struct passwd *pw = NULL;
struct passwd *user_pw = NULL;
struct passwd *sudo_user_pw = NULL;
struct stat st;
acc_stanza_t *curr_acc = NULL;
@@ -1284,7 +1364,7 @@ parse_access_file(fko_srv_options_t *opts)
* stanza for the minimum required data.
*/
if(curr_acc != NULL) {
if(!acc_data_is_valid(user_pw, curr_acc))
if(!acc_data_is_valid(opts, user_pw, sudo_user_pw, curr_acc))
{
log_msg(LOG_ERR, "[*] Data error in access file: '%s'",
opts->config[CONF_ACCESS_FILE]);
@@ -1471,47 +1551,49 @@ parse_access_file(fko_srv_options_t *opts)
{
add_acc_bool(&(curr_acc->enable_cmd_exec), val);
}
else if(CONF_VAR_IS(var, "ENABLE_CMD_SUDO_EXEC"))
{
add_acc_bool(&(curr_acc->enable_cmd_sudo_exec), val);
}
else if(CONF_VAR_IS(var, "CMD_SUDO_EXEC_USER"))
{
if(add_acc_user(&(curr_acc->cmd_sudo_exec_user),
&(curr_acc->cmd_sudo_exec_uid), sudo_user_pw,
val, "CMD_SUDO_EXEC_USER") != SUCCESS)
{
fclose(file_ptr);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
}
else if(CONF_VAR_IS(var, "CMD_SUDO_EXEC_GROUP"))
{
if(add_acc_group(&(curr_acc->cmd_sudo_exec_group),
&(curr_acc->cmd_sudo_exec_gid), val,
"CMD_SUDO_EXEC_GROUP") != SUCCESS)
{
fclose(file_ptr);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
}
else if(CONF_VAR_IS(var, "CMD_EXEC_USER"))
{
if(add_acc_string(&(curr_acc->cmd_exec_user), val) != SUCCESS)
if(add_acc_user(&(curr_acc->cmd_exec_user),
&(curr_acc->cmd_exec_uid), user_pw,
val, "CMD_EXEC_USER") != SUCCESS)
{
fclose(file_ptr);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
errno = 0;
user_pw = pw = getpwnam(val);
if(pw == NULL)
{
log_msg(LOG_ERR, "[*] Unable to determine UID for CMD_EXEC_USER: %s.",
errno ? strerror(errno) : "Not a user on this system");
fclose(file_ptr);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
curr_acc->cmd_exec_uid = pw->pw_uid;
}
else if(CONF_VAR_IS(var, "CMD_EXEC_GROUP"))
{
if(add_acc_string(&(curr_acc->cmd_exec_group), val) != SUCCESS)
if(add_acc_group(&(curr_acc->cmd_exec_group),
&(curr_acc->cmd_exec_gid), val,
"CMD_SUDO_EXEC_GROUP") != SUCCESS)
{
fclose(file_ptr);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
errno = 0;
pw = getpwnam(val);
if(pw == NULL)
{
log_msg(LOG_ERR, "[*] Unable to determine GID for CMD_EXEC_GROUP: %s.",
errno ? strerror(errno) : "Not a group on this system");
fclose(file_ptr);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
curr_acc->cmd_exec_gid = pw->pw_gid;
}
else if(CONF_VAR_IS(var, "REQUIRE_USERNAME"))
{
@@ -1746,7 +1828,7 @@ parse_access_file(fko_srv_options_t *opts)
/* Sanity check the last stanza
*/
if(!acc_data_is_valid(user_pw, curr_acc))
if(!acc_data_is_valid(opts, user_pw, sudo_user_pw, curr_acc))
{
log_msg(LOG_ERR,
"[*] Data error in access file: '%s'",
@@ -1947,7 +2029,11 @@ dump_access_list(const fko_srv_options_t *opts)
" HMAC_DIGEST_TYPE: %d\n"
" FW_ACCESS_TIMEOUT: %i\n"
" ENABLE_CMD_EXEC: %s\n"
" ENABLE_CMD_SUDO_EXEC: %s\n"
" CMD_SUDO_EXEC_USER: %s\n"
" CMD_SUDO_EXEC_GROUP: %s\n"
" CMD_EXEC_USER: %s\n"
" CMD_EXEC_GROUP: %s\n"
" REQUIRE_USERNAME: %s\n"
" REQUIRE_SOURCE_ADDRESS: %s\n"
" FORCE_NAT (ip): %s\n"
@@ -1980,7 +2066,11 @@ dump_access_list(const fko_srv_options_t *opts)
acc->hmac_type,
acc->fw_access_timeout,
acc->enable_cmd_exec ? "Yes" : "No",
acc->enable_cmd_sudo_exec ? "Yes" : "No",
(acc->cmd_sudo_exec_user == NULL) ? "<not set>" : acc->cmd_sudo_exec_user,
(acc->cmd_sudo_exec_group == NULL) ? "<not set>" : acc->cmd_sudo_exec_group,
(acc->cmd_exec_user == NULL) ? "<not set>" : acc->cmd_exec_user,
(acc->cmd_exec_group == NULL) ? "<not set>" : acc->cmd_exec_group,
(acc->require_username == NULL) ? "<not set>" : acc->require_username,
acc->require_source_address ? "Yes" : "No",
acc->force_nat ? acc->force_nat_ip : "<not set>",
+15 -1
View File
@@ -48,10 +48,12 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"PCAP_DISPATCH_COUNT",
"PCAP_LOOP_SLEEP",
"ENABLE_PCAP_ANY_DIRECTION",
"EXIT_AT_INTF_DOWN",
"MAX_SNIFF_BYTES",
"ENABLE_SPA_PACKET_AGING",
"MAX_SPA_PACKET_AGE",
"ENABLE_DIGEST_PERSISTENCE",
"RULES_CHECK_THRESHOLD",
"CMD_EXEC_TIMEOUT",
//"BLACKLIST",
"ENABLE_SPA_OVER_HTTP",
@@ -126,6 +128,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
#endif
"GPG_HOME_DIR",
"GPG_EXE",
"SUDO_EXE",
"FIREWALL_EXE",
"VERBOSE",
#if AFL_FUZZING
@@ -141,9 +144,14 @@ enum {
FW_LIST = 0x200,
FW_LIST_ALL,
FW_FLUSH,
KEY_GEN_FILE,
KEY_LEN,
HMAC_KEY_LEN,
HMAC_DIGEST_TYPE,
AFL_PKT_FILE,
GPG_HOME_DIR,
GPG_EXE_PATH,
SUDO_EXE_PATH,
FIREWD_DISABLE_CHECK_SUPPORT,
IPT_DISABLE_CHECK_SUPPORT,
PCAP_FILE,
@@ -178,7 +186,12 @@ static struct option cmd_opts[] =
{"fault-injection-tag", 1, NULL, FAULT_INJECTION_TAG},
{"help", 0, NULL, 'h'},
{"interface", 1, NULL, 'i'},
{"kill", 0, NULL, 'K'},
{"key-gen", 0, NULL, 'k'},
{"key-gen-file", 1, NULL, KEY_GEN_FILE },
{"key-len", 1, NULL, KEY_LEN },
{"hmac-key-len", 1, NULL, HMAC_KEY_LEN },
{"hmac-digest-type", 1, NULL, HMAC_DIGEST_TYPE },
{"kill", 0, NULL, 'K' },
{"fw-flush", 0, NULL, FW_FLUSH },
{"fw-list", 0, NULL, FW_LIST },
{"fw-list-all", 0, NULL, FW_LIST_ALL },
@@ -196,6 +209,7 @@ static struct option cmd_opts[] =
{"run-dir", 1, NULL, 'r'},
{"restart", 0, NULL, 'R'},
{"status", 0, NULL, 'S'},
{"sudo-exe", 1, NULL, SUDO_EXE_PATH },
{"test", 0, NULL, 't'},
{"udp-server", 0, NULL, 'U'},
{"verbose", 0, NULL, 'v'},
+184 -11
View File
@@ -149,6 +149,8 @@ validate_int_var_ranges(fko_srv_options_t *opts)
1, RCHK_MAX_SPA_PACKET_AGE);
range_check(opts, "MAX_SNIFF_BYTES", opts->config[CONF_MAX_SNIFF_BYTES],
1, RCHK_MAX_SNIFF_BYTES);
range_check(opts, "RULES_CHECK_THRESHOLD", opts->config[CONF_RULES_CHECK_THRESHOLD],
0, RCHK_MAX_RULES_CHECK_THRESHOLD);
range_check(opts, "TCPSERV_PORT", opts->config[CONF_TCPSERV_PORT],
1, RCHK_MAX_TCPSERV_PORT);
range_check(opts, "UDPSERV_PORT", opts->config[CONF_UDPSERV_PORT],
@@ -201,6 +203,69 @@ validate_int_var_ranges(fko_srv_options_t *opts)
return;
}
/**
* @brief Generate Rijndael + HMAC keys from /dev/urandom (base64 encoded).
*
* @param options FKO command line option structure
*/
static void
generate_keys(fko_srv_options_t *options)
{
char key_base64[MAX_B64_KEY_LEN+1];
char hmac_key_base64[MAX_B64_KEY_LEN+1];
FILE *key_gen_file_ptr = NULL;
int res;
/* Set defaults and validate for --key-gen mode
*/
if(options->key_len == 0)
options->key_len = FKO_DEFAULT_KEY_LEN;
if(options->hmac_key_len == 0)
options->hmac_key_len = FKO_DEFAULT_HMAC_KEY_LEN;
if(options->hmac_type == 0)
options->hmac_type = FKO_DEFAULT_HMAC_MODE;
/* Zero out the key buffers */
memset(key_base64, 0x00, sizeof(key_base64));
memset(hmac_key_base64, 0x00, sizeof(hmac_key_base64));
/* Generate the key through libfko */
res = fko_key_gen(key_base64, options->key_len,
hmac_key_base64, options->hmac_key_len,
options->hmac_type);
if(res != FKO_SUCCESS)
{
log_msg(LOG_ERR, "%s: fko_key_gen: Error %i - %s",
MY_NAME, res, fko_errstr(res));
clean_exit(options, NO_FW_CLEANUP, EXIT_FAILURE);
}
if(options->key_gen_file[0] != '\0')
{
if ((key_gen_file_ptr = fopen(options->key_gen_file, "w")) == NULL)
{
log_msg(LOG_ERR, "Unable to create key gen file: %s: %s",
options->key_gen_file, strerror(errno));
clean_exit(options, NO_FW_CLEANUP, EXIT_FAILURE);
}
fprintf(key_gen_file_ptr, "KEY_BASE64: %s\nHMAC_KEY_BASE64: %s\n",
key_base64, hmac_key_base64);
fclose(key_gen_file_ptr);
fprintf(stdout, "[+] Wrote Rijndael and HMAC keys to: %s",
options->key_gen_file);
}
else
{
fprintf(stdout, "KEY_BASE64: %s\nHMAC_KEY_BASE64: %s\n",
key_base64, hmac_key_base64);
}
clean_exit(options, NO_FW_CLEANUP, EXIT_SUCCESS);
}
/* Parse the config file...
*/
static void
@@ -394,6 +459,13 @@ validate_options(fko_srv_options_t *opts)
set_config_entry(opts, CONF_PCAP_LOOP_SLEEP,
DEF_PCAP_LOOP_SLEEP);
/* Control whether to exit if the interface where we're sniffing
* goes down.
*/
if(opts->config[CONF_EXIT_AT_INTF_DOWN] == NULL)
set_config_entry(opts, CONF_EXIT_AT_INTF_DOWN,
DEF_EXIT_AT_INTF_DOWN);
/* PCAP Filter.
*/
if(opts->config[CONF_PCAP_FILTER] == NULL)
@@ -421,13 +493,20 @@ validate_options(fko_srv_options_t *opts)
set_config_entry(opts, CONF_MAX_SPA_PACKET_AGE,
DEF_MAX_SPA_PACKET_AGE);
/* Enable digest persistence.
*/
if(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE] == NULL)
set_config_entry(opts, CONF_ENABLE_DIGEST_PERSISTENCE,
DEF_ENABLE_DIGEST_PERSISTENCE);
/* Set firewall rule "deep" collection interval - this allows
* fwknopd to remove rules with proper _exp_<time> expiration
* times even when added by a different program.
*/
if(opts->config[CONF_RULES_CHECK_THRESHOLD] == NULL)
set_config_entry(opts, CONF_RULES_CHECK_THRESHOLD,
DEF_RULES_CHECK_THRESHOLD);
/* Enable destination rule.
*/
if(opts->config[CONF_ENABLE_DESTINATION_RULE] == NULL)
@@ -801,6 +880,11 @@ validate_options(fko_srv_options_t *opts)
if(opts->config[CONF_GPG_EXE] == NULL)
set_config_entry(opts, CONF_GPG_EXE, DEF_GPG_EXE);
/* sudo executable
*/
if(opts->config[CONF_SUDO_EXE] == NULL)
set_config_entry(opts, CONF_SUDO_EXE, DEF_SUDO_EXE);
/* Enable SPA over HTTP.
*/
if(opts->config[CONF_ENABLE_SPA_OVER_HTTP] == NULL)
@@ -926,10 +1010,72 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
*/
optind = 0;
/* First, scan the command-line args for -h/--help or an alternate
/* First, scan the command-line args to see if we are in key-generation
* mode. This is independent of config parsing and other operations, so
* it is done as the very first thing. Also handle printing of the fwknop
* version string since we don't need to parse a config for this.
*/
while ((cmd_arg = getopt_long(argc, argv,
GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
switch(cmd_arg) {
case 'V':
fprintf(stdout, "fwknopd server %s, compiled for firewall bin: %s\n",
MY_VERSION, FIREWALL_EXE);
clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
case 'k':
opts->key_gen = 1;
break;
case KEY_GEN_FILE:
opts->key_gen = 1;
strlcpy(opts->key_gen_file, optarg, sizeof(opts->key_gen_file));
break;
case KEY_LEN: /* used in --key-gen mode only */
opts->key_len = strtol_wrapper(optarg, 1,
MAX_KEY_LEN, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR,
"Invalid key length '%s', must be in [%d-%d]",
optarg, 1, MAX_KEY_LEN);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case HMAC_DIGEST_TYPE: /* used in --key-gen mode only */
if((opts->hmac_type = hmac_digest_strtoint(optarg)) < 0)
{
log_msg(LOG_ERR,
"* Invalid hmac digest type: %s, use {md5,sha1,sha256,sha384,sha512}",
optarg);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case HMAC_KEY_LEN: /* used in --key-gen mode only */
opts->hmac_key_len = strtol_wrapper(optarg, 1,
MAX_KEY_LEN, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR,
"Invalid hmac key length '%s', must be in [%d-%d]",
optarg, 1, MAX_KEY_LEN);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
}
}
if(opts->key_gen)
generate_keys(opts); /* this function exits */
/* Reset the options index so we can run through them again.
*/
optind = 0;
/* Now, scan the command-line args for -h/--help or an alternate
* configuration file. If we find an alternate config file, use it,
* otherwise use the default. We also grab any override config files
* as well.
* otherwise use the default. We also grab any override config files
* as well. In addition, we handle key generation here since this is
* independent of configuration parsing.
*/
while ((cmd_arg = getopt_long(argc, argv,
GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
@@ -1108,6 +1254,19 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
case FW_FLUSH:
opts->fw_flush = 1;
break;
case GPG_EXE_PATH:
if (is_valid_exe(optarg))
{
set_config_entry(opts, CONF_GPG_EXE, optarg);
}
else
{
log_msg(LOG_ERR,
"[*] gpg path '%s' could not stat()/not executable?",
optarg);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case GPG_HOME_DIR:
if (is_valid_dir(optarg))
{
@@ -1116,7 +1275,7 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
else
{
log_msg(LOG_ERR,
"[*] Directory '%s' could not stat()/does not exist?",
"[*] gpg home directory '%s' could not stat()/does not exist?",
optarg);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
@@ -1163,6 +1322,19 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
case 'S':
opts->status = 1;
break;
case SUDO_EXE_PATH:
if (is_valid_exe(optarg))
{
set_config_entry(opts, CONF_SUDO_EXE, optarg);
}
else
{
log_msg(LOG_ERR,
"[*] sudo path '%s' could not stat()/not executable?",
optarg);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case 't':
opts->test = 1;
break;
@@ -1176,9 +1348,6 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
case SYSLOG_ENABLE:
opts->syslog_enable = 1;
break;
case 'V':
fprintf(stdout, "fwknopd server %s\n", MY_VERSION);
clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
default:
usage();
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
@@ -1242,6 +1411,8 @@ usage(void)
" override the PCAP_FILTER variable 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 the file\n"
" to the same path with the -old suffix.\n"
" -r, --run-dir - Set path to local state run directory.\n"
" - Rotate the digest cache file by renaming it to\n"
" '<name>-old', and starting a new one.\n"
@@ -1253,8 +1424,8 @@ usage(void)
" --syslog-enable - Allow messages to be sent to syslog even if the\n"
" foreground mode is set.\n"
" -V, --version - Print version number.\n"
" -A, --afl-fuzzing - Run in American Fuzzy Lop (AFL) fuzzing mode\n"
" plaintext SPA packets are accepted via stdin.\n"
" -A, --afl-fuzzing - Run in American Fuzzy Lop (AFL) fuzzing mode so\n"
" that plaintext SPA packets are accepted via stdin.\n"
" -h, --help - Print this usage message and exit.\n"
" --dump-serv-err-codes - List all server error codes (only needed by the\n"
" test suite).\n"
@@ -1277,6 +1448,8 @@ usage(void)
" done in the access.conf file).\n"
" --gpg-exe - Specify the path to GPG (this is normally done in\n"
" the access.conf file).\n"
" --sudo-exe - Specify the path to sudo (the default path is\n"
" /usr/bin/sudo).\n"
" --no-firewd-check-support\n"
" - Disable test for 'firewall-cmd ... -C' support.\n"
" --no-ipt-check-support - Disable test for 'iptables -C' support.\n"
+86 -47
View File
@@ -74,15 +74,51 @@ alarm_handler(int sig)
}
*/
static void
copy_or_search(char *so_read_buf, char *so_buf, const size_t so_buf_sz,
const char *substr_search, const int cflag, int *found_str,
int *do_break)
{
if(so_buf != NULL)
{
if(cflag & WANT_STDOUT_GETLINE)
{
memset(so_buf, 0x0, so_buf_sz);
strlcpy(so_buf, so_read_buf, so_buf_sz);
}
else
{
strlcat(so_buf, so_read_buf, so_buf_sz);
if(strlen(so_buf) >= so_buf_sz-1)
*do_break = 1;
}
}
if(substr_search != NULL) /* we are looking for a substring */
{
/* Search the current line in so_read_buf instead of
* so_buf (which may contain a partial line at the
* end at this point).
*/
if(!IS_EMPTY_LINE(so_read_buf[0])
&& strstr(so_read_buf, substr_search) != NULL)
{
*found_str = 1;
*do_break = 1;
}
}
return;
}
/* Run an external command returning exit status, and optionally filling
* provided buffer with STDOUT output up to the size provided.
* provided buffer with STDOUT output up to the size provided.
*
* Note: XXX: We are not using the timeout parameter at present. We still need
* to implement a reliable timeout mechanism.
*/
static int
_run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
const size_t so_buf_sz, const int want_stderr, const int timeout,
const size_t so_buf_sz, const int cflag, const int timeout,
const char *substr_search, int *pid_status,
const fko_srv_options_t * const opts)
{
@@ -90,7 +126,7 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
pid_t pid=0;
FILE *output;
int retval = EXTCMD_SUCCESS_ALL_OUTPUT;
int line_ctr = 0, found_str = 0;
int line_ctr = 0, found_str = 0, do_break = 0;
char *argv_new[MAX_CMDLINE_ARGS]; /* for validation and/or execvpe() */
int argc_new=0;
@@ -99,6 +135,12 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
int pipe_fd[2];
#endif
#if AFL_FUZZING
/* Don't allow command execution in AFL fuzzing mode
*/
return 0;
#endif
*pid_status = 0;
/* Even without execvpe() we examine the command for basic validity
@@ -144,7 +186,7 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
{
close(pipe_fd[0]);
dup2(pipe_fd[1], STDOUT_FILENO);
if(want_stderr)
if(cflag & WANT_STDERR)
dup2(pipe_fd[1], STDERR_FILENO);
else
close(STDERR_FILENO);
@@ -185,29 +227,18 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
{
line_ctr++;
if(so_buf != NULL)
{
strlcat(so_buf, so_read_buf, so_buf_sz);
copy_or_search(so_read_buf, so_buf, so_buf_sz,
substr_search, cflag, &found_str, &do_break);
if(strlen(so_buf) >= so_buf_sz-1)
break;
}
else /* we are looking for a substring */
{
/* Get past comments and empty lines (note: we only look at the
* first character).
*/
if(IS_EMPTY_LINE(so_read_buf[0]))
continue;
if(strstr(so_read_buf, substr_search) != NULL)
{
found_str = 1;
break;
}
}
if(do_break)
break;
}
fclose(output);
/* Make sure we only have complete lines
*/
if(!(cflag & ALLOW_PARTIAL_LINES))
truncate_partial_line(so_buf);
}
else
{
@@ -281,28 +312,19 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL)
{
line_ctr++;
if(so_buf != NULL)
{
strlcat(so_buf, so_read_buf, so_buf_sz);
if(strlen(so_buf) >= so_buf_sz-1)
break;
}
else /* we are looking for a substring */
{
/* Get past comments and empty lines (note: we only look at the
* first character).
*/
if(IS_EMPTY_LINE(so_read_buf[0]))
continue;
if(strstr(so_read_buf, substr_search) != NULL)
{
found_str = 1;
break;
}
}
copy_or_search(so_read_buf, so_buf, so_buf_sz,
substr_search, cflag, &found_str, &do_break);
if(do_break)
break;
}
pclose(output);
/* Make sure we only have complete lines
*/
if(!(cflag & ALLOW_PARTIAL_LINES))
truncate_partial_line(so_buf);
}
}
@@ -565,6 +587,10 @@ int _run_extcmd_write(const char *cmd, const char *cmd_write, int *pid_status,
FILE *fd = NULL;
#endif
#if AFL_FUZZING
return 0;
#endif
*pid_status = 0;
/* Even without execvpe() we examine the command for basic validity
@@ -658,8 +684,8 @@ run_extcmd(const char *cmd, char *so_buf, const size_t so_buf_sz,
const int want_stderr, const int timeout, int *pid_status,
const fko_srv_options_t * const opts)
{
return _run_extcmd(0, 0, cmd, so_buf, so_buf_sz, want_stderr,
timeout, NULL, pid_status, opts);
return _run_extcmd(ROOT_UID, ROOT_GID, cmd, so_buf, so_buf_sz,
want_stderr, timeout, NULL, pid_status, opts);
}
/* _run_extcmd() wrapper, run an external command as the specified user.
@@ -680,8 +706,21 @@ search_extcmd(const char *cmd, const int want_stderr, const int timeout,
const char *substr_search, int *pid_status,
const fko_srv_options_t * const opts)
{
return _run_extcmd(0, 0, cmd, NULL, 0, want_stderr, timeout,
substr_search, pid_status, opts);
return _run_extcmd(ROOT_UID, ROOT_GID, cmd, NULL, 0, want_stderr,
timeout, substr_search, pid_status, opts);
}
/* _run_extcmd() wrapper, search command output for a substring and return
* the matching line.
*/
int
search_extcmd_getline(const char *cmd, char *so_buf, const size_t so_buf_sz,
const int timeout, const char *substr_search, int *pid_status,
const fko_srv_options_t * const opts)
{
return _run_extcmd(ROOT_UID, ROOT_GID, cmd, so_buf, so_buf_sz,
WANT_STDERR | WANT_STDOUT_GETLINE, timeout, substr_search,
pid_status, opts);
}
/* _run_extcmd_write() wrapper, run a command which is expecting input via stdin
+8 -1
View File
@@ -34,8 +34,12 @@
#define IO_READ_BUF_LEN 256
#define EXTCMD_DEF_TIMEOUT 15
#define NO_TIMEOUT 0
#define WANT_STDERR 1
#define WANT_STDERR 0x01
#define WANT_STDOUT_GETLINE 0x02
#define ALLOW_PARTIAL_LINES 0x04
#define NO_STDERR 0
#define ROOT_UID 0
#define ROOT_GID 0
/* The various return status states in which an external command result
* may end up in.
@@ -88,6 +92,9 @@ int run_extcmd_as(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
int search_extcmd(const char *cmd, const int want_stderr,
const int timeout, const char *substr_search,
int *pid_status, const fko_srv_options_t * const opts);
int search_extcmd_getline(const char *cmd, char *so_buf, const size_t so_buf_sz,
const int timeout, const char *substr_search, int *pid_status,
const fko_srv_options_t * const opts);
int run_extcmd_write(const char *cmd, const char *cmd_write, int *pid_status,
const fko_srv_options_t * const opts);
#endif /* EXTCMD_H */
+3 -1
View File
@@ -39,6 +39,7 @@
#define EXPIRE_COMMENT_PREFIX "_exp_"
#define TMP_COMMENT "__TMPCOMMENT__"
#define DUMMY_IP "127.0.0.2"
#if FIREWALL_FIREWALLD
#include "fw_util_firewalld.h"
@@ -65,7 +66,8 @@
int fw_config_init(fko_srv_options_t * const opts);
int fw_initialize(const fko_srv_options_t * const opts);
int fw_cleanup(const fko_srv_options_t * const opts);
void check_firewall_rules(const fko_srv_options_t * const opts);
void check_firewall_rules(const fko_srv_options_t * const opts,
const int chk_rm_all);
int fw_dump_rules(const fko_srv_options_t * const opts);
int process_spa_request(const fko_srv_options_t * const opts,
const acc_stanza_t * const acc, spa_data_t * const spadat);
+698 -550
View File
File diff suppressed because it is too large Load Diff
+10 -4
View File
@@ -31,7 +31,10 @@
#ifndef FW_UTIL_FIREWALLD_H
#define FW_UTIL_FIREWALLD_H
#define SNAT_TARGET_BUFSIZE 64
#define SNAT_TARGET_BUFSIZE 64
#define FIREWD_CMD_FAIL_STR "COMMAND_FAILED" /* returned by firewall-cmd */
#define FIREWD_CMD_PREFIX "--direct --passthrough ipv4"
#if HAVE_EXECVPE
#define SH_REDIR "" /* the shell is not used when execvpe() is available */
@@ -45,11 +48,14 @@
#define FIREWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
#define FIREWD_OUT_RULE_ARGS "-t %s -p %i -d %s -s %s --sport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
#define FIREWD_FWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
#define FIREWD_FWD_ALL_RULE_ARGS "-t %s -s %s -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
#define FIREWD_DNAT_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i" SH_REDIR
#define FIREWD_DNAT_ALL_RULE_ARGS "-t %s -s %s -d %s -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s" SH_REDIR
#define FIREWD_SNAT_RULE_ARGS "-t %s -p %i -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s" SH_REDIR
#define FIREWD_TMP_COMMENT_ARGS "-t %s -I %s %i -s 127.0.0.2 -m comment --comment " TMP_COMMENT " -j %s" SH_REDIR
#define FIREWD_TMP_CHK_RULE_ARGS "-t %s -I %s %i -s 127.0.0.2 -p udp -j %s" SH_REDIR
#define FIREWD_TMP_VERIFY_CHK_ARGS "-t %s -C %s -s 127.0.0.2 -p udp -j %s" SH_REDIR
#define FIREWD_SNAT_ALL_RULE_ARGS "-t %s -s %s -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s" SH_REDIR
#define FIREWD_TMP_COMMENT_ARGS "-t %s -I %s %i -s " DUMMY_IP " -m comment --comment " TMP_COMMENT " -j %s" SH_REDIR
#define FIREWD_TMP_CHK_RULE_ARGS "-t %s -I %s %i -s " DUMMY_IP " -p udp -j %s" SH_REDIR
#define FIREWD_TMP_VERIFY_CHK_ARGS "-t %s -C %s -s " DUMMY_IP " -p udp -j %s" SH_REDIR
#define FIREWD_DEL_RULE_ARGS "-t %s -D %s %i" SH_REDIR
#define FIREWD_NEW_CHAIN_ARGS "-t %s -N %s" SH_REDIR
#define FIREWD_FLUSH_CHAIN_ARGS "-t %s -F %s" SH_REDIR
+2 -1
View File
@@ -153,7 +153,8 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
* firewall rules.
*/
void
check_firewall_rules(const fko_srv_options_t *opts)
check_firewall_rules(const fko_srv_options_t *opts,
const int chk_rm_all)
{
/* TODO: Implement me */
+12 -1
View File
@@ -601,7 +601,8 @@ process_spa_request(const fko_srv_options_t * const opts,
* firewall rules.
*/
void
check_firewall_rules(const fko_srv_options_t * const opts)
check_firewall_rules(const fko_srv_options_t * const opts,
const int chk_rm_all)
{
char exp_str[12] = {0};
char rule_num_str[6] = {0};
@@ -639,6 +640,7 @@ check_firewall_rules(const fko_srv_options_t * const opts)
res = run_extcmd(cmd_buf, cmd_out, STANDARD_CMD_OUT_BUFSIZE,
WANT_STDERR, NO_TIMEOUT, &pid_status, opts);
chop_newline(cmd_out);
log_msg(LOG_DEBUG, "check_firewall_rules() CMD: '%s' (res: %d)",
cmd_buf, res);
@@ -681,6 +683,15 @@ check_firewall_rules(const fko_srv_options_t * const opts)
tmp_mark = ndx;
strlcpy(exp_str, ndx, sizeof(exp_str));
chop_spaces(exp_str);
if(!is_digits(exp_str))
{
/* go to the next rule if it exists
*/
ndx = strstr(tmp_mark, EXPIRE_COMMENT_PREFIX);
continue;
}
rule_exp = (time_t)atoll(exp_str);
if(rule_exp <= now)
+612 -402
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -47,10 +47,12 @@
#define IPT_FWD_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
#define IPT_FWD_ALL_RULE_ARGS "-t %s -s %s -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s" SH_REDIR
#define IPT_DNAT_RULE_ARGS "-t %s -p %i -s %s -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s:%i" SH_REDIR
#define IPT_DNAT_ALL_RULE_ARGS "-t %s -s %s -d %s -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s --to-destination %s" SH_REDIR
#define IPT_SNAT_RULE_ARGS "-t %s -p %i -d %s --dport %i -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s" SH_REDIR
#define IPT_TMP_COMMENT_ARGS "-t %s -I %s %i -s 127.0.0.2 -m comment --comment " TMP_COMMENT " -j %s" SH_REDIR
#define IPT_TMP_CHK_RULE_ARGS "-t %s -I %s %i -s 127.0.0.2 -p udp -j %s" SH_REDIR
#define IPT_TMP_VERIFY_CHK_ARGS "-t %s -C %s -s 127.0.0.2 -p udp -j %s" SH_REDIR
#define IPT_SNAT_ALL_RULE_ARGS "-t %s -s %s -m comment --comment " EXPIRE_COMMENT_PREFIX "%u -j %s %s" SH_REDIR
#define IPT_TMP_COMMENT_ARGS "-t %s -I %s %i -s " DUMMY_IP " -m comment --comment " TMP_COMMENT " -j %s" SH_REDIR
#define IPT_TMP_CHK_RULE_ARGS "-t %s -I %s %i -s " DUMMY_IP " -p udp -j %s" SH_REDIR
#define IPT_TMP_VERIFY_CHK_ARGS "-t %s -C %s -s " DUMMY_IP " -p udp -j %s" SH_REDIR
#define IPT_DEL_RULE_ARGS "-t %s -D %s %i" SH_REDIR
#define IPT_NEW_CHAIN_ARGS "-t %s -N %s" SH_REDIR
#define IPT_FLUSH_CHAIN_ARGS "-t %s -F %s" SH_REDIR
+14 -1
View File
@@ -336,7 +336,8 @@ process_spa_request(const fko_srv_options_t * const opts,
* firewall rules.
*/
void
check_firewall_rules(const fko_srv_options_t * const opts)
check_firewall_rules(const fko_srv_options_t * const opts,
const int chk_rm_all)
{
char exp_str[12] = {0};
char anchor_rules_copy[STANDARD_CMD_OUT_BUFSIZE] = {0};
@@ -369,6 +370,8 @@ check_firewall_rules(const fko_srv_options_t * const opts)
res = run_extcmd(cmd_buf, cmd_out, STANDARD_CMD_OUT_BUFSIZE,
WANT_STDERR, NO_TIMEOUT, &pid_status, opts);
chop_newline(cmd_out);
if(!EXTCMD_IS_SUCCESS(res))
{
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, cmd_out);
@@ -405,6 +408,16 @@ check_firewall_rules(const fko_srv_options_t * const opts)
tmp_mark = ndx;
strlcpy(exp_str, ndx, sizeof(exp_str));
chop_spaces(exp_str);
chop_char(exp_str, 0x22); /* there is a trailing quote */
if(!is_digits(exp_str))
{
/* go to the next rule if it exists
*/
ndx = strstr(tmp_mark, EXPIRE_COMMENT_PREFIX);
continue;
}
rule_exp = (time_t)atoll(exp_str);
if(rule_exp <= now)
+106 -16
View File
@@ -2,12 +2,12 @@
.\" Title: fwknopd
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 11/26/2014
.\" Date: 08/24/2015
.\" Manual: Fwknop Server
.\" Source: Fwknop Server
.\" Language: English
.\"
.TH "FWKNOPD" "8" "11/26/2014" "Fwknop Server" "Fwknop Server"
.TH "FWKNOPD" "8" "08/24/2015" "Fwknop Server" "Fwknop Server"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -94,7 +94,7 @@ Specify the location of the
file\&. If this option is not given,
\fIfwknopd\fR
will use the compile\-time default location (typically
\fI@localstatedir@/run/fwknop/digest\&.cache\fR)\&.
\fI@localstatedir@/fwknop/digest\&.cache\fR)\&.
.RE
.PP
\fB\-D, \-\-dump\-config\fR
@@ -190,13 +190,40 @@ Override config variable values that are normally read from the
file with values from the specified file\&. Multiple override config files can be given as a comma\-separated list\&.
.RE
.PP
\fB\-\-key\-gen\fR
.RS 4
Have
\fBfwknopd\fR
generate both Rijndael and HMAC keys that can be used for SPA packet encryption and authentication\&. These keys are derived from /dev/urandom and then base64 encoded before being printed to stdout, and are meant to be manually included in a stanza within the
\fI@sysconfdir@/fwknop/access\&.conf\fR
file\&. Such keys are generally more secure than passphrases\&.
.RE
.PP
\fB\-\-key\-gen\-file\fR=\fI<file>\fR
.RS 4
Write generated keys to the specified file\&. Note that the file is overwritten if it already exists\&. If this option is not given, then
\fB\-\-key\-gen\fR
writes the keys to stdout\&.
.RE
.PP
\fB\-\-key\-len\fR=\fI<length>\fR
.RS 4
Specify the number of bytes for a generated Rijndael key\&. The maximum size is currently 128 bytes\&.
.RE
.PP
\fB\-\-hmac\-key\-len\fR=\fI<length>\fR
.RS 4
Specify the number of bytes for a generated HMAC key\&. The maximum size is currently 128 bytes\&.
.RE
.PP
\fB\-p, \-\-pid\-file\fR=\fI<pid\-file>\fR
.RS 4
Specify the location of the
\fIfwknopd\&.pid\fR
file\&. If this option is not given,
\fIfwknopd\fR
will use the compile\-time default location (typically \*(Aq@localstatedir@/run/fwknop/fwknopd\&.pid)\&.
will use the compile\-time default location (typically
\fI@localstatedir@/fwknop/fwknopd\&.pid\fR)\&.
.RE
.PP
\fB\-P, \-\-pcap\-filter\fR=\fI<filter>\fR
@@ -244,7 +271,7 @@ files\&. This will also force a flush of the current \(lqFWKNOP\(rq iptables cha
\fB\-\-rotate\-digest\-cache\fR
.RS 4
Rotate the digest cache file by renaming it to \(lq<name>\-old\(rq, and starting a new one\&. The digest cache file is typically found in
\fI@localstatedir@/run/fwknop/digest\&.cache\fR\&.
\fI@localstatedir@/fwknop/digest\&.cache\fR\&.
.RE
.PP
\fB\-r, \-\-run\-dir\fR=\fI<path>\fR
@@ -252,7 +279,7 @@ Rotate the digest cache file by renaming it to \(lq<name>\-old\(rq, and starting
Specify the directory where
\fBfwknopd\fR
writes run time state files\&. The default is
\fI@localstatedir@/run\fR\&.
\fI@localstatedir@\fR\&.
.RE
.PP
\fB\-S, \-\-status\fR
@@ -360,6 +387,16 @@ Track digest sums associated with previous SPA packets processed by
will not check incoming SPA packet data against any previously save digests\&. It is a good idea to leave this feature on to reduce the possibility of being vulnerable to a replay attack\&.
.RE
.PP
\fBRULES_CHECK_THRESHOLD\fR \fI<count>\fR
.RS 4
Defines the number of times firewall rule expiration times must be checked before a "deep" check is run\&. This allows
\fBfwknopd\fR
to remove rules that contain a proper
\fI\fIexp\fR\fR\fI<time>\fR
even if a third party program added them instead of
\fBfwknopd\fR\&. The default value for this variable is 20, and this typically results in this check being run every two seconds or so\&. To disable this type of checking altogether, set this variable to zero\&.
.RE
.PP
\fBENABLE_IPT_FORWARDING\fR \fI<Y/N>\fR
.RS 4
Allow SPA clients to request access to services through an iptables firewall instead of just to it (i\&.e\&. access through the FWKNOP_FORWARD chain instead of the INPUT chain)\&.
@@ -391,7 +428,9 @@ Specify the IP address for SNAT\&. This functionality is only enabled when \(lqE
\fI@sysconfdir@/fwknop/fwknopd\&.conf\fR
file), but if you want
\fBfwknopd\fR
to use the SNAT target, you must also define an IP address with the \(lqSNAT_TRANSLATE_IP\(rq variable\&.
to use the SNAT target, you must also define an IP address with the \(lqSNAT_TRANSLATE_IP\(rq variable\&. Note that this variable is generally deprecated in favor of the \(lqFORCE_SNAT\(rq variable in the
\fI@sysconfdir@/fwknop/access\&.conf\fR
file which enables per\-stanza control over the SNAT IP\&.
.RE
.PP
\fBENABLE_IPT_OUTPUT\fR \fI<Y/N>\fR
@@ -418,6 +457,13 @@ Flush all existing rules in the fwknop chains when
is stopped or otherwise exits cleanly\&. The default is \(lqY\(rq\&.
.RE
.PP
\fBEXIT_AT_INTF_DOWN\fR \fI<Y/N>\fR
.RS 4
When
\fBfwknopd\fR
is sniffing an interface, if the interface is administratively downed or unplugged, fwknopd will cleanly exit and an assumption is made that any process monitoring infrastructure like systemd or upstart will restart it\&. However, if fwknopd is not being monitored by systemd, upstart, or anything else, this behavior can be disabled with the \(lqEXIT_AT_INTF_DOWN\(rq variable\&. If disabled, fwknopd will try to recover when a downed interface comes back up\&.
.RE
.PP
\fBGPG_HOME_DIR\fR \fI<path>\fR
.RS 4
If GPG keys are used instead of a Rijndael symmetric key, this is the default GPG keys directory\&. Note that each access stanza in
@@ -519,20 +565,20 @@ Override syslog identity on message logged by
Override syslog facility\&. The \(lqSYSLOG_FACILITY\(rq variable can be set to
.RE
.PP
\fBFWKNOP_RUN_DIR\fR \fI<path>\fR
.RS 4
Specify the directory where
\fBfwknopd\fR
writes run time state files\&. The default is
\fI@localstatedir@/run\fR\&.
.RE
.PP
\fBENABLE_DESTINATION_RULE\fR \fI<Y/N>\fR
.RS 4
Controls whether
\fBfwknopd\fR
will set the destination field on the firewall rule to the destination address specified on the incoming SPA packet\&. This is useful for interfaces with multiple IP addresses hosting separate services\&. If \(lqENABLE_IPT_OUTPUT\(rq is set to \(lqY\(rq, the source field of the firewall rule is set\&. FORWARD and SNAT rules are not affected however, DNAT rules will also have their destination field set\&. The default is \(lqN\(rq, which sets the destination field to 0\&.0\&.0\&.0/0 (any)\&.
.RE
.PP
\fBFWKNOP_RUN_DIR\fR \fI<path>\fR
.RS 4
Specify the directory where
\fBfwknopd\fR
writes run time state files\&. The default is
\fI@localstatedir@\fR\&.
.RE
.SS "ACCESS\&.CONF VARIABLES"
.sp
This section describes the access control directives in the \fI@sysconfdir@/fwknop/access\&.conf\fR file\&. Theses directives define encryption keys and level of access that is granted to \fBfwknop\fR clients that have generated the appropriate encrypted message\&.
@@ -638,9 +684,35 @@ server as the user specified by the \(lqCMD_EXEC_USER\(rq or as the user that st
if that is not set\&.
.RE
.PP
\fBENABLE_CMD_SUDO_EXEC\fR \fI<Y/N>\fR
.RS 4
\fBsudo\fR
provides a powerful means of restricting the sets of commands that users can execute via the \(lqsudoers\(rq file\&. By enabling this feature (and in \(lqENABLE_CMD_EXEC\(rq mode), all incoming commands from valid SPA packets will be prefixed by \(lq/path/to/sudo \-u <user> \-g <group>\(rq where the path to sudo is set by the \(lqSUDO_EXE\(rq variable, \(lq<user>\(rq is set by the \(lqCMD_SUDO_EXEC_USER\(rq variable (default is \(lqroot\(rq if not set), and \(lq<group>\(rq is set by \(lqCMD_SUDO_EXEC_GROUP\(rq (default is also \(lqroot\(rq if not set)\&.
.RE
.PP
\fBCMD_EXEC_USER\fR \fI<username>\fR
.RS 4
This specifies the user that will execute commands contained within a SPA packet\&. If not specified, fwknopd will execute it as the user it is running as (most likely root)\&. Setting this to a non\-root user is highly recommended\&.
Specify the user (via setuid) that will execute a command contained within a SPA packet\&. If this variable is not given, fwknopd will execute the command as the user it is running as (most likely root)\&. Setting this to a non\-root user such as \(lqnobody\(rq is highly recommended if elevated permissions are not needed\&.
.RE
.PP
\fBCMD_SUDO_EXEC_USER\fR \fI<username>\fR
.RS 4
Specify the user (via \(lqsudo \-u <user>\(rq) that will execute a command contained within a SPA packet\&. If this variable is not given, fwknopd will assume the command should be executed as root\&.
.RE
.PP
\fBCMD_EXEC_GROUP\fR \fI<groupname>\fR
.RS 4
Specify the group (via setgid) that will execute a command contained within a SPA packet\&. If this variable is not given, fwknopd will execute the command as the user it is running as (most likely root)\&. Setting this to a non\-root user such as \(lqnobody\(rq is highly recommended if elevated permissions are not needed\&.
.RE
.PP
\fBCMD_SUDO_EXEC_GROUP\fR \fI<groupname>\fR
.RS 4
Specify the group (via \(lqsudo \-gu <group>\(rq) that will execute a command contained within a SPA packet\&. If this variable is not given, fwknopd will assume the command should be executed as root\&.
.RE
.PP
\fBSUDO_EXE\fR \fI<path>\fR
.RS 4
Define the path to the sudo binary\&. Default is \(lq/usr/bin/sudo\(rq\&.
.RE
.PP
\fBREQUIRE_USERNAME\fR \fI<username>\fR
@@ -683,6 +755,24 @@ file except that it is per access stanza and overrides any value set with \(lqSN
This is similar to the \(lqFORCE_SNAT\(rq variable, except that it is not necessary to also specify an IP address for SNAT rules because the MASQUERADE target is used instead\&.
.RE
.PP
\fBFORWARD_ALL\fR \fI<Y/N>\fR
.RS 4
In NAT scenarios, control whether all traffic is forwarded through the
\fBfwknopd\fR
system as opposed to just forwarding connections to specific services as requested by the
\fBfwknop\fR
client\&.
.RE
.PP
\fBDISABLE_DNAT\fR \fI<Y/N>\fR
.RS 4
Control whether DNAT rules are created in FORCE_NAT scenarios\&. This is mainly used in conjunction with the FORWARD_ALL variable to allow
\fBfwknopd\fR
to act essentially as an SPA gateway\&. I\&.e\&., the
\fBfwknop\fR
client is used to gain access via SPA to the broader Internet after being granted an IP via DHCP, but prior to sending the SPA packet all traffic is blocked by default to the Internet\&.
.RE
.PP
\fBGPG_DECRYPT_ID\fR \fI<keyID>\fR
.RS 4
Define a GnuPG key ID to use for decrypting SPA messages that have been encrypted by an
+9 -2
View File
@@ -224,7 +224,11 @@ main(int argc, char **argv)
/* If the TCP server option was set, fire it up here. Note that in
* this mode, fwknopd still acquires SPA packets via libpcap. If you
* want to use UDP only without the libpcap dependency, see the FIXME...
* want to use UDP only without the libpcap dependency, then fwknop
* needs to be compiled with --enable-udp-server. Note that the UDP
* server can be run even when fwknopd links against libpcap as well,
* but there is no reason to link against it if SPA packets are
* always going to be acquired via a UDP socket.
*/
if(strncasecmp(opts.config[CONF_ENABLE_TCP_SERVER], "Y", 1) == 0)
{
@@ -238,8 +242,11 @@ main(int argc, char **argv)
#if USE_LIBPCAP
/* Intiate pcap capture mode...
*/
if(strncasecmp(opts.config[CONF_ENABLE_UDP_SERVER], "N", 1) == 0)
if(!opts.enable_udp_server
&& strncasecmp(opts.config[CONF_ENABLE_UDP_SERVER], "N", 1) == 0)
{
pcap_capture(&opts);
}
#endif
/* Deal with any signals that we've received and break out
+21 -21
View File
@@ -13,13 +13,13 @@
# You will need to edit the access.conf file in order for fwknop to function
# correctly.
#
# Most of these can remain commented out unless you need to overide the
# Most of these can remain commented out unless you need to override the
# default setting.
#
# It is also important to note that there are some subtle (and some not
# so subtle) differences between this configuration file, its parameters
# and valid values and the configuration file used by the legacy Perl
# version of fwknopd. Please pay careful attention to the format and
# version of fwknopd. Please pay careful attention to the format and
# values used in this file if you are migrating from the legacy Perl
# version.
#
@@ -28,8 +28,8 @@
#
# Define the default verbosity level the fwknop server should use.
# A value of "0" is the default verbosity level. Setting it up to "1" or
# higher will allow debugging messges be displayed.
# A value of "0" is the default verbosity level. Setting it up to "1" or
# higher will allow debugging messages to be displayed.
#
#VERBOSE 0;
@@ -81,7 +81,7 @@
# man page.
#PCAP_DISPATCH_COUNT 0;
# Sets the number of microseconds to passed as an argument to usleep() in
# Sets the number of microseconds to pass as an argument to usleep() in
# the pcap loop. The default is 100000 microseconds, or 1/10th of a second.
#PCAP_LOOP_SLEEP 100000;
@@ -111,8 +111,8 @@
# Enable the fwknopd TCP server. This is a "dummy" TCP server that will
# accept TCP connection requests on the specified TCPSERV_PORT.
# If set to "Y", fwknopd will fork off a child process to listen for, and
# accept incoming TCP request. This server only accepts the
# If set to "Y", fwknopd will fork off a child process to listen for and
# accept incoming TCP requests. This server only accepts the
# request. It does not otherwise communicate. This is only to allow the
# incoming SPA over TCP packet which is detected via PCAP. The connection
# is closed after 1 second regardless.
@@ -142,7 +142,7 @@
# This variable controls whether fwknopd is permitted to sniff SPA packets
# regardless of whether they are received on the sniffing interface or sent
# from the sniffing interface. In the later case, this can be useful to have
# from the sniffing interface. In the latter case, this can be useful to have
# fwknopd sniff SPA packets that are forwarded through a system and destined
# for a different network. If the sniffing interface is the egress interface
# for such packets, then this variable will need to be set to "Y" in order for
@@ -153,11 +153,11 @@
# ENABLE_PCAP_ANY_DIRECTION N;
# Controls whether fwknopd will set the destination field on the firewall
# rule to the destination address specified on the incoming SPA packet.
# rule to the destination address specified on the incoming SPA packet.
# This is useful for interfaces with multiple IP addresses hosting separate
# services. If ENABLE_IPT_OUTPUT is set to "Y", the source field of
# the firewall rule is set. FORWARD and SNAT rules are not affected however,
# DNAT rules will also have their destination field set. The default is
# services. If ENABLE_IPT_OUTPUT is set to "Y", the source field of
# the firewall rule is set. FORWARD and SNAT rules are not affected however,
# DNAT rules will also have their destination field set. The default is
# "N", which sets the destination field to 0.0.0.0/0 (any).
#
# ENABLE_DESTINATION_RULE Y;
@@ -167,7 +167,7 @@
# This is a possible future feature of fwknopd.
#
# The following four variables control whether a global set of "open" and
# "close" commands are executed after receving a valid SPA packet. These
# "close" commands are executed after receiving a valid SPA packet. These
# variables are used only if FIREWALL_TYPE is set to "external_cmd", but
# the same variables can also exist within the access.conf file so that
# mixed deployments are possible - that is, some SPA packets will operate
@@ -216,7 +216,7 @@
#FLUSH_FIREWD_AT_EXIT Y;
#
# Allow SPA clients to request access to services through an firewalld
# Allow SPA clients to request access to services through a firewalld
# firewall instead of just to it (i.e. access through the FWKNOP_FORWARD
# chain instead of the INPUT chain).
#
@@ -240,7 +240,7 @@
# when ENABLE_FIREWD_SNAT is set to "Y", and by default SNAT rules are built
# with the MASQUERADE target (since then the internal IP does not have to be
# defined here in the fwknop.conf file), but if you want fwknopd to use the
# SNAT target then also defined an IP address with the SNAT_TRANSLATE_IP
# SNAT target then also define an IP address with the SNAT_TRANSLATE_IP
# variable.
#
#ENABLE_FIREWD_SNAT N;
@@ -283,7 +283,7 @@
# where fwknop rules are added.
#
# "Rule_position":
# Defines the position where rule are added within the To_chain.
# Defines the position where rules are added within the To_chain.
#
#FIREWD_INPUT_ACCESS ACCEPT, filter, INPUT, 1, FWKNOP_INPUT, 1;
@@ -303,13 +303,13 @@
# FIREWD_MASQUERADE_ACCESS variable.
#
#FIREWD_SNAT_ACCESS SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#FIREWD_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#FIREWD_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1;
# The ENABLE_COMMENT_MATCH_CHECK variable instructs fwknopd to check for the
# firewalld 'comment' match at start up. If it's not found, then fwknopd will
# exit and throw an error. This variable is enabled by default, but can be
# disabled if you want fwknopd to run without being sure that the comment match
# if available (not recommended, since the comment match enables new SPA rules
# is available (not recommended, since the comment match enables new SPA rules
# to be timed out).
#
#ENABLE_FIREWD_COMMENT_CHECK Y;
@@ -348,7 +348,7 @@
# when ENABLE_IPT_SNAT is set to "Y", and by default SNAT rules are built
# with the MASQUERADE target (since then the internal IP does not have to be
# defined here in the fwknop.conf file), but if you want fwknopd to use the
# SNAT target then also defined an IP address with the SNAT_TRANSLATE_IP
# SNAT target then also define an IP address with the SNAT_TRANSLATE_IP
# variable.
#
#ENABLE_IPT_SNAT N;
@@ -411,13 +411,13 @@
# IPT_MASQUERADE_ACCESS variable.
#
#IPT_SNAT_ACCESS SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#IPT_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#IPT_MASQUERADE_ACCESS MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1;
# The ENABLE_COMMENT_MATCH_CHECK variable instructs fwknopd to check for the
# iptables 'comment' match at start up. If it's not found, then fwknopd will
# exit and throw an error. This variable is enabled by default, but can be
# disabled if you want fwknopd to run without being sure that the comment match
# if available (not recommended, since the comment match enables new SPA rules
# is available (not recommended, since the comment match enables new SPA rules
# to be timed out).
#
#ENABLE_IPT_COMMENT_CHECK Y;
+40 -14
View File
@@ -70,7 +70,7 @@
/* Our default run directory is based on LOCALSTATEDIR as set by the
* configure script. This is where we put the PID and digest cache files.
*/
#define DEF_RUN_DIR SYSRUNDIR"/run/"PACKAGE_NAME
#define DEF_RUN_DIR SYSRUNDIR"/"PACKAGE_NAME
#endif
/* More Conf defaults
@@ -88,9 +88,11 @@
#define DEF_PCAP_DISPATCH_COUNT "100"
#define DEF_PCAP_LOOP_SLEEP "100000" /* a tenth of a second (in microseconds) */
#define DEF_ENABLE_PCAP_ANY_DIRECTION "N"
#define DEF_EXIT_AT_INTF_DOWN "Y"
#define DEF_ENABLE_SPA_PACKET_AGING "Y"
#define DEF_MAX_SPA_PACKET_AGE "120"
#define DEF_ENABLE_DIGEST_PERSISTENCE "Y"
#define DEF_RULES_CHECK_THRESHOLD "20"
#define DEF_MAX_SNIFF_BYTES "1500"
#define DEF_GPG_HOME_DIR "/root/.gnupg"
#ifdef GPG_EXE
@@ -98,6 +100,11 @@
#else
#define DEF_GPG_EXE "/usr/bin/gpg"
#endif
#ifdef SUDO_EXE
#define DEF_SUDO_EXE SUDO_EXE
#else
#define DEF_SUDO_EXE "/usr/bin/sudo"
#endif
#define DEF_ENABLE_SPA_OVER_HTTP "N"
#define DEF_ENABLE_TCP_SERVER "N"
#define DEF_TCPSERV_PORT "62201"
@@ -124,6 +131,7 @@
#define RCHK_MAX_UDPSERV_SELECT_TIMEOUT (2 << 22)
#define RCHK_MAX_PCAP_DISPATCH_COUNT (2 << 22)
#define RCHK_MAX_FW_TIMEOUT (2 << 22)
#define RCHK_MAX_RULES_CHECK_THRESHOLD ((2 << 16) - 1)
/* FirewallD-specific defines
*/
@@ -141,7 +149,7 @@
#define DEF_FIREWD_FORWARD_ACCESS "ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1"
#define DEF_FIREWD_DNAT_ACCESS "DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1"
#define DEF_FIREWD_SNAT_ACCESS "SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1"
#define DEF_FIREWD_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1"
#define DEF_FIREWD_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1"
#define RCHK_MAX_FIREWD_RULE_NUM (2 << 15)
@@ -161,7 +169,7 @@
#define DEF_IPT_FORWARD_ACCESS "ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1"
#define DEF_IPT_DNAT_ACCESS "DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1"
#define DEF_IPT_SNAT_ACCESS "SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1"
#define DEF_IPT_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1"
#define DEF_IPT_MASQUERADE_ACCESS "MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1"
#define RCHK_MAX_IPT_RULE_NUM (2 << 15)
@@ -226,10 +234,12 @@ enum {
CONF_PCAP_DISPATCH_COUNT,
CONF_PCAP_LOOP_SLEEP,
CONF_ENABLE_PCAP_ANY_DIRECTION,
CONF_EXIT_AT_INTF_DOWN,
CONF_MAX_SNIFF_BYTES,
CONF_ENABLE_SPA_PACKET_AGING,
CONF_MAX_SPA_PACKET_AGE,
CONF_ENABLE_DIGEST_PERSISTENCE,
CONF_RULES_CHECK_THRESHOLD,
CONF_CMD_EXEC_TIMEOUT,
//CONF_BLACKLIST,
CONF_ENABLE_SPA_OVER_HTTP,
@@ -305,6 +315,7 @@ enum {
#endif
CONF_GPG_HOME_DIR,
CONF_GPG_EXE,
CONF_SUDO_EXE,
CONF_FIREWALL_EXE,
CONF_VERBOSE,
#if AFL_FUZZING
@@ -366,6 +377,11 @@ typedef struct acc_stanza
unsigned char use_rijndael;
int fw_access_timeout;
unsigned char enable_cmd_exec;
unsigned char enable_cmd_sudo_exec;
char *cmd_sudo_exec_user;
char *cmd_sudo_exec_group;
uid_t cmd_sudo_exec_uid;
gid_t cmd_sudo_exec_gid;
char *cmd_exec_user;
char *cmd_exec_group;
uid_t cmd_exec_uid;
@@ -395,8 +411,8 @@ typedef struct acc_stanza
char *force_nat_ip;
char *force_nat_proto;
unsigned int force_nat_port;
unsigned char disable_dnat;
unsigned char forward_all;
unsigned char disable_dnat;
unsigned char force_snat;
char *force_snat_ip;
unsigned char force_masquerade;
@@ -449,9 +465,6 @@ typedef struct acc_stanza
struct fw_chain chain[NUM_FWKNOP_ACCESS_TYPES];
char fw_command[MAX_PATH_LEN];
/* Flag for firewalld SNAT vs. MASQUERADE usage
*/
unsigned char use_masquerade;
/* Flag for setting destination field in rule
*/
unsigned char use_destination;
@@ -499,9 +512,6 @@ typedef struct acc_stanza
struct fw_chain chain[NUM_FWKNOP_ACCESS_TYPES];
char fw_command[MAX_PATH_LEN];
/* Flag for iptables SNAT vs. MASQUERADE usage
*/
unsigned char use_masquerade;
/* Flag for setting destination field in rule
*/
unsigned char use_destination;
@@ -591,10 +601,14 @@ typedef struct fko_srv_options
unsigned char fw_list; /* List current firewall rules */
unsigned char fw_list_all; /* List all current firewall rules */
unsigned char fw_flush; /* Flush current firewall rules */
unsigned char key_gen; /* Generate keys and exit */
unsigned char exit_after_parse_config; /* Parse config and exit */
/* Operational flags
*/
unsigned char test; /* Test mode flag */
unsigned char afl_fuzzing; /* SPA pkts from stdin for AFL fuzzing */
unsigned char verbose; /* Verbose mode flag */
unsigned char exit_after_parse_config; /* Parse config and exit */
unsigned char enable_udp_server; /* Enable UDP server mode */
unsigned char firewd_disable_check_support; /* Don't use firewall-cmd ... -C */
@@ -611,6 +625,13 @@ typedef struct fko_srv_options
int tcp_server_pid;
int lock_fd;
/* Values used in --key-gen mode only
*/
char key_gen_file[MAX_PATH_LEN];
int key_len;
int hmac_key_len;
int hmac_type;
#if USE_FILE_CACHE
struct digest_cache_list *digest_cache; /* In-memory digest cache list */
#endif
@@ -634,18 +655,23 @@ typedef struct fko_srv_options
*/
struct fw_config *fw_config;
/* Rule checking counter - this is for garbage cleanup mode to remove
* any rules with an expired timer (even those that may have been
* added by a third-party program).
*/
unsigned int check_rules_ctr;
/* Set to 1 when messages have to go through syslog, 0 otherwise */
unsigned char syslog_enable;
} fko_srv_options_t;
extern fko_srv_options_t options;
/* For cleaning up memory before exiting
*/
#define FW_CLEANUP 1
#define NO_FW_CLEANUP 0
void clean_exit(fko_srv_options_t *opts, unsigned int fw_cleanup_flag, unsigned int exit_status);
void clean_exit(fko_srv_options_t *opts,
unsigned int fw_cleanup_flag, unsigned int exit_status);
#endif /* FWKNOPD_COMMON_H */
+648 -436
View File
File diff suppressed because it is too large Load Diff
+39 -5
View File
@@ -31,6 +31,7 @@
#if USE_LIBPCAP
#include <pcap.h>
#include <errno.h>
#endif
#include "fwknopd_common.h"
@@ -64,9 +65,11 @@ pcap_capture(fko_srv_options_t *opts)
int pcap_file_mode = 0;
int status;
int useconds;
int rules_chk_threshold;
int pcap_dispatch_count;
int max_sniff_bytes;
int is_err;
int chk_rm_all = 0;
pid_t child_pid;
#if FIREWALL_IPFW
@@ -77,7 +80,7 @@ pcap_capture(fko_srv_options_t *opts)
0, RCHK_MAX_PCAP_LOOP_SLEEP, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR, "[*] invalid PCAP_LOOP_SLEEP_value");
log_msg(LOG_ERR, "[*] invalid PCAP_LOOP_SLEEP value");
clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
}
@@ -89,6 +92,14 @@ pcap_capture(fko_srv_options_t *opts)
clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
}
rules_chk_threshold = strtol_wrapper(opts->config[CONF_RULES_CHECK_THRESHOLD],
0, RCHK_MAX_RULES_CHECK_THRESHOLD, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR, "[*] invalid RULES_CHECK_THRESHOLD");
clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
}
/* Set promiscuous mode if ENABLE_PCAP_PROMISC is set to 'Y'.
*/
if(strncasecmp(opts->config[CONF_ENABLE_PCAP_PROMISC], "Y", 1) == 0)
@@ -288,9 +299,20 @@ pcap_capture(fko_srv_options_t *opts)
*/
else if(res == -1)
{
log_msg(LOG_ERR, "[*] Error from pcap_dispatch: %s",
pcap_geterr(pcap)
);
if((strncasecmp(opts->config[CONF_EXIT_AT_INTF_DOWN], "Y", 1) == 0)
&& errno == ENETDOWN)
{
log_msg(LOG_ERR, "[*] Fatal error from pcap_dispatch: %s",
pcap_geterr(pcap)
);
clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
}
else
{
log_msg(LOG_ERR, "[*] Error from pcap_dispatch: %s",
pcap_geterr(pcap)
);
}
if(pcap_errcnt++ > MAX_PCAP_ERRORS_BEFORE_BAIL)
{
@@ -312,7 +334,19 @@ pcap_capture(fko_srv_options_t *opts)
/* Check for any expired firewall rules and deal with them.
*/
if(!opts->test)
check_firewall_rules(opts);
{
if(rules_chk_threshold > 0)
{
opts->check_rules_ctr++;
if ((opts->check_rules_ctr % rules_chk_threshold) == 0)
{
chk_rm_all = 1;
opts->check_rules_ctr = 0;
}
}
check_firewall_rules(opts, chk_rm_all);
chk_rm_all = 0;
}
#if FIREWALL_IPFW
/* Purge expired rules that no longer have any corresponding
+10 -14
View File
@@ -58,6 +58,7 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
unsigned char *pkt_data;
unsigned short pkt_data_len;
unsigned char *pkt_end;
unsigned char *fr_end;
unsigned int ip_hdr_words;
@@ -85,7 +86,7 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
/* Determine packet end.
*/
pkt_end = (unsigned char *) packet + packet_header->caplen;
fr_end = (unsigned char *) packet + packet_header->caplen;
/* The ethernet header.
*/
@@ -128,7 +129,7 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
/* If IP header is past calculated packet end, bail.
*/
if ((unsigned char*)(iph_p + 1) > pkt_end)
if ((unsigned char*)(iph_p + 1) > fr_end)
return;
/* ip_hdr_words is the number of 32 bit words in the IP header. After
@@ -140,19 +141,14 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
if (ip_hdr_words < MIN_IPV4_WORDS)
return;
/* Support for the cases where libpcap returns the Ethernet Frame Check
* Sequence (4 bytes at the end of the Ethernet frame) as part of the
* capture. libpcap returning the FCS is fairly rare. Default settings on
* the following system included an Ethernet FCS in the libpcap capture:
* BeagleBone Black rev C running 3.8.13-bone50 #1 SMP Tue May 13
* 13:24:52 UTC 2014 armv7l GNU/Linux
*
* Calculate the new pkt_end from the length in the ip header.
/* Make sure to calculate the packet end based on the length in the
* IP header. This allows additional bytes that may be added to the
* frame (such as a 4-byte Ethernet Frame Check Sequence) to not
* interfere with SPA operations.
*/
if(((unsigned char*)iph_p)+ntohs(iph_p->tot_len) == pkt_end-FCS_HEADER_LEN) {
log_msg(LOG_DEBUG, "Adjusting packet end to account for FCS header on Ethernet frame");
pkt_end -= FCS_HEADER_LEN;
}
pkt_end = ((unsigned char*)iph_p)+ntohs(iph_p->tot_len);
if(pkt_end > fr_end)
return;
/* Now, find the packet data payload (depending on IPPROTO).
*/
+2 -2
View File
@@ -33,7 +33,6 @@
#define IPV4_VER_MASK 0x15
#define MIN_IPV4_WORDS 0x05
#define FCS_HEADER_LEN 0x04
/* For items not defined by this system
*/
@@ -47,7 +46,8 @@
/* Prototypes
*/
#if USE_LIBPCAP
void process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, const unsigned char *packet);
void process_packet(unsigned char *args,
const struct pcap_pkthdr *packet_header, const unsigned char *packet);
#endif
#endif /* PROCESS_PACKET_H */
+2 -2
View File
@@ -134,8 +134,8 @@ rotate_digest_cache_file(fko_srv_options_t *opts)
);
#endif /* NO_DIGEST_CACHE */
if(new_file != NULL)
free(new_file);
free(new_file);
return;
}
static void
+22 -2
View File
@@ -53,7 +53,8 @@ int
run_udp_server(fko_srv_options_t *opts)
{
int s_sock, sfd_flags, selval, pkt_len;
int is_err, s_timeout, rv=1;
int is_err, s_timeout, rv=1, chk_rm_all=0;
int rules_chk_threshold;
fd_set sfd_set;
struct sockaddr_in saddr, caddr;
struct timeval tv;
@@ -76,6 +77,13 @@ run_udp_server(fko_srv_options_t *opts)
log_msg(LOG_ERR, "[*] Invalid max UDPSERV_SELECT_TIMEOUT value.");
return -1;
}
rules_chk_threshold = strtol_wrapper(opts->config[CONF_RULES_CHECK_THRESHOLD],
0, RCHK_MAX_RULES_CHECK_THRESHOLD, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR, "[*] invalid RULES_CHECK_THRESHOLD");
clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
}
log_msg(LOG_INFO, "Kicking off UDP server to listen on port %i.", port);
@@ -148,7 +156,19 @@ run_udp_server(fko_srv_options_t *opts)
/* Check for any expired firewall rules and deal with them.
*/
if(!opts->test)
check_firewall_rules(opts);
{
if(rules_chk_threshold > 0)
{
opts->check_rules_ctr++;
if ((opts->check_rules_ctr % rules_chk_threshold) == 0)
{
chk_rm_all = 1;
opts->check_rules_ctr = 0;
}
}
check_firewall_rules(opts, chk_rm_all);
chk_rm_all = 0;
}
/* Initialize and setup the socket for select.
*/
+110 -7
View File
@@ -76,31 +76,54 @@ hex_dump(const unsigned char *data, const int size)
return;
}
/* Basic directory checks (stat() and whether the path is actually
* a directory).
/* Basic directory/binary checks (stat() and whether the path is actually
* a directory or an executable).
*/
int
is_valid_dir(const char *path)
static int
is_valid_path(const char *path, const int file_type)
{
#if HAVE_STAT
struct stat st;
/* If we are unable to stat the given dir, then return with error.
/* If we are unable to stat the given path, then return with error.
*/
if(stat(path, &st) != 0)
{
log_msg(LOG_ERR, "[-] unable to stat() directory: %s: %s",
log_msg(LOG_ERR, "[-] unable to stat() path: %s: %s",
path, strerror(errno));
return(0);
}
if(!S_ISDIR(st.st_mode))
if(file_type == IS_DIR)
{
if(!S_ISDIR(st.st_mode))
return(0);
}
else if(file_type == IS_EXE)
{
if(!S_ISREG(st.st_mode) || ! (st.st_mode & S_IXUSR))
return(0);
}
else
return(0);
#endif /* HAVE_STAT */
return(1);
}
int
is_valid_dir(const char *path)
{
return is_valid_path(path, IS_DIR);
}
int
is_valid_exe(const char *path)
{
return is_valid_path(path, IS_EXE);
}
int
verify_file_perms_ownership(const char *file)
{
@@ -163,6 +186,86 @@ verify_file_perms_ownership(const char *file)
return 1;
}
void
chop_char(char *str, const char chop)
{
if(str != NULL && str[0] != 0x0 && str[strlen(str)-1] == chop)
str[strlen(str)-1] = 0x0;
return;
}
void
chop_newline(char *str)
{
chop_char(str, 0x0a);
return;
}
void chop_spaces(char *str)
{
int i;
if (str != NULL && str[0] != 0x0)
{
for (i=strlen(str)-1; i > 0; i--)
{
if(str[i] != 0x20)
break;
str[i] = 0x0;
}
}
return;
}
void
truncate_partial_line(char *str)
{
int i, have_newline=0;
if(str != NULL && str[0] != 0x0)
{
for (i=0; i < strlen(str); i++)
{
if(str[i] == 0x0a)
{
have_newline = 1;
break;
}
}
/* Don't zero out any data unless there is at least
* one newline
*/
if(have_newline)
{
for (i=strlen(str)-1; i > 0; i--)
{
if(str[i] == 0x0a)
break;
str[i] = 0x0;
}
}
}
return;
}
/* Simple test to see if a string only contains digits
*/
int
is_digits(const char * const str)
{
int i;
if (str != NULL && str[0] != 0x0)
{
for (i=0; i<strlen(str); i++)
{
if(!isdigit(str[i]))
return 0;
i++;
}
}
return 1;
}
static int
add_argv(char **argv_new, int *argc_new,
const char *new_arg, const fko_srv_options_t * const opts)
+9
View File
@@ -54,12 +54,21 @@
x == '#' || x == '\n' || x == '\r' || x == ';' || x == '\0' \
)
#define IS_DIR 1
#define IS_EXE 2
/* Prototypes
*/
void hex_dump(const unsigned char *data, const int size);
char* dump_ctx(fko_ctx_t ctx);
int is_valid_dir(const char *path);
int is_valid_exe(const char *path);
int verify_file_perms_ownership(const char *file);
void chop_newline(char *str);
void chop_char(char *str, const char chop);
void chop_spaces(char *str);
void truncate_partial_line(char *str);
int is_digits(const char * const str);
int strtoargv(const char * const args_str, char **argv_new, int *argc_new,
const fko_srv_options_t * const opts);
void free_argv(char **argv_new, int *argc_new);
-7
View File
@@ -26,13 +26,6 @@ to the *libpng-nocrc.patch* patch included in the AFL sources. The corresponding
commit that enables this functionality in fwknop is aaa44656bcfcb705d80768a7b9aa0d45a0e55e21
(see: [https://github.com/mrash/fwknop/commit/aaa44656bcfcb705d80768a7b9aa0d45a0e55e21])
One exception to the need for compiling fwknop wtih *--enable-afl-fuzzing* is
when using AFL to fuzz the fwknoprc file that is leveraged by the fwknop client.
In this case, fwknop should not be compiled with
*--enable-afl-fuzzing* (use the *compile/afl-compile-no-enable-arg.sh* script)
since the fwknoprc file parsing routines are fuzzed instead of the SPA packet
encoding/decoding cycles.
## AFL Wrappers
The top level directory contains enabling scripts in order to make it easy to
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh -x
. ./compile/fcns
### set either afl-gcc or afl-clang (defaults to afl-gcc)
set_afl_cc
cd ../../
AFL_USE_ASAN=1 CC=$AFL_CC ./extras/apparmor/configure_args.sh --enable-afl-fuzzing --without-gpgme --enable-32bit-mode --enable-asan-support $@
if [ $? -ne 0 ]
then
echo "[*] autogen configure script failure, exiting"
exit 1
fi
make clean
AFL_HARDEN=1 make
cd test/afl
exit $?
+22 -4
View File
@@ -1,9 +1,27 @@
#!/bin/sh -x
#
# Recompile fwknop with AFL code enabled, but without using afl-gcc. The
# purpose of this is to allow the generated fuzzing corpus under an AFL
# fuzzing run to be sent back through the fwknop code to see which
# functions/lines were executed by AFL. This can be used to help tune the
# original test case inputs. A main consumer of fwknop compiled in this way
# is the afl-cov project (https://github.com/mrash/afl-cov/) which shows code
# coverage achieved by test inputs.
#
cd ..
./rm-coverage-files.sh
cd afl
cd ../../
./compile/afl-compile.sh --enable-profile-coverage
./extras/apparmor/configure_args.sh --enable-afl-fuzzing --enable-profile-coverage $@
if [ $? -ne 0 ]
then
echo "[*] autogen configure script failure, exiting"
exit 1
fi
make clean
make
cd test/afl
exit $?
@@ -1,10 +0,0 @@
#!/bin/sh -x
# this is for the fuzzing-wrappers/client-rc.sh script
cd ../../
CC=afl-gcc ./extras/apparmor/configure_args.sh $@
make clean
make
cd test/afl
exit $?
+15 -2
View File
@@ -1,8 +1,21 @@
#!/bin/sh -x
. ./compile/fcns
### set either afl-gcc or afl-clang (defaults to afl-gcc)
set_afl_cc
cd ../../
CC=afl-gcc ./extras/apparmor/configure_args.sh --enable-afl-fuzzing $@
CC=$AFL_CC ./extras/apparmor/configure_args.sh --enable-afl-fuzzing $@
if [ $? -ne 0 ]
then
echo "[*] autogen configure script failure, exiting"
exit 1
fi
make clean
make
AFL_HARDEN=1 make
cd test/afl
exit $?
-13
View File
@@ -1,13 +0,0 @@
#!/bin/sh -x
RESULTS_DIR=afl-lcov-results
[ -d $RESULTS_DIR ] && rm -rf $RESULTS_DIR
cd ..
./gen-coverage-report.sh
mv lcov-results afl/$RESULTS_DIR
cd afl
echo "[+] Code coverage available in the $RESULTS_DIR/ directory"
exit $?
+11
View File
@@ -0,0 +1,11 @@
AFL_CC=afl-gcc
set_afl_cc() {
$AFL_CC /dev/null 2>&1 | grep -q -i "On Apple systems.*wrapper for clang"
if [ $? -eq 0 ]
then
### Need to switch to afl-clang
AFL_CC=afl-clang
fi
}
+30 -7
View File
@@ -1,7 +1,12 @@
#!/bin/sh -x
#
# Fuzz the fwknop client fwknoprc file
# Fuzz the fwknop client fwknoprc file. This wrapper also has the ability to
# kick of afl-cov to produce code coverage results at the same time. Note that
# CODE_DIR points to the fwknop project code compiled with gcov profiling
# support.
#
# $ AFL_COV=1 CODE_DIR=/path/to/code/fwknop.git ./fuzzing-wrappers/client-rc.sh
#
. ./fuzzing-wrappers/fcns
@@ -20,18 +25,36 @@ BANNER="$TSTR$GIT_STR"
### set up directories
dir_init $ARCHIVE_DIR $FDIR $OUT_DIR PREV_OUT_DIR
### see if we're going to enable code coverage with afl-cov
if [ "$AFL_COV" != "" ]
then
echo "[+] Enabling afl-cov coverage mode..."
if [ "$CODE_DIR" = "" ]
then
echo "[*] Must set CODE_DIR with path to gcov compiled code"
exit 1
fi
### kick off afl-cov in --background mode
afl-cov -d $OUT_DIR --live --background --sleep 10 --coverage-cmd \
"LD_LIBRARY_PATH=$CODE_DIR/test/afl/$LIB_DIR $CODE_DIR/test/afl/$CLIENT --rc-file AFL_FILE -T -a 1.1.1.1 -n testhost2.com" \
--code-dir $CODE_DIR
fi
### make sure the client rc file can be parsed (a failure
### exit status is expected though)
./fuzzing-wrappers/helpers/fwknop-rc-test.sh && exit $?
### support resuming from a previous run
if [ $@ ] && [ "$1" = "resume" ]
then
IN_DIR=$PREV_OUT_DIR
fi
### make sure the client can handle the rc file
./fuzzing-wrappers/helpers/fwknop-rc-test.sh || \
{ echo "[*] Client rc file fuzzing requires compilation with ./compile/afl-compile-no-enable-args.sh"; exit 1; }
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz \
-T $BANNER -t 1000 -i $IN_DIR -o $OUT_DIR -f $OUT_DIR/fwknoprc \
$CLIENT --rc-file $OUT_DIR/fwknoprc -T -a 1.1.1.1 -n testhost.com
-m $MEM_LIMIT -T $BANNER -t $TIMEOUT \
-i $IN_DIR -o $OUT_DIR -f $OUT_DIR/fwknoprc \
$CLIENT --rc-file $OUT_DIR/fwknoprc -T \
-a 1.1.1.1 -n testhost2.com
exit $?
+14
View File
@@ -5,6 +5,20 @@ SERVER="../../server/.libs/fwknopd"
CLIENT="../../client/.libs/fwknop"
LIB_DIR="../../lib/.libs"
MEM_LIMIT=800
TIMEOUT=1000
fw_type() {
### default to iptables
FW="/iptables"
LD_LIBRARY_PATH=$LIB_DIR $SERVER --version | grep "firewall-cmd"
if [ "$?" = "0" ]
then
FW="/firewalld"
fi
eval "$2=$1$FW"
}
git_banner() {
if [ -d '../../.git' ] && [ `which git` ]
then
@@ -0,0 +1,13 @@
Normally the test corpus in the test/afl/test-cases/ directory is sufficient
for effective AFL fuzzing rounds. However, if you want to test with an expanded
set of files that have gone through afl-cmin, then you can leverage the scripts
in this directory. This uses the complete set of main test suite config files
in the test/conf/ directory as the input corpus for afl-cmin. The work flow
would be (for the server-access.sh fuzzing wrapper for example):
$ cd fwknop.git/test/afl/
$ ./compile/afl-compile.sh
$ ./fuzzing-wrappers/helpers/afl-cmin/server-access-cmin.sh
<edit the script below to use the new test-cases/server-access.cmin directory>
$ ./fuzzing-wrappers/server-access.sh
@@ -0,0 +1,18 @@
#!/bin/sh -x
. ./fuzzing-wrappers/fcns
### generate test corpus directly from the main test suite
### config files
CONF_DIR=../conf
IN_DIR=$CONF_DIR
OUT_DIR="test-cases/server-access.cmin"
FUZZ_FILE=access_tmp.conf
LD_LIBRARY_PATH=../../lib/.libs afl-cmin -i $IN_DIR \
-f $FUZZ_FILE -o $OUT_DIR $SERVER \
-c $CONF_DIR/ipt_snat_fwknopd.conf \
-a $FUZZ_FILE -O $CONF_DIR/override_no_digest_tracking_fwknopd.conf \
-A -f -t --exit-parse-config -v -v -v -r `pwd`/run
exit $?
@@ -0,0 +1,18 @@
#!/bin/sh -x
. ./fuzzing-wrappers/fcns
### generate test corpus directly from the main test suite
### config files
CONF_DIR=../conf
IN_DIR=$CONF_DIR
OUT_DIR="test-cases/server-conf.cmin"
FUZZ_FILE=fwknopd_conf.tmp
LD_LIBRARY_PATH=../../lib/.libs afl-cmin -i $IN_DIR \
-f $FUZZ_FILE -o $OUT_DIR $SERVER \
-a $CONF_DIR/default_access.conf \
-c $FUZZ_FILE -O $CONF_DIR/override_no_digest_tracking_fwknopd.conf \
-A -f -t --exit-parse-config -v -v -v -r `pwd`/run
exit $?
@@ -0,0 +1,12 @@
#!/bin/sh -x
. ./fuzzing-wrappers/fcns
IN_DIR="test-cases/spa-pkts"
OUT_DIR=${IN_DIR}.cmin
CONF_DIR=../conf
LD_LIBRARY_PATH=../../lib/.libs afl-cmin -i $IN_DIR \
-o ${IN_DIR}.cmin $SERVER -c ../conf/default_fwknopd.conf \
-a $CONF_DIR/default_access.conf -A -f -t
exit $?
@@ -1,12 +1,12 @@
#!/bin/sh -x
RC_FILE="test-cases/client-rc/fwknoprc"
RC_FILE="test-cases/client-rc/fwknoprc2"
if [ $@ ]
then
RC_FILE=$@
fi
LD_LIBRARY_PATH=../../lib/.libs ../../client/.libs/fwknop --rc-file $RC_FILE -T -a 1.1.1.1 -n testhost.com
LD_LIBRARY_PATH=../../lib/.libs ../../client/.libs/fwknop -v -v --rc-file $RC_FILE -T -a 1.1.1.1 -n testhost2.com
exit $?
@@ -1,6 +1,13 @@
#!/bin/sh -x
FWKNOPD_CONF_FILE="test-cases/server-conf/fwknopd.conf"
. ./fuzzing-wrappers/fcns
IN_DIR_BASE="test-cases/server-conf"
IN_DIR=''
CONF_FILE="/fwknopd.conf"
fw_type $IN_DIR_BASE IN_DIR
FWKNOPD_CONF_FILE="$IN_DIR$CONF_FILE"
if [ $@ ]
then
@@ -1,7 +1,10 @@
#!/bin/sh -x
SPA_PKT="1716411011200157:root:1397329899:2.0.1:1:127.0.0.2,tcp/22:AAAAA"
IN_DIR="test-cases/spa-pkts.cmin"
echo -n $SPA_PKT | LD_LIBRARY_PATH=../../lib/.libs ../../server/.libs/fwknopd -c ../conf/default_fwknopd.conf -a ../conf/default_access.conf -A -f -t
for spa_pkt_file in $IN_DIR/*
do
cat $spa_pkt_file | LD_LIBRARY_PATH=../../lib/.libs ../../server/.libs/fwknopd -c ../conf/default_fwknopd.conf -a ../conf/default_access.conf -A -f -t || exit $?
done
exit $?
exit 0
+5 -4
View File
@@ -10,6 +10,7 @@ FDIR="server-access.out"
OUT_DIR="$TOP_DIR/$FDIR"
PREV_OUT_DIR=''
IN_DIR="test-cases/server-access"
FUZZ_FILE=$OUT_DIR/afl_access.conf
### build up our afl-fuzz text banner
TSTR="fwknopd,access.conf"
@@ -31,10 +32,10 @@ fi
### run afl-fuzz
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz \
-T $BANNER -t 1000 -i $IN_DIR \
-o $OUT_DIR -f $OUT_DIR/afl_access.conf $SERVER \
-c ../conf/ipt_snat_fwknopd.conf \
-a $OUT_DIR/afl_access.conf \
-m $MEM_LIMIT -T $BANNER -t $TIMEOUT \
-i $IN_DIR -o $OUT_DIR -f $FUZZ_FILE \
$SERVER -c ../conf/ipt_snat_fwknopd.conf \
-a $FUZZ_FILE \
-O ../conf/override_no_digest_tracking_fwknopd.conf \
-A -f -t --exit-parse-config -v -v -v -r `pwd`/run
+10 -4
View File
@@ -9,7 +9,9 @@
FDIR="server-conf.out"
OUT_DIR="$TOP_DIR/$FDIR"
PREV_OUT_DIR=''
IN_DIR="test-cases/server-conf"
IN_DIR_BASE="test-cases/server-conf"
IN_DIR=''
FUZZ_FILE=$OUT_DIR/afl_fwknopd.conf
### build up our afl-fuzz text banner
TSTR="fwknopd,fwknopd.conf"
@@ -17,6 +19,9 @@ GIT_STR=''
git_banner GIT_STR
BANNER="$TSTR$GIT_STR"
### point to the appropriate test cases (iptables vs. firewalld)
fw_type $IN_DIR_BASE IN_DIR
### set up directories
dir_init $ARCHIVE_DIR $FDIR $OUT_DIR PREV_OUT_DIR
@@ -29,11 +34,12 @@ fi
### make sure that parsing the fwknopd.conf file works
./fuzzing-wrappers/helpers/fwknopd-parse-conf.sh || exit $?
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz -T $BANNER -t 1000 -i $IN_DIR \
-o $OUT_DIR -f $OUT_DIR/afl_fwknopd.conf $SERVER \
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz \
-m $MEM_LIMIT -T $BANNER -t $TIMEOUT -i $IN_DIR \
-o $OUT_DIR -f $FUZZ_FILE $SERVER \
-O ../conf/override_no_digest_tracking_fwknopd.conf \
-a ../conf/default_access.conf \
-c $OUT_DIR/afl_fwknopd.conf \
-c $FUZZ_FILE \
-A -f -t --exit-parse-config -v -v -v -r `pwd`/run
exit $?
@@ -31,7 +31,7 @@ fi
### run afl-fuzz
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz \
-T $BANNER -t 1000 -i $IN_DIR \
-m $MEM_LIMIT -T $BANNER -t $TIMEOUT -i $IN_DIR \
-o $OUT_DIR -f $OUT_DIR/afl_digest_cache.conf $SERVER \
-c ../conf/ipt_snat_fwknopd.conf \
-a ../conf/default_access.conf \
+1 -1
View File
@@ -32,7 +32,7 @@ fi
./fuzzing-wrappers/helpers/fwknopd-enc-pkt-file.sh
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz \
-T $BANNER -t 1000 -i $IN_DIR \
-m $MEM_LIMIT -T $BANNER -t $TIMEOUT -i $IN_DIR \
-o $OUT_DIR -f $OUT_DIR/afl_enc_pkt.data $SERVER \
-c ../conf/default_fwknopd.conf \
-a ../conf/default_access.conf \
+3 -2
View File
@@ -9,7 +9,7 @@
FDIR="spa-pkts.out"
OUT_DIR="$TOP_DIR/$FDIR"
PREV_OUT_DIR=''
IN_DIR="test-cases/spa-pkts"
IN_DIR="test-cases/spa-pkts.cmin"
### build up our afl-fuzz text banner
TSTR="fwknopd,SPA,encode/decode"
@@ -29,7 +29,8 @@ fi
### make sure that a basic SPA packet to stdin in fwknopd -A mode works
./fuzzing-wrappers/helpers/fwknopd-stdin-test.sh || exit $?
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz -T $BANNER -t 1000 \
LD_LIBRARY_PATH=$LIB_DIR afl-fuzz \
-m $MEM_LIMIT -T $BANNER -t $TIMEOUT \
-i $IN_DIR -o $OUT_DIR $SERVER \
-c ../conf/default_fwknopd.conf \
-a ../conf/default_access.conf -A -f -t

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Some files were not shown because too many files have changed in this diff Show More