summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-12-15 17:37:26 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-12-15 17:37:26 +0000
commitbdff1384e04efafd8ca457e61b6fb8163f061675 (patch)
tree405e85fe3ded648281899bfe5322ea44ae7175fc /usr.sbin
parent27c876e7127cf7e3b3d08a23f3a70eaeb8df469e (diff)
remove popa3d. Sorry, no plaintext password only daemons allowed anymore.
ok deraadt and co.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/popa3d/DESIGN210
-rw-r--r--usr.sbin/popa3d/LICENSE9
-rw-r--r--usr.sbin/popa3d/Makefile16
-rw-r--r--usr.sbin/popa3d/VIRTUAL5
-rw-r--r--usr.sbin/popa3d/auth_passwd.c41
-rw-r--r--usr.sbin/popa3d/database.c95
-rw-r--r--usr.sbin/popa3d/database.h57
-rw-r--r--usr.sbin/popa3d/mailbox.c503
-rw-r--r--usr.sbin/popa3d/mailbox.h32
-rw-r--r--usr.sbin/popa3d/misc.c89
-rw-r--r--usr.sbin/popa3d/misc.h29
-rw-r--r--usr.sbin/popa3d/params.h250
-rw-r--r--usr.sbin/popa3d/pop_auth.c98
-rw-r--r--usr.sbin/popa3d/pop_auth.h28
-rw-r--r--usr.sbin/popa3d/pop_root.c275
-rw-r--r--usr.sbin/popa3d/pop_trans.c266
-rw-r--r--usr.sbin/popa3d/pop_trans.h12
-rw-r--r--usr.sbin/popa3d/popa3d.8187
-rw-r--r--usr.sbin/popa3d/protocol.c287
-rw-r--r--usr.sbin/popa3d/protocol.h106
-rw-r--r--usr.sbin/popa3d/standalone.c339
-rw-r--r--usr.sbin/popa3d/startup.c91
-rw-r--r--usr.sbin/popa3d/version.c9
-rw-r--r--usr.sbin/popa3d/virtual.c197
-rw-r--r--usr.sbin/popa3d/virtual.h36
25 files changed, 0 insertions, 3267 deletions
diff --git a/usr.sbin/popa3d/DESIGN b/usr.sbin/popa3d/DESIGN
deleted file mode 100644
index e1466b9b251..00000000000
--- a/usr.sbin/popa3d/DESIGN
+++ /dev/null
@@ -1,210 +0,0 @@
-This file describes the design goals and the reasoning behind some of
-the design decisions for my tiny POP3 daemon, popa3d.
-
-
- Why popa3d?
-
-There're lots of different POP3 servers -- with different feature
-sets, performance, and reliability. However, as far as I know, before
-I started the work on popa3d, there had been only one with security as
-one of its primary design goals: qmail-pop3d. Unfortunately, it would
-only work with qmail, and only with its new maildir format. While
-both qmail and maildirs do indeed have some advantages, a lot of
-people continue running other MTAs, and/or use the older mailbox
-format, for various reasons. Many of them need a POP3 server.
-
-
- The design goals.
-
-Well, the goals themselves are obvious; they're probably the same for
-most other POP3 servers as well. It's their priority that differs.
-For popa3d, the goals are:
-
-1. Security (to the extent that is possible with POP3 at all, of
-course).
-
-2. Reliability (again, as limited by the mailbox format and the
-protocol).
-
-3. RFC compliance (slightly relaxed to work with real-world POP3
-clients).
-
-4. Performance (limited by the more important goals, above).
-
-Obviously, just like the comments indicate, none of the goals can be
-met completely, and balanced decisions need to be made.
-
-
- Security.
-
-First, it is important that none of the popa3d users get a false sense
-of security just because it was the primary design goal. The POP3
-protocol transmits passwords in plaintext and thus, if you care about
-the security of your individual user accounts, should only be used
-either in trusted networks or tunneled over encrypted channels.
-There exist extensions to the protocol that are supposed to fix this
-problem. I am not supporting them yet, partly because this isn't
-going to fully fix the problem. In fact, APOP and the weaker defined
-SASL mechanisms such as CRAM-MD5 may potentially be even less secure
-than transmission of plaintext passwords because of the requirement
-that plaintext equivalents be stored on the server.
-
-It is also important to understand that nothing can be perfectly
-secure. I can make mistakes. While the design of popa3d makes it
-harder for those to turn into security holes, this is nevertheless
-still possible.
-
-Having that said, let's get to the security-critical design decisions.
-
-
- Privilege management.
-
-Initially, popa3d is started as root to handle a connection. However,
-it does very little work as root: switching to less privileged UIDs,
-communication with child processes, and authentication information
-checks (which often involve accessing shadow or master.passwd files).
-
-The following privilege switches happen during a successful POP3
-session, with /etc/shadow authentication:
-
- startup as root
- |
- -----------------
- |child |parent
- v v
- drop to user popa3d, still as root,
- handle the AUTHORIZATION wait for and
- state, write the results, - - > read the authentication
- and exit information
- |
- -----------------
- |child |parent
- v v
- getspnam(3), crypt(3), wait for and
- check, write the result, - - > read the authentication
- and exit (to clean up) result
- |
- v
- drop to the authenticated user,
- handle the TRANSACTION state,
- possibly UPDATE the mailbox,
- and exit
-
-
- Trust.
-
-No part of popa3d trusts any information obtained from external
-sources (that is, the data is never assumed to be of the expected
-format, and is treated as subject to authorization checks). This
-includes POP3 commands, mailbox contents, and even popa3d's own
-less-privileged child process for the AUTHORIZATION state handling.
-
-
- DoS attacks.
-
-Just like with most other software, there exist ways to cause a Denial
-of Service, by supplying popa3d with an enormous amount of otherwise
-valid input. I am aware of the following attacks on popa3d itself:
-
-1. Connection flood. When running in the standalone mode, popa3d does
-quite a few checks to significantly reduce the impact of such attacks
-by limiting resource consumption (child processes and logging rate),
-while still providing full service for other source IP addresses and
-logging everything that might be important. However, when running
-from an inetd clone, the handling of these attacks is left up to your
-inetd and the kernel.
-
-2. Huge mailbox sizes, either in message count or bytes. There're
-limits in popa3d (see params.h) that are intended to prevent this
-attack from stopping the entire service. Depending on your disk and
-other quotas, it may still be possible to stop individual users from
-getting their mail.
-
-
- Reliability.
-
-Quoting Dan Bernstein, "the mbox format ... is inherently unreliable".
-
-While popa3d, just like other mail software that deals with mailboxes,
-doesn't guarantee reliability over system crashes, it still makes
-sense to talk about its operation on an otherwise stable system.
-
-
- Interaction with other MUAs.
-
-Similarly to cucipop (but unlike qpopper), popa3d works on the
-original mailbox file, without copying. However, unlike cucipop,
-popa3d is able to ensure that the mailbox doesn't get corrupted if
-another MUA modifies it during the POP session. Before each mailbox
-access, popa3d checks its timestamp and, if that has changed,
-determines if that is due to new mail that has just been delivered, or
-other changes made to the mailbox. In the latter case, the POP
-session is silently aborted (which doesn't violate the RFC). popa3d
-is careful to make sure the timestamp will change if the mailbox is
-written to, by keeping the lock for up to a second if necessary.
-
-
- Mailbox access.
-
-Except for the total size and message count limits mentioned above
-(and you can disable even those), there're no other artificial limits
-on the mailbox contents. In particular, there're no line length
-limits; unlike with qmail-pop3d, lines don't even need to fit in the
-available memory. NUL bytes are allowed in messages as well.
-
-
- Locking.
-
-Because of dropping to the user "completely" (that is, not even
-keeping a GID of mail like some other POP3 servers do), popa3d only
-uses fcntl(2) or flock(2) for locking. As a result, it may not be
-safe over NFS. This is where I choose security over either
-functionality or reliability.
-
-
- RFC compliance.
-
-I tried to make popa3d as strictly RFC 1939 compliant as possible.
-Most other POP3 servers have extra "features" that violate the RFC.
-Examples include: wrapping long commands (no matter if they're valid
-or not) and thus generating multiple -ERR responses (if not even
-worse: processing something from the middle of the line as a command)
-to a single command, processing "LIST 4294967297" as "LIST 1" instead
-of reporting the error, ignoring past a NUL byte till end of line and
-thus misinterpreting the command. While these are mostly harmless,
-they can theoretically cause a POP3 client not to detect the
-unavailability of a protocol extension.
-
-There's however one place where popa3d's RFC compliance is
-deliberately relaxed: popa3d accepts commands terminated by single
-LFs, even though the RFC says the commands are terminated by a CRLF
-pair.
-
-
- Performance.
-
-Despite the two extra "security" fork(2) calls, popa3d seems to behave
-fairly efficiently: the efficient mailbox parsing code and the lack of
-mailbox copying compensate for the extra fork's.
-
-Here's some real performance data that I've collected (popa3d running
-via inetd; larger sites would use the standalone mode instead):
-
- 24864 295.50re 16.92cp popa3d*
- 12749 4578.88re 15.50cp popa3d
-
-That is, 12749 POP3 sessions took 32.42 minutes of CPU time (on a 350
-MHz Pentium II); of those, more than a half was spent in the temporary
-child processes. It's not that bad though, as this system was running
-an (intentionally) expensive crypt(3) that got accounted to the child
-/etc/shadow authentication processes.
-
-Before upgrading to popa3d, the same machine was running qpopper (out
-of inetd, too):
-
- 12025 3169.38re 35.56cp popper
-
-It used to take a bit more CPU for less POP3 sessions.
-
---
-Solar Designer <solar at openwall.com>
diff --git a/usr.sbin/popa3d/LICENSE b/usr.sbin/popa3d/LICENSE
deleted file mode 100644
index dc50971f05d..00000000000
--- a/usr.sbin/popa3d/LICENSE
+++ /dev/null
@@ -1,9 +0,0 @@
-You're allowed to do whatever you like with this software (including
-re-distribution in source and/or binary form, with or without
-modification), provided that credit is given where it is due and any
-modified versions are marked as such. There's absolutely no warranty.
-
-Note that you don't have to re-distribute this software under these
-same relaxed terms. In particular, you're free to place modified
-versions under (L)GPL, thus disallowing further re-distribution in
-binary-only form.
diff --git a/usr.sbin/popa3d/Makefile b/usr.sbin/popa3d/Makefile
deleted file mode 100644
index 2d71146b2df..00000000000
--- a/usr.sbin/popa3d/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# $OpenBSD: Makefile,v 1.4 2003/05/12 19:28:22 camield Exp $
-
-PROG= popa3d
-MAN= popa3d.8
-SRCS= auth_passwd.c database.c mailbox.c misc.c pop_auth.c pop_root.c \
- pop_trans.c protocol.c standalone.c startup.c version.c
-
-CFLAGS+=-Wall -DHAVE_PROGNAME
-
-.include <bsd.prog.mk>
-
-.if (${TCP_WRAPPERS:L} == "yes")
-CFLAGS+= -DLIBWRAP
-LDADD+= -lwrap
-DPADD+= ${LIBWRAP}
-.endif
diff --git a/usr.sbin/popa3d/VIRTUAL b/usr.sbin/popa3d/VIRTUAL
deleted file mode 100644
index 23341277b81..00000000000
--- a/usr.sbin/popa3d/VIRTUAL
+++ /dev/null
@@ -1,5 +0,0 @@
-The virtual domain support in popa3d is in development and is currently
-undocumented.
-
-Please only use it if you know what you are doing, -- it is too easy to
-misconfigure it in dangerous ways.
diff --git a/usr.sbin/popa3d/auth_passwd.c b/usr.sbin/popa3d/auth_passwd.c
deleted file mode 100644
index d0503ac7aa7..00000000000
--- a/usr.sbin/popa3d/auth_passwd.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* $OpenBSD: auth_passwd.c,v 1.2 2001/09/21 20:22:06 camield Exp $ */
-
-/*
- * The /etc/passwd authentication routine.
- */
-
-#include "params.h"
-
-#if AUTH_PASSWD && !VIRTUAL_ONLY
-
-#define _XOPEN_SOURCE 4
-#define _XOPEN_SOURCE_EXTENDED
-#define _XOPEN_VERSION 4
-#define _XPG4_2
-#include <unistd.h>
-#include <string.h>
-#include <pwd.h>
-#include <sys/types.h>
-
-struct passwd *auth_userpass(char *user, char *pass, int *known)
-{
- struct passwd *pw, *result;
-
- *known = (pw = getpwnam(user)) != NULL;
- endpwent();
- result = NULL;
-
- if (!pw || !*pw->pw_passwd ||
- *pw->pw_passwd == '*' || *pw->pw_passwd == '!')
- crypt(pass, AUTH_DUMMY_SALT);
- else
- if (!strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd))
- result = pw;
-
- if (pw)
- memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
-
- return result;
-}
-
-#endif
diff --git a/usr.sbin/popa3d/database.c b/usr.sbin/popa3d/database.c
deleted file mode 100644
index c85ffcc8d77..00000000000
--- a/usr.sbin/popa3d/database.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $OpenBSD: database.c,v 1.2 2003/05/12 19:28:22 camield Exp $ */
-
-/*
- * Message database management.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "params.h"
-#include "database.h"
-
-struct db_main db;
-
-void db_init(void)
-{
- db.head = db.tail = NULL;
- db.total_count = 0;
- db.total_size = 0;
- db.flags = 0;
-#if POP_SUPPORT_LAST
- db.last = 0;
-#endif
-}
-
-int db_add(struct db_message *msg)
-{
- struct db_message *entry;
-
- if (db.total_count >= MAX_MAILBOX_MESSAGES) goto out_fail;
- if (++db.total_count <= 0) goto out_undo_count;
- if ((db.total_size += msg->size) < msg->size) goto out_undo_size;
-
- entry = malloc(sizeof(struct db_message));
- if (!entry) goto out_undo_size;
-
- memcpy(entry, msg, sizeof(struct db_message));
- entry->next = NULL;
- entry->flags = 0;
-
- if (db.tail)
- db.tail = db.tail->next = entry;
- else
- db.tail = db.head = entry;
-
- return 0;
-
-out_undo_size:
- db.total_size -= msg->size;
-
-out_undo_count:
- db.total_count--;
-
-out_fail:
- return 1;
-}
-
-int db_delete(struct db_message *msg)
-{
- if (msg->flags & MSG_DELETED) return 1;
-
- msg->flags |= MSG_DELETED;
-
- db.visible_count--;
- db.visible_size -= msg->size;
- db.flags |= DB_DIRTY;
-
- return 0;
-}
-
-int db_fix(void)
-{
- unsigned long size;
- struct db_message *entry;
- unsigned int index;
-
- db.visible_count = db.total_count;
- db.visible_size = db.total_size;
-
- if (!db.total_count) return 0;
-
- size = sizeof(struct db_message *) * db.total_count;
- if (size / sizeof(struct db_message *) != db.total_count) return 1;
-
- db.array = malloc(size);
- if (!db.array) return 1;
-
- entry = db.head;
- index = 0;
- do {
- db.array[index++] = entry;
- } while ((entry = entry->next));
-
- return 0;
-}
diff --git a/usr.sbin/popa3d/database.h b/usr.sbin/popa3d/database.h
deleted file mode 100644
index 71dc9ee4956..00000000000
--- a/usr.sbin/popa3d/database.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $OpenBSD: database.h,v 1.2 2003/05/12 19:28:22 camield Exp $ */
-
-/*
- * Message database management.
- */
-
-#ifndef _POP_DATABASE_H
-#define _POP_DATABASE_H
-
-#include "params.h"
-
-/*
- * Message flags.
- */
-/* Marked for deletion */
-#define MSG_DELETED 0x00000001
-
-/*
- * Database flags.
- */
-/* Some messages are marked for deletion, mailbox update is needed */
-#define DB_DIRTY 0x00000001
-/* Another MUA has modified our part of the mailbox */
-#define DB_STALE 0x00000002
-
-struct db_message {
- struct db_message *next;
- unsigned long size; /* Size as reported via POP */
- unsigned int flags; /* MSG_* flags defined above */
- unsigned long raw_offset; /* Raw, with the "From " line */
- unsigned long raw_size;
- unsigned long data_offset; /* Just the message itself */
- unsigned long data_size;
- unsigned char hash[16]; /* MD5 hash, to be used for UIDL */
-};
-
-struct db_main {
- struct db_message *head, *tail; /* Messages in a linked list */
- struct db_message **array; /* Direct access to messages */
- unsigned int total_count; /* All loaded messages and */
- unsigned int visible_count; /* just those not DELEted */
- unsigned long total_size; /* Their cumulative sizes, */
- unsigned long visible_size; /* to be reported via POP */
- unsigned int flags; /* DB_* flags defined above */
-#if POP_SUPPORT_LAST
- unsigned int last; /* Last message touched */
-#endif
-};
-
-extern struct db_main db;
-
-extern void db_init(void);
-extern int db_add(struct db_message *msg);
-extern int db_delete(struct db_message *msg);
-extern int db_fix(void);
-
-#endif
diff --git a/usr.sbin/popa3d/mailbox.c b/usr.sbin/popa3d/mailbox.c
deleted file mode 100644
index 70968f69de9..00000000000
--- a/usr.sbin/popa3d/mailbox.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* $OpenBSD: mailbox.c,v 1.7 2009/12/20 15:57:26 tobias Exp $ */
-
-/*
- * Mailbox access.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <errno.h>
-
-#include <md5.h>
-
-#include "misc.h"
-#include "params.h"
-#include "protocol.h"
-#include "database.h"
-
-static int mailbox_fd; /* fd for the mailbox, or -1 */
-static time_t mailbox_mtime; /* mtime, as of the last check */
-static unsigned long mailbox_size; /* Its original size */
-
-static struct db_message *cmp;
-
-/*
- * If a message has changed since the database was filled in, then we
- * consider the database stale. This is called for every message when
- * the mailbox is being re-parsed (because of its mtime change).
- */
-static int db_compare(struct db_message *msg)
-{
- if (!cmp) return 1;
-
- if (msg->raw_size != cmp->raw_size || msg->size != cmp->size ||
- memcmp(msg->hash, cmp->hash, sizeof(msg->hash))) {
- db.flags |= DB_STALE;
- return 1;
- }
-
- cmp = cmp->next;
-
- return 0;
-}
-
-/*
- * Checks if the buffer pointed to by s1, of n1 chars, starts with the
- * string s2, of n2 chars.
- */
-#ifdef __GNUC__
-__inline__
-#endif
-static int eq(char *s1, int n1, char *s2, int n2)
-{
- if (n1 < n2) return 0;
- if (!memcmp(s1, s2, n2)) return 1;
- return !strncasecmp(s1, s2, n2);
-}
-
-/*
- * The mailbox parsing routine: first called to fill the database in,
- * then to check if the database is still up to date. We implement a
- * state machine at the line fragment level (that is, full or partial
- * lines). This is faster than dealing with individual characters (we
- * leave that job for libc), and doesn't require ever loading entire
- * lines into memory.
- */
-static int mailbox_parse(int init)
-{
- struct stat stat; /* File information */
- struct db_message msg; /* Message being parsed */
- MD5_CTX hash; /* Its hash being computed */
- int (*db_op)(struct db_message *msg); /* db_add or db_compare */
- char *file_buffer, *line_buffer; /* Our internal buffers */
- unsigned long file_offset, line_offset; /* Their offsets in the file */
- unsigned long offset; /* A line fragment's offset */
- char *current, *next, *line; /* Line pointers */
- int block, saved, extra, length; /* Internal block sizes */
- int done, start, end; /* Various boolean flags: */
- int blank, header, body; /* the state information */
- int fixed, received; /* ...and more of it */
-
- if (fstat(mailbox_fd, &stat)) return 1;
-
- if (init) {
-/* Prepare for the database initialization */
- if (!S_ISREG(stat.st_mode)) return 1;
- mailbox_mtime = stat.st_mtime;
- if (stat.st_size > MAX_MAILBOX_OPEN_BYTES ||
- stat.st_size > ~0UL) return 1;
- mailbox_size = stat.st_size;
- if (!mailbox_size) return 0;
- db_op = db_add;
- } else {
-/* Prepare for checking against the database */
- if (mailbox_mtime == stat.st_mtime) return 0;
- if (!mailbox_size) return 0;
- if (stat.st_size < mailbox_size) {
- db.flags |= DB_STALE;
- return 1;
- }
- if (stat.st_size > MAX_MAILBOX_WORK_BYTES ||
- stat.st_size > ~0UL) return 1;
- if (lseek(mailbox_fd, 0, SEEK_SET) < 0) return 1;
- db_op = db_compare; cmp = db.head;
- }
-
- memset(&msg, 0, sizeof(msg));
- MD5Init(&hash);
-
- file_buffer = malloc(FILE_BUFFER_SIZE + LINE_BUFFER_SIZE);
- if (!file_buffer) return 1;
- line_buffer = &file_buffer[FILE_BUFFER_SIZE];
-
- file_offset = 0; line_offset = 0; offset = 0; /* Start at 0, with */
- current = file_buffer; block = 0; saved = 0; /* empty buffers */
-
- done = 0; /* Haven't reached EOF or the original size yet */
- end = 1; /* Assume we've just seen a LF: parse a new line */
- blank = 1; /* Assume we've seen a blank line: look for "From " */
- header = 0; /* Not in message headers, */
- body = 0; /* and not in message body */
- fixed = 0; /* Not in a "fixed" part of a message, */
- received = 0; /* and haven't got a Received: header yet */
-
-/*
- * The main loop. Its first part extracts the line fragments, while the
- * second one manages the state flags and performs whatever is required
- * based on the state. Unfortunately, splitting this into two functions
- * didn't seem to simplify the code.
- */
- do {
-/*
- * Part 1.
- * The line fragment extraction.
- */
-
-/* Look for the next LF in the file buffer */
- if ((next = memchr(current, '\n', block))) {
-/* Found it: get the length of this piece, and check for buffered data */
- length = ++next - current;
- if (saved) {
-/* Have this line's beginning in the line buffer: combine them */
- extra = LINE_BUFFER_SIZE - saved;
- if (extra > length) extra = length;
- memcpy(&line_buffer[saved], current, extra);
- current += extra; block -= extra;
- length = saved + extra;
- line = line_buffer;
- offset = line_offset;
- start = end; end = current == next;
- saved = 0;
- } else {
-/* Nothing in the line buffer: just process what we've got now */
- line = current;
- offset = file_offset - block;
- start = end; end = 1;
- current = next; block -= length;
- }
- } else {
-/* No more LFs in the file buffer */
- if (saved || block <= LINE_BUFFER_SIZE) {
-/* Have this line's beginning in the line buffer: combine them */
-/* Not enough data to process right now: buffer it */
- extra = LINE_BUFFER_SIZE - saved;
- if (extra > block) extra = block;
- if (!saved) line_offset = file_offset - block;
- memcpy(&line_buffer[saved], current, extra);
- current += extra; block -= extra;
- saved += extra;
- length = saved;
- line = line_buffer;
- offset = line_offset;
- } else {
-/* Nothing in the line buffer and we've got enough data: just process it */
- length = block - 1;
- line = current;
- offset = file_offset - block;
- current += length;
- block = 1;
- }
- if (!block) {
-/* We've emptied the file buffer: fetch some more data */
- current = file_buffer;
- block = FILE_BUFFER_SIZE;
- if (!init &&
- block > mailbox_size - file_offset)
- block = mailbox_size - file_offset;
- block = read(mailbox_fd, file_buffer, block);
- if (block < 0) break;
- file_offset += block;
- if (block > 0 && saved < LINE_BUFFER_SIZE)
- continue;
- if (!saved) {
-/* Nothing in the line buffer, and read(2) returned 0: we're done */
- offset = file_offset;
- done = 1;
- break;
- }
- }
- start = end; end = !block;
- saved = 0;
- }
-
-/*
- * Part 2.
- * The following variables are set when we get here:
- * -- line the line fragment, not NUL terminated;
- * -- length its length;
- * -- offset its offset in the file;
- * -- start whether it's at the start of the line;
- * -- end whether it's at the end of the line
- * (all four combinations of "start" and "end" are possible).
- */
-
-/* Check for a new message if we've just seen a blank line */
- if (blank && start)
- if (line[0] == 'F' && length >= 5 &&
- line[1] == 'r' && line[2] == 'o' && line[3] == 'm' &&
- line[4] == ' ') {
-/* Process the previous one first, if exists */
- if (offset) {
-/* If we aren't at the very beginning, there must have been a message */
- if (!msg.data_offset) break;
- msg.raw_size = offset - msg.raw_offset;
- msg.data_size = offset - body - msg.data_offset;
- msg.size -= body << 1;
- MD5Final(msg.hash, &hash);
- if (db_op(&msg)) break;
- }
-/* Now prepare for parsing the new one */
- msg.raw_offset = offset;
- msg.data_offset = 0;
- MD5Init(&hash);
- header = 1; body = 0;
- fixed = received = 0;
- continue;
- }
-
-/* Memorize file offset of the message data (the line next to "From ") */
- if (header && start && !msg.data_offset) {
- msg.data_offset = offset;
- msg.data_size = 0;
- msg.size = 0;
- }
-
-/* Count this fragment, with LFs as CRLF, into the message size */
- if (msg.data_offset)
- msg.size += length + end;
-
-/* If we see LF at start of line, then this is a blank line :-) */
- blank = start && line[0] == '\n';
-
- if (!header) {
-/* If we're no longer in message headers and we see more data, then it's
- * the body. */
- if (msg.data_offset)
- body = 1;
-/* The rest of actions in this loop are for header lines only */
- continue;
- }
-
-/* Blank line ends message headers */
- if (blank) {
- header = 0;
- continue;
- }
-
-/* Some header lines are known to remain fixed over MUA runs */
- if (start)
- switch (line[0]) {
- case '\t':
- case ' ':
-/* Inherit "fixed" from the previous line */
- break;
-
- case 'R':
- case 'r':
-/* One Received: header from the local MTA should be sufficient */
- fixed = !received &&
- (received = eq(line, length, "Received:", 9));
- break;
-
- case 'D':
- case 'd':
- fixed = eq(line, length, "Delivered-To:", 13) ||
- (!received && eq(line, length, "Date:", 5));
- break;
-
- case 'M':
- case 'm':
- fixed = !received &&
- eq(line, length, "Message-ID:", 11);
- break;
-
- case 'X':
-/* Let the local delivery agent help generate unique IDs but don't blindly
- * trust this header alone as it could just as easily come from the remote. */
- fixed = eq(line, length, "X-Delivery-ID:", 14);
- break;
-
- default:
- fixed = 0;
- continue;
- }
-
-/* We can hash all fragments of those lines, for UIDL */
- if (fixed)
- MD5Update(&hash, (u_char *)line, length);
- } while (1);
-
- free(file_buffer);
-
- if (done) {
-/* Process the last message */
- if (offset != mailbox_size) return 1;
- if (!msg.data_offset) return 1;
- msg.raw_size = offset - msg.raw_offset;
- msg.data_size = offset - (blank & body) - msg.data_offset;
- msg.size -= (blank & body) << 1;
- MD5Final(msg.hash, &hash);
- if (db_op(&msg)) return 1;
-
-/* Everything went well, update our timestamp if we were checking */
- if (!init) mailbox_mtime = stat.st_mtime;
- }
-
- return !done;
-}
-
-int mailbox_open(char *spool, char *mailbox)
-{
- char *pathname;
- int result;
-
- mailbox_fd = -1;
-
- if (asprintf(&pathname, "%s/%s", spool, mailbox) == -1)
- return 1;
-
- mailbox_fd = open(pathname,
- O_RDWR | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK);
-
- free(pathname);
-
- if (mailbox_fd < 0)
- return errno != ENOENT;
-
- if (lock_fd(mailbox_fd, 1)) return 1;
-
- result = mailbox_parse(1);
-
- if (!result && time(NULL) == mailbox_mtime)
- if (sleep_select(1, 0)) result = 1;
-
- if (unlock_fd(mailbox_fd)) return 1;
-
- return result;
-}
-
-static int mailbox_changed(void)
-{
- struct stat stat;
- int result;
-
- if (fstat(mailbox_fd, &stat)) return 1;
- if (mailbox_mtime == stat.st_mtime) return 0;
-
- if (lock_fd(mailbox_fd, 1)) return 1;
-
- result = mailbox_parse(0);
-
- if (!result && time(NULL) == mailbox_mtime)
- if (sleep_select(1, 0)) result = 1;
-
- if (unlock_fd(mailbox_fd)) return 1;
-
- return result;
-}
-
-int mailbox_get(struct db_message *msg, int lines)
-{
- int event;
-
- if (mailbox_changed()) return POP_CRASH_SERVER;
-
-/* The calls to mailbox_changed() will set DB_STALE if that is the case */
- if (lseek(mailbox_fd, msg->data_offset, SEEK_SET) < 0) {
- mailbox_changed();
- return POP_CRASH_SERVER;
- }
- if ((event = pop_reply_multiline(mailbox_fd, msg->data_size, lines))) {
- if (event == POP_CRASH_SERVER) mailbox_changed();
- return event;
- }
-
- if (mailbox_changed()) return POP_CRASH_SERVER;
-
- if (pop_reply_terminate()) return POP_CRASH_NETFAIL;
-
- return POP_OK;
-}
-
-static int mailbox_write(char *buffer)
-{
- struct db_message *msg;
- unsigned long old, new;
- unsigned long size;
- int block;
-
- msg = db.head;
- old = new = 0;
- do {
- if (msg->flags & MSG_DELETED) continue;
- old = msg->raw_offset;
-
- if (old == new) {
- old = (new += msg->raw_size);
- continue;
- }
-
- while ((size = msg->raw_size - (old - msg->raw_offset))) {
- if (lseek(mailbox_fd, old, SEEK_SET) < 0) return 1;
- if (size > FILE_BUFFER_SIZE)
- size = FILE_BUFFER_SIZE;
- block = read(mailbox_fd, buffer, size);
- if (!block && old == mailbox_size) break;
- if (block <= 0) return 1;
-
- if (lseek(mailbox_fd, new, SEEK_SET) < 0) return 1;
- if (write_loop(mailbox_fd, buffer, block) != block)
- return 1;
-
- old += block; new += block;
- }
- } while ((msg = msg->next));
-
- old = mailbox_size;
- while (1) {
- if (lseek(mailbox_fd, old, SEEK_SET) < 0) return 1;
- block = read(mailbox_fd, buffer, FILE_BUFFER_SIZE);
- if (!block) break;
- if (block < 0) return 1;
-
- if (lseek(mailbox_fd, new, SEEK_SET) < 0) return 1;
- if (write_loop(mailbox_fd, buffer, block) != block) return 1;
-
-/* Cannot overflow unless locking is bypassed */
- if ((old += block) < block || (new += block) < block) return 1;
- }
-
- if (ftruncate(mailbox_fd, new)) return 1;
-
- return fsync(mailbox_fd);
-}
-
-static int mailbox_write_blocked(void)
-{
- sigset_t blocked_set, old_set;
- char *buffer;
- int result;
-
- if (sigfillset(&blocked_set)) return 1;
- if (sigprocmask(SIG_BLOCK, &blocked_set, &old_set)) return 1;
-
- if ((buffer = malloc(FILE_BUFFER_SIZE))) {
- result = mailbox_write(buffer);
- free(buffer);
- } else
- result = 1;
-
- if (sigprocmask(SIG_SETMASK, &old_set, NULL)) return 1;
-
- return result;
-}
-
-int mailbox_update(void)
-{
- int result;
-
- if (mailbox_fd < 0 || !(db.flags & DB_DIRTY)) return 0;
-
- if (lock_fd(mailbox_fd, 0)) return 1;
-
- if (!(result = mailbox_parse(0)))
- result = mailbox_write_blocked();
-
- if (unlock_fd(mailbox_fd)) return 1;
-
- return result;
-}
-
-int mailbox_close(void)
-{
- if (mailbox_fd < 0) return 0;
-
- return close(mailbox_fd);
-}
diff --git a/usr.sbin/popa3d/mailbox.h b/usr.sbin/popa3d/mailbox.h
deleted file mode 100644
index 102774ec97f..00000000000
--- a/usr.sbin/popa3d/mailbox.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* $OpenBSD: mailbox.h,v 1.2 2001/09/21 20:22:06 camield Exp $ */
-
-/*
- * Mailbox access.
- */
-
-#ifndef _POP_MAILBOX_H
-#define _POP_MAILBOX_H
-
-/*
- * Opens the mailbox, filling in the message database. Returns a non-zero
- * value on error.
- */
-extern int mailbox_open(char *spool, char *mailbox);
-
-/*
- * Sends (first lines of) a message to the POP client. Returns one of the
- * POP_* event codes.
- */
-extern int mailbox_get(struct db_message *msg, int lines);
-
-/*
- * Rewrites the mailbox according to flags in the database.
- */
-extern int mailbox_update(void);
-
-/*
- * Closes the mailbox file.
- */
-extern int mailbox_close(void);
-
-#endif
diff --git a/usr.sbin/popa3d/misc.c b/usr.sbin/popa3d/misc.c
deleted file mode 100644
index 7b43a5d8134..00000000000
--- a/usr.sbin/popa3d/misc.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* $OpenBSD: misc.c,v 1.1 2001/08/19 13:05:57 deraadt Exp $ */
-
-/*
- * Miscellaneous syscall wrappers. See misc.h for the descriptions.
- */
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/file.h>
-
-#include "params.h"
-
-int sleep_select(int sec, int usec)
-{
- struct timeval timeout;
-
- timeout.tv_sec = sec;
- timeout.tv_usec = usec;
-
- return select(0, NULL, NULL, NULL, &timeout);
-}
-
-int lock_fd(int fd, int shared)
-{
-#if LOCK_FCNTL
- struct flock l;
-
- memset(&l, 0, sizeof(l));
- l.l_whence = SEEK_SET;
- l.l_type = shared ? F_RDLCK : F_WRLCK;
- while (fcntl(fd, F_SETLKW, &l)) {
- if (errno != EBUSY) return -1;
- sleep_select(1, 0);
- }
-#endif
-
-#if LOCK_FLOCK
- while (flock(fd, shared ? LOCK_SH : LOCK_EX)) {
- if (errno != EBUSY) return -1;
- sleep_select(1, 0);
- }
-#endif
-
- return 0;
-}
-
-int unlock_fd(int fd)
-{
-#if LOCK_FCNTL
- struct flock l;
-
- memset(&l, 0, sizeof(l));
- l.l_whence = SEEK_SET;
- l.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &l)) return -1;
-#endif
-
-#if LOCK_FLOCK
- if (flock(fd, LOCK_UN)) return -1;
-#endif
-
- return 0;
-}
-
-int write_loop(int fd, char *buffer, int count)
-{
- int offset, block;
-
- offset = 0;
- while (count > 0) {
- block = write(fd, &buffer[offset], count);
-
-/* If any write(2) fails, we consider that the entire write_loop() has
- * failed to do its job. We don't even ignore EINTR here. We also don't
- * retry when a write(2) returns zero, as we could start eating up the
- * CPU if we did. */
- if (block < 0) return block;
- if (!block) return offset;
-
- offset += block;
- count -= block;
- }
-
-/* Should be equal to the requested size, unless our kernel got crazy. */
- return offset;
-}
diff --git a/usr.sbin/popa3d/misc.h b/usr.sbin/popa3d/misc.h
deleted file mode 100644
index 2dba9f555fa..00000000000
--- a/usr.sbin/popa3d/misc.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $OpenBSD: misc.h,v 1.2 2001/09/19 10:58:08 mpech Exp $ */
-
-/*
- * Miscellaneous syscall wrappers.
- */
-
-#ifndef _POP_MISC_H
-#define _POP_MISC_H
-
-/*
- * A select(2)-based sleep() equivalent: no more problems with SIGALRM,
- * subsecond precision.
- */
-extern int sleep_select(int sec, int usec);
-
-/*
- * Obtain or remove a lock.
- */
-extern int lock_fd(int fd, int shared);
-extern int unlock_fd(int fd);
-
-/*
- * Attempts to write all the supplied data. Returns the number of bytes
- * written. Any value that differs from the requested count means that
- * an error has occurred; if the value is -1, errno is set appropriately.
- */
-extern int write_loop(int fd, char *buffer, int count);
-
-#endif
diff --git a/usr.sbin/popa3d/params.h b/usr.sbin/popa3d/params.h
deleted file mode 100644
index f27e171eaa8..00000000000
--- a/usr.sbin/popa3d/params.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/* $OpenBSD: params.h,v 1.10 2012/07/17 11:34:47 otto Exp $ */
-
-/*
- * Global POP daemon parameters.
- */
-
-#ifndef _POP_PARAMS_H
-#define _POP_PARAMS_H
-
-/*
- * Our name to use when talking to various interfaces.
- */
-#define POP_SERVER "popa3d"
-
-/*
- * Are we going to be a standalone server or start via an inetd clone?
- */
-#define POP_STANDALONE 1
-
-#if POP_STANDALONE
-
-/*
- * Should the command line options be supported?
- * If enabled, popa3d will default to inetd mode and will require a -D
- * to actually enable the standalone mode.
- */
-#define POP_OPTIONS 1
-
-/*
- * The address and port to listen on.
- */
-#define DAEMON_ADDR "0.0.0.0" /* INADDR_ANY */
-#define DAEMON_PORT 110
-
-/*
- * Should libwrap be used?
- *
- * This may make things slower and also adds to code running as root,
- * so it is recommended that you use a packet filter instead. This
- * option is provided primarily as a way to meet conventions of certain
- * systems where all services obey libwrap access controls.
- */
-#ifdef LIBWRAP
-#define DAEMON_LIBWRAP 1
-#else
-#define DAEMON_LIBWRAP 0
-#endif
-
-#if DAEMON_LIBWRAP
-/*
- * How do we talk to libwrap?
- */
-#define DAEMON_LIBWRAP_IDENT POP_SERVER
-#endif
-
-/*
- * Limit the number of POP sessions we can handle at a time to reduce
- * the impact of connection flood DoS attacks.
- */
-#define MAX_SESSIONS 100
-#define MAX_SESSIONS_PER_SOURCE 10
-#define MAX_BACKLOG 5
-#define MIN_DELAY 10
-
-#endif
-
-/*
- * Do we want to support virtual domains?
- */
-#define POP_VIRTUAL 0
-
-#if POP_VIRTUAL
-
-/*
- * VIRTUAL_HOME_PATH is where the virtual domain root directories live.
- */
-#define VIRTUAL_HOME_PATH "/vhome"
-
-/*
- * Subdirectories within each virtual domain root for the authentication
- * information and mailboxes, respectively. These defaults correspond to
- * full pathnames of the form "/vhome/IP/{auth,mail}/username".
- */
-#define VIRTUAL_AUTH_PATH "auth"
-#define VIRTUAL_SPOOL_PATH "mail"
-
-/*
- * Do we want to support virtual domains only? Normally, if the connected
- * IP address doesn't correspond to a directory in VIRTUAL_HOME_PATH, the
- * authentication will be done globally.
- */
-#define VIRTUAL_ONLY 0
-
-#else
-
-/*
- * We don't support virtual domains (!POP_VIRTUAL), so we're definitely
- * not virtual-only. Don't edit this.
- */
-#define VIRTUAL_ONLY 0
-
-#endif
-
-/*
- * A pseudo-user to run as before authentication. The user and its UID
- * must not be used for any other purpose.
- */
-#define POP_USER POP_SERVER
-
-/*
- * An empty directory to chroot to before authentication. The directory
- * and its parent directories must not be writable by anyone but root.
- */
-#define POP_CHROOT "/var/empty"
-
-/*
- * Sessions will be closed if idle for longer than POP_TIMEOUT seconds.
- * RFC 1939 says that "such a timer MUST be of at least 10 minutes'
- * duration", so I've made 10 minutes the default. In practice, you
- * may want to reduce this to, say, 2 minutes.
- */
-#define POP_TIMEOUT (10 * 60)
-
-/*
- * Do we want to support the obsolete LAST command, as defined in RFC
- * 1460? It has been removed from the protocol in 1994 by RFC 1725,
- * and isn't even mentioned in RFC 1939. Still, some software doesn't
- * work without it.
- */
-#define POP_SUPPORT_LAST 1
-
-/*
- * Introduce some sane limits on the mailbox size in order to prevent
- * a single huge mailbox from stopping the entire POP service.
- */
-#define MAX_MAILBOX_MESSAGES 200000
-#define MAX_MAILBOX_OPEN_BYTES 2000000000LL
-#define MAX_MAILBOX_WORK_BYTES 2500000000LL
-
-#if !VIRTUAL_ONLY
-
-/*
- * Choose the password authentication method your system uses:
- *
- * AUTH_PASSWD Use getpwnam(3) only, for *BSD or readable passwd;
- *
- * Note that there's no built-in password aging support.
- */
-#define AUTH_PASSWD 1
-
-#endif
-
-#if POP_VIRTUAL || AUTH_PASSWD
-
-/*
- * A salt used to waste some CPU time on dummy crypt(3) calls and make
- * it harder (but still far from impossible, on most systems) to check
- * for valid usernames. Adjust it for your crypt(3).
- */
-/* echo -n "dummyblowfishsalt" | encrypt -b 6 */
-#define AUTH_DUMMY_SALT "$2a$06$bycSsJMBAEDy1E6zzaL5u.vd4GlIrmCWyDgB33OD36h6mrRympUwS"
-
-#endif
-
-/*
- * Message to return to the client when authentication fails. You can
- * #undef this for no message.
- */
-#define AUTH_FAILED_MESSAGE "Authentication failed (bad password?)"
-
-#if !VIRTUAL_ONLY
-
-/*
- * Your mail spool directory. Note: only local (non-NFS) mode 775 mail
- * spools are currently supported.
- *
- * #undef this for qmail-style $HOME/Mailbox mailboxes.
- */
-#define MAIL_SPOOL_PATH "/var/mail"
-
-#ifndef MAIL_SPOOL_PATH
-/*
- * The mailbox file name relative to the user's home directory.
- */
-#define HOME_MAILBOX_NAME "Mailbox"
-#endif
-
-#endif
-
-/*
- * Locking method your system uses for user mailboxes. It is important
- * that you set this correctly.
- *
- * *BSDs use flock(2), others typically use fcntl(2).
- */
-#define LOCK_FCNTL 0
-#define LOCK_FLOCK 1
-
-/*
- * How do we talk to syslogd? These should be fine for most systems.
- */
-#define SYSLOG_IDENT POP_SERVER
-#define SYSLOG_OPTIONS LOG_PID
-#define SYSLOG_FACILITY LOG_DAEMON
-#define SYSLOG_PRI_LO LOG_INFO
-#define SYSLOG_PRI_HI LOG_NOTICE
-#define SYSLOG_PRI_ERROR LOG_CRIT
-
-/*
- * There's probably no reason to touch anything below this comment.
- */
-
-/*
- * According to RFC 1939: "Keywords and arguments are each separated by
- * a single SPACE character. Keywords are three or four characters long.
- * Each argument may be up to 40 characters long." We're only processing
- * up to two arguments, so it is safe to truncate after this length.
- */
-#define POP_BUFFER_SIZE 0x80
-
-/*
- * There's no reason to change this one either. Making this larger would
- * waste memory, and smaller values could make the authentication fail.
- */
-#define AUTH_BUFFER_SIZE (2 * POP_BUFFER_SIZE)
-
-#if POP_VIRTUAL
-
-/*
- * Buffer size for reading entire per-user authentication files.
- */
-#define VIRTUAL_AUTH_SIZE 0x100
-
-#endif
-
-/*
- * File buffer sizes to use while parsing the mailbox and retrieving a
- * message, respectively. Can be changed.
- */
-#define FILE_BUFFER_SIZE 0x10000
-#define RETR_BUFFER_SIZE 0x8000
-
-/*
- * The mailbox parsing code isn't allowed to truncate lines earlier than
- * this length. Keep this at least as large as the longest header field
- * name we need to check for, but not too large for performance reasons.
- */
-#define LINE_BUFFER_SIZE 0x20
-
-#endif
diff --git a/usr.sbin/popa3d/pop_auth.c b/usr.sbin/popa3d/pop_auth.c
deleted file mode 100644
index 31d66f764b4..00000000000
--- a/usr.sbin/popa3d/pop_auth.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $OpenBSD: pop_auth.c,v 1.4 2009/12/20 15:55:42 tobias Exp $ */
-
-/*
- * AUTHORIZATION state handling.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "misc.h"
-#include "params.h"
-#include "protocol.h"
-#include "pop_auth.h"
-#if POP_VIRTUAL
-#include "virtual.h"
-#endif
-
-static char *pop_user, *pop_pass;
-
-static int pop_auth_quit(char *params)
-{
- if (params) return POP_ERROR;
- return POP_LEAVE;
-}
-
-static int pop_auth_user(char *params)
-{
- char *user;
-
- user = pop_get_param(&params);
- if (!user || pop_user || params) return POP_ERROR;
- if (!(pop_user = strdup(user))) return POP_CRASH_SERVER;
- return POP_OK;
-}
-
-static int pop_auth_pass(char *params)
-{
- if (!params) return POP_ERROR;
- if (!pop_user) {
- memset(params, 0, strlen(params));
- return POP_ERROR;
- }
- pop_pass = strdup(params);
- memset(params, 0, strlen(params));
- if (pop_pass == NULL) return POP_CRASH_SERVER;
- return POP_STATE;
-}
-
-static struct pop_command pop_auth_commands[] = {
- {"QUIT", pop_auth_quit},
- {"USER", pop_auth_user},
- {"PASS", pop_auth_pass},
- {NULL, NULL}
-};
-
-int do_pop_auth(int channel)
-{
- pop_init();
-
- if (pop_reply_ok()) return 1;
-
- pop_user = NULL;
- if (pop_handle_state(pop_auth_commands) == POP_STATE) {
- pop_clean();
- write_loop(channel, (char *)&pop_buffer, sizeof(pop_buffer));
- write_loop(channel, pop_user, strlen(pop_user) + 1);
- write_loop(channel, pop_pass, strlen(pop_pass) + 1);
- memset(pop_pass, 0, strlen(pop_pass));
- if (close(channel)) return 1;
- }
-
- return 0;
-}
-
-void log_pop_auth(int result, char *user)
-{
- if (result == AUTH_NONE) {
- syslog(SYSLOG_PRI_LO, "Didn't attempt authentication");
- return;
- }
-
-#if POP_VIRTUAL
- if (virtual_domain) {
- syslog(result == AUTH_OK ? SYSLOG_PRI_LO : SYSLOG_PRI_HI,
- "Authentication %s for %s@%s",
- result == AUTH_OK ? "passed" : "failed",
- user ? user : "UNKNOWN USER",
- virtual_domain);
- return;
- }
-#endif
- syslog(result == AUTH_OK ? SYSLOG_PRI_LO : SYSLOG_PRI_HI,
- "Authentication %s for %s",
- result == AUTH_OK ? "passed" : "failed",
- user ? user : "UNKNOWN USER");
-}
diff --git a/usr.sbin/popa3d/pop_auth.h b/usr.sbin/popa3d/pop_auth.h
deleted file mode 100644
index 2708dcd6058..00000000000
--- a/usr.sbin/popa3d/pop_auth.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $OpenBSD: pop_auth.h,v 1.2 2001/09/21 20:22:06 camield Exp $ */
-
-/*
- * AUTHORIZATION state handling.
- */
-
-#ifndef _POP_AUTH_H
-#define _POP_AUTH_H
-
-/*
- * Possible authentication results.
- */
-#define AUTH_OK 0
-#define AUTH_NONE 1
-#define AUTH_FAILED 2
-
-/*
- * Handles the AUTHORIZATION state commands, and writes authentication
- * data into the channel.
- */
-extern int do_pop_auth(int channel);
-
-/*
- * Logs an authentication attempt for user, use NULL for non-existent.
- */
-extern void log_pop_auth(int result, char *user);
-
-#endif
diff --git a/usr.sbin/popa3d/pop_root.c b/usr.sbin/popa3d/pop_root.c
deleted file mode 100644
index 972d8a63557..00000000000
--- a/usr.sbin/popa3d/pop_root.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* $OpenBSD: pop_root.c,v 1.5 2005/05/03 05:44:35 djm Exp $ */
-
-/*
- * Main daemon code: invokes the actual POP handling routines. Most calls
- * to functions in other source files are done as a non-root user (either
- * POP_USER or the authenticated user). Depending on compile-time options
- * in params.h, the following files may contain code executed as root:
- *
- * startup.c if supporting command line options (POP_OPTIONS)
- * standalone.c if not running via an inetd clone (POP_STANDALONE)
- * virtual.c if supporting virtual domains (POP_VIRTUAL)
- * auth_passwd.c if using passwd or *BSD (AUTH_PASSWD && !VIRTUAL_ONLY)
- */
-
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <errno.h>
-#include <time.h>
-#include <grp.h>
-#include <pwd.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-
-#include "params.h"
-#include "protocol.h"
-#include "pop_auth.h"
-#include "pop_trans.h"
-#if POP_VIRTUAL
-#include "virtual.h"
-#endif
-
-#if !VIRTUAL_ONLY
-extern struct passwd *auth_userpass(char *user, char *pass, int *known);
-#endif
-
-/* POP_USER's pw_uid and pw_gid, other fields may not be valid */
-static struct passwd pop_pw;
-
-static int known;
-static char *user;
-static char *spool, *mailbox;
-
-int log_error(char *s)
-{
- syslog(SYSLOG_PRI_ERROR, "%s: %m", s);
- return 1;
-}
-
-static int set_user(struct passwd *pw)
-{
- gid_t groups[2];
-
- if (!pw->pw_uid) return 1;
-
- groups[0] = groups[1] = pw->pw_gid;
- if (setgroups(1, groups))
- return log_error("setgroups");
- if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid))
- return log_error("setresgid");
- if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
- return log_error("setresuid");
-
- return 0;
-}
-
-static int drop_root(void)
-{
- tzset();
- openlog(SYSLOG_IDENT, SYSLOG_OPTIONS | LOG_NDELAY, SYSLOG_FACILITY);
-
- if (chroot(POP_CHROOT)) return log_error("chroot");
- if (chdir("/")) return log_error("chdir");
-
- return set_user(&pop_pw);
-}
-
-/*
- * Attempts to read until EOF, and returns the number of bytes read.
- * We don't expect any signals, so even EINTR is considered an error.
- */
-static int read_loop(int fd, char *buffer, int count)
-{
- int offset, block;
-
- offset = 0;
- while (count > 0) {
- block = read(fd, &buffer[offset], count);
-
- if (block < 0) return block;
- if (!block) return offset;
-
- offset += block;
- count -= block;
- }
-
- return offset;
-}
-
-/*
- * The root-privileged part of the AUTHORIZATION state handling: reads
- * the authentication data obtained over POP from its end of the pipe,
- * attempts authentication, and, if successful, drops privilege to the
- * authenticated user. Returns one of the AUTH_* result codes.
- */
-static int do_root_auth(int channel)
-{
- static char auth[AUTH_BUFFER_SIZE + 2];
- char *pass;
- struct passwd *pw;
-
- known = 0;
-#if POP_VIRTUAL
- virtual_domain = NULL;
-#endif
-
-/* The POP client could have sent extra commands without waiting for
- * successful authentication. We're passing them into the TRANSACTION
- * state if we ever get there. */
- if (read_loop(channel, (char *)&pop_buffer, sizeof(pop_buffer)) !=
- sizeof(pop_buffer)) return AUTH_NONE;
-
-/* Now, the authentication data. */
- memset(auth, 0, sizeof(auth)); /* Ensure NUL termination */
- if (read_loop(channel, auth, AUTH_BUFFER_SIZE) < 0) {
- memset(auth, 0, sizeof(auth));
- return AUTH_NONE;
- }
-
- user = auth;
- pass = &user[strlen(user) + 1];
-
- pw = NULL;
-#if POP_VIRTUAL
- if (!(pw = virtual_userpass(user, pass, &known)) && virtual_domain) {
- memset(pass, 0, strlen(pass));
- return AUTH_FAILED;
- }
-#endif
-#if VIRTUAL_ONLY
- if (!pw) {
- memset(pass, 0, strlen(pass));
- return AUTH_FAILED;
- }
-#else
- if (!pw && !(pw = auth_userpass(user, pass, &known))) {
- memset(pass, 0, strlen(pass));
- return AUTH_FAILED;
- }
-#endif
- if (!*pass) return AUTH_FAILED;
- memset(pass, 0, strlen(pass));
- if (!*user) return AUTH_FAILED;
-
-#if VIRTUAL_ONLY
- if (!virtual_domain) return AUTH_FAILED;
-#endif
-
- if (set_user(pw)) return AUTH_FAILED;
-
-#if POP_VIRTUAL
- if (virtual_domain) {
- spool = virtual_spool;
- mailbox = user;
-
- return AUTH_OK;
- }
-#endif
-
-#if VIRTUAL_ONLY
- /* never reached */
- return AUTH_FAILED;
-#else
-#ifdef MAIL_SPOOL_PATH
- spool = MAIL_SPOOL_PATH;
- mailbox = user;
-#else
- spool = pw->pw_dir;
- mailbox = HOME_MAILBOX_NAME;
-#endif
-
- return AUTH_OK;
-#endif
-}
-
-int do_pop_startup(void)
-{
- struct passwd *pw;
-
- umask(077);
- signal(SIGPIPE, SIG_IGN);
-
- openlog(SYSLOG_IDENT, SYSLOG_OPTIONS, SYSLOG_FACILITY);
-
- errno = 0;
- if (!(pw = getpwnam(POP_USER))) {
- syslog(SYSLOG_PRI_ERROR, "getpwnam(\"" POP_USER "\"): %s",
- errno ? strerror(errno) : "No such user");
- return 1;
- }
- memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
- endpwent();
- pop_pw.pw_uid = pw->pw_uid;
- pop_pw.pw_gid = pw->pw_gid;
-
-#if POP_VIRTUAL
- if (virtual_startup()) return 1;
-#endif
-
- return 0;
-}
-
-int do_pop_session(void)
-{
- int channel[2];
- int result, status;
-
-/* For SIGCHLD, default action is to ignore the signal. {SIGCHLD, SIG_IGN}
- * may be invalid (POSIX) or may enable a different behavior (SUSv2), none
- * of which are any good for us. */
- signal(SIGCHLD, SIG_DFL);
-
- if (pipe(channel)) return log_error("pipe");
-
- switch (fork()) {
- case -1:
- return log_error("fork");
-
- case 0:
- if (close(channel[0])) return log_error("close");
- if (drop_root()) return 1;
- return do_pop_auth(channel[1]);
- }
-
- if (close(channel[1]))
- result = AUTH_NONE;
- else
- result = do_root_auth(channel[0]);
-
- if (wait(&status) < 0)
- status = 1;
- else
- if (WIFEXITED(status))
- status = WEXITSTATUS(status);
- else
- status = 1;
-
- if (result == AUTH_OK) {
- if (close(channel[0])) return log_error("close");
- log_pop_auth(result, user);
- return do_pop_trans(spool, mailbox);
- }
-
- if (drop_root()) return 1;
- log_pop_auth(result, known ? user : NULL);
-
-#ifdef AUTH_FAILED_MESSAGE
- if (result == AUTH_FAILED) pop_reply("-ERR %s", AUTH_FAILED_MESSAGE);
-#else
- if (result == AUTH_FAILED) pop_reply_error();
-#endif
-
- return status;
-}
-
-#if !POP_STANDALONE && !POP_OPTIONS
-int main(void)
-{
- if (do_pop_startup()) return 1;
- return do_pop_session();
-}
-#endif
diff --git a/usr.sbin/popa3d/pop_trans.c b/usr.sbin/popa3d/pop_trans.c
deleted file mode 100644
index 2c2f97cb3bb..00000000000
--- a/usr.sbin/popa3d/pop_trans.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* $OpenBSD: pop_trans.c,v 1.6 2009/12/17 11:04:39 sobrado Exp $ */
-
-/*
- * TRANSACTION state handling.
- */
-
-#include <stdio.h>
-#include <syslog.h>
-
-#include "params.h"
-#include "protocol.h"
-#include "database.h"
-#include "mailbox.h"
-
-static int pop_trans_quit(char *params)
-{
- if (params) return POP_ERROR;
- return POP_STATE;
-}
-
-static int pop_trans_noop(char *params)
-{
- if (params) return POP_ERROR;
- return POP_OK;
-}
-
-static int pop_trans_stat(char *params)
-{
- if (params) return POP_ERROR;
- if (pop_reply("+OK %u %lu", db.visible_count, db.visible_size))
- return POP_CRASH_NETFAIL;
- return POP_QUIET;
-}
-
-static int pop_trans_list_or_uidl_all(int uidl)
-{
- unsigned int number;
- struct db_message *msg;
-
- if (pop_reply_ok()) return POP_CRASH_NETFAIL;
- for (number = 1; number <= db.total_count; number++) {
- msg = db.array[number - 1];
- if (msg->flags & MSG_DELETED) continue;
- if (uidl) {
- if (pop_reply("%u "
- "%02x%02x%02x%02x%02x%02x%02x%02x",
- number,
- msg->hash[3], msg->hash[2],
- msg->hash[1], msg->hash[0],
- msg->hash[7], msg->hash[6],
- msg->hash[5], msg->hash[4]))
- return POP_CRASH_NETFAIL;
- } else
- if (pop_reply("%u %lu", number, msg->size))
- return POP_CRASH_NETFAIL;
- }
- if (pop_reply_terminate()) return POP_CRASH_NETFAIL;
- return POP_QUIET;
-}
-
-static int pop_trans_list_or_uidl(char *params, int uidl)
-{
- int number;
- struct db_message *msg;
-
- if (!params)
- return pop_trans_list_or_uidl_all(uidl);
-
- number = pop_get_int(&params);
- if (number < 1 || number > db.total_count || params)
- return POP_ERROR;
- msg = db.array[number - 1];
- if (msg->flags & MSG_DELETED) return POP_ERROR;
- if (uidl) {
- if (pop_reply("+OK %d "
- "%02x%02x%02x%02x%02x%02x%02x%02x",
- number,
- msg->hash[3], msg->hash[2],
- msg->hash[1], msg->hash[0],
- msg->hash[7], msg->hash[6],
- msg->hash[5], msg->hash[4]))
- return POP_CRASH_NETFAIL;
- } else
- if (pop_reply("+OK %d %lu", number, msg->size))
- return POP_CRASH_NETFAIL;
- return POP_QUIET;
-}
-
-static int pop_trans_list(char *params)
-{
- return pop_trans_list_or_uidl(params, 0);
-}
-
-static int pop_trans_uidl(char *params)
-{
- return pop_trans_list_or_uidl(params, 1);
-}
-
-static int pop_trans_retr(char *params)
-{
- int number;
- struct db_message *msg;
- int event;
-
- number = pop_get_int(&params);
- if (number < 1 || number > db.total_count || params) return POP_ERROR;
- msg = db.array[number - 1];
- if (msg->flags & MSG_DELETED) return POP_ERROR;
- if ((event = mailbox_get(msg, -1)) != POP_OK) return event;
-#if POP_SUPPORT_LAST
- if (number > db.last) db.last = number;
-#endif
- return POP_QUIET;
-}
-
-static int pop_trans_top(char *params)
-{
- int number, lines;
- struct db_message *msg;
- int event;
-
- number = pop_get_int(&params);
- if (number < 1 || number > db.total_count) return POP_ERROR;
- lines = pop_get_int(&params);
- if (lines < 0 || params) return POP_ERROR;
- msg = db.array[number - 1];
- if (msg->flags & MSG_DELETED) return POP_ERROR;
- if ((event = mailbox_get(msg, lines)) != POP_OK) return event;
- return POP_QUIET;
-}
-
-static int pop_trans_dele(char *params)
-{
- int number;
- struct db_message *msg;
-
- number = pop_get_int(&params);
- if (number < 1 || number > db.total_count || params) return POP_ERROR;
- msg = db.array[number - 1];
- if (db_delete(msg)) return POP_ERROR;
-#if POP_SUPPORT_LAST
- if (number > db.last) db.last = number;
-#endif
- return POP_OK;
-}
-
-static int pop_trans_rset(char *params)
-{
- struct db_message *msg;
-
- if (params) return POP_ERROR;
-
- if ((msg = db.head))
- do {
- msg->flags &= ~MSG_DELETED;
- } while ((msg = msg->next));
-
- db.visible_count = db.total_count;
- db.visible_size = db.total_size;
- db.flags &= ~DB_DIRTY;
-#if POP_SUPPORT_LAST
- db.last = 0;
-#endif
-
- return POP_OK;
-}
-
-#if POP_SUPPORT_LAST
-static int pop_trans_last(char *params)
-{
- if (params) return POP_ERROR;
- if (pop_reply("+OK %u", db.last)) return POP_CRASH_NETFAIL;
- return POP_QUIET;
-}
-#endif
-
-static struct pop_command pop_trans_commands[] = {
- {"QUIT", pop_trans_quit},
- {"NOOP", pop_trans_noop},
- {"STAT", pop_trans_stat},
- {"LIST", pop_trans_list},
- {"UIDL", pop_trans_uidl},
- {"RETR", pop_trans_retr},
- {"TOP", pop_trans_top},
- {"DELE", pop_trans_dele},
- {"RSET", pop_trans_rset},
-#if POP_SUPPORT_LAST
- {"LAST", pop_trans_last},
-#endif
- {NULL, NULL}
-};
-
-static int db_load(char *spool, char *mailbox)
-{
- db_init();
-
- if (mailbox_open(spool, mailbox)) return 1;
-
- if (db_fix()) {
- mailbox_close();
- return 1;
- }
-
- return 0;
-}
-
-int do_pop_trans(char *spool, char *mailbox)
-{
- int event;
-
- if (!pop_sane()) return 1;
-
- if (db_load(spool, mailbox)) {
- syslog(SYSLOG_PRI_HI,
- "Failure reading %s/%s or mailbox limits exceeded",
- spool, mailbox);
- pop_reply_error();
- return 0;
- }
-
- syslog(SYSLOG_PRI_LO, "%u message%s (%lu byte%s) loaded",
- db.total_count, db.total_count == 1 ? "" : "s",
- db.total_size, db.total_size == 1 ? "" : "s");
-
- if (pop_reply_ok())
- event = POP_CRASH_NETFAIL;
- else
- switch ((event = pop_handle_state(pop_trans_commands))) {
- case POP_STATE:
- if (mailbox_update()) {
- if (db.flags & DB_STALE) break;
- syslog(SYSLOG_PRI_ERROR,
- "Failed to update %s/%s",
- spool, mailbox);
- pop_reply_error();
- break;
- }
-
- syslog(SYSLOG_PRI_LO, "%u (%lu) deleted, %u (%lu) left",
- db.total_count - db.visible_count,
- db.total_size - db.visible_size,
- db.visible_count,
- db.visible_size);
- pop_reply_ok();
- break;
-
- case POP_CRASH_NETFAIL:
- syslog(SYSLOG_PRI_LO, "Premature disconnect");
- break;
-
- case POP_CRASH_NETTIME:
- syslog(SYSLOG_PRI_LO, "Connection timed out");
- }
-
- if (db.flags & DB_STALE)
- syslog(SYSLOG_PRI_LO, "Another MUA active, giving up");
- else
- if (event == POP_CRASH_SERVER)
- syslog(SYSLOG_PRI_ERROR,
- "Server failure accessing %s/%s",
- spool, mailbox);
-
- mailbox_close();
-
- return 0;
-}
diff --git a/usr.sbin/popa3d/pop_trans.h b/usr.sbin/popa3d/pop_trans.h
deleted file mode 100644
index 0e0edd91cf9..00000000000
--- a/usr.sbin/popa3d/pop_trans.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* $OpenBSD: pop_trans.h,v 1.1 2001/08/19 13:05:57 deraadt Exp $ */
-
-/*
- * TRANSACTION state handling.
- */
-
-#ifndef _POP_TRANS_H
-#define _POP_TRANS_H
-
-extern int do_pop_trans(char *spool, char *mailbox);
-
-#endif
diff --git a/usr.sbin/popa3d/popa3d.8 b/usr.sbin/popa3d/popa3d.8
deleted file mode 100644
index 9474c904cd1..00000000000
--- a/usr.sbin/popa3d/popa3d.8
+++ /dev/null
@@ -1,187 +0,0 @@
-.\" $OpenBSD: popa3d.8,v 1.19 2013/08/14 06:32:36 jmc Exp $
-.\"
-.\" Copyright (c) 2001-2003 Camiel Dobbelaar (cd@sentia.nl)
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd $Mdocdate: August 14 2013 $
-.Dt POPA3D 8
-.Os
-.Sh NAME
-.Nm popa3d
-.Nd Post Office Protocol (POP3) server
-.Sh SYNOPSIS
-.Nm
-.Op Fl 46DV
-.Sh DESCRIPTION
-.Nm
-is a POP3 server.
-It offers network access to user mailboxes through the POP3 protocol.
-The server uses the
-.Tn TCP
-protocol
-and listens at the port specified in the
-.Dq pop3
-service specification; see
-.Xr services 5 .
-.Pp
-A POP3 server operates on local mailboxes on behalf of its remote
-users.
-Users can connect at any time to check their mailbox and fetch the
-mail that has accumulated.
-The advantage of this ``pull'' approach is that any user with a simple
-POP3-capable mail reader program can receive mail, eschewing the need
-for a full-fledged Mail Transfer Agent (MTA) and a permanent network
-connection.
-.Pp
-Note that POP3 can only be used to retrieve mail, not to send it.
-To send mail, the SMTP protocol is commonly used; see
-.Xr sendmail 8 .
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl 4
-In standalone mode
-.Pq Fl D ,
-listen to IPv4 only.
-.It Fl 6
-In standalone mode
-.Pq Fl D ,
-listen to IPv6 only.
-.It Fl D
-With this option set,
-.Nm
-will detach and become a daemon, accepting connections on the pop3
-port and forking child processes to handle them.
-This has lower overhead than starting
-.Nm
-from
-.Xr inetd 8
-and is thus useful on busy servers to reduce load.
-.Pp
-In this mode
-.Nm
-also does quite a few checks to significantly reduce the impact of
-connection flood attacks.
-.It Fl V
-Show version information and exit.
-.El
-.Pp
-Alternatively,
-.Nm
-can be used through
-.Xr inetd 8 .
-This requires the following entry to be activated in
-.Pa /etc/inetd.conf :
-.Pp
-.Dl pop3 stream tcp nowait root /usr/sbin/popa3d popa3d
-.Pp
-or, using
-.Xr tcpd 8
-for TCP-wrappers access control:
-.Pp
-.Dl pop3 stream tcp nowait root /usr/libexec/tcpd /usr/sbin/popa3d
-.Pp
-For access to a mailbox through the POP3 service, the username must
-be in the password database.
-Additionally,
-.Nm
-does not permit null passwords and will refuse to serve mail for
-root (uid 0) users.
-.Sh COMMANDS
-A normal POP3 session progresses through three states: authorization,
-transaction and update.
-.Pp
-After the TCP connection opens, the client must authenticate itself
-to the server in the authorization state.
-The following commands are supported in the authorization state.
-All commands are case-insensitive.
-.Bl -column "PASS string" "Description""Description" -offset indent
-.It Sy Command Ta Sy Description
-.It USER name Ta "authenticate as user ``name''"
-.It PASS string Ta "authenticate using password ``string''"
-.It QUIT Ta "quit; do not enter update state"
-.El
-.Pp
-When authorization is successful, the server enters the transaction
-state.
-The client can now list and retrieve messages or mark messages for
-deletion.
-The following commands are supported in the transaction state.
-.Bl -column "LIST [msg]" "Description" -offset indent
-.It Sy Command Ta Sy Description
-.It DELE msg Ta "mark message for deletion"
-.It LAST Ta "show highest message number accessed (obsolete)"
-.It LIST [msg] Ta "list message number and size"
-.It NOOP Ta "do nothing"
-.It QUIT Ta "quit; enter update state"
-.It RETR msg Ta "retrieve message"
-.It RSET Ta "clear deletion marks"
-.It STAT Ta "return total number of messages and total size"
-.It TOP msg n Ta "show top n lines of message body"
-.It UIDL [msg] Ta "list message number and digest"
-.El
-.Pp
-When the client issues the QUIT command in the transaction state,
-the server enters the update state.
-All messages that were marked for deletion are now removed.
-The server then closes the connection.
-.Sh FILES
-.Bl -tag -width "/var/mailXX"
-.It Pa /var/mail
-User mail spools
-.It Pa /etc/hosts.allow, /etc/hosts.deny
-TCP-wrappers access controls may be defined here as described in
-.Xr hosts_access 5 .
-Valid if
-.Nm
-is started in daemon-mode, or if
-.Nm
-is running through
-.Xr inetd 8
-and is used in combination with
-.Xr tcpd 8 .
-.El
-.Sh SEE ALSO
-.Xr hosts_access 5 ,
-.Xr inetd 8 ,
-.Xr sendmail 8 ,
-.Xr tcpd 8
-.Pp
-.Lk http://www.openwall.com/popa3d/
-.Sh STANDARDS
-.Rs
-.%A J. Myers
-.%A M. Rose
-.%D May 1996
-.%R RFC 1939
-.%T Post Office Protocol \(en Version 3
-.Re
-.Sh HISTORY
-.Nm
-first appeared in
-.Ox 3.0 .
-.Sh AUTHORS
-.An Solar Designer Aq Mt solar@openwall.com
-.Sh CAVEATS
-POP3 authenticates using cleartext passwords.
diff --git a/usr.sbin/popa3d/protocol.c b/usr.sbin/popa3d/protocol.c
deleted file mode 100644
index 0ae47dd4b82..00000000000
--- a/usr.sbin/popa3d/protocol.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* $OpenBSD: protocol.c,v 1.4 2005/04/13 02:33:09 deraadt Exp $ */
-
-/*
- * POP protocol handling.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#include "misc.h"
-#include "params.h"
-#include "protocol.h"
-
-struct pop_buffer pop_buffer;
-static sigjmp_buf pop_timed_out;
-
-void pop_init(void)
-{
- pop_buffer.ptr = pop_buffer.size = 0;
-}
-
-void pop_clean(void)
-{
- memset(pop_buffer.data, 0, pop_buffer.ptr);
- memmove(pop_buffer.data, &pop_buffer.data[pop_buffer.ptr],
- pop_buffer.size -= pop_buffer.ptr);
- pop_buffer.ptr = 0;
-}
-
-int pop_sane(void)
-{
- return pop_buffer.size <= sizeof(pop_buffer.data) &&
- pop_buffer.ptr <= pop_buffer.size;
-}
-
-static void pop_timeout(int signum)
-{
- signal(SIGALRM, SIG_DFL);
- siglongjmp(pop_timed_out, 1);
-}
-
-static void pop_fetch(void)
-{
- int size;
-
- signal(SIGALRM, pop_timeout);
- alarm(POP_TIMEOUT);
-
- size = read(STDIN_FILENO, pop_buffer.data, sizeof(pop_buffer.data));
-
- alarm(0);
- signal(SIGALRM, SIG_DFL);
-
- pop_buffer.ptr = 0;
- pop_buffer.size = (size >= 0) ? size : 0;
-}
-
-static int pop_get_char(void)
-{
- if (pop_buffer.ptr >= pop_buffer.size) {
- pop_fetch();
- if (!pop_buffer.size) return -1;
- }
-
- return (unsigned char)pop_buffer.data[pop_buffer.ptr++];
-}
-
-static char *pop_get_line(char *line, int size)
-{
- int pos;
- int seen_cr, seen_nul;
- int c;
-
- pos = 0;
- seen_cr = seen_nul = 0;
- while ((c = pop_get_char()) >= 0) {
- if (c == '\n') {
- if (seen_cr) line[pos - 1] = 0;
- break;
- }
- if (pos < size - 1)
- seen_cr = ((line[pos++] = c) == '\r');
- else
- seen_cr = 0;
- seen_nul |= !c;
- }
- line[pos] = 0;
-
- if (seen_nul)
- line[0] = 0;
-
- if (pos || c >= 0)
- return line;
- else
- return NULL;
-}
-
-int pop_handle_state(struct pop_command *commands)
-{
- char line[POP_BUFFER_SIZE];
- char *params;
- struct pop_command *command;
- int response;
-
- if (sigsetjmp(pop_timed_out, 1)) return POP_CRASH_NETTIME;
-
- while (pop_get_line(line, sizeof(line))) {
- if ((params = strchr(line, ' '))) {
- *params++ = 0;
- if (!*params) params = NULL;
- }
-
- response = POP_ERROR;
- for (command = commands; command->name; command++)
- if (!strcasecmp(command->name, line)) {
- response = command->handler(params);
- break;
- }
-
- switch (response) {
- case POP_OK:
- if (pop_reply_ok()) return POP_CRASH_NETFAIL;
- break;
-
- case POP_ERROR:
- if (pop_reply_error()) return POP_CRASH_NETFAIL;
-
- case POP_QUIET:
- break;
-
- case POP_LEAVE:
- if (pop_reply_ok()) return POP_CRASH_NETFAIL;
-
- default:
- return response;
- }
- }
-
- return POP_CRASH_NETFAIL;
-}
-
-char *pop_get_param(char **params)
-{
- char *current, *next;
-
- if ((current = *params)) {
- if ((next = strchr(current, ' '))) {
- *next++ = 0;
- *params = *next ? next : NULL;
- } else
- *params = NULL;
-
- if (strlen(current) > 40) current = NULL;
- }
-
- return current;
-}
-
-int pop_get_int(char **params)
-{
- char *param, *error;
- long value;
-
- if ((param = pop_get_param(params))) {
-/* SUSv2 says:
- * "Because 0, LONG_MIN and LONG_MAX are returned on error and are also
- * valid returns on success, an application wishing to check for error
- * situations should set errno to 0, then call strtol(), then check errno." */
- errno = 0;
- value = strtol(param, &error, 10);
- if (errno || !*param || *error ||
- value < 0 || (long)(int)value != value)
- return -1;
-
- return (int)value;
- }
-
- return -1;
-}
-
-int pop_reply(char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vfprintf(stdout, format, args);
- va_end(args);
-
- putc('\r', stdout);
- putc('\n', stdout);
-
- switch (format[0]) {
- case '+':
- case '-':
- return fflush(stdout);
-
- case '.':
- if (!format[1]) return fflush(stdout);
- }
-
- return ferror(stdout);
-}
-
-int pop_reply_ok(void)
-{
- return pop_reply("+OK");
-}
-
-int pop_reply_error(void)
-{
- return pop_reply("-ERR");
-}
-
-int pop_reply_multiline(int fd, unsigned long size, int lines)
-{
- char *in_buffer, *out_buffer;
- char *in, *out;
- int in_block, out_block;
- int start, body;
-
- if (lines >= 0) lines++;
-
- if (pop_reply_ok()) return POP_CRASH_NETFAIL;
-
- in_buffer = malloc(RETR_BUFFER_SIZE * 3);
- if (!in_buffer) return POP_CRASH_SERVER;
- out_buffer = &in_buffer[RETR_BUFFER_SIZE];
-
- start = 1;
- body = 0;
- while (size && lines) {
- if (size > RETR_BUFFER_SIZE)
- in_block = read(fd, in_buffer, RETR_BUFFER_SIZE);
- else
- in_block = read(fd, in_buffer, size);
- if (in_block <= 0) {
- free(in_buffer);
- return POP_CRASH_SERVER;
- }
-
- in = in_buffer;
- out = out_buffer;
- while (in < &in_buffer[in_block] && lines)
- switch (*in) {
- case '\n':
- *out++ = '\r';
- *out++ = *in++;
- if (start) body = 1;
- if (body) lines--;
- start = 1;
- break;
-
- case '.':
- if (start) *out++ = '.';
-
- default:
- *out++ = *in++;
- start = 0;
- }
-
- out_block = out - out_buffer;
- if (write_loop(1, out_buffer, out_block) != out_block) {
- free(in_buffer);
- return POP_CRASH_NETFAIL;
- }
-
- size -= in_block;
- }
-
- free(in_buffer);
-
- if (!start)
- if (pop_reply("%s", "")) return POP_CRASH_NETFAIL;
-
- return POP_OK;
-}
-
-int pop_reply_terminate(void)
-{
- return pop_reply(".");
-}
diff --git a/usr.sbin/popa3d/protocol.h b/usr.sbin/popa3d/protocol.h
deleted file mode 100644
index e5bd394f9be..00000000000
--- a/usr.sbin/popa3d/protocol.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* $OpenBSD: protocol.h,v 1.3 2003/05/12 19:28:22 camield Exp $ */
-
-/*
- * POP protocol handling.
- */
-
-#ifndef _POP_PROTOCOL_H
-#define _POP_PROTOCOL_H
-
-/*
- * Responses and events, to be returned by command and state handlers.
- */
-#define POP_OK 0 /* Reply with "+OK" */
-#define POP_ERROR 1 /* Reply with "-ERR" */
-#define POP_QUIET 2 /* We've already replied */
-#define POP_LEAVE 3 /* Leave the session */
-#define POP_STATE 4 /* Advance the state */
-#define POP_CRASH_NETFAIL 5 /* Network failure */
-#define POP_CRASH_NETTIME 6 /* Network timeout */
-#define POP_CRASH_SERVER 7 /* POP server failure */
-
-/*
- * POP command description.
- */
-struct pop_command {
- char *name;
- int (*handler)(char *params);
-};
-
-/*
- * Internal POP command buffer.
- */
-struct pop_buffer {
- unsigned int ptr, size;
- char data[POP_BUFFER_SIZE];
-};
-
-extern struct pop_buffer pop_buffer;
-
-/*
- * Initializes the buffer.
- */
-extern void pop_init(void);
-
-/*
- * Zeroes out the part of the buffer that has already been processed.
- */
-extern void pop_clean(void);
-
-/*
- * Checks if the buffer is sane.
- */
-extern int pop_sane(void);
-
-/*
- * Handles a POP protocol state (AUTHORIZATION or TRANSACTION, as defined
- * in RFC 1939), processing the supplied commands. Returns when the state
- * is changed.
- */
-extern int pop_handle_state(struct pop_command *commands);
-
-/*
- * Returns the next parameter, or NULL if there's none or it is too long
- * to be valid (as defined in the RFC).
- */
-extern char *pop_get_param(char **params);
-
-/*
- * Returns the next parameter as a non-negative number, or -1 if there's
- * none or the syntax is invalid.
- */
-extern int pop_get_int(char **params);
-
-/*
- * Produces a generic POP response. Returns a non-zero value on error;
- * the POP session then has to crash.
- */
-extern int pop_reply(char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format (printf, 1, 2)));
-#else
- ;
-#endif
-
-/*
- * The two simple POP responses. Return a non-zero value on error; the
- * POP session then has to crash.
- */
-extern int pop_reply_ok(void);
-extern int pop_reply_error(void);
-
-/*
- * Produces a multi-line POP response, reading the data from the supplied
- * file descriptor for up to the requested size or number of lines of the
- * message body, if that number is non-negative. Returns POP_OK or one of
- * the POP_CRASH_* event codes.
- */
-extern int pop_reply_multiline(int fd, unsigned long size, int lines);
-
-/*
- * Terminates a multi-line POP response. Returns a non-zero value on error;
- * the POP session then has to crash.
- */
-extern int pop_reply_terminate(void);
-
-#endif
diff --git a/usr.sbin/popa3d/standalone.c b/usr.sbin/popa3d/standalone.c
deleted file mode 100644
index b3be2844793..00000000000
--- a/usr.sbin/popa3d/standalone.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* $OpenBSD: standalone.c,v 1.14 2009/11/12 11:03:37 jsg Exp $ */
-
-/*
- * Standalone POP server: accepts connections, checks the anti-flood limits,
- * logs and starts the actual POP sessions.
- */
-
-#include "params.h"
-
-#if POP_STANDALONE
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <syslog.h>
-#include <time.h>
-#include <errno.h>
-#include <netdb.h>
-#include <poll.h>
-#include <sys/times.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#if DAEMON_LIBWRAP
-#include <tcpd.h>
-int allow_severity = SYSLOG_PRI_LO;
-int deny_severity = SYSLOG_PRI_HI;
-#endif
-
-/*
- * These are defined in pop_root.c.
- */
-extern int log_error(char *s);
-extern int do_pop_startup(void);
-extern int do_pop_session(void);
-extern int af;
-
-typedef volatile sig_atomic_t va_int;
-
-/*
- * Active POP sessions. Those that were started within the last MIN_DELAY
- * seconds are also considered active (regardless of their actual state),
- * to allow for limiting the logging rate without throwing away critical
- * information about sessions that we could have allowed to proceed.
- */
-static struct {
- char addr[NI_MAXHOST]; /* Source IP address */
- va_int pid; /* PID of the server, or 0 for none */
- clock_t start; /* When the server was started */
- clock_t log; /* When we've last logged a failure */
-} sessions[MAX_SESSIONS];
-
-static va_int child_blocked; /* We use blocking to avoid races */
-static va_int child_pending; /* Are any dead children waiting? */
-
-int handle(int);
-
-/*
- * SIGCHLD handler.
- */
-static void handle_child(int signum)
-{
- int saved_errno;
- pid_t pid;
- int i;
-
- saved_errno = errno;
-
- if (child_blocked)
- child_pending = 1;
- else {
- child_pending = 0;
-
- while ((pid = waitpid(0, NULL, WNOHANG)) > 0)
- for (i = 0; i < MAX_SESSIONS; i++)
- if (sessions[i].pid == pid) {
- sessions[i].pid = 0;
- break;
- }
- }
-
- signal(SIGCHLD, handle_child);
-
- errno = saved_errno;
-}
-
-#if DAEMON_LIBWRAP
-static void check_access(int sock)
-{
- struct request_info request;
-
- request_init(&request,
- RQ_DAEMON, DAEMON_LIBWRAP_IDENT,
- RQ_FILE, sock,
- 0);
- fromhost(&request);
-
- if (!hosts_access(&request)) {
-/* refuse() shouldn't return... */
- refuse(&request);
-/* ...but just in case */
- exit(1);
- }
-}
-#endif
-
-#if POP_OPTIONS
-int do_standalone(void)
-#else
-int main(void)
-#endif
-{
- int error, i, n, true = 1;
- struct pollfd *pfds;
- struct addrinfo hints, *res, *res0;
- char sbuf[NI_MAXSERV];
-
- if (do_pop_startup()) return 1;
-
- snprintf(sbuf, sizeof(sbuf), "%u", DAEMON_PORT);
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = af;
- hints.ai_flags = AI_PASSIVE;
- error = getaddrinfo(NULL, sbuf, &hints, &res0);
- if (error)
- return log_error("getaddrinfo");
-
- i = 0;
- for (res = res0; res; res = res->ai_next)
- i++;
-
- pfds = calloc(i, sizeof(pfds[0]));
- if (!pfds) {
- freeaddrinfo(res0);
- return log_error("malloc");
- }
-
- i = 0;
- for (res = res0; res; res = res->ai_next) {
- if ((pfds[i].fd = socket(res->ai_family, res->ai_socktype,
- res->ai_protocol)) < 0)
- continue;
-
- if (setsockopt(pfds[i].fd, SOL_SOCKET, SO_REUSEADDR,
- (void *)&true, sizeof(true))) {
- close(pfds[i].fd);
- continue;
- }
-
-#ifdef IPV6_V6ONLY
- if (res->ai_family == AF_INET6)
- (void)setsockopt(pfds[i].fd, IPPROTO_IPV6, IPV6_V6ONLY,
- (void *)&true, sizeof(true));
-#endif
-
- if (bind(pfds[i].fd, res->ai_addr, res->ai_addrlen)) {
- close(pfds[i].fd);
- continue;
- }
-
- if (listen(pfds[i].fd, MAX_BACKLOG)) {
- close(pfds[i].fd);
- continue;
- }
-
- pfds[i].events = POLLIN;
- i++;
- }
- freeaddrinfo(res0);
-
- if (i == 0) {
- free(pfds);
- return log_error("socket");
- }
-
- n = i;
-
- chdir("/");
- setsid();
-
- switch (fork()) {
- case -1:
- free(pfds);
- return log_error("fork");
-
- case 0:
- break;
-
- default:
- free(pfds);
- return 0;
- }
-
- setsid();
-
- child_blocked = 1;
- child_pending = 0;
- signal(SIGCHLD, handle_child);
-
- memset((void *)sessions, 0, sizeof(sessions));
-
- while (1) {
- child_blocked = 0;
- if (child_pending) raise(SIGCHLD);
-
- i = poll(pfds, n, INFTIM);
- if (i < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- free(pfds);
- return log_error("poll");
- }
-
- for (i = 0; i < n; i++)
- if (pfds[i].revents & POLLIN)
- handle(pfds[i].fd);
- }
-}
-
-int
-handle(int sock)
-{
- clock_t now, log;
- int new;
- char hbuf[NI_MAXHOST];
- struct sockaddr_storage addr;
- socklen_t addrlen;
- pid_t pid;
- struct tms buf;
- int error;
- int j, n, i, s;
-
- log = 0;
- new = 0;
-
- addrlen = sizeof(addr);
- new = accept(sock, (struct sockaddr *)&addr, &addrlen);
-/*
- * I wish there was a portable way to classify errno's... In this case,
- * it appears to be better to risk eating up the CPU on a fatal error
- * rather than risk terminating the entire service because of a minor
- * temporary error having to do with one particular connection attempt.
- */
- if (new < 0)
- return -1;
-
- error = getnameinfo((struct sockaddr *)&addr, addrlen,
- hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
- if (error) {
- syslog(SYSLOG_PRI_HI,
- "could not get host address");
- close(new);
- return -1;
- }
-
- now = times(&buf);
- if (!now)
- now = 1;
-
- child_blocked = 1;
-
- j = -1;
- n = 0;
- s = 0;
- for (i = 0; i < MAX_SESSIONS; i++) {
- s = i;
- if (sessions[i].start > now)
- sessions[i].start = 0;
- if (sessions[i].pid ||
- (sessions[i].start &&
- now - sessions[i].start < MIN_DELAY * CLK_TCK)) {
- if (strcmp(sessions[i].addr, hbuf) == 0)
- if (++n >= MAX_SESSIONS_PER_SOURCE)
- break;
- } else if (j < 0)
- j = i;
- }
-
- if (n >= MAX_SESSIONS_PER_SOURCE) {
- if (!sessions[s].log ||
- now < sessions[s].log ||
- now - sessions[s].log >= MIN_DELAY * CLK_TCK) {
- syslog(SYSLOG_PRI_HI,
- "%s: per source limit reached",
- hbuf);
- sessions[s].log = now;
- }
- close(new);
- return -1;
- }
-
- if (j < 0) {
- if (!log ||
- now < log || now - log >= MIN_DELAY * CLK_TCK) {
- syslog(SYSLOG_PRI_HI,
- "%s: sessions limit reached", hbuf);
- log = now;
- }
- close(new);
- return -1;
- }
-
- switch ((pid = fork())) {
- case -1:
- syslog(SYSLOG_PRI_ERROR, "%s: fork: %m", hbuf);
- close(new);
- return -1;
-
- case 0:
-#if DAEMON_LIBWRAP
- check_access(new);
-#endif
- syslog(SYSLOG_PRI_LO, "Session from %s",
- hbuf);
- if (dup2(new, 0) < 0 || dup2(new, 1) < 0 || dup2(new, 2) < 0) {
- log_error("dup2");
- _exit(1);
- }
- closefrom(3);
- _exit(do_pop_session());
-
- default:
- close(new);
- strlcpy(sessions[j].addr, hbuf,
- sizeof(sessions[j].addr));
- sessions[j].pid = (va_int)pid;
- sessions[j].start = now;
- sessions[j].log = 0;
- return 0;
- }
-}
-
-#endif
diff --git a/usr.sbin/popa3d/startup.c b/usr.sbin/popa3d/startup.c
deleted file mode 100644
index 0e41d5d6499..00000000000
--- a/usr.sbin/popa3d/startup.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $OpenBSD: startup.c,v 1.7 2008/05/17 23:31:52 sobrado Exp $ */
-
-/*
- * Command line option parsing.
- */
-
-#include "params.h"
-
-#if POP_OPTIONS
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* version.c */
-extern char popa3d_version[];
-extern char popa3d_date[];
-
-/* standalone.c */
-extern int do_standalone(void);
-
-/* pop_root.c */
-extern int do_pop_startup(void);
-extern int do_pop_session(void);
-
-#ifdef HAVE_PROGNAME
-extern char *__progname;
-#define progname __progname
-#else
-static char *progname;
-#endif
-
-int af = PF_UNSPEC;
-
-static void usage(void)
-{
- fprintf(stderr, "usage: %s [-46DV]\n", progname);
- exit(1);
-}
-
-static void version(void)
-{
- printf("popa3d version %s (%.10s)\n", popa3d_version, popa3d_date + 7);
- exit(0);
-}
-
-int main(int argc, char **argv)
-{
- int c;
- int standalone = 0;
-
-#ifndef HAVE_PROGNAME
- if (!(progname = argv[0]))
- progname = POP_SERVER;
-#endif
-
- while ((c = getopt(argc, argv, "46DV")) != -1) {
- switch (c) {
- case '4':
- af = AF_INET;
- break;
-
- case '6':
- af = AF_INET6;
- break;
-
- case 'D':
- standalone++;
- break;
-
- case 'V':
- version();
-
- default:
- usage();
- }
- }
-
- if (optind != argc)
- usage();
-
- if (standalone)
- return do_standalone();
-
- if (do_pop_startup()) return 1;
- return do_pop_session();
-}
-
-#endif
diff --git a/usr.sbin/popa3d/version.c b/usr.sbin/popa3d/version.c
deleted file mode 100644
index 31adeea49ab..00000000000
--- a/usr.sbin/popa3d/version.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* $OpenBSD: version.c,v 1.1 2003/05/12 19:28:22 camield Exp $ */
-
-/*
- * popa3d version information.
- */
-
-char popa3d_version[] = "0.6.2";
-char popa3d_date[] = "$Date: 2003/05/12 19:28:22 $";
-char popa3d_id[] = "@(#) $Id: version.c,v 1.1 2003/05/12 19:28:22 camield Exp $";
diff --git a/usr.sbin/popa3d/virtual.c b/usr.sbin/popa3d/virtual.c
deleted file mode 100644
index 1153fd474bd..00000000000
--- a/usr.sbin/popa3d/virtual.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* $OpenBSD: virtual.c,v 1.6 2004/06/20 05:18:07 itojun Exp $ */
-
-/*
- * Virtual domain support.
- */
-
-#include "params.h"
-
-#if POP_VIRTUAL
-
-#define _XOPEN_SOURCE 4
-#define _XOPEN_SOURCE_EXTENDED
-#define _XOPEN_VERSION 4
-#define _XPG4_2
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <pwd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#ifndef NAME_MAX
-#define NAME_MAX 255
-#endif
-
-extern int log_error(char *s);
-
-char *virtual_domain;
-char *virtual_spool;
-
-int virtual_startup(void)
-{
- return 0;
-}
-
-static char *lookup(void)
-{
- struct sockaddr_storage ss;
- int length;
- int error;
- static char hbuf[NI_MAXHOST];
-
- length = sizeof(ss);
- if (getsockname(0, (struct sockaddr *)&ss, &length)) {
- if (errno == ENOTSOCK) return "";
- log_error("getsockname");
- return NULL;
- }
-
- error = getnameinfo((struct sockaddr *)&ss, length, hbuf, sizeof(hbuf),
- NULL, 0, NI_NUMERICHOST);
- if (error) {
- /* logging? */
- return NULL;
- }
-
- return hbuf;
-}
-
-static int is_valid_user(char *user)
-{
- unsigned char *p;
-
-/* This is pretty liberal, but we're going to use direct syscalls only,
- * and they have to accept all the printable characters */
- for (p = (unsigned char *)user; *p; p++)
- if (*p < ' ' || *p > 0x7E || *p == '.' || *p == '/') return 0;
-
- if (p - (unsigned char *)user > NAME_MAX) return 0;
-
- return 1;
-}
-
-struct passwd *virtual_userpass(char *user, char *pass, int *known)
-{
- struct passwd *pw, *result;
- struct stat stat;
- char auth[VIRTUAL_AUTH_SIZE];
- char *address, *pathname;
- char *template, *passwd;
- int fail;
- int fd, size;
-
- *known = 0;
-
-/* Make sure we don't try to authenticate globally if something fails
- * before we find out whether the virtual domain is known to us */
- virtual_domain = "UNKNOWN";
- virtual_spool = NULL;
-
- if (!(address = lookup())) return NULL;
-
-/* Authenticate globally (if supported) if run on a non-socket */
- if (!*address) {
- virtual_domain = NULL;
- return NULL;
- }
-
- fail = 0;
- if (!is_valid_user(user)) {
- user = "INVALID";
- fail = 1;
- }
-
-/* This "can't happen", but is just too critical to not check explicitly */
- if (strchr(address, '/') || strchr(user, '/'))
- return NULL;
-
- if (asprintf(&pathname, "%s/%s", VIRTUAL_HOME_PATH, address) == -1)
- return NULL;
-
- if (lstat(pathname, &stat)) {
- if (errno == ENOENT)
- virtual_domain = NULL;
- else
- log_error("lstat");
- free(pathname);
- return NULL;
- }
-
- if (!(address = strdup(address))) {
- free(pathname);
- return NULL;
- }
- virtual_domain = address;
-
- free(pathname);
-
- if (asprintf(&pathname, "%s/%s/%s/%s", VIRTUAL_HOME_PATH, address,
- VIRTUAL_AUTH_PATH, user) == -1)
- return NULL;
-
- if ((fd = open(pathname, O_RDONLY)) < 0 && errno != ENOENT) {
- log_error("open");
- fail = 1;
- }
-
- free(pathname);
-
- if (asprintf(&virtual_spool, "%s/%s/%s", VIRTUAL_HOME_PATH,
- virtual_domain, VIRTUAL_SPOOL_PATH) == -1) {
- close(fd);
- return NULL;
- }
-
- size = 0;
- if (fd >= 0) {
- *known = !fail;
-
- if ((size = read(fd, auth, sizeof(auth))) < 0) {
- log_error("read");
- size = 0;
- fail = 1;
- }
-
- close(fd);
- }
-
- if (size >= sizeof(auth)) {
- size = 0;
- fail = 1;
- }
-
- auth[size] = 0;
-
- if (!(template = strtok(auth, ":")) || !*template) {
- template = "INVALID";
- fail = 1;
- }
- if (!(passwd = strtok(NULL, ":")) || !*passwd ||
- *passwd == '*' || *passwd == '!') {
- passwd = AUTH_DUMMY_SALT;
- fail = 1;
- }
- if (!strtok(NULL, ":")) fail = 1;
-
- if ((pw = getpwnam(template)))
- memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
- endpwent();
-
- result = NULL;
- if (!strcmp(crypt(pass, passwd), passwd) && !fail)
- result = pw;
-
- memset(auth, 0, sizeof(auth));
-
- return result;
-}
-
-#endif
diff --git a/usr.sbin/popa3d/virtual.h b/usr.sbin/popa3d/virtual.h
deleted file mode 100644
index 307c21a05df..00000000000
--- a/usr.sbin/popa3d/virtual.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $OpenBSD: virtual.h,v 1.3 2002/03/27 14:08:43 camield Exp $ */
-
-/*
- * Virtual domain support.
- */
-
-#ifndef _POP_VIRTUAL_H
-#define _POP_VIRTUAL_H
-
-#include <pwd.h>
-#include <sys/types.h>
-
-/*
- * These are set by the authentication routine, below.
- */
-extern char *virtual_domain;
-extern char *virtual_spool;
-
-/*
- * Initializes the virtual domain support at startup. Note that this will
- * only be called once in standalone mode, so don't expect an open socket
- * here. Returns a non-zero value on error.
- */
-extern int virtual_startup(void);
-
-/*
- * Tries to authenticate a username/password pair for the virtual domain
- * indicated either by the connected IP address (the socket is available
- * on fd 0), or as a part of the username. If the virtual domain is known,
- * virtual_domain and virtual_spool are set appropriately. If the username
- * is known as well, known is set. Returns the template user to run as if
- * authentication succeeds, or NULL otherwise.
- */
-extern struct passwd *virtual_userpass(char *user, char *pass, int *known);
-
-#endif