Skip to content
Browse files

Fixed memory leak issue in libfko when fko_new_with_data() was called…

… with a bad key. Added autoconf checks for gdbm with fallback to ndbm for server builds. Added digest cache capability using gdbm (in ndbm compatibility mode) or ndbm for replay detection.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@153 510a4753-2344-4c79-9c09-4d669213fbeb
  • Loading branch information...
1 parent 8b4b55f commit 8c1261ca39fba47568542b8afdb5ca1b16cadf3e Damien Stuart committed Oct 16, 2009
Showing with 265 additions and 37 deletions.
  1. +13 −6 configure.ac
  2. +1 −0 lib/fko_encryption.c
  3. +28 −7 lib/fko_funcs.c
  4. +1 −5 server/Makefile.am
  5. +8 −7 server/fwknopd.c
  6. +21 −12 server/incoming_spa.c
  7. +156 −0 server/replay_dbm.c
  8. +37 −0 server/replay_dbm.h
View
19 configure.ac
@@ -189,15 +189,23 @@ AC_ARG_ENABLE([server],
[])
AM_CONDITIONAL([WANT_SERVER], [test "$want_server" = yes])
-dnl Check for libpcap if we are building the server component
+dnl Check for libpcap, gdbm (or ndbm) if we are building the server component
dnl
-have_pcap=yes
AS_IF([test "$want_server" = yes],
- AC_CHECK_LIB([pcap],[pcap_open_live],
- AC_DEFINE([HAVE_LIBPCAP], [1], [Define if you have libpcap]), [have_pcap=no]
+ # Looking for libpcap
+ #
+ AC_CHECK_LIB([pcap],[pcap_open_live], [],
+ [ AC_MSG_ERROR([fwknopd needs libpcap])]
+ )
+
+ # Looking for gdbm or fallback to ndbm or bail
+ #
+ AC_CHECK_LIB([gdbm],[dbm_open], [],
+ [ AC_CHECK_LIB([ndbm],[dbm_open], [],
+ [ AC_MSG_ERROR([fwknopd needs either gdbm or ndbm])]
+ )]
)
)
-AM_CONDITIONAL([HAVE_LIBPCAP],[test "$have_pcap" = yes])
AC_CONFIG_FILES([Makefile
lib/Makefile
@@ -213,6 +221,5 @@ echo "
============================================
Client build: $want_client
Server build: $want_server
- - with libpcap: $have_pcap
GPG encryption support: $have_gpgme
"
View
1 lib/fko_encryption.c
@@ -111,6 +111,7 @@ _rijndael_decrypt(fko_ctx_t ctx, char *dec_key, int b64_len)
return(FKO_ERROR_MEMORY_ALLOCATION);
memmove(tbuf+strlen(B64_RIJNDAEL_SALT), tbuf, b64_len);
+
ctx->encrypted_msg = memcpy(tbuf, B64_RIJNDAEL_SALT, strlen(B64_RIJNDAEL_SALT));
/* Adjust b64_len for added SALT value and Make sure we are still
View
35 lib/fko_funcs.c
@@ -158,12 +158,11 @@ int
fko_new_with_data(fko_ctx_t *r_ctx, char *enc_msg, char *dec_key)
{
fko_ctx_t ctx;
+ int res = FKO_SUCCESS; /* Are we optimistic or what? */
- int res = fko_new(r_ctx);
- if(res != FKO_SUCCESS)
- return res;
-
- ctx = *r_ctx;
+ ctx = calloc(1, sizeof *ctx);
+ if(ctx == NULL)
+ return(FKO_ERROR_MEMORY_ALLOCATION);
/* First, add the data to the context.
*/
@@ -174,13 +173,35 @@ fko_new_with_data(fko_ctx_t *r_ctx, char *enc_msg, char *dec_key)
return(FKO_ERROR_MEMORY_ALLOCATION);
}
+ /* Consider it initialized here.
+ */
+ ctx->initval = FKO_CTX_INITIALIZED;
+ FKO_SET_CTX_INITIALIZED(ctx);
+
/* If a decryption password is provided, go ahead and decrypt and
* decode.
*/
if(dec_key != NULL)
- return(fko_decrypt_spa_data(ctx, dec_key));
+ {
+ res = fko_decrypt_spa_data(ctx, dec_key);
- return(FKO_SUCCESS);
+ if(res != FKO_SUCCESS)
+ {
+ fko_destroy(ctx);
+ return(res);
+ }
+ }
+
+#if HAVE_LIBGPGME
+ /* Set gpg signature verify on.
+ */
+ ctx->verify_gpg_sigs = 1;
+#endif /* HAVE_LIBGPGME */
+
+
+ *r_ctx = ctx;
+
+ return(res);
}
/* Destroy a context and free its resources
View
6 server/Makefile.am
@@ -4,14 +4,10 @@ fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
fwknopd_common.h incoming_spa.c incoming_spa.h \
pcap_capture.c pcap_capture.h process_packet.c \
process_packet.h log_msg.c log_msg.h utils.c utils.h \
- sig_handler.c sig_handler.h
+ sig_handler.c sig_handler.h replay_dbm.c replay_dbm.h
fwknopd_LDADD = $(top_builddir)/lib/libfko.la
-if HAVE_LIBPCAP
- fwknopd_LDADD += -lpcap
-endif
-
fwknopd_CPPFLAGS = -I $(top_srcdir)/lib -I $(top_srcdir)/common -DSYSCONFDIR=\"$(sysconfdir)\"
fwknopddir = @sysconfdir@/fwknop
View
15 server/fwknopd.c
@@ -33,6 +33,7 @@
#include "log_msg.h"
#include "utils.h"
#include "sig_handler.h"
+#include "replay_dbm.h"
/* Prototypes
*/
@@ -44,7 +45,7 @@ int
main(int argc, char **argv)
{
fko_ctx_t ctx;
- int res, last_sig;
+ int res, last_sig, rpdb_count;
char *spa_data, *version;
char access_buf[MAX_LINE_LEN];
pid_t old_pid;
@@ -176,12 +177,12 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
-#ifndef HAVE_LIBPCAP
- log_msg(LOG_ERR|LOG_STDERR,
- "libpcap is not avaiable, I'm hosed (for now).");
- exit(EXIT_FAILURE);
-#endif
-
+ /* Initialize the digest cache (replay attack detection dbm).
+ */
+ rpdb_count = replay_db_init(&opts);
+
+fprintf(stderr, "RPDB Count: %i\n", rpdb_count);
+
/* Intiate pcap capture mode...
*/
pcap_capture(&opts);
View
33 server/incoming_spa.c
@@ -25,6 +25,7 @@
*/
#include "fwknopd_common.h"
#include "incoming_spa.h"
+#include "log_msg.h"
/* The pcap capture routine.
*/
@@ -45,27 +46,35 @@ fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
/* Get the decryption key
*/
+ // TODO: finish me
+ /* Decode the packet data
+ * --DSS TEMP note using the hard-coded "sdf" as the password.
+ * this is just for dev testing until I get the
+ * access.conf handling in.
+ */
res = fko_new_with_data(&ctx, spa_pkt->packet_data, "sdf");
- if(res == FKO_SUCCESS)
- {
-
-fprintf(stderr, "Decode res = %i\n", res);
- display_ctx(ctx);
+ /* Reset the packet data length to 0.
+ */
+ spa_pkt->packet_data_len = 0;
- fko_destroy(ctx);
- }
- else
+ if(res != FKO_SUCCESS)
{
fprintf(stderr, "Error creating fko context: %s\n", fko_errstr(res));
+ return(-1);
}
- /* Reset the packet data length to 0.
- */
- spa_pkt->packet_data_len = 0;
+fprintf(stderr, "Decode res = %i\n", res);
+
+
+ display_ctx(ctx);
+
+ res = replay_check(opts, ctx);
+
+ fko_destroy(ctx);
- return(0);
+ return(res);
}
/***EOF***/
View
156 server/replay_dbm.c
@@ -0,0 +1,156 @@
+/*
+ *****************************************************************************
+ *
+ * File: replay_dbm.c
+ *
+ * Author: Damien S. Stuart
+ *
+ * Purpose: Provides the functions to check for possible replay attacks
+ * by using a dbm (ndbm or gdbm in ndbm compatibility mode) file
+ * to store a digest of previously received SPA packets.
+ *
+ * Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
+ *
+ * License (GNU Public License):
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ *****************************************************************************
+*/
+#include "replay_dbm.h"
+#include "log_msg.h"
+
+#if HAVE_LIBGDBM
+ /* NOTE: We are using gdbm in ndbm compatibility mode so we grab its
+ * version of ndbm.h
+ */
+// #include <gdbm.h>
+ #include <gdbm/ndbm.h>
+#elif HAVE_LIBNDBM
+ #include <ndbm.h>
+#else
+ #error "No DBM header file found. WTF?"
+#endif
+
+#if HAVE_SYS_SOCKET_H
+ #include <sys/socket.h>
+#endif
+#include <arpa/inet.h>
+
+#include <fcntl.h>
+
+#define MAX_DIGEST_SIZE 64
+
+/* 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.
+*/
+int
+replay_db_init(fko_srv_options_t *opts)
+{
+ DBM *rpdb;
+ datum db_ent;
+
+ int db_count = 0;
+
+ rpdb = dbm_open(opts->config[CONF_DIGEST_FILE], O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+
+ if(!rpdb)
+ {
+ perror("Unable to create digest cache file: ");
+ return(-1);
+ }
+
+ for (db_ent = dbm_firstkey(rpdb); db_ent.dptr != NULL; db_ent = dbm_nextkey(rpdb))
+ db_count++;
+
+ dbm_close(rpdb);
+
+ return(db_count);
+}
+
+/* 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),
+ * 0 for no match, and -1 on error.
+*/
+int
+replay_check(fko_srv_options_t *opts, fko_ctx_t ctx)
+{
+ DBM *rpdb;
+ datum db_key, db_ent;
+
+ char ipaddr[INET_ADDRSTRLEN+1] = {0};
+
+ char *digest;
+ int digest_len, res;
+
+ res = fko_get_spa_digest(ctx, &digest);
+ if(res != FKO_SUCCESS)
+ {
+ log_msg(LOG_WARNING|LOG_STDERR, "Error getting digest from SPA data: %s",
+ fko_errstr(res));
+
+ return(-1);
+ }
+
+ digest_len = strlen(digest);
+
+ db_key.dptr = digest;
+ db_key.dsize = digest_len;
+
+ /* Check the db for the key
+ */
+ rpdb = dbm_open(opts->config[CONF_DIGEST_FILE], O_RDWR, 0);
+
+ if(!rpdb)
+ {
+ log_msg(LOG_WARNING|LOG_STDERR, "Error opening digest_cache: %s",
+ strerror(errno));
+
+ return(-1);
+ }
+
+ db_ent = dbm_fetch(rpdb, db_key);
+
+ /* If the datum is not null, we have a match. Otherwise, we add
+ * this entry to the cache.
+ */
+ if(db_ent.dptr != NULL)
+ {
+ /* Convert the IP to a human readable form
+ */
+ inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip),
+ ipaddr, INET_ADDRSTRLEN);
+
+ log_msg(LOG_WARNING|LOG_STDERR,
+ "Replay detected from source IP: %s", ipaddr);
+
+ res = 1;
+ } else {
+ db_ent.dptr = (char*)&(opts->spa_pkt.packet_src_ip);
+ db_ent.dsize = sizeof(opts->spa_pkt.packet_src_ip);
+
+ if(dbm_store(rpdb, db_key, db_ent, DBM_INSERT) != 0)
+ {
+ log_msg(LOG_WARNING|LOG_STDERR, "Error adding entry digest_cache: %s",
+ strerror(errno));
+
+ res = -1;
+ }
+
+ res = 0;
+ }
+
+ dbm_close(rpdb);
+
+ return(res);
+}
+
+/***EOF***/
View
37 server/replay_dbm.h
@@ -0,0 +1,37 @@
+/*
+ *****************************************************************************
+ *
+ * File: replay_dbm.h
+ *
+ * Author: Damien Stuart (dstuart@dstuart.org)
+ *
+ * Purpose: Header file for fwknopd replay_dbm.c functions.
+ *
+ * Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
+ *
+ * License (GNU Public License):
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ *****************************************************************************
+*/
+#ifndef REPLAY_DBM_H
+#define REPLAY_DBM_H
+
+#include "fwknopd_common.h"
+#include "fko.h"
+
+/* Prototypes
+*/
+int replay_db_init(fko_srv_options_t *opts);
+int replay_check(fko_srv_options_t *opts, fko_ctx_t ctx);
+
+#endif /* REPLAY_DBM_H */

0 comments on commit 8c1261c

Please sign in to comment.
Something went wrong with that request. Please try again.