Permalink
Browse files

Better SPA message validation upon SPA decrypt/decode.

Added SPA message validation calls to fko decoding routines to help
ensure that SPA messages conform to expected values.
  • Loading branch information...
1 parent 4c25aa1 commit 5ef07c73e2a6bcecbc3c9914340cc63c266f816b @mrash committed Jul 21, 2012
Showing with 84 additions and 21 deletions.
  1. +3 −1 ChangeLog
  2. +4 −4 Makefile.am
  3. +0 −2 common/common.h
  4. +2 −2 lib/Makefile.am
  5. +1 −0 lib/fko.h
  6. +1 −0 lib/fko_common.h
  7. +8 −0 lib/fko_decode.c
  8. +3 −0 lib/fko_limits.h
  9. +2 −11 lib/fko_message.c
  10. +45 −0 lib/fko_message.h
  11. +15 −1 server/incoming_spa.c
View
@@ -9,8 +9,10 @@ fwknop-2.0.1 (07//2012):
digest list right after the first access.conf stanza match, so when SPA
packet data matched the second access.conf stanza a matching replay
digest would already be there.
+ - Added SPA message validation calls to fko decoding routines to help
+ ensure that SPA messages conform to expected values.
- Bug fix for PF firewalls: updated the PF anchor check to not rely on
- listing the PF policy - use 'pfctl -s Anchor' instead.
+ listing the PF policy - fwknopd now uses 'pfctl -s Anchor' instead.
- [test suite] Added parsing of valgrind output to produce a listing of
functions that have been flagged - this assists in the development
process to ensure that fwknop is not leaking memory.
View
@@ -103,10 +103,10 @@ EXTRA_DIST = \
perl/FKO/lib/FKO.pm \
perl/FKO/lib/FKO_Constants.pl \
perl/FKO/Changes \
- python/README \
- python/setup.py \
- python/fkomodule.c \
- python/fko.py \
+ python/README \
+ python/setup.py \
+ python/fkomodule.c \
+ python/fko.py \
ShortLog* \
test/conf/client-gpg/pubring.gpg \
test/conf/client-gpg/secring.gpg \
View
@@ -104,8 +104,6 @@ enum {
#define MAX_PORT 65535
#define MAX_PORT_STR_LEN 6
#define MAX_PROTO_STR_LEN 6
-#define MAX_IPV4_STR_LEN 16
-#define MIN_IPV4_STR_LEN 9
#define MAX_SERVER_STR_LEN 50
#define MAX_LINE_LEN 1024
View
@@ -4,8 +4,8 @@ libfko_source_files = \
base64.c base64.h cipher_funcs.c cipher_funcs.h digest.c digest.h \
fko_client_timeout.c fko_common.h fko_digest.c fko_encode.c \
fko_decode.c fko_encryption.c fko_error.c fko_funcs.c fko_message.c \
- fko_nat_access.c fko_rand_value.c fko_server_auth.c fko.h fko_limits.h \
- fko_timestamp.c fko_user.c fko_util.h md5.c md5.h \
+ fko_message.h fko_nat_access.c fko_rand_value.c fko_server_auth.c \
+ fko.h fko_limits.h fko_timestamp.c fko_user.c fko_util.h md5.c md5.h \
rijndael.c rijndael.h sha1.c sha1.h sha2.c sha2.h strlcat.c \
strlcpy.c fko_state.h fko_context.h gpgme_funcs.c gpgme_funcs.h
View
@@ -32,6 +32,7 @@
#define FKO_H 1
#include <time.h>
+#include "fko_limits.h"
#ifdef __cplusplus
extern "C" {
View
@@ -120,6 +120,7 @@
#include "fko_limits.h"
#include "fko_state.h"
#include "fko_context.h"
+#include "fko_message.h"
/* Try to cover for those that do not have bzero.
*/
View
@@ -281,6 +281,14 @@ fko_decode_spa_data(fko_ctx_t ctx)
b64_decode(tbuf, (unsigned char*)ctx->message);
+ /* Require a message similar to: 1.2.3.4,tcp/22
+ */
+ if(validate_access_msg(ctx->message) != FKO_SUCCESS)
+ {
+ free(tbuf);
+ return(FKO_ERROR_INVALID_DATA);
+ }
+
/* Extract nat_access string if the message_type indicates so.
*/
if( ctx->message_type == FKO_NAT_ACCESS_MSG
View
@@ -48,6 +48,9 @@
#define MIN_SPA_FIELDS 6
#define MAX_SPA_FIELDS 10
+#define MAX_IPV4_STR_LEN 16
+#define MIN_IPV4_STR_LEN 7
+
/* Misc.
*/
#define FKO_ENCODE_TMP_BUF_SIZE 1024
View
@@ -32,15 +32,6 @@
#include "fko_common.h"
#include "fko.h"
-/* SPA message format validation functions.
- * (These called from the spa_message function here only).
-*/
-int validate_cmd_msg(const char *msg);
-int validate_access_msg(const char *msg);
-int validate_proto_port_spec(const char *msg);
-int validate_nat_access_msg(const char *msg);
-int got_allow_ip(const char *msg);
-
/* Set the SPA message type.
*/
int
@@ -90,13 +81,13 @@ fko_set_spa_message(fko_ctx_t ctx, const char *msg)
/* Gotta have a valid string.
*/
- if(msg == NULL || strlen(msg) == 0)
+ if(msg == NULL || strnlen(msg, MAX_SPA_MESSAGE_SIZE) == 0)
return(FKO_ERROR_INVALID_DATA);
/* --DSS XXX: Bail out for now. But consider just
* truncating in the future...
*/
- if(strlen(msg) > MAX_SPA_MESSAGE_SIZE)
+ if(strnlen(msg, MAX_SPA_MESSAGE_SIZE) == MAX_SPA_MESSAGE_SIZE)
return(FKO_ERROR_DATA_TOO_LARGE);
/* Basic message type and format checking...
View
@@ -0,0 +1,45 @@
+/*
+ *****************************************************************************
+ *
+ * File: fko_message.h
+ *
+ * Author: Michael Rash
+ *
+ * Purpose: Provide validation functions for SPA messages
+ *
+ * Copyright 2012 Michael Rash (mbr@cipherdyne.org)
+ *
+ * License (GNU Public License):
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 FKO_MESSAGE_H
+#define FKO_MESSAGE_H 1
+
+/* SPA message format validation functions.
+*/
+int validate_cmd_msg(const char *msg);
+int validate_access_msg(const char *msg);
+int validate_proto_port_spec(const char *msg);
+int validate_nat_access_msg(const char *msg);
+int got_allow_ip(const char *msg);
+
+#endif /* FKO_MESSAGE_H */
+
+/***EOF***/
View
@@ -569,7 +569,21 @@ incoming_spa(fko_srv_options_t *opts)
continue;
}
- strlcpy(spadat.spa_message_src_ip, spadat.spa_message, (spa_ip_demark-spadat.spa_message)+1);
+ strlcpy(spadat.spa_message_src_ip,
+ spadat.spa_message, (spa_ip_demark-spadat.spa_message)+1);
+
+ if(strnlen(spadat.spa_message_src_ip,
+ MIN_IPV4_STR_LEN) < MIN_IPV4_STR_LEN)
+ {
+ log_msg(LOG_WARNING, "(stanza #%d) Invalid source IP in SPA message, ignoring SPA packet",
+ stanza_num, fko_errstr(res));
+
+ if(ctx != NULL)
+ fko_destroy(ctx);
+ acc = acc->next;
+ break;
+ }
+
strlcpy(spadat.spa_message_remain, spa_ip_demark+1, 1024);
/* If use source IP was requested (embedded IP of 0.0.0.0), make sure it

0 comments on commit 5ef07c7

Please sign in to comment.