pop3e.c
author Sunil Nimmagadda <sunil@nimmagadda.net>
Thu, 04 Sep 2014 20:28:47 +0500
changeset 39 6d2a560793d3
parent 14 1f2f363d10cc
child 41 0cb519e770ba
permissions -rw-r--r--
Whitespace.
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
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    51
pop3_main(int pair[2], struct passwd *pw)
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();
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    76
	if ((ssl_ctx = ssl_setup()) == NULL)
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);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   179
	l->ss = ss;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   180
	session_init(l, s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   181
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   182
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   183
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   184
pop3_pause(int fd, short events, void *arg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   185
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   186
	struct listener *l = arg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   187
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   188
	event_add(&l->ev, NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   189
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   190
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   191
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   192
pop3d_imsgev(struct imsgev *iev, int code, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   193
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   194
	extern struct session_tree	sessions;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   195
	struct session			key, *r;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   196
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   197
	switch (code) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   198
	case IMSGEV_IMSG:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   199
		key.id = imsg->hdr.peerid;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   200
		r = SPLAY_FIND(session_tree, &sessions, &key);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   201
		if (r == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   202
			logit(LOG_INFO, "%u: session not found", key.id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   203
			fatalx("pop3e: session lost");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   204
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   205
		switch (imsg->hdr.type) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   206
		case IMSG_AUTH:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   207
			auth_response(r, imsg->fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   208
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   209
		default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   210
			logit(LOG_DEBUG, "%s: unexpected imsg %d",
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   211
			    __func__, imsg->hdr.type);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   212
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   213
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   214
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   215
	case IMSGEV_EREAD:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   216
	case IMSGEV_EWRITE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   217
	case IMSGEV_EIMSG:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   218
		fatal("pop3e: imsgev read/write error");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   219
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   220
	case IMSGEV_DONE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   221
		event_loopexit(NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   222
		break;
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
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   226
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   227
auth_response(struct session *s, int fd)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   228
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   229
	if (fd == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   230
		session_reply(s, "%s", "-ERR auth failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   231
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   232
		session_close(s, 1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   233
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   234
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   235
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   236
	session_imsgev_init(s, fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   237
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   238
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   239
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   240
needfd(struct imsgev *iev)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   241
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   242
	/* XXX can anything be done to handle fd exhaustion? */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   243
	fatalx("pop3e needs an fd");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   244
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   245
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   246
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   247
sig_handler(int sig, short event, void *arg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   248
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   249
	switch (sig) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   250
	case SIGINT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   251
	case SIGTERM:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   252
		event_loopexit(NULL);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   253
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   254
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   255