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***/
|