diff -Nru fwknop-2.0.0rc2/debian/changelog fwknop-2.0.0rc2/debian/changelog
--- fwknop-2.0.0rc2/debian/changelog	2012-06-24 20:59:28.000000000 +0200
+++ fwknop-2.0.0rc2/debian/changelog	2012-10-10 21:13:56.000000000 +0200
@@ -1,4 +1,13 @@
-fwknop (2.0.0rc2-2) sid; urgency=low
+fwknop (2.0.0rc2-2+deb7u1) testing-proposed-updates; urgency=high
+
+  * Patches to fix CVE (Closes: #688151):
+    - CVE-2012-4434
+    - CVE-2012-4435
+    - CVE-2012-4436
+
+ -- Franck Joncourt <franck@debian.org>  Sun, 07 Oct 2012 20:50:09 +0200
+
+fwknop (2.0.0rc2-2) unstable; urgency=low
 
   * Acknowledged NMU : 1.9.12-3.1
   * Set Architecture as linux-any (Closes: #647654)
diff -Nru fwknop-2.0.0rc2/debian/patches/cve_2012-4434.patch fwknop-2.0.0rc2/debian/patches/cve_2012-4434.patch
--- fwknop-2.0.0rc2/debian/patches/cve_2012-4434.patch	1970-01-01 01:00:00.000000000 +0100
+++ fwknop-2.0.0rc2/debian/patches/cve_2012-4434.patch	2012-10-10 21:13:56.000000000 +0200
@@ -0,0 +1,395 @@
+From d46ba1c027a11e45821ba897a4928819bccc8f22 Mon Sep 17 00:00:00 2001
+From: Michael Rash <mbr@cipherdyne.org>
+Date: Fri, 24 Aug 2012 22:12:19 -0400
+Subject: [PATCH] (Fernando Arnaboldi, IOActive) Found and fixed several
+ DoS/code execution vulns for authenticated clients
+
+- [server] Fernando Arnaboldi from IOActive found several DoS/code
+execution vulnerabilities for malicious fwknop clients that manage to
+get past the authentication stage (so a such a client must be in
+possession of a valid access.conf encryption key).  These vulnerbilities
+manifested themselves in the handling of malformed access requests, and
+both the fwknopd server code along with libfko now perform stronger input
+validation of access request data.  These vulnerabilities affect
+pre-2.0.3 fwknop releases.
+---
+
+--- a/lib/fko_message.c
++++ b/lib/fko_message.c
+@@ -30,17 +30,9 @@
+  *****************************************************************************
+ */
+ #include "fko_common.h"
++#include "fko_message.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
+@@ -204,6 +196,8 @@
+     do {
+         ndx++;
+         res = validate_proto_port_spec(ndx);
++        if(res != FKO_SUCCESS)
++            break;
+     } while((ndx = strchr(ndx, ',')));
+ 
+     return(res);
+@@ -212,7 +206,7 @@
+ int
+ validate_proto_port_spec(const char *msg)
+ {
+-    int     startlen    = strlen(msg);
++    int     startlen    = strnlen(msg, MAX_SPA_MESSAGE_SIZE), port_str_len = 0;
+ 
+     const char   *ndx   = msg;
+ 
+@@ -226,19 +220,25 @@
+         return(FKO_ERROR_INVALID_SPA_ACCESS_MSG);
+ 
+     ndx = strchr(ndx, '/');
+-    if(ndx == NULL || (1+(ndx - msg)) >= startlen)
++    if(ndx == NULL || ((1+(ndx - msg)) > MAX_PROTO_STR_LEN))
+         return(FKO_ERROR_INVALID_SPA_ACCESS_MSG);
+ 
+-    /* Skip over the ',' and make sure we only have digits.
++    /* Skip over the '/' and make sure we only have digits.
+     */
+     ndx++;
+-    while(*ndx != '\0')
++
++    /* Must have at least one digit for the port number
++    */
++    if(isdigit(*ndx) == 0)
++        return(FKO_ERROR_INVALID_SPA_ACCESS_MSG);
++
++    while(*ndx != '\0' && *ndx != ',')
+     {
+-        if(isdigit(*ndx) == 0)
++        port_str_len++;
++        if((isdigit(*ndx) == 0) || (port_str_len > MAX_PORT_STR_LEN))
+             return(FKO_ERROR_INVALID_SPA_ACCESS_MSG);
+         ndx++;
+     }
+-
+     return(FKO_SUCCESS);
+ }
+ 
+--- a/server/access.c
++++ b/server/access.c
+@@ -75,7 +75,7 @@
+ /* Take an IP or Subnet/Mask and convert it to mask for later
+  * comparisons of incoming source IPs against this mask.
+ */
+-static void
++static int
+ add_source_mask(acc_stanza_t *acc, char *ip)
+ {
+     char                *ndx;
+@@ -144,7 +144,7 @@
+             free(new_sle);
+             new_sle = NULL;
+ 
+-            return;
++            return 0;
+         }
+ 
+         /* Store our mask converted from CIDR to a 32-bit value.
+@@ -156,15 +156,17 @@
+         */
+         new_sle->maddr = ntohl(in.s_addr) & new_sle->mask;
+     }
++    return 1;
+ }
+ 
+ /* Expand the access SOURCE string to a list of masks.
+ */
+-void
++static int
+ expand_acc_source(acc_stanza_t *acc)
+ {
+     char           *ndx, *start;
+-    char            buf[32];
++    char            buf[ACCESS_BUF_LEN];
++    int             res = 1;
+ 
+     start = acc->source;
+ 
+@@ -177,8 +179,13 @@
+             while(isspace(*start))
+                 start++;
+ 
++            if(((ndx-start)+1) >= ACCESS_BUF_LEN)
++                return 0;
++
+             strlcpy(buf, start, (ndx-start)+1);
+-            add_source_mask(acc, buf);
++            res = add_source_mask(acc, buf);
++            if(res == 0)
++                return res;
+             start = ndx+1;
+         }
+     }
+@@ -188,15 +195,20 @@
+     while(isspace(*start))
+         start++;
+ 
++    if(((ndx-start)+1) >= ACCESS_BUF_LEN)
++        return 0;
++
+     strlcpy(buf, start, (ndx-start)+1);
+-    add_source_mask(acc, buf);
++    res = add_source_mask(acc, buf);
++
++    return res;
+ }
+ 
+ static int
+ parse_proto_and_port(char *pstr, int *proto, int *port)
+ {
+     char    *ndx;
+-    char    proto_str[32];
++    char    proto_str[ACCESS_BUF_LEN];
+ 
+     /* Parse the string into its components.
+     */
+@@ -210,8 +222,24 @@
+  
+     strlcpy(proto_str, pstr,  (ndx - pstr)+1);
+ 
++    if(((ndx - pstr)+1) >= ACCESS_BUF_LEN)
++    {
++        log_msg(LOG_ERR,
++            "Parse error on access port entry: %s", pstr);
++        return(-1);
++    }
++
++    strlcpy(proto_str, pstr, (ndx - pstr)+1);
++
+     *port = atoi(ndx+1);
+ 
++    if((*port < 0) || (*port > MAX_PORT))
++    {
++        log_msg(LOG_ERR,
++            "Invalid port in access request: %s", pstr);
++        return(-1);
++    }
++
+     if(strcasecmp(proto_str, "tcp") == 0)
+         *proto = PROTO_TCP;
+     else if(strcasecmp(proto_str, "udp") == 0)
+@@ -220,7 +248,6 @@
+     {
+         log_msg(LOG_ERR,
+             "Invalid protocol in access port entry: %s", pstr);
+-
+         return(-1);
+     }
+ 
+@@ -320,15 +347,15 @@
+ 
+ /* Expand a proto/port access string to a list of access proto-port struct.
+ */
+-void
++int
+ expand_acc_port_list(acc_port_list_t **plist, char *plist_str)
+ {
+     char           *ndx, *start;
+-    char            buf[32];
++    char            buf[ACCESS_BUF_LEN];
+ 
+     start = plist_str;
+ 
+-    for(ndx = start; *ndx; ndx++)
++    for(ndx = start; *ndx != '\0'; ndx++)
+     {
+         if(*ndx == ',')
+         {
+@@ -337,6 +364,9 @@
+             while(isspace(*start))
+                 start++;
+ 
++            if(((ndx-start)+1) >= ACCESS_BUF_LEN)
++                return 0;
++
+             strlcpy(buf, start, (ndx-start)+1);
+             add_port_list_ent(plist, buf);
+             start = ndx+1;
+@@ -348,9 +378,14 @@
+     while(isspace(*start))
+         start++;
+ 
++    if(((ndx-start)+1) >= ACCESS_BUF_LEN)
++        return 0;
++
+     strlcpy(buf, start, (ndx-start)+1);
+ 
+     add_port_list_ent(plist, buf);
++
++    return 1;
+ }
+ 
+ /* Expand a comma-separated string into a simple acc_string_list.
+@@ -500,7 +535,11 @@
+     {
+         /* Expand the source string to 32-bit integer masks foreach entry.
+         */
+-        expand_acc_source(acc);
++        if(expand_acc_source(acc) == 0)
++        {
++            acc = acc->next;
++            continue;
++        }
+ 
+         /* Now expand the open_ports string.
+         */
+@@ -946,9 +985,9 @@
+ int
+ acc_check_port_access(acc_stanza_t *acc, char *port_str)
+ {
+-    int             res     = 1;
++    int             res = 1, ctr = 0;
+ 
+-    char            buf[32];
++    char            buf[ACCESS_BUF_LEN];
+     char           *ndx, *start;
+ 
+     acc_port_list_t *o_pl   = acc->oport_list;
+@@ -961,14 +1000,34 @@
+     /* Create our own internal port_list from the incoming SPA data
+      * for comparison.
+     */
+-    for(ndx = start; *ndx; ndx++)
++    for(ndx = start; *ndx != '\0'; ndx++)
+     {
+         if(*ndx == ',')
+         {
++            if((ctr >= ACCESS_BUF_LEN)
++                    || (((ndx-start)+1) >= ACCESS_BUF_LEN))
++            {
++                log_msg(LOG_ERR,
++                    "Unable to create acc_port_list from incoming data: %s",
++                    port_str
++                );
++                return(0);
++            }
+             strlcpy(buf, start, (ndx-start)+1);
+             add_port_list_ent(&in_pl, buf);
+             start = ndx+1;
++            ctr = 0;
+         }
++        ctr++;
++    }
++    if((ctr >= ACCESS_BUF_LEN)
++            || (((ndx-start)+1) >= ACCESS_BUF_LEN))
++    {
++        log_msg(LOG_ERR,
++            "Unable to create acc_port_list from incoming data: %s",
++            port_str
++        );
++        return(0);
+     }
+     strlcpy(buf, start, (ndx-start)+1);
+     add_port_list_ent(&in_pl, buf);
+--- a/server/access.h
++++ b/server/access.h
+@@ -34,6 +34,8 @@
+ #define PROTO_TCP   6
+ #define PROTO_UDP   17
+ 
++#define ACCESS_BUF_LEN  32
++
+ /* Function Prototypes
+ */
+ void parse_access_file(fko_srv_options_t *opts);
+@@ -41,7 +43,7 @@
+ int acc_check_port_access(acc_stanza_t *acc, char *port_str);
+ int acc_check_gpg_remote_id(acc_stanza_t *acc, char *gpg_id);
+ void dump_access_list(fko_srv_options_t *opts);
+-void expand_acc_port_list(acc_port_list_t **plist, char *plist_str);
++int expand_acc_port_list(acc_port_list_t **plist, char *plist_str);
+ void free_acc_port_list(acc_port_list_t *plist);
+ 
+ #endif /* ACCESS_H */
+--- a/server/fw_util_iptables.c
++++ b/server/fw_util_iptables.c
+@@ -436,7 +436,8 @@
+ 
+     /* Parse and expand our access message.
+     */
+-    expand_acc_port_list(&port_list, spadat->spa_message_remain);
++    if(expand_acc_port_list(&port_list, spadat->spa_message_remain) != 1)
++        return res;
+ 
+     /* Start at the top of the proto-port list...
+     */
+--- /dev/null
++++ b/lib/fko_message.h
+@@ -0,0 +1,58 @@
++/*
++ *****************************************************************************
++ *
++ * 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
++
++#if PLATFORM_OPENBSD
++  #include <sys/types.h>
++  #include <netinet/in.h>
++#else
++  #if HAVE_SYS_SOCKET_H
++    #include <sys/socket.h>
++  #endif
++#endif
++#include <arpa/inet.h>
++
++#define MAX_PROTO_STR_LEN   4  /* tcp, udp, icmp for now */
++#define MAX_PORT_STR_LEN    5
++
++/* 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***/
diff -Nru fwknop-2.0.0rc2/debian/patches/cve_2012-4435.patch fwknop-2.0.0rc2/debian/patches/cve_2012-4435.patch
--- fwknop-2.0.0rc2/debian/patches/cve_2012-4435.patch	1970-01-01 01:00:00.000000000 +0100
+++ fwknop-2.0.0rc2/debian/patches/cve_2012-4435.patch	2012-10-10 21:13:56.000000000 +0200
@@ -0,0 +1,61 @@
+From f4c16bc47fc24a96b63105556b62d61c1ba7d799 Mon Sep 17 00:00:00 2001
+From: Michael Rash <mbr@cipherdyne.org>
+Date: Sat, 25 Aug 2012 23:08:55 -0400
+Subject: [PATCH] [server] Stronger IP validation based on a bug found by
+ Fernando Arnaboldi from IOActive
+
+This commit fixes a condition in which the server did not properly validate
+allow IP addresses from malicious authenticated clients.  This has been fixed
+with stronger allow IP validation.
+---
+
+--- a/lib/fko_message.c
++++ b/lib/fko_message.c
+@@ -261,23 +261,31 @@
+ got_allow_ip(const char *msg)
+ {
+     const char *ndx     = msg;
+-    int         dot_cnt = 0;
++    int         dot_ctr = 0, char_ctr = 0;
+     int         res     = FKO_SUCCESS;
+ 
+     while(*ndx != ',' && *ndx != '\0')
+     {
++        char_ctr++;
++        if(char_ctr >= MAX_IPV4_STR_LEN)
++        {
++            res = FKO_ERROR_INVALID_ALLOW_IP;
++            break;
++        }
+         if(*ndx == '.')
+-            dot_cnt++;
++            dot_ctr++;
+         else if(isdigit(*ndx) == 0)
+         {
+             res = FKO_ERROR_INVALID_ALLOW_IP;
+             break;
+         }
+-
+         ndx++;
+     }
+ 
+-    if(dot_cnt != 3)
++    if (char_ctr < MIN_IPV4_STR_LEN)
++        res = FKO_ERROR_INVALID_ALLOW_IP;
++
++    if(dot_ctr != 3)
+         res = FKO_ERROR_INVALID_ALLOW_IP;
+ 
+     return(res);
+--- a/lib/fko_limits.h
++++ b/lib/fko_limits.h
+@@ -43,6 +43,9 @@
+ #define MIN_SPA_ENCODED_MSG_SIZE     36 /* Somewhat arbitrary */
+ #define MIN_GNUPG_MSG_SIZE          400
+ 
++#define MAX_IPV4_STR_LEN             16
++#define MIN_IPV4_STR_LEN              7
++
+ /* Misc.
+ */
+ #define FKO_ENCODE_TMP_BUF_SIZE    1024
diff -Nru fwknop-2.0.0rc2/debian/patches/cve_2012-4436.patch fwknop-2.0.0rc2/debian/patches/cve_2012-4436.patch
--- fwknop-2.0.0rc2/debian/patches/cve_2012-4436.patch	1970-01-01 01:00:00.000000000 +0100
+++ fwknop-2.0.0rc2/debian/patches/cve_2012-4436.patch	2012-10-10 21:13:56.000000000 +0200
@@ -0,0 +1,396 @@
+From a60f05ad44e824f6230b22f8976399340cb535dc Mon Sep 17 00:00:00 2001
+From: Michael Rash <mbr@cipherdyne.org>
+Date: Wed, 29 Aug 2012 22:21:43 -0400
+Subject: [PATCH] file permissions and client buffer overflow fix
+
+- [client+server] Fernando Arnaboldi from IOActive found that strict
+filesystem permissions for various fwknop files are not verified.  Added
+warnings whenever permissions are not strict enough, and ensured that
+files created by the fwknop client and server are only set to user
+read/write.
+- [client] Fernando Arnaboldi from IOActive found a local buffer overflow
+in --last processing with a maliciously constructed ~/.fwknop.run file.
+This has been fixed with proper validation of .fwknop.run arguments.
+---
+
+--- a/client/config_init.c
++++ b/client/config_init.c
+@@ -124,9 +124,9 @@
+ static int
+ create_fwknoprc(char *rcfile)
+ {
+-    FILE    *rc;
++    FILE    *rc = NULL;
+ 
+-    fprintf(stderr, "Creating initial rc file: %s.\n", rcfile);
++    fprintf(stdout, "[*] Creating initial rc file: %s.\n", rcfile);
+ 
+     if ((rc = fopen(rcfile, "w")) == NULL)
+     {
+@@ -188,7 +188,7 @@
+         "# User-provided named stanzas:\n"
+         "\n"
+         "# Example for a destination server of 192.168.1.20 to open access to \n"
+-        "# SSH for an IP that is resoved exteranlly, and one with a NAT request\n"
++        "# SSH for an IP that is resolved externally, and one with a NAT request\n"
+         "# for a specific source IP that maps port 8088 on the server\n"
+         "# to port 88 on 192.168.1.55 with timeout.\n"
+         "#\n"
+@@ -208,6 +208,8 @@
+         "###EOF###\n"
+     );
+ 
++    set_file_perms(rcfile);
++
+     return(0);
+ }
+ 
+@@ -407,6 +409,13 @@
+     rcfile[strlen(rcfile)] = PATH_SEP;
+     strlcat(rcfile, ".fwknoprc", MAX_PATH_LEN);
+ 
++    /* Check rc file permissions - if anything other than user read/write,
++     * then don't process it.  This change was made to help ensure that the
++     * client consumes a proper rc file with strict permissions set (thanks
++     * to Fernando Arnaboldi from IOActive for pointing this out).
++    */
++    verify_file_perms_ownership(rcfile);
++
+     /* Open the rc file for reading, if it does not exist, then create
+      * an initial .fwknoprc file with defaults and go on.
+     */
+--- a/client/fwknop.c
++++ b/client/fwknop.c
+@@ -49,6 +49,7 @@
+ 
+ int resolve_ip_http(fko_cli_options_t *options);
+ 
++#define MAX_CMDLINE_ARGS    50  /* should be way more than enough */
+ 
+ int
+ main(int argc, char **argv)
+@@ -534,6 +535,8 @@
+     exit(EXIT_FAILURE);
+ #endif
+ 
++    verify_file_perms_ownership(args_save_file);
++
+     if (get_save_file(args_save_file)) {
+         if ((args_file_ptr = fopen(args_save_file, "r")) == NULL) {
+             fprintf(stderr, "Could not open args file: %s\n",
+@@ -565,7 +568,7 @@
+     char            args_save_file[MAX_PATH_LEN] = {0};
+     char            args_str[MAX_LINE_LEN] = {0};
+     char            arg_tmp[MAX_LINE_LEN]  = {0};
+-    char           *argv_new[200];  /* should be way more than enough */
++    char           *argv_new[MAX_CMDLINE_ARGS];  /* should be way more than enough */
+ 
+ 
+ #ifdef WIN32
+@@ -577,6 +580,9 @@
+ 
+     if (get_save_file(args_save_file))
+     {
++
++        verify_file_perms_ownership(args_save_file);
++
+         if ((args_file_ptr = fopen(args_save_file, "r")) == NULL)
+         {
+             fprintf(stderr, "Could not open args file: %s\n",
+@@ -601,12 +607,17 @@
+                     argv_new[argc_new] = malloc(strlen(arg_tmp)+1);
+                     if (argv_new[argc_new] == NULL)
+                     {
+-                        fprintf(stderr, "malloc failure for cmd line arg.\n");
++                        fprintf(stderr, "[*] malloc failure for cmd line arg.\n");
+                         exit(EXIT_FAILURE);
+                     }
+                     strcpy(argv_new[argc_new], arg_tmp);
+                     current_arg_ctr = 0;
+                     argc_new++;
++                    if(argc_new >= MAX_CMDLINE_ARGS)
++                    {
++                        fprintf(stderr, "[*] max command line args exceeded.\n");
++                        exit(EXIT_FAILURE);
++                    }
+                 }
+             }
+         }
+@@ -658,6 +669,9 @@
+         fprintf(args_file_ptr, "%s\n", args_str);
+         fclose(args_file_ptr);
+     }
++
++    set_file_perms(args_save_file);
++
+     return;
+ }
+ 
+--- a/client/utils.c
++++ b/client/utils.c
+@@ -28,8 +28,6 @@
+  *
+  *****************************************************************************
+ */
+-#include <stdio.h>
+-#include <string.h>
+ #include "utils.h"
+ 
+ /* Generic hex dump function.
+@@ -69,5 +67,77 @@
+     }
+ }
+ 
++int
++set_file_perms(const char *file)
++{
++    int res = 0;
++
++    res = chmod(file, S_IRUSR | S_IWUSR);
++
++    if(res != 0)
++    {
++        fprintf(stderr,
++            "[-] unable to chmod file %s to user read/write (0600, -rw-------): %s\n",
++            file,
++            strerror(errno)
++        );
++    }
++    return res;
++}
++
++int
++verify_file_perms_ownership(const char *file)
++{
++#if HAVE_STAT
++    struct stat st;
++
++    /* Every file that the fwknop client deals with should be owned
++     * by the user and permissions set to 600 (user read/write)
++    */
++    if((stat(file, &st)) != 0)
++    {
++        /* If the path does not exist, just return, but otherwise something went wrong */
++        if (errno == ENOENT)
++        {
++            return 0;
++        }
++        else
++        {
++            fprintf(stderr, "[-] unable to run stat() against file: %s: %s\n",
++                file, strerror(errno));
++            exit(EXIT_FAILURE);
++        }
++    }
++
++    /* Make sure it is a regular file or symbolic link
++    */
++    if(S_ISREG(st.st_mode) != 1 && S_ISLNK(st.st_mode) != 1)
++    {
++        fprintf(stderr,
++            "[-] file: %s is not a regular file or symbolic link.\n",
++            file
++        );
++        return 0;
++    }
++
++    if((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != (S_IRUSR|S_IWUSR))
++    {
++        fprintf(stderr,
++            "[-] file: %s permissions should only be user read/write (0600, -rw-------)\n",
++            file
++        );
++        return 0;
++    }
++
++    if(st.st_uid != getuid())
++    {
++        fprintf(stderr, "[-] file: %s not owned by current effective user id.\n",
++            file);
++        return 0;
++    }
++#endif
++
++    return 1;
++}
+ 
+ /***EOF***/
+--- a/client/utils.h
++++ b/client/utils.h
+@@ -31,10 +31,22 @@
+ #ifndef UTILS_H
+ #define UTILS_H
+ 
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <errno.h>
++
++#if HAVE_CONFIG_H
++  #include "config.h"
++#endif
+ 
+ /* Prototypes
+ */
+ void hex_dump(unsigned char *data, int size);
++int set_file_perms(const char *file);
++int verify_file_perms_ownership(const char *file);
+ size_t strlcat(char *dst, const char *src, size_t siz);
+ size_t strlcpy(char *dst, const char *src, size_t siz);
+ 
+--- a/configure.ac
++++ b/configure.ac
+@@ -121,7 +121,7 @@
+ AC_FUNC_REALLOC
+ AC_FUNC_STAT
+ 
+-AC_CHECK_FUNCS([bzero gettimeofday memmove memset socket strchr strcspn strdup strncasecmp strndup strrchr strspn])
++AC_CHECK_FUNCS([bzero gettimeofday memmove memset socket strchr strcspn strdup strncasecmp strndup strrchr strspn strnlen stat chmod chown])
+ 
+ AC_SEARCH_LIBS([socket], [socket])
+ AC_SEARCH_LIBS([inet_addr], [nsl])
+--- a/server/access.c
++++ b/server/access.c
+@@ -694,6 +694,8 @@
+         exit(EXIT_FAILURE);
+     }
+ 
++    verify_file_perms_ownership(opts->config[CONF_ACCESS_FILE]);
++
+     if ((file_ptr = fopen(opts->config[CONF_ACCESS_FILE], "r")) == NULL)
+     {
+         fprintf(stderr, "[*] Could not open access file: %s\n",
+--- a/server/config_init.c
++++ b/server/config_init.c
+@@ -136,6 +136,8 @@
+         exit(EXIT_FAILURE);
+     }
+ 
++    verify_file_perms_ownership(config_file);
++
+     if ((cfile_ptr = fopen(config_file, "r")) == NULL)
+     {
+         fprintf(stderr, "[*] Could not open config file: %s\n",
+--- a/server/fwknopd.c
++++ b/server/fwknopd.c
+@@ -646,6 +646,8 @@
+     char    buf[6]  = {0};
+     pid_t   rpid    = 0;
+ 
++    verify_file_perms_ownership(opts->config[CONF_FWKNOP_PID_FILE]);
++
+     op_fd = open(opts->config[CONF_FWKNOP_PID_FILE], O_RDONLY);
+ 
+     if(op_fd > 0)
+--- a/server/utils.c
++++ b/server/utils.c
+@@ -147,17 +147,95 @@
+ int
+ is_valid_dir(const char *path)
+ {
++#if HAVE_STAT
+     struct stat     st;
+ 
+     /* If we are unable to stat the given dir, then return with error.
+     */
+     if(stat(path, &st) != 0)
+-        return(0);
++    {
++        fprintf(stderr, "[-] unable to run stat() directory: %s: %s\n",
++            path, strerror(errno));
++        exit(EXIT_FAILURE);
++    }
+ 
+     if(!S_ISDIR(st.st_mode))
+         return(0);
+ 
++#endif /* HAVE_STAT */
++
+     return(1);
+ }
+ 
++int
++set_file_perms(const char *file)
++{
++    int res = 0;
++
++    res = chmod(file, S_IRUSR | S_IWUSR);
++
++    if(res != 0)
++    {
++        fprintf(stderr, "[-] unable to chmod file %s to user read/write: %s\n",
++            file, strerror(errno));
++    }
++    return res;
++}
++
++int
++verify_file_perms_ownership(const char *file)
++{
++#if HAVE_STAT
++    struct stat st;
++
++    /* Every file that the fwknop client deals with should be owned
++     * by the user and permissions set to 600 (user read/write)
++    */
++    if((stat(file, &st)) != 0)
++    {
++        /* If the path does not exist, just return, but otherwise something went wrong */
++        if (errno == ENOENT)
++        {
++            return 0;
++        }
++        else
++        {
++            fprintf(stderr, "[-] unable to run stat() against file: %s: %s\n",
++                file, strerror(errno));
++            exit(EXIT_FAILURE);
++        }
++    }
++
++    /* Make sure it is a regular file
++    */
++    if(S_ISREG(st.st_mode) != 1 && S_ISLNK(st.st_mode) != 1)
++    {
++        fprintf(stderr,
++            "[-] file: %s is not a regular file or symbolic link.\n",
++            file
++        );
++        return 0;
++    }
++
++    if((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != (S_IRUSR|S_IWUSR))
++    {
++        fprintf(stderr,
++            "[-] file: %s permissions should only be user read/write (0600, -rw-------)\n",
++            file
++        );
++        return 0;
++    }
++
++    if(st.st_uid != getuid())
++    {
++        fprintf(stderr, "[-] file: %s not owned by current effective user id\n",
++            file);
++        return 0;
++    }
++#endif
++
++    return 1;
++}
++
++
+ /***EOF***/
+--- a/server/utils.h
++++ b/server/utils.h
+@@ -40,6 +40,8 @@
+ void hex_dump(unsigned char *data, int size);
+ char* dump_ctx(fko_ctx_t ctx);
+ int is_valid_dir(const char *path);
++int set_file_perms(const char *file);
++int verify_file_perms_ownership(const char *file);
+ 
+ size_t strlcat(char *dst, const char *src, size_t siz);
+ size_t strlcpy(char *dst, const char *src, size_t siz);
diff -Nru fwknop-2.0.0rc2/debian/patches/series fwknop-2.0.0rc2/debian/patches/series
--- fwknop-2.0.0rc2/debian/patches/series	2012-06-24 20:59:28.000000000 +0200
+++ fwknop-2.0.0rc2/debian/patches/series	2012-10-10 21:13:56.000000000 +0200
@@ -1 +1,4 @@
 licence.patch
+cve_2012-4434.patch
+cve_2012-4435.patch
+cve_2012-4436.patch
