diff -r -bw -u popa3d-0.4/Makefile popa3d-0.4-krb4/Makefile --- popa3d-0.4/Makefile Mon Jan 31 22:56:46 2000 +++ popa3d-0.4-krb4/Makefile Tue May 30 13:13:36 2000 @@ -1,8 +1,8 @@ CC = gcc LD = gcc RM = rm -f -CFLAGS = -c -Wall -O2 -fomit-frame-pointer -LDFLAGS = -s +CFLAGS = -c -Wall -O2 -fomit-frame-pointer -I/usr/include/kerberosIV +LDFLAGS = -s -lkrb -ldes #LDFLAGS = -s -lcrypt PROJ = popa3d diff -r -bw -u popa3d-0.4/params.h popa3d-0.4-krb4/params.h --- popa3d-0.4/params.h Tue Feb 1 01:16:24 2000 +++ popa3d-0.4-krb4/params.h Tue May 30 13:13:36 2000 @@ -16,7 +16,7 @@ * The address and port to listen at. */ #define DAEMON_ADDR "0.0.0.0" /* INADDR_ANY */ -#define DAEMON_PORT 110 +#define DAEMON_PORT 1109 /* * Limit the number of POP sessions we can handle at a time to reduce @@ -57,6 +57,12 @@ */ #define MAX_MAILBOX_MESSAGES 100000 #define MAX_MAILBOX_BYTES 100000000 + +/* + * MIT Kerberos v4 KPOP support by Dug Song . + */ +#define AUTH_KRB4 1 +#define KPOP_SERVICE "pop" /* * Do we have shadow passwords? (Not for *BSD.) diff -r -bw -u popa3d-0.4/pop_auth.c popa3d-0.4-krb4/pop_auth.c --- popa3d-0.4/pop_auth.c Wed Mar 24 23:25:55 1999 +++ popa3d-0.4-krb4/pop_auth.c Tue May 30 13:13:36 2000 @@ -12,6 +12,12 @@ #include "protocol.h" #include "pop_auth.h" +#if AUTH_KRB4 +#include + +extern int pop_auth_krb4(); +#endif + static char *pop_user, *pop_pass; static int pop_auth_quit(char *params) @@ -46,13 +52,21 @@ int do_pop_auth(int channel) { + KTEXT_ST ticket; + pop_init(); +#if AUTH_KRB4 + if (pop_auth_krb4(&ticket)) return 1; +#endif if (pop_reply_ok()) return 1; pop_user = NULL; if (pop_handle_state(pop_auth_commands) == POP_STATE) { write_loop(channel, (char *)&pop_buffer, sizeof(pop_buffer)); +#if AUTH_KRB4 + write_loop(channel, (char *)&ticket, sizeof(ticket)); +#endif write_loop(channel, pop_user, strlen(pop_user) + 1); write_loop(channel, pop_pass, strlen(pop_pass) + 1); if (close(channel)) return 1; diff -r -bw -u popa3d-0.4/pop_root.c popa3d-0.4-krb4/pop_root.c --- popa3d-0.4/pop_root.c Tue Feb 1 01:18:12 2000 +++ popa3d-0.4-krb4/pop_root.c Tue May 30 13:15:46 2000 @@ -21,6 +21,13 @@ #include "pop_auth.h" #include "pop_trans.h" +#if AUTH_KRB4 +#include +#include +#include +#include +#endif + #if AUTH_SHADOW #include #ifdef __GLIBC__ @@ -73,7 +80,42 @@ return offset; } -#if AUTH_SHADOW +#if AUTH_KRB4 +/* + * Support for MIT Kerberos v4 KPOP. + */ +static struct passwd *do_krb4_auth(char *user, KTEXT_ST *ticket) +{ + struct passwd *pw; + struct sockaddr_in client; + char *instance, hostname[MAXHOSTNAMELEN]; + AUTH_DAT kauth; + int length; + + if ((pw = getpwnam(user))) mailbox = user; + endpwent(); + + if (gethostname(hostname, sizeof(hostname)) < 0) + return NULL; + + instance = krb_get_phost(hostname); + + length = sizeof(client); + + if (getpeername(0, (struct sockaddr *)&client, &length) < 0) + return NULL; + + if (krb_rd_req(ticket, KPOP_SERVICE, instance, + client.sin_addr.s_addr, &kauth, "") != KSUCCESS) + return NULL; + + if (kuserok(&kauth, user) != 0) + return NULL; + + return pw; +} + +#elif AUTH_SHADOW /* * The /etc/shadow authentication routine. This one is really tricky, * in order to make sure we don't have an /etc/shadow fd or sensitive @@ -161,6 +203,9 @@ */ static int do_root_auth(int channel) { +#if AUTH_KRB4 + KTEXT_ST ticket; +#endif static char auth[AUTH_BUFFER_SIZE + 2]; char *user, *pass; struct passwd *pw; @@ -174,19 +219,28 @@ sizeof(pop_buffer)) return AUTH_NONE; /* Now, the authentication data. */ +#if AUTH_KRB4 + if (read_loop(channel, (char *)&ticket, sizeof(ticket)) < 0) + return AUTH_NONE; +#endif memset(auth, 0, sizeof(auth)); /* Ensure the NUL termination */ if (read_loop(channel, auth, AUTH_BUFFER_SIZE) < 0) return AUTH_NONE; user = auth; pass = &user[strlen(user) + 1]; -#if AUTH_SHADOW +#if AUTH_KRB4 + if (!(pw = do_krb4_auth(user, &ticket))) return AUTH_FAILED; +#elif AUTH_SHADOW if (!(pw = do_shadow_auth(user, pass))) return AUTH_FAILED; #else if (!(pw = do_passwd_auth(user, pass))) return AUTH_FAILED; #endif if (!*user || !*pass) return AUTH_FAILED; +#if AUTH_KRB4 + memset((char *)&ticket, 0, sizeof(ticket)); +#endif memset(pass, 0, strlen(pass)); if (set_user(pw)) return AUTH_FAILED; diff -r -bw -u popa3d-0.4/protocol.c popa3d-0.4-krb4/protocol.c --- popa3d-0.4/protocol.c Wed Mar 24 23:25:55 1999 +++ popa3d-0.4-krb4/protocol.c Tue May 30 13:13:36 2000 @@ -14,6 +14,11 @@ #include "params.h" #include "protocol.h" +#if AUTH_KRB4 +#include +#include +#endif + struct pop_buffer pop_buffer; static jmp_buf pop_timed_out; @@ -85,6 +90,49 @@ else return NULL; } + +#ifdef AUTH_KRB4 +static char *pop_get_bytes(char *bytes, int size) +{ + int i, j; + + for (i = 0; i < size; i += j) { + if (pop_buffer.ptr >= pop_buffer.size) + if (pop_fetch()) return NULL; + + j = MIN(pop_buffer.size - pop_buffer.ptr, size - i); + memcpy(&bytes[i], &pop_buffer.data[pop_buffer.ptr], j); + pop_buffer.ptr += j; + } + return (bytes); +} + +int pop_auth_krb4(KTEXT_ST *ticket) +{ + char version[KRB_SENDAUTH_VLEN]; + + /* Skip protocol version string. */ + if (!pop_get_bytes(version, sizeof(version))) + return -1; + + /* Skip application version string. */ + if (!pop_get_bytes(version, sizeof(version))) + return -1; + + if (!pop_get_bytes((char *)&ticket->length, sizeof(ticket->length))) + return -1; + + ticket->length = ntohl(ticket->length); + + if (ticket->length <= 0 || ticket->length > sizeof(ticket->dat)) + return -1; + + if (!pop_get_bytes((char *)&ticket->dat, ticket->length)) + return -1; + + return 0; +} +#endif /* AUTH_KRB4 */ int pop_handle_state(struct pop_command *commands) {