36
37
int allow_severity =0, deny_severity = 0;
40
40
/* check result and die, printing the offending address and error */
41
41
void check_res_dumpdie(int res, struct addrinfo *addr, char* syscall)
82
82
(*sockfd)[i] = socket(saddr->ss_family, SOCK_STREAM, 0);
83
83
check_res_dumpdie((*sockfd)[i], addr, "socket");
86
res = setsockopt((*sockfd)[i], SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
87
check_res_dumpdie(res, addr, "setsockopt");
86
res = setsockopt((*sockfd)[i], SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one));
87
check_res_dumpdie(res, addr, "setsockopt(SO_REUSEADDR)");
90
res = setsockopt((*sockfd)[i], IPPROTO_IP, IP_FREEBIND, (char*)&one, sizeof(one));
91
check_res_dumpdie(res, addr, "setsockopt(IP_FREEBIND)");
89
94
res = bind((*sockfd)[i], addr->ai_addr, addr->ai_addrlen);
90
95
check_res_dumpdie(res, addr, "bind");
110
115
from.ai_addr = (struct sockaddr*)&ss;
111
116
from.ai_addrlen = sizeof(ss);
118
/* getpeername can fail with ENOTCONN if connection was dropped before we
113
120
res = getpeername(fd_from, from.ai_addr, &from.ai_addrlen);
114
CHECK_RES_DIE(res, "getpeername");
121
CHECK_RES_RETURN(res, "getpeername");
115
122
res = setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &trans, sizeof(trans));
116
123
CHECK_RES_DIE(res, "setsockopt");
117
124
res = bind(fd, from.ai_addr, from.ai_addrlen);
123
130
/* Connect to first address that works and returns a file descriptor, or -1 if
125
132
* If transparent proxying is on, use fd_from peer address on external address
126
* of new file descriptor.
127
* cnx_name points to the name of the service (for logging) */
128
int connect_addr(struct addrinfo *addr, int fd_from, const char* cnx_name)
133
* of new file descriptor. */
134
int connect_addr(struct connection *cnx, int fd_from)
130
136
struct addrinfo *a;
131
137
char buf[NI_MAXHOST];
134
for (a = addr; a; a = a->ai_next) {
140
for (a = cnx->proto->saddr; a; a = a->ai_next) {
136
142
fprintf(stderr, "connecting to %s family %d len %d\n",
137
143
sprintaddr(buf, sizeof(buf), a),
138
144
a->ai_addr->sa_family, a->ai_addrlen);
139
145
fd = socket(a->ai_family, SOCK_STREAM, 0);
141
log_message(LOG_ERR, "forward to %s failed:socket: %s\n", cnx_name, strerror(errno));
147
log_message(LOG_ERR, "forward to %s failed:socket: %s\n",
148
cnx->proto->description, strerror(errno));
144
bind_peer(fd, fd_from);
151
res = bind_peer(fd, fd_from);
152
CHECK_RES_RETURN(res, "bind_peer");
145
154
res = connect(fd, a->ai_addr, a->ai_addrlen);
147
156
log_message(LOG_ERR, "forward to %s failed:connect: %s\n",
148
cnx_name, strerror(errno));
157
cnx->proto->description, strerror(errno));
157
166
/* Store some data to write to the queue later */
158
167
int defer_write(struct queue *q, void* data, int data_size)
161
fprintf(stderr, "**** writing defered on fd %d\n", q->fd);
162
q->defered_data = malloc(data_size);
163
q->begin_defered_data = q->defered_data;
164
q->defered_data_size = data_size;
165
memcpy(q->defered_data, data, data_size);
171
fprintf(stderr, "**** writing deferred on fd %d\n", q->fd);
173
p = realloc(q->begin_deferred_data, q->deferred_data_size + data_size);
179
q->deferred_data = q->begin_deferred_data = p;
180
p += q->deferred_data_size;
181
q->deferred_data_size += data_size;
182
memcpy(p, data, data_size);
171
188
* Upon success, the number of bytes written is returned.
172
189
* Upon failure, -1 returned (e.g. connexion closed)
174
int flush_defered(struct queue *q)
191
int flush_deferred(struct queue *q)
179
fprintf(stderr, "flushing defered data to fd %d\n", q->fd);
196
fprintf(stderr, "flushing deferred data to fd %d\n", q->fd);
181
n = write(q->fd, q->defered_data, q->defered_data_size);
198
n = write(q->fd, q->deferred_data, q->deferred_data_size);
185
if (n == q->defered_data_size) {
202
if (n == q->deferred_data_size) {
186
203
/* All has been written -- release the memory */
187
free(q->begin_defered_data);
188
q->begin_defered_data = NULL;
189
q->defered_data = NULL;
190
q->defered_data_size = 0;
204
free(q->begin_deferred_data);
205
q->begin_deferred_data = NULL;
206
q->deferred_data = NULL;
207
q->deferred_data_size = 0;
192
209
/* There is data left */
193
q->defered_data += n;
194
q->defered_data_size -= n;
210
q->deferred_data += n;
211
q->deferred_data_size -= n;
203
220
memset(cnx, 0, sizeof(*cnx));
204
221
cnx->q[0].fd = -1;
205
222
cnx->q[1].fd = -1;
223
cnx->proto = get_first_protocol();
208
226
void dump_connection(struct connection *cnx)
210
228
printf("state: %d\n", cnx->state);
211
printf("fd %d, %d defered\n", cnx->q[0].fd, cnx->q[0].defered_data_size);
212
printf("fd %d, %d defered\n", cnx->q[1].fd, cnx->q[1].defered_data_size);
229
printf("fd %d, %d deferred\n", cnx->q[0].fd, cnx->q[0].deferred_data_size);
230
printf("fd %d, %d deferred\n", cnx->q[1].fd, cnx->q[1].deferred_data_size);
217
235
* moves data from one fd to other
219
* retuns number of bytes copied if success
237
* returns number of bytes copied if success
220
238
* returns 0 (FD_CNXCLOSED) if incoming socket closed
221
239
* returns FD_NODATA if no data was available
222
240
* returns FD_STALLED if data was read, could not be written, and has been
380
398
addr.ai_addrlen = sizeof(ss);
382
400
res = getpeername(cnx->q[0].fd, addr.ai_addr, &addr.ai_addrlen);
383
if (res == -1) return; /* that should never happen, right? */
401
if (res == -1) return; /* Can happen if connection drops before we get here.
402
In that case, don't log anything (there is no connection) */
384
403
sprintaddr(peer, sizeof(peer), &addr);
386
405
addr.ai_addrlen = sizeof(ss);
423
442
res = getpeername(in_socket, &peeraddr, &size);
424
CHECK_RES_DIE(res, "getpeername");
443
CHECK_RES_RETURN(res, "getpeername");
426
445
/* extract peer address */
427
446
res = getnameinfo(&peeraddr, size, addr_str, sizeof(addr_str), NULL, 0, NI_NUMERICHOST);
464
483
res = sigaction(SIGCHLD, &action, NULL);
465
484
CHECK_RES_DIE(res, "sigaction");
467
/* Set SIGTERM to exit. For some reason if it's not set explicitely,
486
/* Set SIGTERM to exit. For some reason if it's not set explicitly,
468
487
* coverage information is lost when killing the process */
469
488
memset(&action, 0, sizeof(action));
470
489
action.sa_handler = exit;
482
501
* banner is made up of basename(bin_name)+"[pid]" */
483
502
void setup_syslog(const char* bin_name) {
484
503
char *name1, *name2;
486
506
name1 = strdup(bin_name);
487
asprintf(&name2, "%s[%d]", basename(name1), getpid());
507
res = asprintf(&name2, "%s[%d]", basename(name1), getpid());
508
CHECK_RES_DIE(res, "asprintf");
488
509
openlog(name2, LOG_CONS, LOG_AUTH);
490
511
/* Don't free name2, as openlog(3) uses it (at least in glibc) */
492
513
log_message(LOG_INFO, "%s %s started\n", server_type, VERSION);
495
/* We don't want to run as root -- drop priviledges if required */
516
/* Ask OS to keep capabilities over a setuid(nonzero) */
517
void set_keepcaps(int val) {
520
res = prctl(PR_SET_KEEPCAPS, val, 0, 0, 0);
528
/* set needed capabilities for effective and permitted, clear rest */
529
void set_capabilities(void) {
533
cap_value_t cap_list[10];
537
cap_list[ncap++] = CAP_NET_ADMIN;
541
#define _cap_set_flag(flag) do { \
542
res = cap_clear_flag(caps, flag); \
543
CHECK_RES_DIE(res, "cap_clear_flag(" #flag ")"); \
545
res = cap_set_flag(caps, flag, ncap, cap_list, CAP_SET); \
546
CHECK_RES_DIE(res, "cap_set_flag(" #flag ")"); \
550
_cap_set_flag(CAP_EFFECTIVE);
551
_cap_set_flag(CAP_PERMITTED);
555
res = cap_set_proc(caps);
556
CHECK_RES_DIE(res, "cap_set_proc");
558
res = cap_free(caps);
566
/* We don't want to run as root -- drop privileges if required */
496
567
void drop_privileges(const char* user_name)
505
576
fprintf(stderr, "turning into %s\n", user_name);
507
580
res = setgid(pw->pw_gid);
508
581
CHECK_RES_DIE(res, "setgid");
582
res = setuid(pw->pw_uid);
510
583
CHECK_RES_DIE(res, "setuid");
513
589
/* Writes my PID */