LCOV - code coverage report
Current view: top level - client - utils.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 41 48 85.4 %
Date: 2016-06-07 Functions: 5 5 100.0 %
Branches: 22 30 73.3 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * \file client/utils.c
       3                 :            :  *
       4                 :            :  * \brief General/Generic functions for the fwknop client.
       5                 :            :  */
       6                 :            : 
       7                 :            : /*  Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
       8                 :            :  *  Copyright (C) 2009-2015 fwknop developers and contributors. For a full
       9                 :            :  *  list of contributors, see the file 'CREDITS'.
      10                 :            :  *
      11                 :            :  *  License (GNU General Public License):
      12                 :            :  *
      13                 :            :  *  This program is free software; you can redistribute it and/or
      14                 :            :  *  modify it under the terms of the GNU General Public License
      15                 :            :  *  as published by the Free Software Foundation; either version 2
      16                 :            :  *  of the License, or (at your option) any later version.
      17                 :            :  *
      18                 :            :  *  This program is distributed in the hope that it will be useful,
      19                 :            :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      20                 :            :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21                 :            :  *  GNU General Public License for more details.
      22                 :            :  *
      23                 :            :  *  You should have received a copy of the GNU General Public License
      24                 :            :  *  along with this program; if not, write to the Free Software
      25                 :            :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
      26                 :            :  *  USA
      27                 :            :  *
      28                 :            :  *****************************************************************************
      29                 :            : */
      30                 :            : #include "common.h"
      31                 :            : #include "fwknop_common.h"
      32                 :            : #include "utils.h"
      33                 :            : #ifndef WIN32
      34                 :            : #include <arpa/inet.h>
      35                 :            : #endif
      36                 :            : 
      37                 :            : static void *get_in_addr(struct sockaddr *sa);
      38                 :            : 
      39                 :            : /**
      40                 :            :  * Structure to handle a protocol string and its associated integer value
      41                 :            :  */
      42                 :            : typedef struct fko_protocol
      43                 :            : {
      44                 :            :     const char  str[PROTOCOL_BUFSIZE];      /*!< String which represents a protocol value for the FKO library */
      45                 :            :     int         val;                        /*!< Value of the protocol according to the FKO library */
      46                 :            : } fko_protocol_t;
      47                 :            : 
      48                 :            : static fko_protocol_t fko_protocol_array[] =
      49                 :            : {
      50                 :            :     { "udpraw", FKO_PROTO_UDP_RAW   },
      51                 :            :     { "udp",    FKO_PROTO_UDP       },
      52                 :            :     { "tcpraw", FKO_PROTO_TCP_RAW   },
      53                 :            :     { "tcp",    FKO_PROTO_TCP       },
      54                 :            :     { "icmp",   FKO_PROTO_ICMP      },
      55                 :            :     { "http",   FKO_PROTO_HTTP      }
      56                 :            : };
      57                 :            : 
      58                 :            : int
      59                 :       2932 : verify_file_perms_ownership(const char *file)
      60                 :            : {
      61                 :       2932 :     int res = 1;
      62                 :            : 
      63                 :            : #if HAVE_STAT
      64                 :            :     struct stat st;
      65                 :            : 
      66                 :            :     /* Every file that the fwknop client deals with should be owned
      67                 :            :      * by the user and permissions set to 600 (user read/write)
      68                 :            :     */
      69         [ +  + ]:       2932 :     if((stat(file, &st)) == 0)
      70                 :            :     {
      71                 :            :         /* Make sure it is a regular file
      72                 :            :         */
      73         [ +  + ]:       2927 :         if(S_ISREG(st.st_mode) != 1 && S_ISLNK(st.st_mode) != 1)
      74                 :            :         {
      75                 :          2 :             log_msg(LOG_VERBOSITY_ERROR,
      76                 :            :                 "[-] file: %s is not a regular file or symbolic link.",
      77                 :            :                 file
      78                 :            :             );
      79                 :            :             /* when we start in enforcing this instead of just warning
      80                 :            :              * the user
      81                 :            :             res = 0;
      82                 :            :             */
      83                 :            :         }
      84                 :            : 
      85         [ +  + ]:       2927 :         if((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != (S_IRUSR|S_IWUSR))
      86                 :            :         {
      87                 :         41 :             log_msg(LOG_VERBOSITY_ERROR,
      88                 :            :                 "[-] file: %s permissions should only be user read/write (0600, -rw-------)",
      89                 :            :                 file
      90                 :            :             );
      91                 :            :             /* when we start in enforcing this instead of just warning
      92                 :            :              * the user
      93                 :            :             res = 0;
      94                 :            :             */
      95                 :            :         }
      96                 :            : 
      97         [ +  + ]:       2927 :         if(st.st_uid != getuid())
      98                 :            :         {
      99                 :       1015 :             log_msg(LOG_VERBOSITY_ERROR, "[-] file: %s not owned by current effective user id",
     100                 :            :                 file);
     101                 :            :             /* when we start in enforcing this instead of just warning
     102                 :            :              * the user
     103                 :            :             res = 0;
     104                 :            :             */
     105                 :            :         }
     106                 :            :     }
     107                 :            :     else
     108                 :            :     {
     109                 :            :         /* if the path doesn't exist, just return, but otherwise something
     110                 :            :          * went wrong
     111                 :            :         */
     112         [ +  + ]:          5 :         if(errno != ENOENT)
     113                 :            :         {
     114                 :          1 :             log_msg(LOG_VERBOSITY_ERROR, "[-] stat() against file: %s returned: %s",
     115                 :            :                 file, strerror(errno));
     116                 :          1 :             res = 0;
     117                 :            :         }
     118                 :            :     }
     119                 :            : #endif
     120                 :            : 
     121                 :       2932 :     return res;
     122                 :            : }
     123                 :            : 
     124                 :            : /**
     125                 :            :  * @brief Grab the sin address from the sockaddr structure.
     126                 :            :  *
     127                 :            :  * This function returns the sin address as a sockaddr_in or sockaddr_in6
     128                 :            :  * structure according to the family set (ipv4 or ipv6) in the sockaddr
     129                 :            :  * structure.
     130                 :            :  *
     131                 :            :  * @param sa sockaddr strcuture
     132                 :            :  *
     133                 :            :  * @return the sin addr if the sa family is AF_INET or the sin6_addr otherwise.
     134                 :            :  */
     135                 :            : static void *
     136                 :         12 : get_in_addr(struct sockaddr *sa)
     137                 :            : {
     138         [ +  - ]:         12 :   if (sa->sa_family == AF_INET)
     139                 :            :   {
     140                 :         12 :     return &(((struct sockaddr_in*)sa)->sin_addr);
     141                 :            :   }
     142                 :            : 
     143                 :            :   else
     144                 :            :   {
     145                 :          0 :     return &(((struct sockaddr_in6*)sa)->sin6_addr);
     146                 :            :   }
     147                 :            : }
     148                 :            : 
     149                 :            : /**
     150                 :            :  * @brief  Resolve a domain name as an IP address.
     151                 :            :  *
     152                 :            :  * @param dns_str    Name of the host to resolve.
     153                 :            :  * @param hints      Hints to reduce the number of result from getaddrinfo()
     154                 :            :  * @param ip_str     String where to store the resolve ip address
     155                 :            :  * @param ip_bufsize Number of bytes available in the ip_str buffer
     156                 :            :  * @param opts       Client command line options
     157                 :            :  *
     158                 :            :  * @return 0 if successful, 1 if an error occurred.
     159                 :            :  */
     160                 :            : int
     161                 :         12 : resolve_dst_addr(const char *dns_str, struct addrinfo *hints,
     162                 :            :         char *ip_str, size_t ip_bufsize, fko_cli_options_t *opts)
     163                 :            : {
     164                 :            :     int                 error;      /* Function error return code */
     165                 :            :     struct addrinfo    *result;     /* Result of getaddrinfo() */
     166                 :            :     struct addrinfo    *rp;         /* Element of the linked list returned by getaddrinfo() */
     167                 :            : #if WIN32 && WINVER <= 0x0600
     168                 :            :         struct sockaddr_in *in;
     169                 :            :         char                       *win_ip;
     170                 :            : #else
     171                 :            :     struct sockaddr_in *sai_remote; /* Remote host information as a sockaddr_in structure */
     172                 :            : #endif
     173                 :            : 
     174                 :            :     /* Try to resolve the host name */
     175                 :         12 :     error = getaddrinfo(dns_str, NULL, hints, &result);
     176         [ -  + ]:         12 :     if (error != 0)
     177                 :          0 :         fprintf(stderr, "resolve_dst_addr() : %s\n", gai_strerror(error));
     178                 :            : 
     179                 :            :     else
     180                 :            :     {
     181                 :         12 :         error = 1;
     182                 :            : 
     183                 :            :         /* Go through the linked list of addrinfo structures */
     184         [ +  - ]:         12 :         for (rp = result; rp != NULL; rp = rp->ai_next)
     185                 :            :         {
     186                 :            :             /* Apply --server-resolve-ipv4 criteria
     187                 :            :             */
     188         [ -  + ]:         12 :             if(opts->spa_server_resolve_ipv4)
     189                 :            :             {
     190         [ #  # ]:          0 :                 if(rp->ai_family != AF_INET)
     191                 :            :                 {
     192                 :          0 :                     log_msg(LOG_VERBOSITY_DEBUG, "Non-IPv4 resolution");
     193                 :          0 :                     continue;
     194                 :            :                 }
     195                 :            :             }
     196                 :            : 
     197                 :            :             memset(ip_str, 0, ip_bufsize);
     198                 :            : #if WIN32 && WINVER <= 0x0600
     199                 :            :                         /* On older Windows systems (anything before Vista?),
     200                 :            :                          * we use inet_ntoa for now.
     201                 :            :                         */
     202                 :            :                         in = (struct sockaddr_in*)(rp->ai_addr);
     203                 :            :                         win_ip = inet_ntoa(in->sin_addr);
     204                 :            : 
     205                 :            :                         if (win_ip != NULL && (strlcpy(ip_str, win_ip, ip_bufsize) > 0))
     206                 :            : #else
     207                 :         12 :             sai_remote = (struct sockaddr_in *)get_in_addr((struct sockaddr *)(rp->ai_addr));
     208         [ -  + ]:         12 :             if (inet_ntop(rp->ai_family, sai_remote, ip_str, ip_bufsize) != NULL)
     209                 :            : #endif
     210                 :            :             {
     211                 :            :                 error = 0;
     212                 :            :                 break;
     213                 :            :             }
     214                 :            :             else
     215                 :          0 :                 log_msg(LOG_VERBOSITY_ERROR, "resolve_dst_addr() : inet_ntop (%d) - %s",
     216                 :          0 :                         errno, strerror(errno));
     217                 :            :         }
     218                 :            : 
     219                 :            :         /* Free our result from getaddrinfo() */
     220                 :         12 :         freeaddrinfo(result);
     221                 :            :     }
     222                 :            : 
     223                 :         12 :     return error;
     224                 :            : }
     225                 :            : 
     226                 :            : /**
     227                 :            :  * @brief Return a protocol string according to a protocol integer value
     228                 :            :  *
     229                 :            :  * This function checks if the protocol integer is valid, and write the protocol
     230                 :            :  * string associated.
     231                 :            :  *
     232                 :            :  * @param proto protocol inetger value (UDP_RAW, UDP, TCPRAW...)
     233                 :            :  * @param proto_str Buffer to write the protocol string
     234                 :            :  * @param proto_size size of the protocol string buffer
     235                 :            :  *
     236                 :            :  * @return -1 if the protocol integer value is not supported, 0 otherwise
     237                 :            :  */
     238                 :            : short
     239                 :       2158 : proto_inttostr(int proto, char *proto_str, size_t proto_size)
     240                 :            : {
     241                 :       2158 :     short           proto_error = -1;
     242                 :            :     unsigned char   ndx_proto;          /* Index for the fko_protocol_t structure */
     243                 :            : 
     244                 :            :     /* Initialize the protocol string */
     245                 :            :     memset(proto_str, 0, proto_size);
     246                 :            : 
     247                 :            :     /* Look into the fko_protocol_array to find out the right protocol */
     248         [ +  - ]:       4381 :     for (ndx_proto = 0 ; ndx_proto < ARRAY_SIZE(fko_protocol_array) ; ndx_proto++)
     249                 :            :     {
     250                 :            :         /* If the protocol matches, grab it */
     251         [ +  + ]:       4381 :         if (fko_protocol_array[ndx_proto].val == proto)
     252                 :            :         {
     253                 :       2158 :             strlcpy(proto_str, fko_protocol_array[ndx_proto].str, proto_size);
     254                 :       2158 :             proto_error = 0;
     255                 :       2158 :             break;
     256                 :            :         }
     257                 :            :     }
     258                 :            : 
     259                 :       2158 :     return proto_error;
     260                 :            : 
     261                 :            : }
     262                 :            : 
     263                 :            : /**
     264                 :            :  * @brief Convert a protocol string to its integer value.
     265                 :            :  *
     266                 :            :  * @param pr_str Protocol string (UDP_RAW, UDP, TCPRAW...)
     267                 :            :  *
     268                 :            :  * @return -1 if the protocol string is not supported, otherwise the protocol value
     269                 :            :  */
     270                 :            : short
     271                 :         51 : proto_strtoint(const char *pr_str)
     272                 :            : {
     273                 :            :     unsigned char   ndx_proto;          /* Index for the fko_protocol_t structure */
     274                 :         51 :     int             proto_int = -1;     /* Protocol integer value */
     275                 :            : 
     276                 :            :     /* Look into the fko_protocol_array to find out the right protocol */
     277         [ +  + ]:        169 :     for (ndx_proto = 0 ; ndx_proto < ARRAY_SIZE(fko_protocol_array) ; ndx_proto++)
     278                 :            :     {
     279                 :            :         /* If the protocol matches, grab it */
     280         [ +  + ]:        167 :         if (strcasecmp(pr_str, fko_protocol_array[ndx_proto].str) == 0)
     281                 :            :         {
     282                 :         49 :             proto_int = fko_protocol_array[ndx_proto].val;
     283                 :         49 :             break;
     284                 :            :         }
     285                 :            :     }
     286                 :            : 
     287                 :         51 :     return proto_int;
     288                 :            : }
     289                 :            : 
     290                 :            : /***EOF***/

Generated by: LCOV version 1.10