Skip to content

Commit

Permalink
Added autoconf support for non-dbm file cache.
Browse files Browse the repository at this point in the history
This change starts on support for a simple file-based cache mechanism
for tracking SPA digests.  This removes the libgdbm/libndbm dependency
by default, but it can be re-enabled with the --disable-file-cache
argument to the ./configure script.
  • Loading branch information
mrash committed Aug 11, 2011
1 parent 2dd7c4a commit 0525cd4
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 36 deletions.
64 changes: 41 additions & 23 deletions configure.ac
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ AC_ARG_ENABLE([digest-cache],
[]) [])
dnl AM_CONDITIONAL([WANT_DIGEST_CACHE], [test "$want_digest_cache" = yes]) dnl AM_CONDITIONAL([WANT_DIGEST_CACHE], [test "$want_digest_cache" = yes])


dnl Decide whether or not to try to look for gdbm/ndbm (default to just
dnl use a file-based solution - reduces dependencies)
dnl
want_file_cache=yes
AC_ARG_ENABLE([file-cache],
[AS_HELP_STRING([--disable-file-cache],
[Replace file cache with gdbm/ndbm @<:@default on@:>@])],
[want_file_cache=$enableval],
[])
AS_IF([test "$want_file_cache" = yes], [
AC_DEFINE([USE_FILE_CACHE], [1], [Define this to enable non-gdbm/ndbm digest storing (eliminates gdbm/ndbm dependency).])
])

AC_GNU_SOURCE AC_GNU_SOURCE


AC_PROG_CC AC_PROG_CC
Expand Down Expand Up @@ -195,36 +208,40 @@ AS_IF([test "$want_server" = yes], [
use_ndbm=no use_ndbm=no
have_digest_cache=yes have_digest_cache=yes
# Looking for gdbm or fallback to ndbm or bail AS_IF([test "$want_file_cache" = no], [
#
AC_CHECK_LIB([gdbm],[gdbm_open], # Looking for gdbm or fallback to ndbm or bail
[ #
AC_DEFINE([HAVE_LIBGDBM], [1], [Define if you have libgdbm]) AC_CHECK_LIB([gdbm],[gdbm_open],
], [
[ AC_CHECK_LIB([ndbm],[dbm_open], AC_DEFINE([HAVE_LIBGDBM], [1], [Define if you have libgdbm])
[ ],
AC_DEFINE([HAVE_LIBNDBM], [1], [Define if you have libndbm]) [ AC_CHECK_LIB([ndbm],[dbm_open],
use_ndbm=yes [
], AC_DEFINE([HAVE_LIBNDBM], [1], [Define if you have libndbm])
[ AC_CHECK_HEADER([ndbm.h], use_ndbm=yes
[ AC_CHECK_FUNC([dbm_open], ],
[ AC_DEFINE([HAVE_LIBNDBM], [1], [Define if you have libndbm])], [ AC_CHECK_HEADER([ndbm.h],
[ [ AC_CHECK_FUNC([dbm_open],
AC_DEFINE([NO_DIGEST_CACHE], [1], [Define this to disable the digest cache for replay detection.]) [ AC_DEFINE([HAVE_LIBNDBM], [1], [Define if you have libndbm])],
AC_MSG_WARN([No DBM implementation found. Replay detection will be disabled.]) [
have_digest_cache=no AC_DEFINE([NO_DIGEST_CACHE], [1], [Define this to disable the digest cache for replay detection - not recommended.])
] AC_MSG_WARN([No DBM implementation found. Replay detection will be disabled.])
)] have_digest_cache=no
)] ]
)] )]
)]
)]
)]
)], )],
[ [
AC_DEFINE([NO_DIGEST_CACHE], [1], [Define this to disable the digest cache for replay detection.]) AC_DEFINE([NO_DIGEST_CACHE], [1], [Define this to disable the digest cache for replay detection - not recommended.])
have_digest_cache=no have_digest_cache=no
] ]
) )
AM_CONDITIONAL([USE_NDBM], [test x$use_ndbm = xyes]) AM_CONDITIONAL([USE_NDBM], [test x$use_ndbm = xyes])
AM_CONDITIONAL([CONFIG_FILE_CACHE], [test x$want_file_cache = xyes])
dnl Check for iptables dnl Check for iptables
dnl dnl
Expand Down Expand Up @@ -312,6 +329,7 @@ dnl
[test "$want_server" = no], [ [test "$want_server" = no], [
use_ndbm=no use_ndbm=no
AM_CONDITIONAL([USE_NDBM], [test x$use_ndbm = xno]) AM_CONDITIONAL([USE_NDBM], [test x$use_ndbm = xno])
AM_CONDITIONAL([CONFIG_FILE_CACHE], [test x$use_ndbm = xno])
] ]
) )
Expand Down
3 changes: 3 additions & 0 deletions server/Makefile.am
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
fw_util_ipfw.c fw_util_ipfw.h fw_util_ipfw.c fw_util_ipfw.h


fwknopd_LDADD = $(top_builddir)/lib/libfko.la -lpcap fwknopd_LDADD = $(top_builddir)/lib/libfko.la -lpcap

if ! CONFIG_FILE_CACHE
if USE_NDBM if USE_NDBM
fwknopd_LDADD += -lndbm fwknopd_LDADD += -lndbm
else else
fwknopd_LDADD += -lgdbm fwknopd_LDADD += -lgdbm
endif endif
endif


fwknopd_CPPFLAGS = -I $(top_srcdir)/lib -I $(top_srcdir)/common -DSYSCONFDIR=\"$(sysconfdir)\" -DSYSRUNDIR=\"$(localstatedir)\" fwknopd_CPPFLAGS = -I $(top_srcdir)/lib -I $(top_srcdir)/common -DSYSCONFDIR=\"$(sysconfdir)\" -DSYSRUNDIR=\"$(localstatedir)\"


Expand Down
11 changes: 6 additions & 5 deletions server/fwknopd.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static pid_t get_running_pid(fko_srv_options_t *opts);
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int res, last_sig, rpdb_count; int res, last_sig, rp_cache_count;
char *locale; char *locale;
pid_t old_pid; pid_t old_pid;


Expand Down Expand Up @@ -239,14 +239,15 @@ main(int argc, char **argv)
dump_access_list(&opts); dump_access_list(&opts);
} }


/* Initialize the digest cache for replay attack detection /* Initialize the digest cache for replay attack detection (either
* with dbm support or with the default simple cache file strategy)
* if so configured. * if so configured.
*/ */
if(strncasecmp(opts.config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0) if(strncasecmp(opts.config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
{ {
rpdb_count = replay_db_init(&opts); rp_cache_count = replay_cache_init(&opts);


if(rpdb_count < 0) if(rp_cache_count < 0)
{ {
log_msg(LOG_WARNING, log_msg(LOG_WARNING,
"Error opening digest cache file. Incoming digests will not be remembered." "Error opening digest cache file. Incoming digests will not be remembered."
Expand All @@ -257,7 +258,7 @@ main(int argc, char **argv)
if(opts.verbose) if(opts.verbose)
log_msg(LOG_ERR, log_msg(LOG_ERR,
"Using Digest Cache: '%s' (entry count = %i)", "Using Digest Cache: '%s' (entry count = %i)",
opts.config[CONF_DIGEST_FILE], rpdb_count opts.config[CONF_DIGEST_FILE], rp_cache_count
); );
} }


Expand Down
116 changes: 112 additions & 4 deletions server/replay_cache.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@


#include <time.h> #include <time.h>


#if HAVE_LIBGDBM #if USE_FILE_CACHE

#elif HAVE_LIBGDBM
#include <gdbm.h> #include <gdbm.h>


#define MY_DBM_FETCH(d, k) gdbm_fetch(d, k) #define MY_DBM_FETCH(d, k) gdbm_fetch(d, k)
Expand All @@ -61,7 +63,7 @@
#define MY_DBM_INSERT DBM_INSERT #define MY_DBM_INSERT DBM_INSERT


#else #else
#error "No GDBM or NDBM header file found. WTF?" #error "File cache method disabled, and No GDBM or NDBM header file found. WTF?"
#endif #endif


#if HAVE_SYS_SOCKET_H #if HAVE_SYS_SOCKET_H
Expand Down Expand Up @@ -108,11 +110,39 @@ rotate_digest_cache_file(fko_srv_options_t *opts)
#endif /* NO_DIGEST_CACHE */ #endif /* NO_DIGEST_CACHE */
} }


int
replay_cache_init(fko_srv_options_t *opts)
{
#ifdef NO_DIGEST_CACHE
return 0;
#else

#if USE_FILE_CACHE
return replay_file_cache_init(opts);
#else
return replay_db_cache_init(opts);
#endif

#endif /* NO_DIGEST_CACHE */
}

#if USE_FILE_CACHE
int
replay_file_cache_init(fko_srv_options_t *opts)
{
/* if the file exists, import the previous SPA digests into
* the cache list
*/
return 0;
}

#else /* USE_FILE_CACHE */

/* Check for the existence of the replay dbm file, and create it if it does /* Check for the existence of the replay dbm file, and create it if it does
* not exist. Returns the number of db entries or -1 on error. * not exist. Returns the number of db entries or -1 on error.
*/ */
int int
replay_db_init(fko_srv_options_t *opts) replay_db_cache_init(fko_srv_options_t *opts)
{ {
#ifdef NO_DIGEST_CACHE #ifdef NO_DIGEST_CACHE
return 0; return 0;
Expand Down Expand Up @@ -173,6 +203,7 @@ replay_db_init(fko_srv_options_t *opts)
return(db_count); return(db_count);
#endif /* NO_DIGEST_CACHE */ #endif /* NO_DIGEST_CACHE */
} }
#endif /* USE_FILE_CACHE */


/* Take an fko context, pull the digest and use it as the key to check the /* Take an fko context, pull the digest and use it as the key to check the
* replay db (digest cache). Returns 1 if there was a match (a replay), * replay db (digest cache). Returns 1 if there was a match (a replay),
Expand All @@ -185,6 +216,82 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx)
return 0; return 0;
#else #else


#if USE_FILE_CACHE
return replay_check_file_cache(opts, ctx);
#else
return replay_check_dbm_cache(opts, ctx);
#endif
#endif /* NO_DIGEST_CACHE */
}

#if USE_FILE_CACHE
int
replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
{
char *digest = NULL;
char src_ip[INET_ADDRSTRLEN+1] = {0};
char dst_ip[INET_ADDRSTRLEN+1] = {0};
int res = 0, digest_len = 0;
FILE *digest_file_cache_ptr = NULL;

digest_cache_info_t dc_info, *dci_p;

res = fko_get_spa_digest(ctx, &digest);
if(res != FKO_SUCCESS)
{
log_msg(LOG_WARNING, "Error getting digest from SPA data: %s",
fko_errstr(res));

return(SPA_MSG_DIGEST_ERROR);
}

digest_len = strlen(digest);

/* Check the cache for the key
*/

if (0)
{
}
else
{
/* This is a new SPA packet that needs to be added to the cache.
*/

/* First, add the digest into the digest cache list
*/

/* Now, write the digest to disk
*/
if ((digest_file_cache_ptr = fopen(opts->config[CONF_DIGEST_FILE], "a")) == NULL)
{
log_msg(LOG_WARNING, "Could not open digest cache: %s",
opts->config[CONF_DIGEST_FILE]);
return(SPA_MSG_DIGEST_CACHE_ERROR);
}

inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip),
src_ip, INET_ADDRSTRLEN);
fprintf(digest_file_cache_ptr, "%s %s %d\n",
digest, src_ip, (unsigned int) time(NULL));

fclose(digest_file_cache_ptr);

res = SPA_MSG_SUCCESS;
}

return(res);
}
#endif /* USE_FILE_CACHE */

#if !USE_FILE_CACHE
int
replay_check_dbm_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
{
#ifdef NO_DIGEST_CACHE
return 0;
#else

#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
GDBM_FILE rpdb; GDBM_FILE rpdb;
#elif HAVE_LIBNDBM #elif HAVE_LIBNDBM
Expand Down Expand Up @@ -250,7 +357,7 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx)
inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip), inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip),
curr_ip, INET_ADDRSTRLEN); curr_ip, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(dci_p->src_ip), last_ip, INET_ADDRSTRLEN); inet_ntop(AF_INET, &(dci_p->src_ip), last_ip, INET_ADDRSTRLEN);

/* Mark the last_replay time. /* Mark the last_replay time.
*/ */
dci_p->last_replay = time(NULL); dci_p->last_replay = time(NULL);
Expand Down Expand Up @@ -322,5 +429,6 @@ replay_check(fko_srv_options_t *opts, fko_ctx_t ctx)
return(res); return(res);
#endif /* NO_DIGEST_CACHE */ #endif /* NO_DIGEST_CACHE */
} }
#endif /* USE_FILE_CACHE */


/***EOF***/ /***EOF***/
15 changes: 11 additions & 4 deletions server/replay_cache.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
* *
***************************************************************************** *****************************************************************************
*/ */
#ifndef REPLAY_DBM_H #ifndef REPLAY_CACHE_H
#define REPLAY_DBM_H #define REPLAY_CACHE_H


#include "fwknopd_common.h" #include "fwknopd_common.h"
#include "fko.h" #include "fko.h"
Expand All @@ -44,7 +44,14 @@ typedef struct digest_cache_info {


/* Prototypes /* Prototypes
*/ */
int replay_db_init(fko_srv_options_t *opts); int replay_cache_init(fko_srv_options_t *opts);
int replay_check(fko_srv_options_t *opts, fko_ctx_t ctx); int replay_check(fko_srv_options_t *opts, fko_ctx_t ctx);
#ifdef USE_FILE_CACHE
int replay_file_cache_init(fko_srv_options_t *opts);
int replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx);
#else
int replay_db_cache_init(fko_srv_options_t *opts);
int replay_check_dbm_cache(fko_srv_options_t *opts, fko_ctx_t ctx);
#endif


#endif /* REPLAY_DBM_H */ #endif /* REPLAY_CACHE_H */

0 comments on commit 0525cd4

Please sign in to comment.