pop3e.c
author Sunil Nimmagadda <sunil@esdenera.com>
Mon, 09 Jan 2017 15:31:05 +0500
changeset 43 6903f7870c4c
parent 41 0cb519e770ba
permissions -rw-r--r--
Provide an option to specify cert/key on commandline. While here, document new options and fix mandoc lint warnings.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     1
/*
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     2
 * Copyright (c) 2014 Sunil Nimmagadda <sunil@nimmagadda.net>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     3
 *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     4
 * Permission to use, copy, modify, and distribute this software for any
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     5
 * purpose with or without fee is hereby granted, provided that the above
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     6
 * copyright notice and this permission notice appear in all copies.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     7
 *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    15
 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    16
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    17
#include <sys/types.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    18
#include <sys/socket.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    19
#include <sys/time.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    20
#include <sys/tree.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    21
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    22
#include <err.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    23
#include <errno.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    24
#include <event.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    25
#include <netdb.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    26
#include <pwd.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    27
#include <signal.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    28
#include <stdlib.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    29
#include <string.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    30
#include <syslog.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    31
#include <unistd.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    32
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    33
#include "imsgev.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    34
#include "pop3d.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    35
#include "ssl.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    36
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    37
#define BACKLOG		5
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    38
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    39
static void auth_response(struct session *, int);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    40
static void pop3_accept(int, short, void *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    41
static void pop3_listen(const char *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    42
static void pop3_pause(int, short, void *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    43
static void pop3d_imsgev(struct imsgev *, int, struct imsg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    44
static void needfd(struct imsgev *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    45
static void sig_handler(int, short, void *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    46
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    47
struct imsgev		iev_pop3d;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    48
void			*ssl_ctx;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    49
14
1f2f363d10cc Since we now waitpid on WAIT_ANY, pop3_main needed return pid.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 0
diff changeset
    50
void
43
6903f7870c4c Provide an option to specify cert/key on commandline.
Sunil Nimmagadda <sunil@esdenera.com>
parents: 41
diff changeset
    51
pop3_main(int pair[2], struct passwd *pw, const char *cert, const char *key)
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    52
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    53
	extern struct session_tree	sessions;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    54
	struct event			ev_sigint, ev_sigterm;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    55
	pid_t				pid;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    56
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    57
	pid = fork();
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    58
	if (pid < 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    59
		fatal("pop3e: fork");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    60
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    61
	if (pid > 0)
14
1f2f363d10cc Since we now waitpid on WAIT_ANY, pop3_main needed return pid.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 0
diff changeset
    62
		return;
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    63
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    64
	close(pair[0]);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    65
	setproctitle("pop3 engine");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    66
	SPLAY_INIT(&sessions);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    67
	event_init();
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    68
	signal_set(&ev_sigint, SIGINT, sig_handler, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    69
	signal_set(&ev_sigterm, SIGTERM, sig_handler, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    70
	signal_add(&ev_sigint, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    71
	signal_add(&ev_sigterm, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    72
	imsgev_init(&iev_pop3d, pair[1], NULL, pop3d_imsgev, needfd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    73
	pop3_listen("pop3");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    74
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    75
	ssl_init();
43
6903f7870c4c Provide an option to specify cert/key on commandline.
Sunil Nimmagadda <sunil@esdenera.com>
parents: 41
diff changeset
    76
	if ((ssl_ctx = ssl_setup(cert, key)) == NULL)
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    77
		fatal("ssl_setup failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    78
	pop3_listen("pop3s");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    79
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    80
	if (chroot(pw->pw_dir) == -1 || chdir("/") == -1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    81
		fatal("chroot");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    82
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    83
	if (setgroups(1, &pw->pw_gid) ||
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    84
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    85
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    86
		fatal("cannot drop privileges");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    87
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    88
	if (event_dispatch() < 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    89
		fatal("event_dispatch");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    90
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    91
	logit(LOG_INFO, "pop3 engine exiting");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    92
	_exit(0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    93
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    94
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    95
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    96
pop3_listen(const char *port)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    97
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    98
	struct listener	*l = NULL;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    99
	struct addrinfo	hints, *res, *res0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   100
	int		error, opt, serrno, s;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   101
	const char	*cause = NULL;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   102
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   103
	memset(&hints, 0, sizeof(hints));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   104
	hints.ai_family = PF_UNSPEC;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   105
	hints.ai_socktype = SOCK_STREAM;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   106
	hints.ai_flags = AI_PASSIVE;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   107
	error = getaddrinfo(NULL, port, &hints, &res0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   108
	if (error)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   109
		errx(1, "%s", gai_strerror(error));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   110
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   111
	for (res = res0; res != NULL; res = res->ai_next) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   112
		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   113
		if (s == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   114
			cause = "socket";
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   115
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   116
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   117
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   118
		opt = 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   119
		if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   120
		    &opt, sizeof(opt)) == -1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   121
			fatal("listener setsockopt(SO_REUSEADDR)");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   122
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   123
		if (bind(s, res->ai_addr, res->ai_addrlen) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   124
			serrno = errno;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   125
			cause = "bind";
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   126
			close(s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   127
			errno = serrno;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   128
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   129
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   130
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   131
		set_nonblocking(s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   132
		if (listen(s, BACKLOG) == -1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   133
			fatal("listen");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   134
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   135
		l = xcalloc(1, sizeof(*l), "pop3_listen");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   136
		l->sock = s;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   137
		if (strcmp(port, "pop3s") == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   138
			l->flags |= POP3S;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   139
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   140
		event_set(&l->ev, s, EV_READ|EV_PERSIST, pop3_accept, l);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   141
		event_add(&l->ev, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   142
		evtimer_set(&l->pause, pop3_pause, l);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   143
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   144
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   145
	if (l == NULL)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   146
		errx(1, "%s", cause);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   147
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   148
	freeaddrinfo(res0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   149
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   150
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   151
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   152
pop3_accept(int fd, short events, void *arg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   153
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   154
	struct sockaddr_storage ss;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   155
	struct listener		*l = arg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   156
	struct timeval		timeout = {1, 0};
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   157
	socklen_t		len;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   158
	int			s;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   159
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   160
	len = sizeof(ss);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   161
	s = accept(fd, (struct sockaddr *)&ss, &len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   162
	if (s == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   163
		switch (errno) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   164
		case EINTR:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   165
		case EWOULDBLOCK:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   166
		case ECONNABORTED:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   167
			return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   168
		case EMFILE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   169
		case ENFILE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   170
			event_del(&l->ev);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   171
			evtimer_add(&l->pause, &timeout);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   172
			return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   173
		default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   174
			fatalx("accept");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   175
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   176
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   177
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   178
	set_nonblocking(s);
41
0cb519e770ba The sockaddr_storage returned by accept(2) belongs to session and
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 14
diff changeset
   179
	session_init(l, s, &ss);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   180
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   181
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   182
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   183
pop3_pause(int fd, short events, void *arg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   184
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   185
	struct listener *l = arg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   186
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   187
	event_add(&l->ev, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   188
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   189
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   190
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   191
pop3d_imsgev(struct imsgev *iev, int code, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   192
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   193
	extern struct session_tree	sessions;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   194
	struct session			key, *r;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   195
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   196
	switch (code) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   197
	case IMSGEV_IMSG:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   198
		key.id = imsg->hdr.peerid;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   199
		r = SPLAY_FIND(session_tree, &sessions, &key);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   200
		if (r == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   201
			logit(LOG_INFO, "%u: session not found", key.id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   202
			fatalx("pop3e: session lost");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   203
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   204
		switch (imsg->hdr.type) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   205
		case IMSG_AUTH:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   206
			auth_response(r, imsg->fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   207
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   208
		default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   209
			logit(LOG_DEBUG, "%s: unexpected imsg %d",
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   210
			    __func__, imsg->hdr.type);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   211
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   212
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   213
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   214
	case IMSGEV_EREAD:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   215
	case IMSGEV_EWRITE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   216
	case IMSGEV_EIMSG:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   217
		fatal("pop3e: imsgev read/write error");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   218
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   219
	case IMSGEV_DONE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   220
		event_loopexit(NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   221
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   222
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   223
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   224
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   225
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   226
auth_response(struct session *s, int fd)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   227
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   228
	if (fd == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   229
		session_reply(s, "%s", "-ERR auth failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   230
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   231
		session_close(s, 1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   232
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   233
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   234
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   235
	session_imsgev_init(s, fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   236
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   237
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   238
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   239
needfd(struct imsgev *iev)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   240
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   241
	/* XXX can anything be done to handle fd exhaustion? */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   242
	fatalx("pop3e needs an fd");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   243
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   244
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   245
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   246
sig_handler(int sig, short event, void *arg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   247
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   248
	switch (sig) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   249
	case SIGINT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   250
	case SIGTERM:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   251
		event_loopexit(NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   252
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   253
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   254