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.
This commit is contained in:
Michael Rash 2012-07-21 15:32:15 -04:00
parent 4c25aa17f3
commit 5ef07c73e2
11 changed files with 84 additions and 21 deletions

View File

@ -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 File

@ -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 File

@ -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 File

@ -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 File

@ -32,6 +32,7 @@
#define FKO_H 1
#include <time.h>
#include "fko_limits.h"
#ifdef __cplusplus
extern "C" {

View File

@ -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 File

@ -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 File

@ -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 File

@ -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...

45
lib/fko_message.h Normal file
View File

@ -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 File

@ -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