1 /* $OpenBSD: relay.c,v 1.150 2012/07/13 07:54:14 benno Exp $ */ 2 3 /* 4 * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/time.h> 22 #include <sys/stat.h> 23 #include <sys/socket.h> 24 #include <sys/un.h> 25 #include <sys/tree.h> 26 #include <sys/hash.h> 27 28 #include <net/if.h> 29 #include <netinet/in_systm.h> 30 #include <netinet/in.h> 31 #include <netinet/ip.h> 32 #include <netinet/tcp.h> 33 #include <arpa/inet.h> 34 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <unistd.h> 40 #include <stdio.h> 41 #include <err.h> 42 #include <pwd.h> 43 #include <event.h> 44 #include <fnmatch.h> 45 46 #include <openssl/ssl.h> 47 48 #include "relayd.h" 49 50 void relay_statistics(int, short, void *); 51 int relay_dispatch_parent(int, struct privsep_proc *, 52 struct imsg *); 53 int relay_dispatch_pfe(int, struct privsep_proc *, 54 struct imsg *); 55 void relay_shutdown(void); 56 57 void relay_nodedebug(const char *, struct protonode *); 58 void relay_protodebug(struct relay *); 59 void relay_init(struct privsep *, struct privsep_proc *p, void *); 60 void relay_launch(void); 61 int relay_socket(struct sockaddr_storage *, in_port_t, 62 struct protocol *, int, int); 63 int relay_socket_listen(struct sockaddr_storage *, in_port_t, 64 struct protocol *); 65 int relay_socket_connect(struct sockaddr_storage *, in_port_t, 66 struct protocol *, int); 67 68 void relay_accept(int, short, void *); 69 void relay_input(struct rsession *); 70 71 int relay_connect(struct rsession *); 72 void relay_connected(int, short, void *); 73 void relay_bindanyreq(struct rsession *, in_port_t, int); 74 void relay_bindany(int, short, void *); 75 76 u_int32_t relay_hash_addr(struct sockaddr_storage *, u_int32_t); 77 78 void relay_write(struct bufferevent *, void *); 79 void relay_read(struct bufferevent *, void *); 80 void relay_error(struct bufferevent *, short, void *); 81 void relay_dump(struct ctl_relay_event *, const void *, size_t); 82 83 int relay_splice(struct ctl_relay_event *); 84 int relay_splicelen(struct ctl_relay_event *); 85 86 int relay_resolve(struct ctl_relay_event *, 87 struct protonode *, struct protonode *); 88 int relay_handle_http(struct ctl_relay_event *, 89 struct protonode *, struct protonode *, 90 struct protonode *, int); 91 int relay_lognode(struct rsession *, 92 struct protonode *, struct protonode *, char *, size_t); 93 void relay_read_http(struct bufferevent *, void *); 94 static int _relay_lookup_url(struct ctl_relay_event *, char *, char *, 95 char *, enum digest_type); 96 int relay_lookup_url(struct ctl_relay_event *, 97 const char *, enum digest_type); 98 int relay_lookup_query(struct ctl_relay_event *); 99 int relay_lookup_cookie(struct ctl_relay_event *, const char *); 100 void relay_read_httpcontent(struct bufferevent *, void *); 101 void relay_read_httpchunks(struct bufferevent *, void *); 102 char *relay_expand_http(struct ctl_relay_event *, char *, 103 char *, size_t); 104 void relay_close_http(struct rsession *, u_int, const char *, 105 u_int16_t); 106 void relay_http_request_close(struct ctl_relay_event *); 107 108 SSL_CTX *relay_ssl_ctx_create(struct relay *); 109 void relay_ssl_transaction(struct rsession *, 110 struct ctl_relay_event *); 111 void relay_ssl_accept(int, short, void *); 112 void relay_ssl_connect(int, short, void *); 113 void relay_ssl_connected(struct ctl_relay_event *); 114 void relay_ssl_readcb(int, short, void *); 115 void relay_ssl_writecb(int, short, void *); 116 117 int relay_bufferevent_add(struct event *, int); 118 #ifdef notyet 119 int relay_bufferevent_printf(struct ctl_relay_event *, 120 const char *, ...); 121 #endif 122 int relay_bufferevent_print(struct ctl_relay_event *, char *); 123 int relay_bufferevent_write_buffer(struct ctl_relay_event *, 124 struct evbuffer *); 125 int relay_bufferevent_write_chunk(struct ctl_relay_event *, 126 struct evbuffer *, size_t); 127 int relay_bufferevent_write(struct ctl_relay_event *, 128 void *, size_t); 129 char *relay_load_file(const char *, off_t *); 130 static __inline int 131 relay_proto_cmp(struct protonode *, struct protonode *); 132 extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t, 133 size_t, void *); 134 135 volatile sig_atomic_t relay_sessions; 136 objid_t relay_conid; 137 138 static struct relayd *env = NULL; 139 int proc_id; 140 141 static struct privsep_proc procs[] = { 142 { "parent", PROC_PARENT, relay_dispatch_parent }, 143 { "pfe", PROC_PFE, relay_dispatch_pfe }, 144 }; 145 146 pid_t 147 relay(struct privsep *ps, struct privsep_proc *p) 148 { 149 env = ps->ps_env; 150 return (proc_run(ps, p, procs, nitems(procs), relay_init, NULL)); 151 } 152 153 void 154 relay_shutdown(void) 155 { 156 config_purge(env, CONFIG_ALL); 157 usleep(200); /* XXX relay needs to shutdown last */ 158 } 159 160 void 161 relay_nodedebug(const char *name, struct protonode *pn) 162 { 163 const char *s; 164 int digest; 165 166 if (pn->action == NODE_ACTION_NONE) 167 return; 168 169 fprintf(stderr, "\t\t"); 170 fprintf(stderr, "%s ", name); 171 172 switch (pn->type) { 173 case NODE_TYPE_HEADER: 174 break; 175 case NODE_TYPE_QUERY: 176 fprintf(stderr, "query "); 177 break; 178 case NODE_TYPE_COOKIE: 179 fprintf(stderr, "cookie "); 180 break; 181 case NODE_TYPE_PATH: 182 fprintf(stderr, "path "); 183 break; 184 case NODE_TYPE_URL: 185 fprintf(stderr, "url "); 186 break; 187 } 188 189 switch (pn->action) { 190 case NODE_ACTION_APPEND: 191 fprintf(stderr, "append \"%s\" to \"%s\"", 192 pn->value, pn->key); 193 break; 194 case NODE_ACTION_CHANGE: 195 fprintf(stderr, "change \"%s\" to \"%s\"", 196 pn->key, pn->value); 197 break; 198 case NODE_ACTION_REMOVE: 199 fprintf(stderr, "remove \"%s\"", 200 pn->key); 201 break; 202 case NODE_ACTION_EXPECT: 203 case NODE_ACTION_FILTER: 204 s = pn->action == NODE_ACTION_EXPECT ? "expect" : "filter"; 205 digest = pn->flags & PNFLAG_LOOKUP_URL_DIGEST; 206 if (strcmp(pn->value, "*") == 0) 207 fprintf(stderr, "%s %s\"%s\"", s, 208 digest ? "digest " : "", pn->key); 209 else 210 fprintf(stderr, "%s \"%s\" from \"%s\"", s, 211 pn->value, pn->key); 212 break; 213 case NODE_ACTION_HASH: 214 fprintf(stderr, "hash \"%s\"", pn->key); 215 break; 216 case NODE_ACTION_LOG: 217 fprintf(stderr, "log \"%s\"", pn->key); 218 break; 219 case NODE_ACTION_MARK: 220 if (strcmp(pn->value, "*") == 0) 221 fprintf(stderr, "mark \"%s\"", pn->key); 222 else 223 fprintf(stderr, "mark \"%s\" from \"%s\"", 224 pn->value, pn->key); 225 break; 226 case NODE_ACTION_NONE: 227 break; 228 } 229 fprintf(stderr, "\n"); 230 } 231 232 void 233 relay_protodebug(struct relay *rlay) 234 { 235 struct protocol *proto = rlay->rl_proto; 236 struct protonode *proot, *pn; 237 struct proto_tree *tree; 238 const char *name; 239 int i; 240 241 fprintf(stderr, "protocol %d: name %s\n", 242 proto->id, proto->name); 243 fprintf(stderr, "\tflags: %s, relay flags: %s\n", 244 printb_flags(proto->flags, F_BITS), 245 printb_flags(rlay->rl_conf.flags, F_BITS)); 246 if (proto->tcpflags) 247 fprintf(stderr, "\ttcp flags: %s\n", 248 printb_flags(proto->tcpflags, TCPFLAG_BITS)); 249 if ((rlay->rl_conf.flags & (F_SSL|F_SSLCLIENT)) && proto->sslflags) 250 fprintf(stderr, "\tssl flags: %s\n", 251 printb_flags(proto->sslflags, SSLFLAG_BITS)); 252 if (proto->cache != -1) 253 fprintf(stderr, "\tssl session cache: %d\n", proto->cache); 254 fprintf(stderr, "\ttype: "); 255 switch (proto->type) { 256 case RELAY_PROTO_TCP: 257 fprintf(stderr, "tcp\n"); 258 break; 259 case RELAY_PROTO_HTTP: 260 fprintf(stderr, "http\n"); 261 break; 262 case RELAY_PROTO_DNS: 263 fprintf(stderr, "dns\n"); 264 break; 265 } 266 267 name = "request"; 268 tree = &proto->request_tree; 269 show: 270 i = 0; 271 RB_FOREACH(proot, proto_tree, tree) { 272 #if DEBUG > 1 273 i = 0; 274 #endif 275 PROTONODE_FOREACH(pn, proot, entry) { 276 #if DEBUG > 1 277 i = 0; 278 #endif 279 if (++i > 100) 280 break; 281 relay_nodedebug(name, pn); 282 } 283 /* Limit the number of displayed lines */ 284 if (++i > 100) { 285 fprintf(stderr, "\t\t...\n"); 286 break; 287 } 288 } 289 if (tree == &proto->request_tree) { 290 name = "response"; 291 tree = &proto->response_tree; 292 goto show; 293 } 294 } 295 296 int 297 relay_privinit(struct relay *rlay) 298 { 299 extern int debug; 300 301 log_debug("%s: adding relay %s", __func__, rlay->rl_conf.name); 302 303 if (debug) 304 relay_protodebug(rlay); 305 306 switch (rlay->rl_proto->type) { 307 case RELAY_PROTO_DNS: 308 relay_udp_privinit(env, rlay); 309 break; 310 case RELAY_PROTO_TCP: 311 case RELAY_PROTO_HTTP: 312 /* Use defaults */ 313 break; 314 } 315 316 if (rlay->rl_conf.flags & F_UDP) 317 rlay->rl_s = relay_udp_bind(&rlay->rl_conf.ss, 318 rlay->rl_conf.port, rlay->rl_proto); 319 else 320 rlay->rl_s = relay_socket_listen(&rlay->rl_conf.ss, 321 rlay->rl_conf.port, rlay->rl_proto); 322 if (rlay->rl_s == -1) 323 return (-1); 324 325 return (0); 326 } 327 328 void 329 relay_init(struct privsep *ps, struct privsep_proc *p, void *arg) 330 { 331 struct timeval tv; 332 333 if (config_init(ps->ps_env) == -1) 334 fatal("failed to initialize configuration"); 335 336 /* We use a custom shutdown callback */ 337 p->p_shutdown = relay_shutdown; 338 339 /* Unlimited file descriptors (use system limits) */ 340 socket_rlimit(-1); 341 342 /* Schedule statistics timer */ 343 evtimer_set(&env->sc_statev, relay_statistics, NULL); 344 bcopy(&env->sc_statinterval, &tv, sizeof(tv)); 345 evtimer_add(&env->sc_statev, &tv); 346 } 347 348 void 349 relay_statistics(int fd, short events, void *arg) 350 { 351 struct relay *rlay; 352 struct ctl_stats crs, *cur; 353 struct timeval tv, tv_now; 354 int resethour = 0, resetday = 0; 355 struct rsession *con, *next_con; 356 357 /* 358 * This is a hack to calculate some average statistics. 359 * It doesn't try to be very accurate, but could be improved... 360 */ 361 362 timerclear(&tv); 363 if (gettimeofday(&tv_now, NULL) == -1) 364 fatal("relay_init: gettimeofday"); 365 366 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) { 367 bzero(&crs, sizeof(crs)); 368 resethour = resetday = 0; 369 370 cur = &rlay->rl_stats[proc_id]; 371 cur->cnt += cur->last; 372 cur->tick++; 373 cur->avg = (cur->last + cur->avg) / 2; 374 cur->last_hour += cur->last; 375 if ((cur->tick % (3600 / env->sc_statinterval.tv_sec)) == 0) { 376 cur->avg_hour = (cur->last_hour + cur->avg_hour) / 2; 377 resethour++; 378 } 379 cur->last_day += cur->last; 380 if ((cur->tick % (86400 / env->sc_statinterval.tv_sec)) == 0) { 381 cur->avg_day = (cur->last_day + cur->avg_day) / 2; 382 resethour++; 383 } 384 bcopy(cur, &crs, sizeof(crs)); 385 386 cur->last = 0; 387 if (resethour) 388 cur->last_hour = 0; 389 if (resetday) 390 cur->last_day = 0; 391 392 crs.id = rlay->rl_conf.id; 393 crs.proc = proc_id; 394 proc_compose_imsg(env->sc_ps, PROC_PFE, -1, IMSG_STATISTICS, -1, 395 &crs, sizeof(crs)); 396 397 for (con = SPLAY_ROOT(&rlay->rl_sessions); 398 con != NULL; con = next_con) { 399 next_con = SPLAY_NEXT(session_tree, 400 &rlay->rl_sessions, con); 401 timersub(&tv_now, &con->se_tv_last, &tv); 402 if (timercmp(&tv, &rlay->rl_conf.timeout, >=)) 403 relay_close(con, "hard timeout"); 404 } 405 } 406 407 /* Schedule statistics timer */ 408 evtimer_set(&env->sc_statev, relay_statistics, NULL); 409 bcopy(&env->sc_statinterval, &tv, sizeof(tv)); 410 evtimer_add(&env->sc_statev, &tv); 411 } 412 413 void 414 relay_launch(void) 415 { 416 void (*callback)(int, short, void *); 417 struct relay *rlay; 418 struct host *host; 419 420 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) { 421 if ((rlay->rl_conf.flags & (F_SSL|F_SSLCLIENT)) && 422 (rlay->rl_ssl_ctx = relay_ssl_ctx_create(rlay)) == NULL) 423 fatal("relay_init: failed to create SSL context"); 424 425 if (rlay->rl_dsttable != NULL) { 426 switch (rlay->rl_conf.dstmode) { 427 case RELAY_DSTMODE_ROUNDROBIN: 428 rlay->rl_dstkey = 0; 429 break; 430 case RELAY_DSTMODE_LOADBALANCE: 431 case RELAY_DSTMODE_HASH: 432 rlay->rl_dstkey = 433 hash32_str(rlay->rl_conf.name, HASHINIT); 434 rlay->rl_dstkey = 435 hash32_str(rlay->rl_dsttable->conf.name, 436 rlay->rl_dstkey); 437 break; 438 } 439 rlay->rl_dstnhosts = 0; 440 TAILQ_FOREACH(host, &rlay->rl_dsttable->hosts, entry) { 441 if (rlay->rl_dstnhosts >= RELAY_MAXHOSTS) 442 fatal("relay_init: " 443 "too many hosts in table"); 444 host->idx = rlay->rl_dstnhosts; 445 rlay->rl_dsthost[rlay->rl_dstnhosts++] = host; 446 } 447 log_info("adding %d hosts from table %s%s", 448 rlay->rl_dstnhosts, rlay->rl_dsttable->conf.name, 449 rlay->rl_dsttable->conf.check ? "" : " (no check)"); 450 } 451 452 switch (rlay->rl_proto->type) { 453 case RELAY_PROTO_DNS: 454 relay_udp_init(rlay); 455 break; 456 case RELAY_PROTO_TCP: 457 case RELAY_PROTO_HTTP: 458 /* Use defaults */ 459 break; 460 } 461 462 log_debug("%s: running relay %s", __func__, 463 rlay->rl_conf.name); 464 465 rlay->rl_up = HOST_UP; 466 467 if (rlay->rl_conf.flags & F_UDP) 468 callback = relay_udp_server; 469 else 470 callback = relay_accept; 471 472 event_set(&rlay->rl_ev, rlay->rl_s, EV_READ, 473 callback, rlay); 474 event_add(&rlay->rl_ev, NULL); 475 evtimer_set(&rlay->rl_evt, callback, rlay); 476 } 477 } 478 479 int 480 relay_socket_af(struct sockaddr_storage *ss, in_port_t port) 481 { 482 switch (ss->ss_family) { 483 case AF_INET: 484 ((struct sockaddr_in *)ss)->sin_port = port; 485 ((struct sockaddr_in *)ss)->sin_len = 486 sizeof(struct sockaddr_in); 487 break; 488 case AF_INET6: 489 ((struct sockaddr_in6 *)ss)->sin6_port = port; 490 ((struct sockaddr_in6 *)ss)->sin6_len = 491 sizeof(struct sockaddr_in6); 492 break; 493 default: 494 return (-1); 495 } 496 497 return (0); 498 } 499 500 in_port_t 501 relay_socket_getport(struct sockaddr_storage *ss) 502 { 503 switch (ss->ss_family) { 504 case AF_INET: 505 return (((struct sockaddr_in *)ss)->sin_port); 506 case AF_INET6: 507 return (((struct sockaddr_in6 *)ss)->sin6_port); 508 default: 509 return (0); 510 } 511 512 /* NOTREACHED */ 513 return (0); 514 } 515 516 int 517 relay_socket(struct sockaddr_storage *ss, in_port_t port, 518 struct protocol *proto, int fd, int reuseport) 519 { 520 int s = -1, val; 521 struct linger lng; 522 523 if (relay_socket_af(ss, port) == -1) 524 goto bad; 525 526 s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM, IPPROTO_TCP) : fd; 527 if (s == -1) 528 goto bad; 529 530 /* 531 * Socket options 532 */ 533 bzero(&lng, sizeof(lng)); 534 if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) 535 goto bad; 536 if (reuseport) { 537 val = 1; 538 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, 539 sizeof(int)) == -1) 540 goto bad; 541 } 542 if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) 543 goto bad; 544 if (proto->tcpflags & TCPFLAG_BUFSIZ) { 545 val = proto->tcpbufsiz; 546 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 547 &val, sizeof(val)) == -1) 548 goto bad; 549 val = proto->tcpbufsiz; 550 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 551 &val, sizeof(val)) == -1) 552 goto bad; 553 } 554 555 /* 556 * IP options 557 */ 558 if (proto->tcpflags & TCPFLAG_IPTTL) { 559 val = (int)proto->tcpipttl; 560 if (setsockopt(s, IPPROTO_IP, IP_TTL, 561 &val, sizeof(val)) == -1) 562 goto bad; 563 } 564 if (proto->tcpflags & TCPFLAG_IPMINTTL) { 565 val = (int)proto->tcpipminttl; 566 if (setsockopt(s, IPPROTO_IP, IP_MINTTL, 567 &val, sizeof(val)) == -1) 568 goto bad; 569 } 570 571 /* 572 * TCP options 573 */ 574 if (proto->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) { 575 if (proto->tcpflags & TCPFLAG_NNODELAY) 576 val = 0; 577 else 578 val = 1; 579 if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 580 &val, sizeof(val)) == -1) 581 goto bad; 582 } 583 if (proto->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) { 584 if (proto->tcpflags & TCPFLAG_NSACK) 585 val = 0; 586 else 587 val = 1; 588 if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE, 589 &val, sizeof(val)) == -1) 590 goto bad; 591 } 592 593 return (s); 594 595 bad: 596 if (s != -1) 597 close(s); 598 return (-1); 599 } 600 601 int 602 relay_socket_connect(struct sockaddr_storage *ss, in_port_t port, 603 struct protocol *proto, int fd) 604 { 605 int s; 606 607 if ((s = relay_socket(ss, port, proto, fd, 0)) == -1) 608 return (-1); 609 610 if (connect(s, (struct sockaddr *)ss, ss->ss_len) == -1) { 611 if (errno != EINPROGRESS) 612 goto bad; 613 } 614 615 return (s); 616 617 bad: 618 close(s); 619 return (-1); 620 } 621 622 int 623 relay_socket_listen(struct sockaddr_storage *ss, in_port_t port, 624 struct protocol *proto) 625 { 626 int s; 627 628 if ((s = relay_socket(ss, port, proto, -1, 1)) == -1) 629 return (-1); 630 631 if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1) 632 goto bad; 633 if (listen(s, proto->tcpbacklog) == -1) 634 goto bad; 635 636 return (s); 637 638 bad: 639 close(s); 640 return (-1); 641 } 642 643 void 644 relay_connected(int fd, short sig, void *arg) 645 { 646 struct rsession *con = (struct rsession *)arg; 647 struct relay *rlay = (struct relay *)con->se_relay; 648 struct protocol *proto = rlay->rl_proto; 649 evbuffercb outrd = relay_read; 650 evbuffercb outwr = relay_write; 651 struct bufferevent *bev; 652 struct ctl_relay_event *out = &con->se_out; 653 socklen_t len; 654 int error; 655 656 if (sig == EV_TIMEOUT) { 657 relay_close_http(con, 504, "connect timeout", 0); 658 return; 659 } 660 661 len = sizeof(error); 662 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, 663 &len) == -1 || error) { 664 if (error) 665 errno = error; 666 relay_close_http(con, 500, "socket error", 0); 667 return; 668 } 669 670 if ((rlay->rl_conf.flags & F_SSLCLIENT) && (out->ssl == NULL)) { 671 relay_ssl_transaction(con, out); 672 return; 673 } 674 675 DPRINTF("%s: session %d: %ssuccessful", __func__, 676 con->se_id, rlay->rl_proto->lateconnect ? "late connect " : ""); 677 678 switch (rlay->rl_proto->type) { 679 case RELAY_PROTO_HTTP: 680 /* Check the servers's HTTP response */ 681 if (!RB_EMPTY(&rlay->rl_proto->response_tree)) { 682 outrd = relay_read_http; 683 if ((con->se_out.nodes = calloc(proto->response_nodes, 684 sizeof(u_int8_t))) == NULL) { 685 relay_close_http(con, 500, 686 "failed to allocate nodes", 0); 687 return; 688 } 689 } 690 break; 691 case RELAY_PROTO_TCP: 692 /* Use defaults */ 693 break; 694 default: 695 fatalx("relay_connected: unknown protocol"); 696 } 697 698 /* 699 * Relay <-> Server 700 */ 701 bev = bufferevent_new(fd, outrd, outwr, relay_error, &con->se_out); 702 if (bev == NULL) { 703 relay_close_http(con, 500, 704 "failed to allocate output buffer event", 0); 705 return; 706 } 707 evbuffer_free(bev->output); 708 bev->output = con->se_out.output; 709 if (bev->output == NULL) 710 fatal("relay_connected: invalid output buffer"); 711 con->se_out.bev = bev; 712 713 /* Initialize the SSL wrapper */ 714 if ((rlay->rl_conf.flags & F_SSLCLIENT) && (out->ssl != NULL)) 715 relay_ssl_connected(out); 716 717 bufferevent_settimeout(bev, 718 rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec); 719 bufferevent_enable(bev, EV_READ|EV_WRITE); 720 721 if (relay_splice(&con->se_out) == -1) 722 relay_close(con, strerror(errno)); 723 } 724 725 void 726 relay_input(struct rsession *con) 727 { 728 struct relay *rlay = (struct relay *)con->se_relay; 729 struct protocol *proto = rlay->rl_proto; 730 evbuffercb inrd = relay_read; 731 evbuffercb inwr = relay_write; 732 733 switch (rlay->rl_proto->type) { 734 case RELAY_PROTO_HTTP: 735 /* Check the client's HTTP request */ 736 if (!RB_EMPTY(&rlay->rl_proto->request_tree) || 737 proto->lateconnect) { 738 inrd = relay_read_http; 739 if ((con->se_in.nodes = calloc(proto->request_nodes, 740 sizeof(u_int8_t))) == NULL) { 741 relay_close(con, "failed to allocate nodes"); 742 return; 743 } 744 } 745 break; 746 case RELAY_PROTO_TCP: 747 /* Use defaults */ 748 break; 749 default: 750 fatalx("relay_input: unknown protocol"); 751 } 752 753 /* 754 * Client <-> Relay 755 */ 756 con->se_in.bev = bufferevent_new(con->se_in.s, inrd, inwr, 757 relay_error, &con->se_in); 758 if (con->se_in.bev == NULL) { 759 relay_close(con, "failed to allocate input buffer event"); 760 return; 761 } 762 763 /* Initialize the SSL wrapper */ 764 if ((rlay->rl_conf.flags & F_SSL) && con->se_in.ssl != NULL) 765 relay_ssl_connected(&con->se_in); 766 767 bufferevent_settimeout(con->se_in.bev, 768 rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec); 769 bufferevent_enable(con->se_in.bev, EV_READ|EV_WRITE); 770 771 if (relay_splice(&con->se_in) == -1) 772 relay_close(con, strerror(errno)); 773 } 774 775 void 776 relay_write(struct bufferevent *bev, void *arg) 777 { 778 struct ctl_relay_event *cre = (struct ctl_relay_event *)arg; 779 struct rsession *con = cre->con; 780 if (gettimeofday(&con->se_tv_last, NULL) == -1) 781 con->se_done = 1; 782 if (con->se_done) 783 relay_close(con, "last write (done)"); 784 } 785 786 void 787 relay_dump(struct ctl_relay_event *cre, const void *buf, size_t len) 788 { 789 if (!len) 790 return; 791 792 /* 793 * This function will dump the specified message directly 794 * to the underlying session, without waiting for success 795 * of non-blocking events etc. This is useful to print an 796 * error message before gracefully closing the session. 797 */ 798 if (cre->ssl != NULL) 799 (void)SSL_write(cre->ssl, buf, len); 800 else 801 (void)write(cre->s, buf, len); 802 } 803 804 void 805 relay_read(struct bufferevent *bev, void *arg) 806 { 807 struct ctl_relay_event *cre = (struct ctl_relay_event *)arg; 808 struct rsession *con = cre->con; 809 struct evbuffer *src = EVBUFFER_INPUT(bev); 810 811 if (gettimeofday(&con->se_tv_last, NULL) == -1) 812 goto fail; 813 if (!EVBUFFER_LENGTH(src)) 814 return; 815 if (relay_bufferevent_write_buffer(cre->dst, src) == -1) 816 goto fail; 817 if (con->se_done) 818 goto done; 819 if (cre->dst->bev) 820 bufferevent_enable(cre->dst->bev, EV_READ); 821 return; 822 done: 823 relay_close(con, "last read (done)"); 824 return; 825 fail: 826 relay_close(con, strerror(errno)); 827 } 828 829 int 830 relay_resolve(struct ctl_relay_event *cre, 831 struct protonode *proot, struct protonode *pn) 832 { 833 struct rsession *con = cre->con; 834 char buf[IBUF_READ_SIZE], *ptr; 835 int id; 836 837 if (pn->mark && (pn->mark != con->se_mark)) 838 return (0); 839 840 switch (pn->action) { 841 case NODE_ACTION_FILTER: 842 id = cre->nodes[proot->id]; 843 if (SIMPLEQ_NEXT(pn, entry) == NULL) 844 cre->nodes[proot->id] = 0; 845 if (id <= 1) 846 return (0); 847 break; 848 case NODE_ACTION_EXPECT: 849 id = cre->nodes[proot->id]; 850 if (SIMPLEQ_NEXT(pn, entry) == NULL) 851 cre->nodes[proot->id] = 0; 852 if (id > 1) 853 return (0); 854 break; 855 default: 856 if (cre->nodes[pn->id]) { 857 cre->nodes[pn->id] = 0; 858 return (0); 859 } 860 break; 861 } 862 switch (pn->action) { 863 case NODE_ACTION_APPEND: 864 case NODE_ACTION_CHANGE: 865 ptr = pn->value; 866 if ((pn->flags & PNFLAG_MACRO) && 867 (ptr = relay_expand_http(cre, pn->value, 868 buf, sizeof(buf))) == NULL) 869 break; 870 if (relay_bufferevent_print(cre->dst, pn->key) == -1 || 871 relay_bufferevent_print(cre->dst, ": ") == -1 || 872 relay_bufferevent_print(cre->dst, ptr) == -1 || 873 relay_bufferevent_print(cre->dst, "\r\n") == -1) { 874 relay_close_http(con, 500, 875 "failed to modify header", 0); 876 return (-1); 877 } 878 DPRINTF("%s: add '%s: %s'", __func__, pn->key, ptr); 879 break; 880 case NODE_ACTION_EXPECT: 881 DPRINTF("%s: missing '%s: %s'", __func__, pn->key, pn->value); 882 relay_close_http(con, 403, "incomplete request", pn->label); 883 return (-1); 884 case NODE_ACTION_FILTER: 885 DPRINTF("%s: filtered '%s: %s'", __func__, pn->key, pn->value); 886 relay_close_http(con, 403, "rejecting request", pn->label); 887 return (-1); 888 default: 889 break; 890 } 891 return (0); 892 } 893 894 char * 895 relay_expand_http(struct ctl_relay_event *cre, char *val, char *buf, size_t len) 896 { 897 struct rsession *con = cre->con; 898 struct relay *rlay = (struct relay *)con->se_relay; 899 char ibuf[128]; 900 901 (void)strlcpy(buf, val, len); 902 903 if (strstr(val, "$REMOTE_") != NULL) { 904 if (strstr(val, "$REMOTE_ADDR") != NULL) { 905 if (print_host(&cre->ss, ibuf, sizeof(ibuf)) == NULL) 906 return (NULL); 907 if (expand_string(buf, len, 908 "$REMOTE_ADDR", ibuf) != 0) 909 return (NULL); 910 } 911 if (strstr(val, "$REMOTE_PORT") != NULL) { 912 snprintf(ibuf, sizeof(ibuf), "%u", ntohs(cre->port)); 913 if (expand_string(buf, len, 914 "$REMOTE_PORT", ibuf) != 0) 915 return (NULL); 916 } 917 } 918 if (strstr(val, "$SERVER_") != NULL) { 919 if (strstr(val, "$SERVER_ADDR") != NULL) { 920 if (print_host(&rlay->rl_conf.ss, 921 ibuf, sizeof(ibuf)) == NULL) 922 return (NULL); 923 if (expand_string(buf, len, 924 "$SERVER_ADDR", ibuf) != 0) 925 return (NULL); 926 } 927 if (strstr(val, "$SERVER_PORT") != NULL) { 928 snprintf(ibuf, sizeof(ibuf), "%u", 929 ntohs(rlay->rl_conf.port)); 930 if (expand_string(buf, len, 931 "$SERVER_PORT", ibuf) != 0) 932 return (NULL); 933 } 934 if (strstr(val, "$SERVER_NAME") != NULL) { 935 if (expand_string(buf, len, 936 "$SERVER_NAME", RELAYD_SERVERNAME) != 0) 937 return (NULL); 938 } 939 } 940 if (strstr(val, "$TIMEOUT") != NULL) { 941 snprintf(ibuf, sizeof(ibuf), "%lu", 942 rlay->rl_conf.timeout.tv_sec); 943 if (expand_string(buf, len, "$TIMEOUT", ibuf) != 0) 944 return (NULL); 945 } 946 947 return (buf); 948 } 949 950 int 951 relay_lognode(struct rsession *con, struct protonode *pn, struct protonode *pk, 952 char *buf, size_t len) 953 { 954 const char *label = NULL; 955 956 if ((pn->flags & PNFLAG_LOG) == 0) 957 return (0); 958 bzero(buf, len); 959 if (pn->label != 0) 960 label = pn_id2name(pn->label); 961 if (snprintf(buf, len, " [%s%s%s: %s]", 962 label == NULL ? "" : label, 963 label == NULL ? "" : ", ", 964 pk->key, pk->value) == -1 || 965 evbuffer_add(con->se_log, buf, strlen(buf)) == -1) 966 return (-1); 967 return (0); 968 } 969 970 int 971 relay_handle_http(struct ctl_relay_event *cre, struct protonode *proot, 972 struct protonode *pn, struct protonode *pk, int header) 973 { 974 struct rsession *con = cre->con; 975 char buf[IBUF_READ_SIZE], *ptr; 976 int ret = PN_DROP, mark = 0; 977 struct protonode *next; 978 979 /* Check if this action depends on a marked session */ 980 if (pn->mark != 0) 981 mark = pn->mark == con->se_mark ? 1 : -1; 982 983 switch (pn->action) { 984 case NODE_ACTION_EXPECT: 985 case NODE_ACTION_FILTER: 986 case NODE_ACTION_MARK: 987 break; 988 default: 989 if (mark == -1) 990 return (PN_PASS); 991 break; 992 } 993 994 switch (pn->action) { 995 case NODE_ACTION_APPEND: 996 if (!header) 997 return (PN_PASS); 998 ptr = pn->value; 999 if ((pn->flags & PNFLAG_MACRO) && 1000 (ptr = relay_expand_http(cre, pn->value, 1001 buf, sizeof(buf))) == NULL) 1002 break; 1003 if (relay_bufferevent_print(cre->dst, pn->key) == -1 || 1004 relay_bufferevent_print(cre->dst, ": ") == -1 || 1005 relay_bufferevent_print(cre->dst, pk->value) == -1 || 1006 relay_bufferevent_print(cre->dst, ", ") == -1 || 1007 relay_bufferevent_print(cre->dst, ptr) == -1 || 1008 relay_bufferevent_print(cre->dst, "\r\n") == -1) 1009 goto fail; 1010 cre->nodes[pn->id] = 1; 1011 DPRINTF("%s: append '%s: %s, %s'", __func__, 1012 pk->key, pk->value, ptr); 1013 break; 1014 case NODE_ACTION_CHANGE: 1015 case NODE_ACTION_REMOVE: 1016 if (!header) 1017 return (PN_PASS); 1018 DPRINTF("%s: change/remove '%s: %s'", __func__, 1019 pk->key, pk->value); 1020 break; 1021 case NODE_ACTION_EXPECT: 1022 /* 1023 * A client may specify the header line for multiple times 1024 * trying to circumvent the filter. 1025 */ 1026 if (cre->nodes[proot->id] > 1) { 1027 relay_close_http(con, 400, "repeated header line", 0); 1028 return (PN_FAIL); 1029 } 1030 /* FALLTHROUGH */ 1031 case NODE_ACTION_FILTER: 1032 DPRINTF("%s: %s '%s: %s'", __func__, 1033 (pn->action == NODE_ACTION_EXPECT) ? "expect" : "filter", 1034 pn->key, pn->value); 1035 1036 /* Do not drop the entity */ 1037 ret = PN_PASS; 1038 1039 if (mark != -1 && 1040 fnmatch(pn->value, pk->value, FNM_CASEFOLD) == 0) { 1041 cre->nodes[proot->id] = 1; 1042 1043 /* Fail instantly */ 1044 if (pn->action == NODE_ACTION_FILTER) { 1045 (void)relay_lognode(con, pn, pk, 1046 buf, sizeof(buf)); 1047 relay_close_http(con, 403, 1048 "rejecting request", pn->label); 1049 return (PN_FAIL); 1050 } 1051 } 1052 next = SIMPLEQ_NEXT(pn, entry); 1053 if (next == NULL || next->action != pn->action) 1054 cre->nodes[proot->id]++; 1055 break; 1056 case NODE_ACTION_HASH: 1057 DPRINTF("%s: hash '%s: %s'", __func__, 1058 pn->key, pk->value); 1059 con->se_hashkey = hash32_str(pk->value, con->se_hashkey); 1060 ret = PN_PASS; 1061 break; 1062 case NODE_ACTION_LOG: 1063 log_info("%s: log '%s: %s'", __func__, pn->key, pk->value); 1064 ret = PN_PASS; 1065 break; 1066 case NODE_ACTION_MARK: 1067 DPRINTF("%s: mark '%s: %s'", __func__, 1068 pn->key, pk->value); 1069 if (fnmatch(pn->value, pk->value, FNM_CASEFOLD) == 0) 1070 con->se_mark = pn->mark; 1071 ret = PN_PASS; 1072 break; 1073 case NODE_ACTION_NONE: 1074 return (PN_PASS); 1075 } 1076 if (mark != -1 && relay_lognode(con, pn, pk, buf, sizeof(buf)) == -1) 1077 goto fail; 1078 1079 return (ret); 1080 fail: 1081 relay_close_http(con, 500, strerror(errno), 0); 1082 return (PN_FAIL); 1083 } 1084 1085 void 1086 relay_read_httpcontent(struct bufferevent *bev, void *arg) 1087 { 1088 struct ctl_relay_event *cre = (struct ctl_relay_event *)arg; 1089 struct rsession *con = cre->con; 1090 struct evbuffer *src = EVBUFFER_INPUT(bev); 1091 size_t size; 1092 1093 if (gettimeofday(&con->se_tv_last, NULL) == -1) 1094 goto fail; 1095 size = EVBUFFER_LENGTH(src); 1096 DPRINTF("%s: size %lu, to read %llu", __func__, 1097 size, cre->toread); 1098 if (!size) 1099 return; 1100 if (relay_bufferevent_write_buffer(cre->dst, src) == -1) 1101 goto fail; 1102 if ((off_t)size >= cre->toread) 1103 bev->readcb = relay_read_http; 1104 cre->toread -= size; 1105 DPRINTF("%s: done, size %lu, to read %llu", __func__, 1106 size, cre->toread); 1107 if (con->se_done) 1108 goto done; 1109 if (bev->readcb != relay_read_httpcontent) 1110 bev->readcb(bev, arg); 1111 bufferevent_enable(bev, EV_READ); 1112 return; 1113 done: 1114 relay_close(con, "last http content read"); 1115 return; 1116 fail: 1117 relay_close(con, strerror(errno)); 1118 } 1119 1120 void 1121 relay_read_httpchunks(struct bufferevent *bev, void *arg) 1122 { 1123 struct ctl_relay_event *cre = (struct ctl_relay_event *)arg; 1124 struct rsession *con = cre->con; 1125 struct evbuffer *src = EVBUFFER_INPUT(bev); 1126 char *line; 1127 long lval; 1128 size_t size; 1129 1130 if (gettimeofday(&con->se_tv_last, NULL) == -1) 1131 goto fail; 1132 size = EVBUFFER_LENGTH(src); 1133 DPRINTF("%s: size %lu, to read %llu", __func__, 1134 size, cre->toread); 1135 if (!size) 1136 return; 1137 1138 if (!cre->toread) { 1139 line = evbuffer_readline(src); 1140 if (line == NULL) { 1141 /* Ignore empty line, continue */ 1142 bufferevent_enable(bev, EV_READ); 1143 return; 1144 } 1145 if (!strlen(line)) { 1146 free(line); 1147 goto next; 1148 } 1149 1150 /* Read prepended chunk size in hex, ingore the trailer */ 1151 if (sscanf(line, "%lx", &lval) != 1) { 1152 free(line); 1153 relay_close(con, "invalid chunk size"); 1154 return; 1155 } 1156 1157 if (relay_bufferevent_print(cre->dst, line) == -1 || 1158 relay_bufferevent_print(cre->dst, "\r\n") == -1) { 1159 free(line); 1160 goto fail; 1161 } 1162 free(line); 1163 1164 /* Last chunk is 0 bytes followed by an empty newline */ 1165 if ((cre->toread = lval) == 0) { 1166 DPRINTF("%s: last chunk", __func__); 1167 1168 line = evbuffer_readline(src); 1169 if (line == NULL) { 1170 relay_close(con, "invalid last chunk"); 1171 return; 1172 } 1173 free(line); 1174 if (relay_bufferevent_print(cre->dst, "\r\n") == -1) 1175 goto fail; 1176 1177 /* Switch to HTTP header mode */ 1178 bev->readcb = relay_read_http; 1179 } 1180 } else { 1181 /* Read chunk data */ 1182 if ((off_t)size > cre->toread) 1183 size = cre->toread; 1184 if (relay_bufferevent_write_chunk(cre->dst, src, size) == -1) 1185 goto fail; 1186 cre->toread -= size; 1187 DPRINTF("%s: done, size %lu, to read %llu", __func__, 1188 size, cre->toread); 1189 1190 if (cre->toread == 0) { 1191 /* Chunk is terminated by an empty (empty) newline */ 1192 line = evbuffer_readline(src); 1193 if (line != NULL) 1194 free(line); 1195 if (relay_bufferevent_print(cre->dst, "\r\n\r\n") == -1) 1196 goto fail; 1197 } 1198 } 1199 1200 next: 1201 if (con->se_done) 1202 goto done; 1203 if (EVBUFFER_LENGTH(src)) 1204 bev->readcb(bev, arg); 1205 bufferevent_enable(bev, EV_READ); 1206 return; 1207 1208 done: 1209 relay_close(con, "last http chunk read (done)"); 1210 return; 1211 fail: 1212 relay_close(con, strerror(errno)); 1213 } 1214 1215 void 1216 relay_http_request_close(struct ctl_relay_event *cre) 1217 { 1218 if (cre->path != NULL) { 1219 free(cre->path); 1220 cre->path = NULL; 1221 } 1222 1223 cre->args = NULL; 1224 cre->version = NULL; 1225 1226 if (cre->buf != NULL) { 1227 free(cre->buf); 1228 cre->buf = NULL; 1229 cre->buflen = 0; 1230 } 1231 1232 cre->line = 0; 1233 cre->method = 0; 1234 cre->done = 0; 1235 cre->chunked = 0; 1236 } 1237 1238 void 1239 relay_read_http(struct bufferevent *bev, void *arg) 1240 { 1241 struct ctl_relay_event *cre = (struct ctl_relay_event *)arg; 1242 struct rsession *con = cre->con; 1243 struct relay *rlay = (struct relay *)con->se_relay; 1244 struct protocol *proto = rlay->rl_proto; 1245 struct evbuffer *src = EVBUFFER_INPUT(bev); 1246 struct protonode *pn, pk, *proot, *pnv = NULL, pkv; 1247 char *line; 1248 int header = 0, ret, pass = 0; 1249 const char *errstr; 1250 size_t size; 1251 1252 if (gettimeofday(&con->se_tv_last, NULL) == -1) 1253 goto fail; 1254 size = EVBUFFER_LENGTH(src); 1255 DPRINTF("%s: size %lu, to read %llu", __func__, size, cre->toread); 1256 if (!size) { 1257 if (cre->dir == RELAY_DIR_RESPONSE) 1258 return; 1259 cre->toread = 0; 1260 goto done; 1261 } 1262 1263 pk.type = NODE_TYPE_HEADER; 1264 1265 while (!cre->done && (line = evbuffer_readline(src)) != NULL) { 1266 /* 1267 * An empty line indicates the end of the request. 1268 * libevent already stripped the \r\n for us. 1269 */ 1270 if (!strlen(line)) { 1271 cre->done = 1; 1272 free(line); 1273 break; 1274 } 1275 pk.key = line; 1276 1277 /* 1278 * The first line is the GET/POST/PUT/... request, 1279 * subsequent lines are HTTP headers. 1280 */ 1281 if (++cre->line == 1) { 1282 pk.value = strchr(pk.key, ' '); 1283 } else 1284 pk.value = strchr(pk.key, ':'); 1285 if (pk.value == NULL || strlen(pk.value) < 3) { 1286 if (cre->line == 1) { 1287 free(line); 1288 relay_close_http(con, 400, "malformed", 0); 1289 return; 1290 } 1291 1292 DPRINTF("%s: request '%s'", __func__, line); 1293 /* Append line to the output buffer */ 1294 if (relay_bufferevent_print(cre->dst, line) == -1 || 1295 relay_bufferevent_print(cre->dst, "\r\n") == -1) { 1296 free(line); 1297 goto fail; 1298 } 1299 free(line); 1300 continue; 1301 } 1302 if (*pk.value == ':') { 1303 *pk.value++ = '\0'; 1304 pk.value += strspn(pk.value, " \t\r\n"); 1305 header = 1; 1306 } else { 1307 *pk.value++ = '\0'; 1308 header = 0; 1309 } 1310 1311 DPRINTF("%s: header '%s: %s'", __func__, pk.key, pk.value); 1312 1313 /* 1314 * Identify and handle specific HTTP request methods 1315 */ 1316 if (cre->line == 1) { 1317 if (cre->dir == RELAY_DIR_RESPONSE) { 1318 cre->method = HTTP_METHOD_RESPONSE; 1319 goto lookup; 1320 } else if (strcmp("HEAD", pk.key) == 0) 1321 cre->method = HTTP_METHOD_HEAD; 1322 else if (strcmp("POST", pk.key) == 0) 1323 cre->method = HTTP_METHOD_POST; 1324 else if (strcmp("PUT", pk.key) == 0) 1325 cre->method = HTTP_METHOD_PUT; 1326 else if (strcmp("DELETE", pk.key) == 0) 1327 cre->method = HTTP_METHOD_DELETE; 1328 else if (strcmp("OPTIONS", pk.key) == 0) 1329 cre->method = HTTP_METHOD_OPTIONS; 1330 else if (strcmp("TRACE", pk.key) == 0) 1331 cre->method = HTTP_METHOD_TRACE; 1332 else if (strcmp("CONNECT", pk.key) == 0) 1333 cre->method = HTTP_METHOD_CONNECT; 1334 else { 1335 /* Use GET method as the default */ 1336 cre->method = HTTP_METHOD_GET; 1337 } 1338 1339 /* 1340 * Decode the path and query 1341 */ 1342 cre->path = strdup(pk.value); 1343 if (cre->path == NULL) { 1344 free(line); 1345 goto fail; 1346 } 1347 cre->version = strchr(cre->path, ' '); 1348 if (cre->version != NULL) 1349 *cre->version++ = '\0'; 1350 cre->args = strchr(cre->path, '?'); 1351 if (cre->args != NULL) 1352 *cre->args++ = '\0'; 1353 #ifdef DEBUG 1354 char buf[BUFSIZ]; 1355 if (snprintf(buf, sizeof(buf), " \"%s\"", 1356 cre->path) == -1 || 1357 evbuffer_add(con->se_log, buf, strlen(buf)) == -1) { 1358 free(line); 1359 goto fail; 1360 } 1361 #endif 1362 1363 /* 1364 * Lookup protocol handlers in the URL path 1365 */ 1366 if ((proto->flags & F_LOOKUP_PATH) == 0) 1367 goto lookup; 1368 1369 pkv.key = cre->path; 1370 pkv.type = NODE_TYPE_PATH; 1371 pkv.value = cre->args == NULL ? "" : cre->args; 1372 1373 DPRINTF("%s: lookup path '%s: %s'", 1374 __func__, pkv.key, pkv.value); 1375 1376 if ((proot = RB_FIND(proto_tree, 1377 cre->tree, &pkv)) == NULL) 1378 goto lookup; 1379 1380 PROTONODE_FOREACH(pnv, proot, entry) { 1381 ret = relay_handle_http(cre, proot, 1382 pnv, &pkv, 0); 1383 if (ret == PN_FAIL) 1384 goto abort; 1385 } 1386 } else if ((cre->method == HTTP_METHOD_DELETE || 1387 cre->method == HTTP_METHOD_GET || 1388 cre->method == HTTP_METHOD_HEAD || 1389 cre->method == HTTP_METHOD_OPTIONS || 1390 cre->method == HTTP_METHOD_POST || 1391 cre->method == HTTP_METHOD_PUT || 1392 cre->method == HTTP_METHOD_RESPONSE) && 1393 strcasecmp("Content-Length", pk.key) == 0) { 1394 /* 1395 * Need to read data from the client after the 1396 * HTTP header. 1397 * XXX What about non-standard clients not using 1398 * the carriage return? And some browsers seem to 1399 * include the line length in the content-length. 1400 */ 1401 cre->toread = strtonum(pk.value, 0, ULLONG_MAX, &errstr); 1402 if (errstr) { 1403 relay_close_http(con, 500, errstr, 0); 1404 goto abort; 1405 } 1406 } else if ((cre->method == HTTP_METHOD_TRACE) && 1407 strcasecmp("Content-Length", pk.key) == 0) { 1408 /* 1409 * This method should not have a body and thus no 1410 * Content-Length header. 1411 */ 1412 relay_close_http(con, 400, "malformed", 0); 1413 goto abort; 1414 } 1415 lookup: 1416 if (strcasecmp("Transfer-Encoding", pk.key) == 0 && 1417 strcasecmp("chunked", pk.value) == 0) 1418 cre->chunked = 1; 1419 1420 /* Match the HTTP header */ 1421 if ((pn = RB_FIND(proto_tree, cre->tree, &pk)) == NULL) 1422 goto next; 1423 1424 if (cre->dir == RELAY_DIR_RESPONSE) 1425 goto handle; 1426 1427 if (pn->flags & PNFLAG_LOOKUP_URL) { 1428 /* 1429 * Lookup the URL of type example.com/path?args. 1430 * Either as a plain string or SHA1/MD5 digest. 1431 */ 1432 if ((pn->flags & PNFLAG_LOOKUP_DIGEST(0)) && 1433 relay_lookup_url(cre, pk.value, 1434 DIGEST_NONE) == PN_FAIL) 1435 goto abort; 1436 if ((pn->flags & PNFLAG_LOOKUP_DIGEST(DIGEST_SHA1)) && 1437 relay_lookup_url(cre, pk.value, 1438 DIGEST_SHA1) == PN_FAIL) 1439 goto abort; 1440 if ((pn->flags & PNFLAG_LOOKUP_DIGEST(DIGEST_MD5)) && 1441 relay_lookup_url(cre, pk.value, 1442 DIGEST_MD5) == PN_FAIL) 1443 goto abort; 1444 } else if (pn->flags & PNFLAG_LOOKUP_QUERY) { 1445 /* Lookup the HTTP query arguments */ 1446 if (relay_lookup_query(cre) == PN_FAIL) 1447 goto abort; 1448 } else if (pn->flags & PNFLAG_LOOKUP_COOKIE) { 1449 /* Lookup the HTTP cookie */ 1450 if (relay_lookup_cookie(cre, pk.value) == PN_FAIL) 1451 goto abort; 1452 } 1453 1454 handle: 1455 pass = 0; 1456 PROTONODE_FOREACH(pnv, pn, entry) { 1457 ret = relay_handle_http(cre, pn, pnv, &pk, header); 1458 if (ret == PN_PASS) 1459 pass = 1; 1460 else if (ret == PN_FAIL) 1461 goto abort; 1462 } 1463 1464 if (pass) { 1465 next: 1466 if (relay_bufferevent_print(cre->dst, pk.key) == -1 || 1467 relay_bufferevent_print(cre->dst, 1468 header ? ": " : " ") == -1 || 1469 relay_bufferevent_print(cre->dst, pk.value) == -1 || 1470 relay_bufferevent_print(cre->dst, "\r\n") == -1) { 1471 free(line); 1472 goto fail; 1473 } 1474 } 1475 free(line); 1476 } 1477 if (cre->done) { 1478 RB_FOREACH(proot, proto_tree, cre->tree) { 1479 PROTONODE_FOREACH(pn, proot, entry) 1480 if (relay_resolve(cre, proot, pn) != 0) 1481 return; 1482 } 1483 1484 switch (cre->method) { 1485 case HTTP_METHOD_NONE: 1486 relay_close_http(con, 406, "no method", 0); 1487 return; 1488 case HTTP_METHOD_CONNECT: 1489 /* Data stream */ 1490 bev->readcb = relay_read; 1491 break; 1492 case HTTP_METHOD_DELETE: 1493 case HTTP_METHOD_GET: 1494 case HTTP_METHOD_HEAD: 1495 case HTTP_METHOD_OPTIONS: 1496 case HTTP_METHOD_POST: 1497 case HTTP_METHOD_PUT: 1498 case HTTP_METHOD_RESPONSE: 1499 /* HTTP request payload */ 1500 if (cre->toread) { 1501 bev->readcb = relay_read_httpcontent; 1502 break; 1503 } 1504 1505 /* Single-pass HTTP response */ 1506 bev->readcb = relay_read; 1507 break; 1508 default: 1509 /* HTTP handler */ 1510 bev->readcb = relay_read_http; 1511 break; 1512 } 1513 if (cre->chunked) { 1514 /* Chunked transfer encoding */ 1515 cre->toread = 0; 1516 bev->readcb = relay_read_httpchunks; 1517 } 1518 1519 /* Write empty newline and switch to relay mode */ 1520 if (relay_bufferevent_print(cre->dst, "\r\n") == -1) 1521 goto fail; 1522 1523 relay_http_request_close(cre); 1524 1525 done: 1526 if (cre->dir == RELAY_DIR_REQUEST && !cre->toread && 1527 proto->lateconnect && cre->dst->bev == NULL) { 1528 if (rlay->rl_conf.fwdmode == FWD_TRANS) { 1529 relay_bindanyreq(con, 0, IPPROTO_TCP); 1530 return; 1531 } 1532 if (relay_connect(con) == -1) 1533 relay_close_http(con, 502, "session failed", 0); 1534 return; 1535 } 1536 } 1537 if (con->se_done) { 1538 relay_close(con, "last http read (done)"); 1539 return; 1540 } 1541 if (EVBUFFER_LENGTH(src) && bev->readcb != relay_read_http) 1542 bev->readcb(bev, arg); 1543 bufferevent_enable(bev, EV_READ); 1544 return; 1545 fail: 1546 relay_close_http(con, 500, strerror(errno), 0); 1547 return; 1548 abort: 1549 free(line); 1550 } 1551 1552 static int 1553 _relay_lookup_url(struct ctl_relay_event *cre, char *host, char *path, 1554 char *query, enum digest_type type) 1555 { 1556 struct rsession *con = cre->con; 1557 struct protonode *proot, *pnv, pkv; 1558 char *val, *md = NULL; 1559 int ret = PN_FAIL; 1560 1561 if (asprintf(&val, "%s%s%s%s", 1562 host, path, 1563 query == NULL ? "" : "?", 1564 query == NULL ? "" : query) == -1) { 1565 relay_close_http(con, 500, "failed to allocate URL", 0); 1566 return (PN_FAIL); 1567 } 1568 1569 DPRINTF("%s: %s", __func__, val); 1570 1571 switch (type) { 1572 case DIGEST_SHA1: 1573 case DIGEST_MD5: 1574 if ((md = digeststr(type, val, strlen(val), NULL)) == NULL) { 1575 relay_close_http(con, 500, 1576 "failed to allocate digest", 0); 1577 goto fail; 1578 } 1579 pkv.key = md; 1580 break; 1581 case DIGEST_NONE: 1582 pkv.key = val; 1583 break; 1584 } 1585 pkv.type = NODE_TYPE_URL; 1586 pkv.value = ""; 1587 1588 if ((proot = RB_FIND(proto_tree, cre->tree, &pkv)) == NULL) 1589 goto done; 1590 1591 PROTONODE_FOREACH(pnv, proot, entry) { 1592 ret = relay_handle_http(cre, proot, pnv, &pkv, 0); 1593 if (ret == PN_FAIL) 1594 goto fail; 1595 } 1596 1597 done: 1598 ret = PN_PASS; 1599 fail: 1600 if (md != NULL) 1601 free(md); 1602 free(val); 1603 return (ret); 1604 } 1605 1606 int 1607 relay_lookup_url(struct ctl_relay_event *cre, const char *str, 1608 enum digest_type type) 1609 { 1610 struct rsession *con = cre->con; 1611 int i, j, dots; 1612 char *hi[RELAY_MAXLOOKUPLEVELS], *p, *pp, *c, ch; 1613 char ph[MAXHOSTNAMELEN]; 1614 int ret; 1615 1616 if (cre->path == NULL) 1617 return (PN_PASS); 1618 1619 /* 1620 * This is an URL lookup algorithm inspired by 1621 * http://code.google.com/apis/safebrowsing/ 1622 * developers_guide.html#PerformingLookups 1623 */ 1624 1625 DPRINTF("%s: host: '%s', path: '%s', query: '%s'", __func__, 1626 str, cre->path, cre->args == NULL ? "" : cre->args); 1627 1628 if (canonicalize_host(str, ph, sizeof(ph)) == NULL) { 1629 relay_close_http(con, 400, "invalid host name", 0); 1630 return (PN_FAIL); 1631 } 1632 1633 bzero(hi, sizeof(hi)); 1634 for (dots = -1, i = strlen(ph) - 1; i > 0; i--) { 1635 if (ph[i] == '.' && ++dots) 1636 hi[dots - 1] = &ph[i + 1]; 1637 if (dots > (RELAY_MAXLOOKUPLEVELS - 2)) 1638 break; 1639 } 1640 if (dots == -1) 1641 dots = 0; 1642 hi[dots] = ph; 1643 1644 if ((pp = strdup(cre->path)) == NULL) { 1645 relay_close_http(con, 500, "failed to allocate path", 0); 1646 return (PN_FAIL); 1647 } 1648 for (i = (RELAY_MAXLOOKUPLEVELS - 1); i >= 0; i--) { 1649 if (hi[i] == NULL) 1650 continue; 1651 1652 /* 1. complete path with query */ 1653 if (cre->args != NULL) 1654 if ((ret = _relay_lookup_url(cre, hi[i], 1655 pp, cre->args, type)) != PN_PASS) 1656 goto done; 1657 1658 /* 2. complete path without query */ 1659 if ((ret = _relay_lookup_url(cre, hi[i], 1660 pp, NULL, type)) != PN_PASS) 1661 goto done; 1662 1663 /* 3. traverse path */ 1664 for (j = 0, p = strchr(pp, '/'); 1665 p != NULL; p = strchr(p, '/'), j++) { 1666 if (j > (RELAY_MAXLOOKUPLEVELS - 2) || ++p == '\0') 1667 break; 1668 c = &pp[p - pp]; 1669 ch = *c; 1670 *c = '\0'; 1671 if ((ret = _relay_lookup_url(cre, hi[i], 1672 pp, NULL, type)) != PN_PASS) 1673 goto done; 1674 *c = ch; 1675 } 1676 } 1677 1678 ret = PN_PASS; 1679 done: 1680 free(pp); 1681 return (ret); 1682 } 1683 1684 int 1685 relay_lookup_query(struct ctl_relay_event *cre) 1686 { 1687 struct rsession *con = cre->con; 1688 struct protonode *proot, *pnv, pkv; 1689 char *val, *ptr; 1690 int ret; 1691 1692 if (cre->path == NULL || cre->args == NULL || strlen(cre->args) < 2) 1693 return (PN_PASS); 1694 if ((val = strdup(cre->args)) == NULL) { 1695 relay_close_http(con, 500, "failed to allocate query", 0); 1696 return (PN_FAIL); 1697 } 1698 1699 ptr = val; 1700 while (ptr != NULL && strlen(ptr)) { 1701 pkv.key = ptr; 1702 pkv.type = NODE_TYPE_QUERY; 1703 if ((ptr = strchr(ptr, '&')) != NULL) 1704 *ptr++ = '\0'; 1705 if ((pkv.value = 1706 strchr(pkv.key, '=')) == NULL || 1707 strlen(pkv.value) < 1) 1708 continue; 1709 *pkv.value++ = '\0'; 1710 1711 if ((proot = RB_FIND(proto_tree, cre->tree, &pkv)) == NULL) 1712 continue; 1713 PROTONODE_FOREACH(pnv, proot, entry) { 1714 ret = relay_handle_http(cre, proot, 1715 pnv, &pkv, 0); 1716 if (ret == PN_FAIL) 1717 goto done; 1718 } 1719 } 1720 1721 ret = PN_PASS; 1722 done: 1723 free(val); 1724 return (ret); 1725 } 1726 1727 int 1728 relay_lookup_cookie(struct ctl_relay_event *cre, const char *str) 1729 { 1730 struct rsession *con = cre->con; 1731 struct protonode *proot, *pnv, pkv; 1732 char *val, *ptr; 1733 int ret; 1734 1735 if ((val = strdup(str)) == NULL) { 1736 relay_close_http(con, 500, "failed to allocate cookie", 0); 1737 return (PN_FAIL); 1738 } 1739 1740 for (ptr = val; ptr != NULL && strlen(ptr);) { 1741 if (*ptr == ' ') 1742 *ptr++ = '\0'; 1743 pkv.key = ptr; 1744 pkv.type = NODE_TYPE_COOKIE; 1745 if ((ptr = strchr(ptr, ';')) != NULL) 1746 *ptr++ = '\0'; 1747 /* 1748 * XXX We do not handle attributes 1749 * ($Path, $Domain, or $Port) 1750 */ 1751 if (*pkv.key == '$') 1752 continue; 1753 1754 if ((pkv.value = 1755 strchr(pkv.key, '=')) == NULL || 1756 strlen(pkv.value) < 1) 1757 continue; 1758 *pkv.value++ = '\0'; 1759 if (*pkv.value == '"') 1760 *pkv.value++ = '\0'; 1761 if (pkv.value[strlen(pkv.value) - 1] == '"') 1762 pkv.value[strlen(pkv.value) - 1] = '\0'; 1763 if ((proot = RB_FIND(proto_tree, cre->tree, &pkv)) == NULL) 1764 continue; 1765 PROTONODE_FOREACH(pnv, proot, entry) { 1766 ret = relay_handle_http(cre, proot, pnv, &pkv, 0); 1767 if (ret == PN_FAIL) 1768 goto done; 1769 } 1770 } 1771 1772 ret = PN_PASS; 1773 done: 1774 free(val); 1775 return (ret); 1776 } 1777 1778 void 1779 relay_close_http(struct rsession *con, u_int code, const char *msg, 1780 u_int16_t labelid) 1781 { 1782 struct relay *rlay = (struct relay *)con->se_relay; 1783 struct bufferevent *bev = con->se_in.bev; 1784 const char *httperr = print_httperror(code), *text = ""; 1785 char *httpmsg; 1786 time_t t; 1787 struct tm *lt; 1788 char tmbuf[32], hbuf[128]; 1789 const char *style, *label = NULL; 1790 1791 /* In some cases this function may be called from generic places */ 1792 if (rlay->rl_proto->type != RELAY_PROTO_HTTP || 1793 (rlay->rl_proto->flags & F_RETURN) == 0) { 1794 relay_close(con, msg); 1795 return; 1796 } 1797 1798 if (bev == NULL) 1799 goto done; 1800 1801 /* Some system information */ 1802 if (print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL) 1803 goto done; 1804 1805 /* RFC 2616 "tolerates" asctime() */ 1806 time(&t); 1807 lt = localtime(&t); 1808 tmbuf[0] = '\0'; 1809 if (asctime_r(lt, tmbuf) != NULL) 1810 tmbuf[strlen(tmbuf) - 1] = '\0'; /* skip final '\n' */ 1811 1812 /* Do not send details of the Internal Server Error */ 1813 if (code != 500) 1814 text = msg; 1815 if (labelid != 0) 1816 label = pn_id2name(labelid); 1817 1818 /* A CSS stylesheet allows minimal customization by the user */ 1819 if ((style = rlay->rl_proto->style) == NULL) 1820 style = "body { background-color: #a00000; color: white; }"; 1821 1822 /* Generate simple HTTP+HTML error document */ 1823 if (asprintf(&httpmsg, 1824 "HTTP/1.x %03d %s\r\n" 1825 "Date: %s\r\n" 1826 "Server: %s\r\n" 1827 "Connection: close\r\n" 1828 "Content-Type: text/html\r\n" 1829 "\r\n" 1830 "<!DOCTYPE HTML PUBLIC " 1831 "\"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" 1832 "<html>\n" 1833 "<head>\n" 1834 "<title>%03d %s</title>\n" 1835 "<style type=\"text/css\"><!--\n%s\n--></style>\n" 1836 "</head>\n" 1837 "<body>\n" 1838 "<h1>%s</h1>\n" 1839 "<div id='m'>%s</div>\n" 1840 "<div id='l'>%s</div>\n" 1841 "<hr><address>%s at %s port %d</address>\n" 1842 "</body>\n" 1843 "</html>\n", 1844 code, httperr, tmbuf, RELAYD_SERVERNAME, 1845 code, httperr, style, httperr, text, 1846 label == NULL ? "" : label, 1847 RELAYD_SERVERNAME, hbuf, ntohs(rlay->rl_conf.port)) == -1) 1848 goto done; 1849 1850 /* Dump the message without checking for success */ 1851 relay_dump(&con->se_in, httpmsg, strlen(httpmsg)); 1852 free(httpmsg); 1853 1854 done: 1855 if (asprintf(&httpmsg, "%s (%03d %s)", msg, code, httperr) == -1) 1856 relay_close(con, msg); 1857 else { 1858 relay_close(con, httpmsg); 1859 free(httpmsg); 1860 } 1861 } 1862 1863 int 1864 relay_splice(struct ctl_relay_event *cre) 1865 { 1866 struct rsession *con = cre->con; 1867 struct relay *rlay = (struct relay *)con->se_relay; 1868 struct protocol *proto = rlay->rl_proto; 1869 struct splice sp; 1870 1871 if ((rlay->rl_conf.flags & (F_SSL|F_SSLCLIENT)) || 1872 (proto->tcpflags & TCPFLAG_NSPLICE)) 1873 return (0); 1874 1875 if (cre->bev->readcb != relay_read) 1876 return (0); 1877 1878 bzero(&sp, sizeof(sp)); 1879 sp.sp_fd = cre->dst->s; 1880 sp.sp_idle = rlay->rl_conf.timeout; 1881 if (setsockopt(cre->s, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp)) == -1) { 1882 log_debug("%s: session %d: splice dir %d failed: %s", 1883 __func__, con->se_id, cre->dir, strerror(errno)); 1884 return (-1); 1885 } 1886 cre->splicelen = 0; 1887 DPRINTF("%s: session %d: splice dir %d successful", 1888 __func__, con->se_id, cre->dir); 1889 return (1); 1890 } 1891 1892 int 1893 relay_splicelen(struct ctl_relay_event *cre) 1894 { 1895 struct rsession *con = cre->con; 1896 off_t len; 1897 socklen_t optlen; 1898 1899 optlen = sizeof(len); 1900 if (getsockopt(cre->s, SOL_SOCKET, SO_SPLICE, &len, &optlen) == -1) { 1901 log_debug("%s: session %d: splice dir %d get length failed: %s", 1902 __func__, con->se_id, cre->dir, strerror(errno)); 1903 return (-1); 1904 } 1905 if (len > cre->splicelen) { 1906 cre->splicelen = len; 1907 return (1); 1908 } 1909 return (0); 1910 } 1911 1912 void 1913 relay_error(struct bufferevent *bev, short error, void *arg) 1914 { 1915 struct ctl_relay_event *cre = (struct ctl_relay_event *)arg; 1916 struct rsession *con = cre->con; 1917 struct evbuffer *dst; 1918 1919 if (error & EVBUFFER_TIMEOUT) { 1920 if (cre->splicelen >= 0) { 1921 bufferevent_enable(bev, EV_READ); 1922 } else if (cre->dst->splicelen >= 0) { 1923 switch (relay_splicelen(cre->dst)) { 1924 case -1: 1925 goto fail; 1926 case 0: 1927 relay_close(con, "buffer event timeout"); 1928 break; 1929 case 1: 1930 bufferevent_enable(bev, EV_READ); 1931 break; 1932 } 1933 } else { 1934 relay_close(con, "buffer event timeout"); 1935 } 1936 return; 1937 } 1938 if (error & EVBUFFER_ERROR && errno == ETIMEDOUT) { 1939 if (cre->dst->splicelen >= 0) { 1940 switch (relay_splicelen(cre->dst)) { 1941 case -1: 1942 goto fail; 1943 case 0: 1944 relay_close(con, "splice timeout"); 1945 return; 1946 case 1: 1947 bufferevent_enable(bev, EV_READ); 1948 break; 1949 } 1950 } 1951 if (relay_splice(cre) == -1) 1952 goto fail; 1953 return; 1954 } 1955 if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) { 1956 bufferevent_disable(bev, EV_READ|EV_WRITE); 1957 1958 con->se_done = 1; 1959 if (cre->dst->bev != NULL) { 1960 dst = EVBUFFER_OUTPUT(cre->dst->bev); 1961 if (EVBUFFER_LENGTH(dst)) 1962 return; 1963 } else 1964 return; 1965 1966 relay_close(con, "done"); 1967 return; 1968 } 1969 relay_close(con, "buffer event error"); 1970 return; 1971 fail: 1972 relay_close(con, strerror(errno)); 1973 } 1974 1975 void 1976 relay_accept(int fd, short event, void *arg) 1977 { 1978 struct relay *rlay = (struct relay *)arg; 1979 struct protocol *proto = rlay->rl_proto; 1980 struct rsession *con = NULL; 1981 struct ctl_natlook *cnl = NULL; 1982 socklen_t slen; 1983 struct timeval tv; 1984 struct sockaddr_storage ss; 1985 int s = -1; 1986 1987 event_add(&rlay->rl_ev, NULL); 1988 if ((event & EV_TIMEOUT)) 1989 return; 1990 1991 slen = sizeof(ss); 1992 if ((s = accept(fd, (struct sockaddr *)&ss, (socklen_t *)&slen)) == -1) { 1993 /* 1994 * Pause accept if we are out of file descriptors, or 1995 * libevent will haunt us here too. 1996 */ 1997 if (errno == ENFILE || errno == EMFILE) { 1998 struct timeval evtpause = { 1, 0 }; 1999 2000 event_del(&rlay->rl_ev); 2001 evtimer_add(&rlay->rl_evt, &evtpause); 2002 } 2003 return; 2004 } 2005 if (relay_sessions >= RELAY_MAX_SESSIONS || 2006 rlay->rl_conf.flags & F_DISABLE) 2007 goto err; 2008 2009 if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) 2010 goto err; 2011 2012 if ((con = calloc(1, sizeof(*con))) == NULL) 2013 goto err; 2014 2015 con->se_in.s = s; 2016 con->se_in.ssl = NULL; 2017 con->se_out.s = -1; 2018 con->se_out.ssl = NULL; 2019 con->se_in.dst = &con->se_out; 2020 con->se_out.dst = &con->se_in; 2021 con->se_in.con = con; 2022 con->se_out.con = con; 2023 con->se_in.splicelen = -1; 2024 con->se_out.splicelen = -1; 2025 con->se_relay = rlay; 2026 con->se_id = ++relay_conid; 2027 con->se_relayid = rlay->rl_conf.id; 2028 con->se_pid = getpid(); 2029 con->se_hashkey = rlay->rl_dstkey; 2030 con->se_in.tree = &proto->request_tree; 2031 con->se_out.tree = &proto->response_tree; 2032 con->se_in.dir = RELAY_DIR_REQUEST; 2033 con->se_out.dir = RELAY_DIR_RESPONSE; 2034 con->se_retry = rlay->rl_conf.dstretry; 2035 con->se_bnds = -1; 2036 if (gettimeofday(&con->se_tv_start, NULL) == -1) 2037 goto err; 2038 bcopy(&con->se_tv_start, &con->se_tv_last, sizeof(con->se_tv_last)); 2039 bcopy(&ss, &con->se_in.ss, sizeof(con->se_in.ss)); 2040 con->se_out.port = rlay->rl_conf.dstport; 2041 switch (ss.ss_family) { 2042 case AF_INET: 2043 con->se_in.port = ((struct sockaddr_in *)&ss)->sin_port; 2044 break; 2045 case AF_INET6: 2046 con->se_in.port = ((struct sockaddr_in6 *)&ss)->sin6_port; 2047 break; 2048 } 2049 2050 relay_sessions++; 2051 SPLAY_INSERT(session_tree, &rlay->rl_sessions, con); 2052 2053 /* Increment the per-relay session counter */ 2054 rlay->rl_stats[proc_id].last++; 2055 2056 /* Pre-allocate output buffer */ 2057 con->se_out.output = evbuffer_new(); 2058 if (con->se_out.output == NULL) { 2059 relay_close(con, "failed to allocate output buffer"); 2060 return; 2061 } 2062 2063 /* Pre-allocate log buffer */ 2064 con->se_log = evbuffer_new(); 2065 if (con->se_log == NULL) { 2066 relay_close(con, "failed to allocate log buffer"); 2067 return; 2068 } 2069 2070 if (rlay->rl_conf.flags & F_DIVERT) { 2071 slen = sizeof(con->se_out.ss); 2072 if (getsockname(s, (struct sockaddr *)&con->se_out.ss, 2073 &slen) == -1) { 2074 relay_close(con, "peer lookup failed"); 2075 return; 2076 } 2077 con->se_out.port = relay_socket_getport(&con->se_out.ss); 2078 2079 /* Detect loop and fall back to the alternate forward target */ 2080 if (bcmp(&rlay->rl_conf.ss, &con->se_out.ss, 2081 sizeof(con->se_out.ss)) == 0 && 2082 con->se_out.port == rlay->rl_conf.port) 2083 con->se_out.ss.ss_family = AF_UNSPEC; 2084 } else if (rlay->rl_conf.flags & F_NATLOOK) { 2085 if ((cnl = (struct ctl_natlook *) 2086 calloc(1, sizeof(struct ctl_natlook))) == NULL) { 2087 relay_close(con, "failed to allocate nat lookup"); 2088 return; 2089 } 2090 2091 con->se_cnl = cnl; 2092 bzero(cnl, sizeof(*cnl)); 2093 cnl->in = -1; 2094 cnl->id = con->se_id; 2095 cnl->proc = proc_id; 2096 cnl->proto = IPPROTO_TCP; 2097 2098 bcopy(&con->se_in.ss, &cnl->src, sizeof(cnl->src)); 2099 slen = sizeof(cnl->dst); 2100 if (getsockname(s, 2101 (struct sockaddr *)&cnl->dst, &slen) == -1) { 2102 relay_close(con, "failed to get local address"); 2103 return; 2104 } 2105 2106 proc_compose_imsg(env->sc_ps, PROC_PFE, -1, IMSG_NATLOOK, -1, 2107 cnl, sizeof(*cnl)); 2108 2109 /* Schedule timeout */ 2110 evtimer_set(&con->se_ev, relay_natlook, con); 2111 bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv)); 2112 evtimer_add(&con->se_ev, &tv); 2113 return; 2114 } 2115 2116 relay_session(con); 2117 return; 2118 err: 2119 if (s != -1) { 2120 close(s); 2121 if (con != NULL) 2122 free(con); 2123 } 2124 } 2125 2126 u_int32_t 2127 relay_hash_addr(struct sockaddr_storage *ss, u_int32_t p) 2128 { 2129 struct sockaddr_in *sin4; 2130 struct sockaddr_in6 *sin6; 2131 2132 if (ss->ss_family == AF_INET) { 2133 sin4 = (struct sockaddr_in *)ss; 2134 p = hash32_buf(&sin4->sin_addr, 2135 sizeof(struct in_addr), p); 2136 } else { 2137 sin6 = (struct sockaddr_in6 *)ss; 2138 p = hash32_buf(&sin6->sin6_addr, 2139 sizeof(struct in6_addr), p); 2140 } 2141 2142 return (p); 2143 } 2144 2145 int 2146 relay_from_table(struct rsession *con) 2147 { 2148 struct relay *rlay = (struct relay *)con->se_relay; 2149 struct host *host; 2150 struct table *table = rlay->rl_dsttable; 2151 u_int32_t p = con->se_hashkey; 2152 int idx = 0; 2153 2154 if (table->conf.check && !table->up && !rlay->rl_backuptable->up) { 2155 log_debug("%s: no active hosts", __func__); 2156 return (-1); 2157 } else if (!table->up && rlay->rl_backuptable->up) { 2158 table = rlay->rl_backuptable; 2159 } 2160 2161 switch (rlay->rl_conf.dstmode) { 2162 case RELAY_DSTMODE_ROUNDROBIN: 2163 if ((int)rlay->rl_dstkey >= rlay->rl_dstnhosts) 2164 rlay->rl_dstkey = 0; 2165 idx = (int)rlay->rl_dstkey; 2166 break; 2167 case RELAY_DSTMODE_LOADBALANCE: 2168 p = relay_hash_addr(&con->se_in.ss, p); 2169 /* FALLTHROUGH */ 2170 case RELAY_DSTMODE_HASH: 2171 p = relay_hash_addr(&rlay->rl_conf.ss, p); 2172 p = hash32_buf(&rlay->rl_conf.port, 2173 sizeof(rlay->rl_conf.port), p); 2174 if ((idx = p % rlay->rl_dstnhosts) >= RELAY_MAXHOSTS) 2175 return (-1); 2176 } 2177 host = rlay->rl_dsthost[idx]; 2178 DPRINTF("%s: host %s, p 0x%08x, idx %d", __func__, 2179 host->conf.name, p, idx); 2180 while (host != NULL) { 2181 DPRINTF("%s: host %s", __func__, host->conf.name); 2182 if (!table->conf.check || host->up == HOST_UP) 2183 goto found; 2184 host = TAILQ_NEXT(host, entry); 2185 } 2186 TAILQ_FOREACH(host, &table->hosts, entry) { 2187 DPRINTF("%s: next host %s", __func__, host->conf.name); 2188 if (!table->conf.check || host->up == HOST_UP) 2189 goto found; 2190 } 2191 2192 /* Should not happen */ 2193 fatalx("relay_from_table: no active hosts, desynchronized"); 2194 2195 found: 2196 if (rlay->rl_conf.dstmode == RELAY_DSTMODE_ROUNDROBIN) 2197 rlay->rl_dstkey = host->idx + 1; 2198 con->se_retry = host->conf.retry; 2199 con->se_out.port = table->conf.port; 2200 bcopy(&host->conf.ss, &con->se_out.ss, sizeof(con->se_out.ss)); 2201 2202 return (0); 2203 } 2204 2205 void 2206 relay_natlook(int fd, short event, void *arg) 2207 { 2208 struct rsession *con = (struct rsession *)arg; 2209 struct relay *rlay = (struct relay *)con->se_relay; 2210 struct ctl_natlook *cnl = con->se_cnl; 2211 2212 if (cnl == NULL) 2213 fatalx("invalid NAT lookup"); 2214 2215 if (con->se_out.ss.ss_family == AF_UNSPEC && cnl->in == -1 && 2216 rlay->rl_conf.dstss.ss_family == AF_UNSPEC && 2217 rlay->rl_dsttable == NULL) { 2218 relay_close(con, "session NAT lookup failed"); 2219 return; 2220 } 2221 if (cnl->in != -1) { 2222 bcopy(&cnl->rdst, &con->se_out.ss, sizeof(con->se_out.ss)); 2223 con->se_out.port = cnl->rdport; 2224 } 2225 free(con->se_cnl); 2226 con->se_cnl = NULL; 2227 2228 relay_session(con); 2229 } 2230 2231 void 2232 relay_session(struct rsession *con) 2233 { 2234 struct relay *rlay = (struct relay *)con->se_relay; 2235 struct ctl_relay_event *in = &con->se_in, *out = &con->se_out; 2236 2237 if (bcmp(&rlay->rl_conf.ss, &out->ss, sizeof(out->ss)) == 0 && 2238 out->port == rlay->rl_conf.port) { 2239 log_debug("%s: session %d: looping", __func__, con->se_id); 2240 relay_close(con, "session aborted"); 2241 return; 2242 } 2243 2244 if (rlay->rl_conf.flags & F_UDP) { 2245 /* 2246 * Call the UDP protocol-specific handler 2247 */ 2248 if (rlay->rl_proto->request == NULL) 2249 fatalx("invalide UDP session"); 2250 if ((*rlay->rl_proto->request)(con) == -1) 2251 relay_close(con, "session failed"); 2252 return; 2253 } 2254 2255 if ((rlay->rl_conf.flags & F_SSL) && (in->ssl == NULL)) { 2256 relay_ssl_transaction(con, in); 2257 return; 2258 } 2259 2260 if (!rlay->rl_proto->lateconnect) { 2261 if (rlay->rl_conf.fwdmode == FWD_TRANS) 2262 relay_bindanyreq(con, 0, IPPROTO_TCP); 2263 else if (relay_connect(con) == -1) { 2264 relay_close(con, "session failed"); 2265 return; 2266 } 2267 } 2268 2269 relay_input(con); 2270 } 2271 2272 void 2273 relay_bindanyreq(struct rsession *con, in_port_t port, int proto) 2274 { 2275 struct relay *rlay = (struct relay *)con->se_relay; 2276 struct ctl_bindany bnd; 2277 struct timeval tv; 2278 2279 bzero(&bnd, sizeof(bnd)); 2280 bnd.bnd_id = con->se_id; 2281 bnd.bnd_proc = proc_id; 2282 bnd.bnd_port = port; 2283 bnd.bnd_proto = proto; 2284 bcopy(&con->se_in.ss, &bnd.bnd_ss, sizeof(bnd.bnd_ss)); 2285 proc_compose_imsg(env->sc_ps, PROC_PARENT, -1, IMSG_BINDANY, 2286 -1, &bnd, sizeof(bnd)); 2287 2288 /* Schedule timeout */ 2289 evtimer_set(&con->se_ev, relay_bindany, con); 2290 bcopy(&rlay->rl_conf.timeout, &tv, sizeof(tv)); 2291 evtimer_add(&con->se_ev, &tv); 2292 } 2293 2294 void 2295 relay_bindany(int fd, short event, void *arg) 2296 { 2297 struct rsession *con = (struct rsession *)arg; 2298 2299 if (con->se_bnds == -1) { 2300 relay_close(con, "bindany failed, invalid socket"); 2301 return; 2302 } 2303 2304 if (relay_connect(con) == -1) 2305 relay_close(con, "session failed"); 2306 } 2307 2308 int 2309 relay_connect(struct rsession *con) 2310 { 2311 struct relay *rlay = (struct relay *)con->se_relay; 2312 int bnds = -1, ret; 2313 2314 if (gettimeofday(&con->se_tv_start, NULL) == -1) 2315 return (-1); 2316 2317 if (rlay->rl_dsttable != NULL) { 2318 if (relay_from_table(con) != 0) 2319 return (-1); 2320 } else if (con->se_out.ss.ss_family == AF_UNSPEC) { 2321 bcopy(&rlay->rl_conf.dstss, &con->se_out.ss, 2322 sizeof(con->se_out.ss)); 2323 con->se_out.port = rlay->rl_conf.dstport; 2324 } 2325 2326 if (rlay->rl_conf.fwdmode == FWD_TRANS) { 2327 if (con->se_bnds == -1) { 2328 log_debug("%s: could not bind any sock", __func__); 2329 return (-1); 2330 } 2331 bnds = con->se_bnds; 2332 } 2333 2334 /* Do the IPv4-to-IPv6 or IPv6-to-IPv4 translation if requested */ 2335 if (rlay->rl_conf.dstaf.ss_family != AF_UNSPEC) { 2336 if (con->se_out.ss.ss_family == AF_INET && 2337 rlay->rl_conf.dstaf.ss_family == AF_INET6) 2338 ret = map4to6(&con->se_out.ss, &rlay->rl_conf.dstaf); 2339 else if (con->se_out.ss.ss_family == AF_INET6 && 2340 rlay->rl_conf.dstaf.ss_family == AF_INET) 2341 ret = map6to4(&con->se_out.ss); 2342 else 2343 ret = 0; 2344 if (ret != 0) { 2345 log_debug("%s: mapped to invalid address", __func__); 2346 return (-1); 2347 } 2348 } 2349 2350 retry: 2351 if ((con->se_out.s = relay_socket_connect(&con->se_out.ss, 2352 con->se_out.port, rlay->rl_proto, bnds)) == -1) { 2353 if (con->se_retry) { 2354 con->se_retry--; 2355 log_debug("%s: session %d: " 2356 "forward failed: %s, %s", __func__, 2357 con->se_id, strerror(errno), 2358 con->se_retry ? "next retry" : "last retry"); 2359 goto retry; 2360 } 2361 log_debug("%s: session %d: forward failed: %s", __func__, 2362 con->se_id, strerror(errno)); 2363 return (-1); 2364 } 2365 2366 if (errno == EINPROGRESS) 2367 event_again(&con->se_ev, con->se_out.s, EV_WRITE|EV_TIMEOUT, 2368 relay_connected, &con->se_tv_start, &rlay->rl_conf.timeout, 2369 con); 2370 else 2371 relay_connected(con->se_out.s, EV_WRITE, con); 2372 2373 return (0); 2374 } 2375 2376 void 2377 relay_close(struct rsession *con, const char *msg) 2378 { 2379 struct relay *rlay = (struct relay *)con->se_relay; 2380 char ibuf[128], obuf[128], *ptr = NULL; 2381 2382 SPLAY_REMOVE(session_tree, &rlay->rl_sessions, con); 2383 2384 event_del(&con->se_ev); 2385 if (con->se_in.bev != NULL) 2386 bufferevent_disable(con->se_in.bev, EV_READ|EV_WRITE); 2387 if (con->se_out.bev != NULL) 2388 bufferevent_disable(con->se_out.bev, EV_READ|EV_WRITE); 2389 2390 if ((env->sc_opts & RELAYD_OPT_LOGUPDATE) && msg != NULL) { 2391 bzero(&ibuf, sizeof(ibuf)); 2392 bzero(&obuf, sizeof(obuf)); 2393 (void)print_host(&con->se_in.ss, ibuf, sizeof(ibuf)); 2394 (void)print_host(&con->se_out.ss, obuf, sizeof(obuf)); 2395 if (EVBUFFER_LENGTH(con->se_log) && 2396 evbuffer_add_printf(con->se_log, "\r\n") != -1) 2397 ptr = evbuffer_readline(con->se_log); 2398 log_info("relay %s, " 2399 "session %d (%d active), %d, %s -> %s:%d, " 2400 "%s%s%s", rlay->rl_conf.name, con->se_id, relay_sessions, 2401 con->se_mark, ibuf, obuf, ntohs(con->se_out.port), msg, 2402 ptr == NULL ? "" : ",", ptr == NULL ? "" : ptr); 2403 if (ptr != NULL) 2404 free(ptr); 2405 } 2406 2407 if (con->se_priv != NULL) 2408 free(con->se_priv); 2409 if (con->se_in.bev != NULL) 2410 bufferevent_free(con->se_in.bev); 2411 else if (con->se_in.output != NULL) 2412 evbuffer_free(con->se_in.output); 2413 if (con->se_in.ssl != NULL) { 2414 /* XXX handle non-blocking shutdown */ 2415 if (SSL_shutdown(con->se_in.ssl) == 0) 2416 SSL_shutdown(con->se_in.ssl); 2417 SSL_free(con->se_in.ssl); 2418 } 2419 if (con->se_in.s != -1) 2420 close(con->se_in.s); 2421 if (con->se_in.path != NULL) 2422 free(con->se_in.path); 2423 if (con->se_in.buf != NULL) 2424 free(con->se_in.buf); 2425 if (con->se_in.nodes != NULL) 2426 free(con->se_in.nodes); 2427 2428 if (con->se_out.bev != NULL) 2429 bufferevent_free(con->se_out.bev); 2430 else if (con->se_out.output != NULL) 2431 evbuffer_free(con->se_out.output); 2432 if (con->se_out.ssl != NULL) { 2433 /* XXX handle non-blocking shutdown */ 2434 if (SSL_shutdown(con->se_out.ssl) == 0) 2435 SSL_shutdown(con->se_out.ssl); 2436 SSL_free(con->se_out.ssl); 2437 } 2438 if (con->se_out.s != -1) { 2439 close(con->se_out.s); 2440 2441 /* Some file descriptors are available again. */ 2442 if (evtimer_pending(&rlay->rl_evt, NULL)) { 2443 evtimer_del(&rlay->rl_evt); 2444 event_add(&rlay->rl_ev, NULL); 2445 } 2446 } 2447 2448 if (con->se_out.path != NULL) 2449 free(con->se_out.path); 2450 if (con->se_out.buf != NULL) 2451 free(con->se_out.buf); 2452 if (con->se_out.nodes != NULL) 2453 free(con->se_out.nodes); 2454 2455 if (con->se_log != NULL) 2456 evbuffer_free(con->se_log); 2457 2458 if (con->se_cnl != NULL) { 2459 #if 0 2460 proc_compose_imsg(env->sc_ps, PROC_PFE, -1, IMSG_KILLSTATES, -1, 2461 cnl, sizeof(*cnl)); 2462 #endif 2463 free(con->se_cnl); 2464 } 2465 2466 free(con); 2467 relay_sessions--; 2468 } 2469 2470 int 2471 relay_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg) 2472 { 2473 struct relay *rlay; 2474 struct rsession *con, se; 2475 struct ctl_natlook cnl; 2476 struct timeval tv; 2477 struct host *host; 2478 struct table *table; 2479 struct ctl_status st; 2480 objid_t id; 2481 int cid; 2482 2483 switch (imsg->hdr.type) { 2484 case IMSG_HOST_DISABLE: 2485 memcpy(&id, imsg->data, sizeof(id)); 2486 if ((host = host_find(env, id)) == NULL) 2487 fatalx("relay_dispatch_pfe: desynchronized"); 2488 if ((table = table_find(env, host->conf.tableid)) == 2489 NULL) 2490 fatalx("relay_dispatch_pfe: invalid table id"); 2491 if (host->up == HOST_UP) 2492 table->up--; 2493 host->flags |= F_DISABLE; 2494 host->up = HOST_UNKNOWN; 2495 break; 2496 case IMSG_HOST_ENABLE: 2497 memcpy(&id, imsg->data, sizeof(id)); 2498 if ((host = host_find(env, id)) == NULL) 2499 fatalx("relay_dispatch_pfe: desynchronized"); 2500 host->flags &= ~(F_DISABLE); 2501 host->up = HOST_UNKNOWN; 2502 break; 2503 case IMSG_TABLE_DISABLE: 2504 memcpy(&id, imsg->data, sizeof(id)); 2505 if ((table = table_find(env, id)) == NULL) 2506 fatalx("relay_dispatch_pfe: desynchronized"); 2507 table->conf.flags |= F_DISABLE; 2508 table->up = 0; 2509 TAILQ_FOREACH(host, &table->hosts, entry) 2510 host->up = HOST_UNKNOWN; 2511 break; 2512 case IMSG_TABLE_ENABLE: 2513 memcpy(&id, imsg->data, sizeof(id)); 2514 if ((table = table_find(env, id)) == NULL) 2515 fatalx("relay_dispatch_pfe: desynchronized"); 2516 table->conf.flags &= ~(F_DISABLE); 2517 table->up = 0; 2518 TAILQ_FOREACH(host, &table->hosts, entry) 2519 host->up = HOST_UNKNOWN; 2520 break; 2521 case IMSG_HOST_STATUS: 2522 IMSG_SIZE_CHECK(imsg, &st); 2523 memcpy(&st, imsg->data, sizeof(st)); 2524 if ((host = host_find(env, st.id)) == NULL) 2525 fatalx("relay_dispatch_pfe: invalid host id"); 2526 if (host->flags & F_DISABLE) 2527 break; 2528 if (host->up == st.up) { 2529 log_debug("%s: host %d => %d", __func__, 2530 host->conf.id, host->up); 2531 fatalx("relay_dispatch_pfe: desynchronized"); 2532 } 2533 2534 if ((table = table_find(env, host->conf.tableid)) 2535 == NULL) 2536 fatalx("relay_dispatch_pfe: invalid table id"); 2537 2538 DPRINTF("%s: [%d] state %d for " 2539 "host %u %s", __func__, proc_id, st.up, 2540 host->conf.id, host->conf.name); 2541 2542 if ((st.up == HOST_UNKNOWN && host->up == HOST_DOWN) || 2543 (st.up == HOST_DOWN && host->up == HOST_UNKNOWN)) { 2544 host->up = st.up; 2545 break; 2546 } 2547 if (st.up == HOST_UP) 2548 table->up++; 2549 else 2550 table->up--; 2551 host->up = st.up; 2552 break; 2553 case IMSG_NATLOOK: 2554 bcopy(imsg->data, &cnl, sizeof(cnl)); 2555 if ((con = session_find(env, cnl.id)) == NULL || 2556 con->se_cnl == NULL) { 2557 log_debug("%s: session %d: expired", 2558 __func__, cnl.id); 2559 break; 2560 } 2561 bcopy(&cnl, con->se_cnl, sizeof(*con->se_cnl)); 2562 evtimer_del(&con->se_ev); 2563 evtimer_set(&con->se_ev, relay_natlook, con); 2564 bzero(&tv, sizeof(tv)); 2565 evtimer_add(&con->se_ev, &tv); 2566 break; 2567 case IMSG_CTL_SESSION: 2568 IMSG_SIZE_CHECK(imsg, &cid); 2569 memcpy(&cid, imsg->data, sizeof(cid)); 2570 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) { 2571 SPLAY_FOREACH(con, session_tree, 2572 &rlay->rl_sessions) { 2573 memcpy(&se, con, sizeof(se)); 2574 se.se_cid = cid; 2575 proc_compose_imsg(env->sc_ps, p->p_id, -1, 2576 IMSG_CTL_SESSION, 2577 -1, &se, sizeof(se)); 2578 } 2579 } 2580 proc_compose_imsg(env->sc_ps, p->p_id, -1, IMSG_CTL_END, 2581 -1, &cid, sizeof(cid)); 2582 break; 2583 default: 2584 return (-1); 2585 } 2586 2587 return (0); 2588 } 2589 2590 int 2591 relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) 2592 { 2593 struct rsession *con; 2594 struct timeval tv; 2595 objid_t id; 2596 2597 switch (imsg->hdr.type) { 2598 case IMSG_BINDANY: 2599 bcopy(imsg->data, &id, sizeof(id)); 2600 if ((con = session_find(env, id)) == NULL) { 2601 log_debug("%s: session %d: expired", 2602 __func__, id); 2603 break; 2604 } 2605 2606 /* Will validate the result later */ 2607 con->se_bnds = imsg->fd; 2608 2609 evtimer_del(&con->se_ev); 2610 evtimer_set(&con->se_ev, relay_bindany, con); 2611 bzero(&tv, sizeof(tv)); 2612 evtimer_add(&con->se_ev, &tv); 2613 break; 2614 case IMSG_CFG_TABLE: 2615 config_gettable(env, imsg); 2616 break; 2617 case IMSG_CFG_HOST: 2618 config_gethost(env, imsg); 2619 break; 2620 case IMSG_CFG_PROTO: 2621 config_getproto(env, imsg); 2622 break; 2623 case IMSG_CFG_PROTONODE: 2624 return (config_getprotonode(env, imsg)); 2625 case IMSG_CFG_RELAY: 2626 config_getrelay(env, imsg); 2627 break; 2628 case IMSG_CFG_DONE: 2629 config_getcfg(env, imsg); 2630 break; 2631 case IMSG_CTL_START: 2632 relay_launch(); 2633 break; 2634 case IMSG_CTL_RESET: 2635 config_getreset(env, imsg); 2636 break; 2637 default: 2638 return (-1); 2639 } 2640 2641 return (0); 2642 } 2643 2644 SSL_CTX * 2645 relay_ssl_ctx_create(struct relay *rlay) 2646 { 2647 struct protocol *proto = rlay->rl_proto; 2648 SSL_CTX *ctx; 2649 2650 ctx = SSL_CTX_new(SSLv23_method()); 2651 if (ctx == NULL) 2652 goto err; 2653 2654 /* Modify session timeout and cache size*/ 2655 SSL_CTX_set_timeout(ctx, rlay->rl_conf.timeout.tv_sec); 2656 if (proto->cache < -1) { 2657 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); 2658 } else if (proto->cache >= -1) { 2659 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); 2660 if (proto->cache >= 0) 2661 SSL_CTX_sess_set_cache_size(ctx, proto->cache); 2662 } 2663 2664 /* Enable all workarounds and set SSL options */ 2665 SSL_CTX_set_options(ctx, SSL_OP_ALL); 2666 SSL_CTX_set_options(ctx, 2667 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 2668 2669 /* Set the allowed SSL protocols */ 2670 if ((proto->sslflags & SSLFLAG_SSLV2) == 0) 2671 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); 2672 if ((proto->sslflags & SSLFLAG_SSLV3) == 0) 2673 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); 2674 if ((proto->sslflags & SSLFLAG_TLSV1) == 0) 2675 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); 2676 2677 if (!SSL_CTX_set_cipher_list(ctx, proto->sslciphers)) 2678 goto err; 2679 2680 /* Verify the server certificate if we have a CA chain */ 2681 if ((rlay->rl_conf.flags & F_SSLCLIENT) && 2682 (rlay->rl_ssl_ca != NULL)) { 2683 if (!ssl_ctx_load_verify_memory(ctx, 2684 rlay->rl_ssl_ca, rlay->rl_conf.ssl_ca_len)) 2685 goto err; 2686 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 2687 } 2688 2689 if ((rlay->rl_conf.flags & F_SSL) == 0) 2690 return (ctx); 2691 2692 log_debug("%s: loading certificate", __func__); 2693 if (!ssl_ctx_use_certificate_chain(ctx, 2694 rlay->rl_ssl_cert, rlay->rl_conf.ssl_cert_len)) 2695 goto err; 2696 2697 log_debug("%s: loading private key", __func__); 2698 if (!ssl_ctx_use_private_key(ctx, rlay->rl_ssl_key, 2699 rlay->rl_conf.ssl_key_len)) 2700 goto err; 2701 if (!SSL_CTX_check_private_key(ctx)) 2702 goto err; 2703 2704 /* Set session context to the local relay name */ 2705 if (!SSL_CTX_set_session_id_context(ctx, rlay->rl_conf.name, 2706 strlen(rlay->rl_conf.name))) 2707 goto err; 2708 2709 return (ctx); 2710 2711 err: 2712 if (ctx != NULL) 2713 SSL_CTX_free(ctx); 2714 ssl_error(rlay->rl_conf.name, "relay_ssl_ctx_create"); 2715 return (NULL); 2716 } 2717 2718 void 2719 relay_ssl_transaction(struct rsession *con, struct ctl_relay_event *cre) 2720 { 2721 struct relay *rlay = (struct relay *)con->se_relay; 2722 SSL *ssl; 2723 const SSL_METHOD *method; 2724 void (*cb)(int, short, void *); 2725 u_int flag; 2726 2727 ssl = SSL_new(rlay->rl_ssl_ctx); 2728 if (ssl == NULL) 2729 goto err; 2730 2731 if (cre->dir == RELAY_DIR_REQUEST) { 2732 cb = relay_ssl_accept; 2733 method = SSLv23_server_method(); 2734 flag = EV_READ; 2735 } else { 2736 cb = relay_ssl_connect; 2737 method = SSLv23_client_method(); 2738 flag = EV_WRITE; 2739 } 2740 2741 if (!SSL_set_ssl_method(ssl, method)) 2742 goto err; 2743 if (!SSL_set_fd(ssl, cre->s)) 2744 goto err; 2745 2746 if (cre->dir == RELAY_DIR_REQUEST) 2747 SSL_set_accept_state(ssl); 2748 else 2749 SSL_set_connect_state(ssl); 2750 2751 cre->ssl = ssl; 2752 2753 DPRINTF("%s: session %d: scheduling on %s", __func__, con->se_id, 2754 (flag == EV_READ) ? "EV_READ" : "EV_WRITE"); 2755 event_again(&con->se_ev, cre->s, EV_TIMEOUT|flag, cb, 2756 &con->se_tv_start, &rlay->rl_conf.timeout, con); 2757 return; 2758 2759 err: 2760 if (ssl != NULL) 2761 SSL_free(ssl); 2762 ssl_error(rlay->rl_conf.name, "relay_ssl_transaction"); 2763 relay_close(con, "session ssl failed"); 2764 } 2765 2766 void 2767 relay_ssl_accept(int fd, short event, void *arg) 2768 { 2769 struct rsession *con = (struct rsession *)arg; 2770 struct relay *rlay = (struct relay *)con->se_relay; 2771 int ret; 2772 int ssl_err; 2773 int retry_flag; 2774 2775 if (event == EV_TIMEOUT) { 2776 relay_close(con, "SSL accept timeout"); 2777 return; 2778 } 2779 2780 retry_flag = ssl_err = 0; 2781 2782 ret = SSL_accept(con->se_in.ssl); 2783 if (ret <= 0) { 2784 ssl_err = SSL_get_error(con->se_in.ssl, ret); 2785 2786 switch (ssl_err) { 2787 case SSL_ERROR_WANT_READ: 2788 retry_flag = EV_READ; 2789 goto retry; 2790 case SSL_ERROR_WANT_WRITE: 2791 retry_flag = EV_WRITE; 2792 goto retry; 2793 case SSL_ERROR_ZERO_RETURN: 2794 case SSL_ERROR_SYSCALL: 2795 if (ret == 0) { 2796 relay_close(con, "closed"); 2797 return; 2798 } 2799 /* FALLTHROUGH */ 2800 default: 2801 ssl_error(rlay->rl_conf.name, "relay_ssl_accept"); 2802 relay_close(con, "SSL accept error"); 2803 return; 2804 } 2805 } 2806 2807 2808 #ifdef DEBUG 2809 log_info( 2810 #else 2811 log_debug( 2812 #endif 2813 "relay %s, session %d established (%d active)", 2814 rlay->rl_conf.name, con->se_id, relay_sessions); 2815 2816 relay_session(con); 2817 return; 2818 2819 retry: 2820 DPRINTF("%s: session %d: scheduling on %s", __func__, con->se_id, 2821 (retry_flag == EV_READ) ? "EV_READ" : "EV_WRITE"); 2822 event_again(&con->se_ev, fd, EV_TIMEOUT|retry_flag, relay_ssl_accept, 2823 &con->se_tv_start, &rlay->rl_conf.timeout, con); 2824 } 2825 2826 void 2827 relay_ssl_connect(int fd, short event, void *arg) 2828 { 2829 struct rsession *con = (struct rsession *)arg; 2830 struct relay *rlay = (struct relay *)con->se_relay; 2831 int ret; 2832 int ssl_err; 2833 int retry_flag; 2834 2835 if (event == EV_TIMEOUT) { 2836 relay_close(con, "SSL connect timeout"); 2837 return; 2838 } 2839 2840 retry_flag = ssl_err = 0; 2841 2842 ret = SSL_connect(con->se_out.ssl); 2843 if (ret <= 0) { 2844 ssl_err = SSL_get_error(con->se_out.ssl, ret); 2845 2846 switch (ssl_err) { 2847 case SSL_ERROR_WANT_READ: 2848 retry_flag = EV_READ; 2849 goto retry; 2850 case SSL_ERROR_WANT_WRITE: 2851 retry_flag = EV_WRITE; 2852 goto retry; 2853 case SSL_ERROR_ZERO_RETURN: 2854 case SSL_ERROR_SYSCALL: 2855 if (ret == 0) { 2856 relay_close(con, "closed"); 2857 return; 2858 } 2859 /* FALLTHROUGH */ 2860 default: 2861 ssl_error(rlay->rl_conf.name, "relay_ssl_connect"); 2862 relay_close(con, "SSL connect error"); 2863 return; 2864 } 2865 } 2866 2867 #ifdef DEBUG 2868 log_info( 2869 #else 2870 log_debug( 2871 #endif 2872 "relay %s, session %d connected (%d active)", 2873 rlay->rl_conf.name, con->se_id, relay_sessions); 2874 2875 relay_connected(fd, EV_WRITE, con); 2876 return; 2877 2878 retry: 2879 DPRINTF("%s: session %d: scheduling on %s", __func__, con->se_id, 2880 (retry_flag == EV_READ) ? "EV_READ" : "EV_WRITE"); 2881 event_again(&con->se_ev, fd, EV_TIMEOUT|retry_flag, relay_ssl_connect, 2882 &con->se_tv_start, &rlay->rl_conf.timeout, con); 2883 } 2884 2885 void 2886 relay_ssl_connected(struct ctl_relay_event *cre) 2887 { 2888 /* 2889 * Hack libevent - we overwrite the internal bufferevent I/O 2890 * functions to handle the SSL abstraction. 2891 */ 2892 event_set(&cre->bev->ev_read, cre->s, EV_READ, 2893 relay_ssl_readcb, cre->bev); 2894 event_set(&cre->bev->ev_write, cre->s, EV_WRITE, 2895 relay_ssl_writecb, cre->bev); 2896 } 2897 2898 void 2899 relay_ssl_readcb(int fd, short event, void *arg) 2900 { 2901 struct bufferevent *bufev = arg; 2902 struct ctl_relay_event *cre = (struct ctl_relay_event *)bufev->cbarg; 2903 struct rsession *con = cre->con; 2904 struct relay *rlay = (struct relay *)con->se_relay; 2905 int ret = 0, ssl_err = 0; 2906 short what = EVBUFFER_READ; 2907 size_t len; 2908 char rbuf[IBUF_READ_SIZE]; 2909 int howmuch = IBUF_READ_SIZE; 2910 2911 if (event == EV_TIMEOUT) { 2912 what |= EVBUFFER_TIMEOUT; 2913 goto err; 2914 } 2915 2916 if (bufev->wm_read.high != 0) 2917 howmuch = MIN(sizeof(rbuf), bufev->wm_read.high); 2918 2919 ret = SSL_read(cre->ssl, rbuf, howmuch); 2920 if (ret <= 0) { 2921 ssl_err = SSL_get_error(cre->ssl, ret); 2922 2923 switch (ssl_err) { 2924 case SSL_ERROR_WANT_READ: 2925 DPRINTF("%s: session %d: want read", 2926 __func__, con->se_id); 2927 goto retry; 2928 case SSL_ERROR_WANT_WRITE: 2929 DPRINTF("%s: session %d: want write", 2930 __func__, con->se_id); 2931 goto retry; 2932 default: 2933 if (ret == 0) 2934 what |= EVBUFFER_EOF; 2935 else { 2936 ssl_error(rlay->rl_conf.name, 2937 "relay_ssl_readcb"); 2938 what |= EVBUFFER_ERROR; 2939 } 2940 goto err; 2941 } 2942 } 2943 2944 if (evbuffer_add(bufev->input, rbuf, ret) == -1) { 2945 what |= EVBUFFER_ERROR; 2946 goto err; 2947 } 2948 2949 relay_bufferevent_add(&bufev->ev_read, bufev->timeout_read); 2950 2951 len = EVBUFFER_LENGTH(bufev->input); 2952 if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) 2953 return; 2954 if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) { 2955 struct evbuffer *buf = bufev->input; 2956 event_del(&bufev->ev_read); 2957 evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev); 2958 return; 2959 } 2960 2961 if (bufev->readcb != NULL) 2962 (*bufev->readcb)(bufev, bufev->cbarg); 2963 return; 2964 2965 retry: 2966 relay_bufferevent_add(&bufev->ev_read, bufev->timeout_read); 2967 return; 2968 2969 err: 2970 (*bufev->errorcb)(bufev, what, bufev->cbarg); 2971 } 2972 2973 void 2974 relay_ssl_writecb(int fd, short event, void *arg) 2975 { 2976 struct bufferevent *bufev = arg; 2977 struct ctl_relay_event *cre = (struct ctl_relay_event *)bufev->cbarg; 2978 struct rsession *con = cre->con; 2979 struct relay *rlay = (struct relay *)con->se_relay; 2980 int ret = 0, ssl_err; 2981 short what = EVBUFFER_WRITE; 2982 2983 if (event == EV_TIMEOUT) { 2984 what |= EVBUFFER_TIMEOUT; 2985 goto err; 2986 } 2987 2988 if (EVBUFFER_LENGTH(bufev->output)) { 2989 if (cre->buf == NULL) { 2990 cre->buflen = EVBUFFER_LENGTH(bufev->output); 2991 if ((cre->buf = malloc(cre->buflen)) == NULL) { 2992 what |= EVBUFFER_ERROR; 2993 goto err; 2994 } 2995 bcopy(EVBUFFER_DATA(bufev->output), 2996 cre->buf, cre->buflen); 2997 } 2998 2999 ret = SSL_write(cre->ssl, cre->buf, cre->buflen); 3000 if (ret <= 0) { 3001 ssl_err = SSL_get_error(cre->ssl, ret); 3002 3003 switch (ssl_err) { 3004 case SSL_ERROR_WANT_READ: 3005 DPRINTF("%s: session %d: want read", 3006 __func__, con->se_id); 3007 goto retry; 3008 case SSL_ERROR_WANT_WRITE: 3009 DPRINTF("%s: session %d: want write", 3010 __func__, con->se_id); 3011 goto retry; 3012 default: 3013 if (ret == 0) 3014 what |= EVBUFFER_EOF; 3015 else { 3016 ssl_error(rlay->rl_conf.name, 3017 "relay_ssl_writecb"); 3018 what |= EVBUFFER_ERROR; 3019 } 3020 goto err; 3021 } 3022 } 3023 evbuffer_drain(bufev->output, ret); 3024 } 3025 if (cre->buf != NULL) { 3026 free(cre->buf); 3027 cre->buf = NULL; 3028 cre->buflen = 0; 3029 } 3030 3031 if (EVBUFFER_LENGTH(bufev->output) != 0) 3032 relay_bufferevent_add(&bufev->ev_write, bufev->timeout_write); 3033 3034 if (bufev->writecb != NULL && 3035 EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low) 3036 (*bufev->writecb)(bufev, bufev->cbarg); 3037 return; 3038 3039 retry: 3040 if (cre->buflen != 0) 3041 relay_bufferevent_add(&bufev->ev_write, bufev->timeout_write); 3042 return; 3043 3044 err: 3045 if (cre->buf != NULL) { 3046 free(cre->buf); 3047 cre->buf = NULL; 3048 cre->buflen = 0; 3049 } 3050 (*bufev->errorcb)(bufev, what, bufev->cbarg); 3051 } 3052 3053 int 3054 relay_bufferevent_add(struct event *ev, int timeout) 3055 { 3056 struct timeval tv, *ptv = NULL; 3057 3058 if (timeout) { 3059 timerclear(&tv); 3060 tv.tv_sec = timeout; 3061 ptv = &tv; 3062 } 3063 3064 return (event_add(ev, ptv)); 3065 } 3066 3067 #ifdef notyet 3068 int 3069 relay_bufferevent_printf(struct ctl_relay_event *cre, const char *fmt, ...) 3070 { 3071 int ret; 3072 va_list ap; 3073 3074 va_start(ap, fmt); 3075 ret = evbuffer_add_vprintf(cre->output, fmt, ap); 3076 va_end(ap); 3077 3078 if (cre->bev != NULL && 3079 ret != -1 && EVBUFFER_LENGTH(cre->output) > 0 && 3080 (cre->bev->enabled & EV_WRITE)) 3081 bufferevent_enable(cre->bev, EV_WRITE); 3082 3083 return (ret); 3084 } 3085 #endif 3086 3087 int 3088 relay_bufferevent_print(struct ctl_relay_event *cre, char *str) 3089 { 3090 if (cre->bev == NULL) 3091 return (evbuffer_add(cre->output, str, strlen(str))); 3092 return (bufferevent_write(cre->bev, str, strlen(str))); 3093 } 3094 3095 int 3096 relay_bufferevent_write_buffer(struct ctl_relay_event *cre, 3097 struct evbuffer *buf) 3098 { 3099 if (cre->bev == NULL) 3100 return (evbuffer_add_buffer(cre->output, buf)); 3101 return (bufferevent_write_buffer(cre->bev, buf)); 3102 } 3103 3104 int 3105 relay_bufferevent_write_chunk(struct ctl_relay_event *cre, 3106 struct evbuffer *buf, size_t size) 3107 { 3108 int ret; 3109 ret = relay_bufferevent_write(cre, buf->buffer, size); 3110 if (ret != -1) 3111 evbuffer_drain(buf, size); 3112 return (ret); 3113 } 3114 3115 int 3116 relay_bufferevent_write(struct ctl_relay_event *cre, void *data, size_t size) 3117 { 3118 if (cre->bev == NULL) 3119 return (evbuffer_add(cre->output, data, size)); 3120 return (bufferevent_write(cre->bev, data, size)); 3121 } 3122 3123 int 3124 relay_cmp_af(struct sockaddr_storage *a, struct sockaddr_storage *b) 3125 { 3126 int ret = -1; 3127 struct sockaddr_in ia, ib; 3128 struct sockaddr_in6 ia6, ib6; 3129 3130 switch (a->ss_family) { 3131 case AF_INET: 3132 bcopy(a, &ia, sizeof(struct sockaddr_in)); 3133 bcopy(b, &ib, sizeof(struct sockaddr_in)); 3134 3135 ret = memcmp(&ia.sin_addr, &ib.sin_addr, 3136 sizeof(ia.sin_addr)); 3137 if (ret == 0) 3138 ret = memcmp(&ia.sin_port, &ib.sin_port, 3139 sizeof(ia.sin_port)); 3140 break; 3141 case AF_INET6: 3142 bcopy(a, &ia6, sizeof(struct sockaddr_in6)); 3143 bcopy(b, &ib6, sizeof(struct sockaddr_in6)); 3144 3145 ret = memcmp(&ia6.sin6_addr, &ib6.sin6_addr, 3146 sizeof(ia6.sin6_addr)); 3147 if (ret == 0) 3148 ret = memcmp(&ia6.sin6_port, &ib6.sin6_port, 3149 sizeof(ia6.sin6_port)); 3150 break; 3151 default: 3152 break; 3153 } 3154 3155 return (ret); 3156 } 3157 3158 char * 3159 relay_load_file(const char *name, off_t *len) 3160 { 3161 struct stat st; 3162 off_t size; 3163 u_int8_t *buf = NULL; 3164 int fd; 3165 3166 if ((fd = open(name, O_RDONLY)) == -1) 3167 return (NULL); 3168 if (fstat(fd, &st) != 0) 3169 goto fail; 3170 size = st.st_size; 3171 if ((buf = (char *)calloc(1, size + 1)) == NULL) 3172 goto fail; 3173 if (read(fd, buf, size) != size) 3174 goto fail; 3175 3176 close(fd); 3177 3178 *len = size; 3179 return (buf); 3180 3181 fail: 3182 if (buf != NULL) 3183 free(buf); 3184 close(fd); 3185 return (NULL); 3186 } 3187 3188 int 3189 relay_load_certfiles(struct relay *rlay) 3190 { 3191 struct protocol *proto = rlay->rl_proto; 3192 int useport = htons(rlay->rl_conf.port); 3193 char certfile[PATH_MAX]; 3194 char hbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; 3195 3196 if ((rlay->rl_conf.flags & F_SSLCLIENT) && strlen(proto->sslca)) { 3197 if ((rlay->rl_ssl_ca = relay_load_file(proto->sslca, 3198 &rlay->rl_conf.ssl_ca_len)) == NULL) 3199 return (-1); 3200 log_debug("%s: using ca %s", __func__, proto->sslca); 3201 } 3202 3203 if ((rlay->rl_conf.flags & F_SSL) == 0) 3204 return (0); 3205 3206 if (print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL) 3207 return (-1); 3208 3209 if (snprintf(certfile, sizeof(certfile), 3210 "/etc/ssl/%s:%u.crt", hbuf, useport) == -1) 3211 return (-1); 3212 if ((rlay->rl_ssl_cert = relay_load_file(certfile, 3213 &rlay->rl_conf.ssl_cert_len)) == NULL) { 3214 if (snprintf(certfile, sizeof(certfile), 3215 "/etc/ssl/%s.crt", hbuf) == -1) 3216 return (-1); 3217 if ((rlay->rl_ssl_cert = relay_load_file(certfile, 3218 &rlay->rl_conf.ssl_cert_len)) == NULL) 3219 return (-1); 3220 useport = 0; 3221 } 3222 log_debug("%s: using certificate %s", __func__, certfile); 3223 3224 if (useport) { 3225 if (snprintf(certfile, sizeof(certfile), 3226 "/etc/ssl/private/%s:%u.key", hbuf, useport) == -1) 3227 return -1; 3228 } else { 3229 if (snprintf(certfile, sizeof(certfile), 3230 "/etc/ssl/private/%s.key", hbuf) == -1) 3231 return -1; 3232 } 3233 if ((rlay->rl_ssl_key = relay_load_file(certfile, 3234 &rlay->rl_conf.ssl_key_len)) == NULL) 3235 return (-1); 3236 log_debug("%s: using private key %s", __func__, certfile); 3237 3238 return (0); 3239 } 3240 3241 static __inline int 3242 relay_proto_cmp(struct protonode *a, struct protonode *b) 3243 { 3244 int ret; 3245 ret = strcasecmp(a->key, b->key); 3246 if (ret == 0) 3247 ret = (int)a->type - b->type; 3248 return (ret); 3249 } 3250 3251 RB_GENERATE(proto_tree, protonode, nodes, relay_proto_cmp); 3252 3253 int 3254 relay_session_cmp(struct rsession *a, struct rsession *b) 3255 { 3256 struct relay *rlay = (struct relay *)b->se_relay; 3257 struct protocol *proto = rlay->rl_proto; 3258 3259 if (proto != NULL && proto->cmp != NULL) 3260 return ((*proto->cmp)(a, b)); 3261 3262 return ((int)a->se_id - b->se_id); 3263 } 3264 3265 SPLAY_GENERATE(session_tree, rsession, se_nodes, relay_session_cmp); 3266