LCOV - code coverage report
Current view: top level - fwknop.git/client - utils.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 41 44 93.2 %
Date: 2014-07-28 Functions: 5 5 100.0 %
Branches: 22 26 84.6 %

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

Generated by: LCOV version 1.9