1 /* $OpenBSD: lka.c,v 1.245 2021/04/21 07:54:10 eric Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 5 * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> 6 * Copyright (c) 2012 Eric Faurot <eric@faurot.net> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/types.h> 22 #include <sys/queue.h> 23 #include <sys/tree.h> 24 #include <sys/socket.h> 25 #include <sys/wait.h> 26 #include <sys/uio.h> 27 28 #include <netinet/in.h> 29 30 #include <ctype.h> 31 #include <err.h> 32 #include <errno.h> 33 #include <event.h> 34 #include <imsg.h> 35 #include <openssl/err.h> 36 #include <openssl/ssl.h> 37 #include <pwd.h> 38 #include <resolv.h> 39 #include <limits.h> 40 #include <signal.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <unistd.h> 45 46 #include "smtpd.h" 47 #include "log.h" 48 #include "ssl.h" 49 50 static void lka_imsg(struct mproc *, struct imsg *); 51 static void lka_shutdown(void); 52 static void lka_sig_handler(int, short, void *); 53 static int lka_authenticate(const char *, const char *, const char *); 54 static int lka_credentials(const char *, const char *, char *, size_t); 55 static int lka_userinfo(const char *, const char *, struct userinfo *); 56 static int lka_addrname(const char *, const struct sockaddr *, 57 struct addrname *); 58 static int lka_mailaddrmap(const char *, const char *, const struct mailaddr *); 59 60 static void proc_timeout(int fd, short event, void *p); 61 62 struct event ev_proc_ready; 63 64 static void 65 lka_imsg(struct mproc *p, struct imsg *imsg) 66 { 67 struct table *table; 68 int ret; 69 struct sockaddr_storage ss; 70 struct userinfo userinfo; 71 struct addrname addrname; 72 struct envelope evp; 73 struct mailaddr maddr; 74 struct msg m; 75 union lookup lk; 76 char buf[LINE_MAX]; 77 const char *tablename, *username, *password, *label, *procname; 78 uint64_t reqid; 79 int v; 80 struct timeval tv; 81 const char *direction; 82 const char *rdns; 83 const char *command; 84 const char *response; 85 const char *ciphers; 86 const char *address; 87 const char *domain; 88 const char *helomethod; 89 const char *heloname; 90 const char *filter_name; 91 const char *result; 92 struct sockaddr_storage ss_src, ss_dest; 93 int filter_response; 94 int filter_phase; 95 const char *filter_param; 96 uint32_t msgid; 97 uint32_t subsystems; 98 uint64_t evpid; 99 size_t msgsz; 100 int ok; 101 int fcrdns; 102 103 if (imsg == NULL) 104 lka_shutdown(); 105 106 switch (imsg->hdr.type) { 107 108 case IMSG_GETADDRINFO: 109 case IMSG_GETNAMEINFO: 110 case IMSG_RES_QUERY: 111 resolver_dispatch_request(p, imsg); 112 return; 113 114 case IMSG_MTA_DNS_HOST: 115 case IMSG_MTA_DNS_MX: 116 case IMSG_MTA_DNS_MX_PREFERENCE: 117 dns_imsg(p, imsg); 118 return; 119 120 case IMSG_SMTP_CHECK_SENDER: 121 m_msg(&m, imsg); 122 m_get_id(&m, &reqid); 123 m_get_string(&m, &tablename); 124 m_get_string(&m, &username); 125 m_get_mailaddr(&m, &maddr); 126 m_end(&m); 127 128 ret = lka_mailaddrmap(tablename, username, &maddr); 129 130 m_create(p, IMSG_SMTP_CHECK_SENDER, 0, 0, -1); 131 m_add_id(p, reqid); 132 m_add_int(p, ret); 133 m_close(p); 134 return; 135 136 case IMSG_SMTP_EXPAND_RCPT: 137 m_msg(&m, imsg); 138 m_get_id(&m, &reqid); 139 m_get_envelope(&m, &evp); 140 m_end(&m); 141 lka_session(reqid, &evp); 142 return; 143 144 case IMSG_SMTP_LOOKUP_HELO: 145 m_msg(&m, imsg); 146 m_get_id(&m, &reqid); 147 m_get_string(&m, &tablename); 148 m_get_sockaddr(&m, (struct sockaddr *)&ss); 149 m_end(&m); 150 151 ret = lka_addrname(tablename, (struct sockaddr*)&ss, 152 &addrname); 153 154 m_create(p, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1); 155 m_add_id(p, reqid); 156 m_add_int(p, ret); 157 if (ret == LKA_OK) 158 m_add_string(p, addrname.name); 159 m_close(p); 160 return; 161 162 case IMSG_SMTP_AUTHENTICATE: 163 m_msg(&m, imsg); 164 m_get_id(&m, &reqid); 165 m_get_string(&m, &tablename); 166 m_get_string(&m, &username); 167 m_get_string(&m, &password); 168 m_end(&m); 169 170 if (!tablename[0]) { 171 m_create(p_parent, IMSG_LKA_AUTHENTICATE, 172 0, 0, -1); 173 m_add_id(p_parent, reqid); 174 m_add_string(p_parent, username); 175 m_add_string(p_parent, password); 176 m_close(p_parent); 177 return; 178 } 179 180 ret = lka_authenticate(tablename, username, password); 181 182 m_create(p, IMSG_SMTP_AUTHENTICATE, 0, 0, -1); 183 m_add_id(p, reqid); 184 m_add_int(p, ret); 185 m_close(p); 186 return; 187 188 case IMSG_MDA_LOOKUP_USERINFO: 189 m_msg(&m, imsg); 190 m_get_id(&m, &reqid); 191 m_get_string(&m, &tablename); 192 m_get_string(&m, &username); 193 m_end(&m); 194 195 ret = lka_userinfo(tablename, username, &userinfo); 196 197 m_create(p, IMSG_MDA_LOOKUP_USERINFO, 0, 0, -1); 198 m_add_id(p, reqid); 199 m_add_int(p, ret); 200 if (ret == LKA_OK) 201 m_add_data(p, &userinfo, sizeof(userinfo)); 202 m_close(p); 203 return; 204 205 case IMSG_MTA_LOOKUP_CREDENTIALS: 206 m_msg(&m, imsg); 207 m_get_id(&m, &reqid); 208 m_get_string(&m, &tablename); 209 m_get_string(&m, &label); 210 m_end(&m); 211 212 lka_credentials(tablename, label, buf, sizeof(buf)); 213 214 m_create(p, IMSG_MTA_LOOKUP_CREDENTIALS, 0, 0, -1); 215 m_add_id(p, reqid); 216 m_add_string(p, buf); 217 m_close(p); 218 return; 219 220 case IMSG_MTA_LOOKUP_SOURCE: 221 m_msg(&m, imsg); 222 m_get_id(&m, &reqid); 223 m_get_string(&m, &tablename); 224 m_end(&m); 225 226 table = table_find(env, tablename); 227 228 m_create(p, IMSG_MTA_LOOKUP_SOURCE, 0, 0, -1); 229 m_add_id(p, reqid); 230 231 if (table == NULL) { 232 log_warn("warn: source address table %s missing", 233 tablename); 234 m_add_int(p, LKA_TEMPFAIL); 235 } 236 else { 237 ret = table_fetch(table, K_SOURCE, &lk); 238 if (ret == -1) 239 m_add_int(p, LKA_TEMPFAIL); 240 else if (ret == 0) 241 m_add_int(p, LKA_PERMFAIL); 242 else { 243 m_add_int(p, LKA_OK); 244 m_add_sockaddr(p, 245 (struct sockaddr *)&lk.source.addr); 246 } 247 } 248 m_close(p); 249 return; 250 251 case IMSG_MTA_LOOKUP_HELO: 252 m_msg(&m, imsg); 253 m_get_id(&m, &reqid); 254 m_get_string(&m, &tablename); 255 m_get_sockaddr(&m, (struct sockaddr *)&ss); 256 m_end(&m); 257 258 ret = lka_addrname(tablename, (struct sockaddr*)&ss, 259 &addrname); 260 261 m_create(p, IMSG_MTA_LOOKUP_HELO, 0, 0, -1); 262 m_add_id(p, reqid); 263 m_add_int(p, ret); 264 if (ret == LKA_OK) 265 m_add_string(p, addrname.name); 266 m_close(p); 267 return; 268 269 case IMSG_MTA_LOOKUP_SMARTHOST: 270 m_msg(&m, imsg); 271 m_get_id(&m, &reqid); 272 m_get_string(&m, &domain); 273 m_get_string(&m, &tablename); 274 m_end(&m); 275 276 table = table_find(env, tablename); 277 278 m_create(p, IMSG_MTA_LOOKUP_SMARTHOST, 0, 0, -1); 279 m_add_id(p, reqid); 280 281 if (table == NULL) { 282 log_warn("warn: smarthost table %s missing", tablename); 283 m_add_int(p, LKA_TEMPFAIL); 284 } 285 else { 286 if (domain == NULL) 287 ret = table_fetch(table, K_RELAYHOST, &lk); 288 else 289 ret = table_lookup(table, K_RELAYHOST, domain, &lk); 290 291 if (ret == -1) 292 m_add_int(p, LKA_TEMPFAIL); 293 else if (ret == 0) 294 m_add_int(p, LKA_PERMFAIL); 295 else { 296 m_add_int(p, LKA_OK); 297 m_add_string(p, lk.relayhost); 298 } 299 } 300 m_close(p); 301 return; 302 303 case IMSG_CONF_START: 304 return; 305 306 case IMSG_CONF_END: 307 if (tracing & TRACE_TABLES) 308 table_dump_all(env); 309 310 /* fork & exec tables that need it */ 311 table_open_all(env); 312 313 /* revoke proc & exec */ 314 if (pledge("stdio rpath inet dns getpw recvfd sendfd", 315 NULL) == -1) 316 err(1, "pledge"); 317 318 /* setup proc registering task */ 319 evtimer_set(&ev_proc_ready, proc_timeout, &ev_proc_ready); 320 tv.tv_sec = 0; 321 tv.tv_usec = 10; 322 evtimer_add(&ev_proc_ready, &tv); 323 return; 324 325 case IMSG_LKA_OPEN_FORWARD: 326 lka_session_forward_reply(imsg->data, imsg->fd); 327 return; 328 329 case IMSG_LKA_AUTHENTICATE: 330 imsg->hdr.type = IMSG_SMTP_AUTHENTICATE; 331 m_forward(p_dispatcher, imsg); 332 return; 333 334 case IMSG_CTL_VERBOSE: 335 m_msg(&m, imsg); 336 m_get_int(&m, &v); 337 m_end(&m); 338 log_trace_verbose(v); 339 return; 340 341 case IMSG_CTL_PROFILE: 342 m_msg(&m, imsg); 343 m_get_int(&m, &v); 344 m_end(&m); 345 profiling = v; 346 return; 347 348 case IMSG_CTL_UPDATE_TABLE: 349 ret = 0; 350 table = table_find(env, imsg->data); 351 if (table == NULL) { 352 log_warnx("warn: Lookup table not found: " 353 "\"%s\"", (char *)imsg->data); 354 } else 355 ret = table_update(table); 356 357 m_compose(p_control, 358 (ret == 1) ? IMSG_CTL_OK : IMSG_CTL_FAIL, 359 imsg->hdr.peerid, 0, -1, NULL, 0); 360 return; 361 362 case IMSG_LKA_PROCESSOR_FORK: 363 m_msg(&m, imsg); 364 m_get_string(&m, &procname); 365 m_get_u32(&m, &subsystems); 366 m_end(&m); 367 368 m_create(p, IMSG_LKA_PROCESSOR_ERRFD, 0, 0, -1); 369 m_add_string(p, procname); 370 m_close(p); 371 372 lka_proc_forked(procname, subsystems, imsg->fd); 373 return; 374 375 case IMSG_LKA_PROCESSOR_ERRFD: 376 m_msg(&m, imsg); 377 m_get_string(&m, &procname); 378 m_end(&m); 379 380 lka_proc_errfd(procname, imsg->fd); 381 shutdown(imsg->fd, SHUT_WR); 382 return; 383 384 case IMSG_REPORT_SMTP_LINK_CONNECT: 385 m_msg(&m, imsg); 386 m_get_string(&m, &direction); 387 m_get_timeval(&m, &tv); 388 m_get_id(&m, &reqid); 389 m_get_string(&m, &rdns); 390 m_get_int(&m, &fcrdns); 391 m_get_sockaddr(&m, (struct sockaddr *)&ss_src); 392 m_get_sockaddr(&m, (struct sockaddr *)&ss_dest); 393 m_end(&m); 394 395 lka_report_smtp_link_connect(direction, &tv, reqid, rdns, fcrdns, &ss_src, &ss_dest); 396 return; 397 398 case IMSG_REPORT_SMTP_LINK_GREETING: 399 m_msg(&m, imsg); 400 m_get_string(&m, &direction); 401 m_get_timeval(&m, &tv); 402 m_get_id(&m, &reqid); 403 m_get_string(&m, &domain); 404 m_end(&m); 405 406 lka_report_smtp_link_greeting(direction, reqid, &tv, domain); 407 return; 408 409 case IMSG_REPORT_SMTP_LINK_DISCONNECT: 410 m_msg(&m, imsg); 411 m_get_string(&m, &direction); 412 m_get_timeval(&m, &tv); 413 m_get_id(&m, &reqid); 414 m_end(&m); 415 416 lka_report_smtp_link_disconnect(direction, &tv, reqid); 417 return; 418 419 case IMSG_REPORT_SMTP_LINK_IDENTIFY: 420 m_msg(&m, imsg); 421 m_get_string(&m, &direction); 422 m_get_timeval(&m, &tv); 423 m_get_id(&m, &reqid); 424 m_get_string(&m, &helomethod); 425 m_get_string(&m, &heloname); 426 m_end(&m); 427 428 lka_report_smtp_link_identify(direction, &tv, reqid, helomethod, heloname); 429 return; 430 431 case IMSG_REPORT_SMTP_LINK_TLS: 432 m_msg(&m, imsg); 433 m_get_string(&m, &direction); 434 m_get_timeval(&m, &tv); 435 m_get_id(&m, &reqid); 436 m_get_string(&m, &ciphers); 437 m_end(&m); 438 439 lka_report_smtp_link_tls(direction, &tv, reqid, ciphers); 440 return; 441 442 case IMSG_REPORT_SMTP_LINK_AUTH: 443 m_msg(&m, imsg); 444 m_get_string(&m, &direction); 445 m_get_timeval(&m, &tv); 446 m_get_id(&m, &reqid); 447 m_get_string(&m, &username); 448 m_get_string(&m, &result); 449 m_end(&m); 450 451 lka_report_smtp_link_auth(direction, &tv, reqid, username, result); 452 return; 453 454 case IMSG_REPORT_SMTP_TX_RESET: 455 m_msg(&m, imsg); 456 m_get_string(&m, &direction); 457 m_get_timeval(&m, &tv); 458 m_get_id(&m, &reqid); 459 m_get_u32(&m, &msgid); 460 m_end(&m); 461 462 lka_report_smtp_tx_reset(direction, &tv, reqid, msgid); 463 return; 464 465 case IMSG_REPORT_SMTP_TX_BEGIN: 466 m_msg(&m, imsg); 467 m_get_string(&m, &direction); 468 m_get_timeval(&m, &tv); 469 m_get_id(&m, &reqid); 470 m_get_u32(&m, &msgid); 471 m_end(&m); 472 473 lka_report_smtp_tx_begin(direction, &tv, reqid, msgid); 474 return; 475 476 case IMSG_REPORT_SMTP_TX_MAIL: 477 m_msg(&m, imsg); 478 m_get_string(&m, &direction); 479 m_get_timeval(&m, &tv); 480 m_get_id(&m, &reqid); 481 m_get_u32(&m, &msgid); 482 m_get_string(&m, &address); 483 m_get_int(&m, &ok); 484 m_end(&m); 485 486 lka_report_smtp_tx_mail(direction, &tv, reqid, msgid, address, ok); 487 return; 488 489 case IMSG_REPORT_SMTP_TX_RCPT: 490 m_msg(&m, imsg); 491 m_get_string(&m, &direction); 492 m_get_timeval(&m, &tv); 493 m_get_id(&m, &reqid); 494 m_get_u32(&m, &msgid); 495 m_get_string(&m, &address); 496 m_get_int(&m, &ok); 497 m_end(&m); 498 499 lka_report_smtp_tx_rcpt(direction, &tv, reqid, msgid, address, ok); 500 return; 501 502 case IMSG_REPORT_SMTP_TX_ENVELOPE: 503 m_msg(&m, imsg); 504 m_get_string(&m, &direction); 505 m_get_timeval(&m, &tv); 506 m_get_id(&m, &reqid); 507 m_get_u32(&m, &msgid); 508 m_get_id(&m, &evpid); 509 m_end(&m); 510 511 lka_report_smtp_tx_envelope(direction, &tv, reqid, msgid, evpid); 512 return; 513 514 case IMSG_REPORT_SMTP_TX_DATA: 515 m_msg(&m, imsg); 516 m_get_string(&m, &direction); 517 m_get_timeval(&m, &tv); 518 m_get_id(&m, &reqid); 519 m_get_u32(&m, &msgid); 520 m_get_int(&m, &ok); 521 m_end(&m); 522 523 lka_report_smtp_tx_data(direction, &tv, reqid, msgid, ok); 524 return; 525 526 case IMSG_REPORT_SMTP_TX_COMMIT: 527 m_msg(&m, imsg); 528 m_get_string(&m, &direction); 529 m_get_timeval(&m, &tv); 530 m_get_id(&m, &reqid); 531 m_get_u32(&m, &msgid); 532 m_get_size(&m, &msgsz); 533 m_end(&m); 534 535 lka_report_smtp_tx_commit(direction, &tv, reqid, msgid, msgsz); 536 return; 537 538 case IMSG_REPORT_SMTP_TX_ROLLBACK: 539 m_msg(&m, imsg); 540 m_get_string(&m, &direction); 541 m_get_timeval(&m, &tv); 542 m_get_id(&m, &reqid); 543 m_get_u32(&m, &msgid); 544 m_end(&m); 545 546 lka_report_smtp_tx_rollback(direction, &tv, reqid, msgid); 547 return; 548 549 case IMSG_REPORT_SMTP_PROTOCOL_CLIENT: 550 m_msg(&m, imsg); 551 m_get_string(&m, &direction); 552 m_get_timeval(&m, &tv); 553 m_get_id(&m, &reqid); 554 m_get_string(&m, &command); 555 m_end(&m); 556 557 lka_report_smtp_protocol_client(direction, &tv, reqid, command); 558 return; 559 560 case IMSG_REPORT_SMTP_PROTOCOL_SERVER: 561 m_msg(&m, imsg); 562 m_get_string(&m, &direction); 563 m_get_timeval(&m, &tv); 564 m_get_id(&m, &reqid); 565 m_get_string(&m, &response); 566 m_end(&m); 567 568 lka_report_smtp_protocol_server(direction, &tv, reqid, response); 569 return; 570 571 case IMSG_REPORT_SMTP_FILTER_RESPONSE: 572 m_msg(&m, imsg); 573 m_get_string(&m, &direction); 574 m_get_timeval(&m, &tv); 575 m_get_id(&m, &reqid); 576 m_get_int(&m, &filter_phase); 577 m_get_int(&m, &filter_response); 578 m_get_string(&m, &filter_param); 579 m_end(&m); 580 581 lka_report_smtp_filter_response(direction, &tv, reqid, 582 filter_phase, filter_response, filter_param); 583 return; 584 585 case IMSG_REPORT_SMTP_TIMEOUT: 586 m_msg(&m, imsg); 587 m_get_string(&m, &direction); 588 m_get_timeval(&m, &tv); 589 m_get_id(&m, &reqid); 590 m_end(&m); 591 592 lka_report_smtp_timeout(direction, &tv, reqid); 593 return; 594 595 case IMSG_FILTER_SMTP_PROTOCOL: 596 m_msg(&m, imsg); 597 m_get_id(&m, &reqid); 598 m_get_int(&m, &filter_phase); 599 m_get_string(&m, &filter_param); 600 m_end(&m); 601 602 lka_filter_protocol(reqid, filter_phase, filter_param); 603 return; 604 605 case IMSG_FILTER_SMTP_BEGIN: 606 m_msg(&m, imsg); 607 m_get_id(&m, &reqid); 608 m_get_string(&m, &filter_name); 609 m_end(&m); 610 611 lka_filter_begin(reqid, filter_name); 612 return; 613 614 case IMSG_FILTER_SMTP_END: 615 m_msg(&m, imsg); 616 m_get_id(&m, &reqid); 617 m_end(&m); 618 619 lka_filter_end(reqid); 620 return; 621 622 case IMSG_FILTER_SMTP_DATA_BEGIN: 623 m_msg(&m, imsg); 624 m_get_id(&m, &reqid); 625 m_end(&m); 626 627 lka_filter_data_begin(reqid); 628 return; 629 630 case IMSG_FILTER_SMTP_DATA_END: 631 m_msg(&m, imsg); 632 m_get_id(&m, &reqid); 633 m_end(&m); 634 635 lka_filter_data_end(reqid); 636 return; 637 638 } 639 640 errx(1, "lka_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type)); 641 } 642 643 static void 644 lka_sig_handler(int sig, short event, void *p) 645 { 646 int status; 647 pid_t pid; 648 649 switch (sig) { 650 case SIGCHLD: 651 do { 652 pid = waitpid(-1, &status, WNOHANG); 653 } while (pid > 0 || (pid == -1 && errno == EINTR)); 654 break; 655 default: 656 fatalx("lka_sig_handler: unexpected signal"); 657 } 658 } 659 660 void 661 lka_shutdown(void) 662 { 663 log_debug("debug: lookup agent exiting"); 664 _exit(0); 665 } 666 667 int 668 lka(void) 669 { 670 struct passwd *pw; 671 struct event ev_sigchld; 672 673 purge_config(PURGE_LISTENERS); 674 675 if ((pw = getpwnam(SMTPD_USER)) == NULL) 676 fatalx("unknown user " SMTPD_USER); 677 678 config_process(PROC_LKA); 679 680 if (initgroups(pw->pw_name, pw->pw_gid) || 681 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 682 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 683 fatal("lka: cannot drop privileges"); 684 685 imsg_callback = lka_imsg; 686 event_init(); 687 688 signal_set(&ev_sigchld, SIGCHLD, lka_sig_handler, NULL); 689 signal_add(&ev_sigchld, NULL); 690 signal(SIGINT, SIG_IGN); 691 signal(SIGTERM, SIG_IGN); 692 signal(SIGPIPE, SIG_IGN); 693 signal(SIGHUP, SIG_IGN); 694 695 config_peer(PROC_PARENT); 696 config_peer(PROC_QUEUE); 697 config_peer(PROC_CONTROL); 698 config_peer(PROC_DISPATCHER); 699 700 /* Ignore them until we get our config */ 701 mproc_disable(p_dispatcher); 702 703 lka_report_init(); 704 lka_filter_init(); 705 706 /* proc & exec will be revoked before serving requests */ 707 if (pledge("stdio rpath inet dns getpw recvfd sendfd proc exec", NULL) == -1) 708 err(1, "pledge"); 709 710 event_dispatch(); 711 fatalx("exited event loop"); 712 713 return (0); 714 } 715 716 static void 717 proc_timeout(int fd, short event, void *p) 718 { 719 struct event *ev = p; 720 struct timeval tv; 721 722 if (!lka_proc_ready()) 723 goto reset; 724 725 lka_filter_ready(); 726 mproc_enable(p_dispatcher); 727 return; 728 729 reset: 730 tv.tv_sec = 0; 731 tv.tv_usec = 10; 732 evtimer_add(ev, &tv); 733 } 734 735 736 static int 737 lka_authenticate(const char *tablename, const char *user, const char *password) 738 { 739 struct table *table; 740 union lookup lk; 741 742 log_debug("debug: lka: authenticating for %s:%s", tablename, user); 743 table = table_find(env, tablename); 744 if (table == NULL) { 745 log_warnx("warn: could not find table %s needed for authentication", 746 tablename); 747 return (LKA_TEMPFAIL); 748 } 749 750 switch (table_lookup(table, K_CREDENTIALS, user, &lk)) { 751 case -1: 752 log_warnx("warn: user credentials lookup fail for %s:%s", 753 tablename, user); 754 return (LKA_TEMPFAIL); 755 case 0: 756 return (LKA_PERMFAIL); 757 default: 758 if (crypt_checkpass(password, lk.creds.password) == 0) 759 return (LKA_OK); 760 return (LKA_PERMFAIL); 761 } 762 } 763 764 static int 765 lka_credentials(const char *tablename, const char *label, char *dst, size_t sz) 766 { 767 struct table *table; 768 union lookup lk; 769 char *buf; 770 int buflen, r; 771 772 table = table_find(env, tablename); 773 if (table == NULL) { 774 log_warnx("warn: credentials table %s missing", tablename); 775 return (LKA_TEMPFAIL); 776 } 777 778 dst[0] = '\0'; 779 780 switch (table_lookup(table, K_CREDENTIALS, label, &lk)) { 781 case -1: 782 log_warnx("warn: credentials lookup fail for %s:%s", 783 tablename, label); 784 return (LKA_TEMPFAIL); 785 case 0: 786 log_warnx("warn: credentials not found for %s:%s", 787 tablename, label); 788 return (LKA_PERMFAIL); 789 default: 790 if ((buflen = asprintf(&buf, "%c%s%c%s", '\0', 791 lk.creds.username, '\0', lk.creds.password)) == -1) { 792 log_warn("warn"); 793 return (LKA_TEMPFAIL); 794 } 795 796 r = base64_encode((unsigned char *)buf, buflen, dst, sz); 797 free(buf); 798 799 if (r == -1) { 800 log_warnx("warn: credentials parse error for %s:%s", 801 tablename, label); 802 return (LKA_TEMPFAIL); 803 } 804 return (LKA_OK); 805 } 806 } 807 808 static int 809 lka_userinfo(const char *tablename, const char *username, struct userinfo *res) 810 { 811 struct table *table; 812 union lookup lk; 813 814 log_debug("debug: lka: userinfo %s:%s", tablename, username); 815 table = table_find(env, tablename); 816 if (table == NULL) { 817 log_warnx("warn: cannot find user table %s", tablename); 818 return (LKA_TEMPFAIL); 819 } 820 821 switch (table_lookup(table, K_USERINFO, username, &lk)) { 822 case -1: 823 log_warnx("warn: failure during userinfo lookup %s:%s", 824 tablename, username); 825 return (LKA_TEMPFAIL); 826 case 0: 827 return (LKA_PERMFAIL); 828 default: 829 *res = lk.userinfo; 830 return (LKA_OK); 831 } 832 } 833 834 static int 835 lka_addrname(const char *tablename, const struct sockaddr *sa, 836 struct addrname *res) 837 { 838 struct table *table; 839 union lookup lk; 840 const char *source; 841 842 source = sa_to_text(sa); 843 844 log_debug("debug: lka: helo %s:%s", tablename, source); 845 table = table_find(env, tablename); 846 if (table == NULL) { 847 log_warnx("warn: cannot find helo table %s", tablename); 848 return (LKA_TEMPFAIL); 849 } 850 851 switch (table_lookup(table, K_ADDRNAME, source, &lk)) { 852 case -1: 853 log_warnx("warn: failure during helo lookup %s:%s", 854 tablename, source); 855 return (LKA_TEMPFAIL); 856 case 0: 857 return (LKA_PERMFAIL); 858 default: 859 *res = lk.addrname; 860 return (LKA_OK); 861 } 862 } 863 864 static int 865 lka_mailaddrmap(const char *tablename, const char *username, const struct mailaddr *maddr) 866 { 867 struct table *table; 868 struct maddrnode *mn; 869 union lookup lk; 870 int found; 871 872 log_debug("debug: lka: mailaddrmap %s:%s", tablename, username); 873 table = table_find(env, tablename); 874 if (table == NULL) { 875 log_warnx("warn: cannot find mailaddrmap table %s", tablename); 876 return (LKA_TEMPFAIL); 877 } 878 879 switch (table_lookup(table, K_MAILADDRMAP, username, &lk)) { 880 case -1: 881 log_warnx("warn: failure during mailaddrmap lookup %s:%s", 882 tablename, username); 883 return (LKA_TEMPFAIL); 884 case 0: 885 return (LKA_PERMFAIL); 886 default: 887 found = 0; 888 TAILQ_FOREACH(mn, &lk.maddrmap->queue, entries) { 889 if (!mailaddr_match(maddr, &mn->mailaddr)) 890 continue; 891 found = 1; 892 break; 893 } 894 maddrmap_free(lk.maddrmap); 895 if (found) 896 return (LKA_OK); 897 return (LKA_PERMFAIL); 898 } 899 return (LKA_OK); 900 } 901