Mercurial > hg > quicktun
comparison src/common.c @ 55:5685fad38195
Fixed compiler warnings from clang (including small bug in private key loading)
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Fri, 31 Jan 2014 22:52:46 +0100 |
parents | 4ff8003d0973 |
children | 4c083d81f5a8 |
comparison
equal
deleted
inserted
replaced
54:4ff8003d0973 | 55:5685fad38195 |
---|---|
25 | 25 |
26 #include <stdio.h> | 26 #include <stdio.h> |
27 #include <stdlib.h> | 27 #include <stdlib.h> |
28 #include <string.h> | 28 #include <string.h> |
29 #include <fcntl.h> | 29 #include <fcntl.h> |
30 #include <unistd.h> | |
30 #include <pwd.h> | 31 #include <pwd.h> |
32 #include <grp.h> | |
31 #ifndef HAVE_NETINET_IN_H | 33 #ifndef HAVE_NETINET_IN_H |
32 #include <netinet/in.h> | 34 #include <netinet/in.h> |
33 #endif | 35 #endif |
34 #include <sys/ioctl.h> | 36 #include <sys/ioctl.h> |
35 #include <sys/socket.h> | 37 #include <sys/socket.h> |
36 #include <poll.h> | 38 #include <poll.h> |
37 #include <netdb.h> | 39 #include <netdb.h> |
38 #include <stdlib.h> | 40 #include <stdlib.h> |
41 #include <arpa/inet.h> | |
39 #include <net/if.h> | 42 #include <net/if.h> |
40 #ifdef linux | 43 #ifdef linux |
41 #include <linux/if_tun.h> | 44 #include <linux/if_tun.h> |
42 #include <linux/if_ether.h> | 45 #include <linux/if_ether.h> |
43 #else | 46 #else |
85 #ifdef COMBINED_BINARY | 88 #ifdef COMBINED_BINARY |
86 extern char* (*getconf)(const char*); | 89 extern char* (*getconf)(const char*); |
87 extern int errorexit(const char*); | 90 extern int errorexit(const char*); |
88 extern int errorexitp(const char*); | 91 extern int errorexitp(const char*); |
89 extern void print_header(); | 92 extern void print_header(); |
90 extern void hex2bin(unsigned char*, unsigned char*, int); | 93 extern void hex2bin(unsigned char*, const char*, const int); |
91 extern int debug; | 94 extern int debug; |
95 extern int qtrun(struct qtproto* p); | |
96 extern int qtprocessargs(int argc, char** argv); | |
92 #else | 97 #else |
93 | 98 |
94 char* (*getconf)(const char*) = getenv; | 99 char* (*getconf)(const char*) = getenv; |
95 int debug = 0; | 100 int debug = 0; |
96 static int gargc = 0; | 101 static int gargc = 0; |
159 char* envval; | 164 char* envval; |
160 fprintf(stderr, "Initializing UDP socket...\n"); | 165 fprintf(stderr, "Initializing UDP socket...\n"); |
161 struct addrinfo *ai_local = NULL, *ai_remote = NULL; | 166 struct addrinfo *ai_local = NULL, *ai_remote = NULL; |
162 unsigned short af = 0; | 167 unsigned short af = 0; |
163 int ret; | 168 int ret; |
164 if (envval = getconf("LOCAL_ADDRESS")) { | 169 if ((envval = getconf("LOCAL_ADDRESS"))) { |
165 if (ret = getaddrinfo(envval, NULL, NULL, &ai_local)) return errorexit2("getaddrinfo(LOCAL_ADDRESS)", gai_strerror(ret)); | 170 if ((ret = getaddrinfo(envval, NULL, NULL, &ai_local))) return errorexit2("getaddrinfo(LOCAL_ADDRESS)", gai_strerror(ret)); |
166 if (!ai_local) return errorexit("LOCAL_ADDRESS lookup failed"); | 171 if (!ai_local) return errorexit("LOCAL_ADDRESS lookup failed"); |
167 if (ai_local->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved LOCAL_ADDRESS is too big"); | 172 if (ai_local->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved LOCAL_ADDRESS is too big"); |
168 af = ai_local->ai_family; | 173 af = ai_local->ai_family; |
169 } | 174 } |
170 if (envval = getconf("REMOTE_ADDRESS")) { | 175 if ((envval = getconf("REMOTE_ADDRESS"))) { |
171 if (ret = getaddrinfo(envval, NULL, NULL, &ai_remote)) return errorexit2("getaddrinfo(REMOTE_ADDRESS)", gai_strerror(ret)); | 176 if ((ret = getaddrinfo(envval, NULL, NULL, &ai_remote))) return errorexit2("getaddrinfo(REMOTE_ADDRESS)", gai_strerror(ret)); |
172 if (!ai_remote) return errorexit("REMOTE_ADDRESS lookup failed"); | 177 if (!ai_remote) return errorexit("REMOTE_ADDRESS lookup failed"); |
173 if (ai_remote->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved REMOTE_ADDRESS is too big"); | 178 if (ai_remote->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved REMOTE_ADDRESS is too big"); |
174 if (af && af != ai_remote->ai_family) return errorexit("Address families do not match"); | 179 if (af && af != ai_remote->ai_family) return errorexit("Address families do not match"); |
175 af = ai_remote->ai_family; | 180 af = ai_remote->ai_family; |
176 } | 181 } |
180 sockaddr_any udpaddr; | 185 sockaddr_any udpaddr; |
181 memset(&udpaddr, 0, sizeof(udpaddr)); | 186 memset(&udpaddr, 0, sizeof(udpaddr)); |
182 udpaddr.any.sa_family = af; | 187 udpaddr.any.sa_family = af; |
183 if (ai_local) memcpy(&udpaddr, ai_local->ai_addr, ai_local->ai_addrlen); | 188 if (ai_local) memcpy(&udpaddr, ai_local->ai_addr, ai_local->ai_addrlen); |
184 int port = 2998; | 189 int port = 2998; |
185 if (envval = getconf("LOCAL_PORT")) port = atoi(envval); | 190 if ((envval = getconf("LOCAL_PORT"))) port = atoi(envval); |
186 if (sockaddr_set_port(&udpaddr, port)) return -1; | 191 if (sockaddr_set_port(&udpaddr, port)) return -1; |
187 if (bind(sfd, (struct sockaddr*)&udpaddr, sizeof(udpaddr))) return errorexitp("Could not bind socket"); | 192 if (bind(sfd, (struct sockaddr*)&udpaddr, sizeof(udpaddr))) return errorexitp("Could not bind socket"); |
188 memset(&udpaddr, 0, sizeof(udpaddr)); | 193 memset(&udpaddr, 0, sizeof(udpaddr)); |
189 udpaddr.any.sa_family = af; | 194 udpaddr.any.sa_family = af; |
190 if (ai_remote) memcpy(&udpaddr, ai_remote->ai_addr, ai_remote->ai_addrlen); | 195 if (ai_remote) memcpy(&udpaddr, ai_remote->ai_addr, ai_remote->ai_addrlen); |
191 if (!ai_remote || sockaddr_is_zero_address(&udpaddr)) { | 196 if (!ai_remote || sockaddr_is_zero_address(&udpaddr)) { |
192 session->remote_float = 1; | 197 session->remote_float = 1; |
193 } else { | 198 } else { |
194 session->remote_float = getconf("REMOTE_FLOAT") ? 1 : 0; | 199 session->remote_float = getconf("REMOTE_FLOAT") ? 1 : 0; |
195 port = 2998; | 200 port = 2998; |
196 if (envval = getconf("REMOTE_PORT")) port = atoi(envval); | 201 if ((envval = getconf("REMOTE_PORT"))) port = atoi(envval); |
197 if (sockaddr_set_port(&udpaddr, port)) return -1; | 202 if (sockaddr_set_port(&udpaddr, port)) return -1; |
198 session->remote_addr = udpaddr; | 203 session->remote_addr = udpaddr; |
199 if (session->remote_float) { | 204 if (session->remote_float) { |
200 session->remote_float = 2; | 205 session->remote_float = 2; |
201 } else { | 206 } else { |
211 static int init_tuntap(struct qtsession* session) { | 216 static int init_tuntap(struct qtsession* session) { |
212 char* envval; | 217 char* envval; |
213 fprintf(stderr, "Initializing tun/tap device...\n"); | 218 fprintf(stderr, "Initializing tun/tap device...\n"); |
214 int ttfd; //Tap device file descriptor | 219 int ttfd; //Tap device file descriptor |
215 int tunmode = 0; | 220 int tunmode = 0; |
216 if (envval = getconf("TUN_MODE")) tunmode = atoi(envval); | 221 if ((envval = getconf("TUN_MODE"))) tunmode = atoi(envval); |
217 session->use_pi = 0; | 222 session->use_pi = 0; |
218 if (tunmode && (envval = getconf("USE_PI"))) session->use_pi = atoi(envval); | 223 if (tunmode && (envval = getconf("USE_PI"))) session->use_pi = atoi(envval); |
219 #if defined(__linux__) | 224 #if defined(__linux__) |
220 struct ifreq ifr; //required for tun/tap setup | 225 struct ifreq ifr; //required for tun/tap setup |
221 memset(&ifr, 0, sizeof(ifr)); | 226 memset(&ifr, 0, sizeof(ifr)); |
222 if ((ttfd = open("/dev/net/tun", O_RDWR)) < 0) return errorexitp("Could not open tun/tap device file"); | 227 if ((ttfd = open("/dev/net/tun", O_RDWR)) < 0) return errorexitp("Could not open tun/tap device file"); |
223 if (envval = getconf("INTERFACE")) strcpy(ifr.ifr_name, envval); | 228 if ((envval = getconf("INTERFACE"))) strcpy(ifr.ifr_name, envval); |
224 ifr.ifr_flags = tunmode ? IFF_TUN : IFF_TAP; | 229 ifr.ifr_flags = tunmode ? IFF_TUN : IFF_TAP; |
225 if (!session->use_pi) ifr.ifr_flags |= IFF_NO_PI; | 230 if (!session->use_pi) ifr.ifr_flags |= IFF_NO_PI; |
226 if (ioctl(ttfd, TUNSETIFF, (void *)&ifr) < 0) return errorexitp("TUNSETIFF ioctl failed"); | 231 if (ioctl(ttfd, TUNSETIFF, (void *)&ifr) < 0) return errorexitp("TUNSETIFF ioctl failed"); |
227 #elif defined SOLARIS | 232 #elif defined SOLARIS |
228 int ip_fd = -1, if_fd = -1, ppa = 0; | 233 int ip_fd = -1, if_fd = -1, ppa = 0; |
249 i = session->use_pi ? 1 : 0; | 254 i = session->use_pi ? 1 : 0; |
250 ioctl(ttfd, TUNSIFHEAD, &i); | 255 ioctl(ttfd, TUNSIFHEAD, &i); |
251 #endif | 256 #endif |
252 } | 257 } |
253 #endif | 258 #endif |
254 if (envval = getconf("TUN_UP_SCRIPT")) system(envval); | 259 if ((envval = getconf("TUN_UP_SCRIPT"))) system(envval); |
255 session->fd_dev = ttfd; | 260 session->fd_dev = ttfd; |
256 return ttfd; | 261 return ttfd; |
257 } | 262 } |
258 | 263 |
259 void hex2bin(unsigned char* dest, unsigned char* src, int count) { | 264 void hex2bin(unsigned char* dest, const char* src, const int count) { |
260 int i; | 265 int i; |
261 for (i = 0; i < count; i++) { | 266 for (i = 0; i < count; i++) { |
262 if (*src >= '0' && *src <= '9') *dest = *src - '0'; | 267 if (*src >= '0' && *src <= '9') *dest = *src - '0'; |
263 else if (*src >= 'a' && * src <='f') *dest = *src - 'a' + 10; | 268 else if (*src >= 'a' && * src <='f') *dest = *src - 'a' + 10; |
264 else if (*src >= 'A' && * src <='F') *dest = *src - 'A' + 10; | 269 else if (*src >= 'A' && * src <='F') *dest = *src - 'A' + 10; |
271 } | 276 } |
272 | 277 |
273 static int drop_privileges() { | 278 static int drop_privileges() { |
274 char* envval; | 279 char* envval; |
275 struct passwd *pw = NULL; | 280 struct passwd *pw = NULL; |
276 if (envval = getconf("SETUID")) { | 281 if ((envval = getconf("SETUID"))) { |
277 pw = getpwnam(envval); | 282 pw = getpwnam(envval); |
278 if (!pw) return errorexitp("getpwnam"); | 283 if (!pw) return errorexitp("getpwnam"); |
279 } | 284 } |
280 if (envval = getconf("CHROOT")) { | 285 if ((envval = getconf("CHROOT"))) { |
281 if (chroot(envval)) return errorexitp("chroot"); | 286 if (chroot(envval)) return errorexitp("chroot"); |
282 if (chdir("/")) return errorexitp("chdir /"); | 287 if (chdir("/")) return errorexitp("chdir /"); |
283 } | 288 } |
284 if (pw) { | 289 if (pw) { |
285 if (setgroups(0, NULL) == -1) return errorexitp("setgroups"); | 290 if (setgroups(0, NULL) == -1) return errorexitp("setgroups"); |
286 if (setgid(pw->pw_gid) == -1) return errorexitp("setgid"); | 291 if (setgid(pw->pw_gid) == -1) return errorexitp("setgid"); |
287 if (setuid(pw->pw_uid) == -1) return errorexitp("setuid"); | 292 if (setuid(pw->pw_uid) == -1) return errorexitp("setuid"); |
288 } | 293 } |
294 return 0; | |
289 } | 295 } |
290 | 296 |
291 static void qtsendnetworkpacket(struct qtsession* session, char* msg, int len) { | 297 static void qtsendnetworkpacket(struct qtsession* session, char* msg, int len) { |
292 if (session->remote_float == 0) { | 298 if (session->remote_float == 0) { |
293 len = write(session->fd_socket, msg, len); | 299 len = write(session->fd_socket, msg, len); |
349 qtsendnetworkpacket(&session, buffer_enc + p->offset_enc, len); | 355 qtsendnetworkpacket(&session, buffer_enc + p->offset_enc, len); |
350 } | 356 } |
351 } | 357 } |
352 if (fds[1].revents & POLLERR) { | 358 if (fds[1].revents & POLLERR) { |
353 int out; | 359 int out; |
354 len = sizeof(out); | 360 socklen_t slen = sizeof(out); |
355 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len); | 361 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &slen); |
356 fprintf(stderr, "Received error %d on udp socket\n", out); | 362 fprintf(stderr, "Received error %d on udp socket\n", out); |
357 } | 363 } |
358 if (fds[1].revents & POLLIN) { | 364 if (fds[1].revents & POLLIN) { |
359 sockaddr_any recvaddr; | 365 sockaddr_any recvaddr; |
360 socklen_t recvaddr_len = sizeof(recvaddr); | 366 socklen_t recvaddr_len = sizeof(recvaddr); |
363 } else { | 369 } else { |
364 len = recvfrom(sfd, buffer_enc + p->offset_enc, p->buffersize_enc, 0, (struct sockaddr*)&recvaddr, &recvaddr_len); | 370 len = recvfrom(sfd, buffer_enc + p->offset_enc, p->buffersize_enc, 0, (struct sockaddr*)&recvaddr, &recvaddr_len); |
365 } | 371 } |
366 if (len < 0) { | 372 if (len < 0) { |
367 long long out; | 373 long long out; |
368 len = sizeof(out); | 374 socklen_t slen = sizeof(out); |
369 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len); | 375 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &slen); |
370 fprintf(stderr, "Received end of file on udp socket (error %lld)\n", out); | 376 fprintf(stderr, "Received end of file on udp socket (error %lld)\n", out); |
371 } else { | 377 } else { |
372 len = p->decode(&session, buffer_enc, buffer_raw + pi_length, len); | 378 len = p->decode(&session, buffer_enc, buffer_raw + pi_length, len); |
373 if (len < 0) continue; | 379 if (len < 0) continue; |
374 if (session.remote_float != 0 && !sockaddr_equal(&session.remote_addr, &recvaddr)) { | 380 if (session.remote_float != 0 && !sockaddr_equal(&session.remote_addr, &recvaddr)) { |
422 i += 2; | 428 i += 2; |
423 } else { | 429 } else { |
424 return errorexit("Unexpected command line argument"); | 430 return errorexit("Unexpected command line argument"); |
425 } | 431 } |
426 } | 432 } |
427 } | 433 return 0; |
428 #endif | 434 } |
429 | 435 #endif |
436 |