/* * atomicpop3pass - advanced qmail POP3 authentification * * main.c - main file * __________________________________________________________ * * Developed by Ondrej Jombik * Copyright (c) 2002-2003 Platon SDG, http://platon.sk/ * All rights reserved. * * See README file for more information about this software. * See COPYING file for license information. * * Download the latest version from * http://platon.sk/projects/libplaton/ */ /* $Platon: */ #include #include #include #include #include #include "main.h" #include "sys/main.h" #include "user/main.h" #ifndef SYSLOG_LEVEL # error SYSLOG_LEVEL not defined #else # if SYSLOG_LEVEL >= 1 # include # endif #endif char *login = NULL; char *password = NULL; char remotehost[BUFLEN] = "\0"; char remoteip[BUFLEN] = "\0"; char remoteinfo[BUFLEN] = "unknown\0"; int main(int argc, char **argv, char *envp[]) /* {{{ */ { int r; int i; int uplen; char up[513]; char **me; if (! argv[1]) exit(2); #if SYSLOG_LEVEL >= 1 /* Opening log */ openlog(PROGRAM_NAME, LOG_PID, SYSLOG_FACILITY); #endif if (atexit(atexit_function0) == -1) { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "cannot register atexit() function"); exit(2); #endif } #if SYSLOG_LEVEL >= 9 syslog(SYSLOG_DEBUG, "debug: started"); #endif for (me = envp; *me; me++) { long ptr; ptr = (long) *(me); if (strncmp(*me, "TCPREMOTEIP", 11) == 0) { ptr += 12; strcpy(remoteip, (char*)(ptr)); } if (strncmp(*me, "TCPREMOTEHOST", 13) == 0) { ptr += 14; strcpy(remotehost, (char*)(ptr)); } if (strncmp(*me, "TCPREMOTEINFO", 13) == 0) { ptr += 14; strcpy(remoteinfo, (char*)(ptr)); } } #if SYSLOG_LEVEL >= 9 syslog(SYSLOG_DEBUG, "debug: POP3 connect from %s@%s [%s]", remoteinfo, remotehost, remoteip); #endif if (argc < 2) { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "exit 2 at point 9 (bad argc)"); #endif exit(2); } uplen = 0; for (;;) { do { r = read(3, up + uplen,sizeof(up) - uplen); } while ((r == -1) && (errno == EINTR)); if (r == -1) exit(111); if (r == 0) break; uplen += r; if (uplen >= sizeof(up)) exit(1); } close(3); i = 0; login = up + i; while (up[i++]) if (i == uplen) { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "exit 2 at point 10"); #endif exit(2); } #if SYSLOG_LEVEL >= 5 syslog(SYSLOG_INFO, "POP3 user %s connected from %s@%s [%s]", login, remoteinfo, remotehost, remoteip); #endif password = up + i; if (i == uplen) { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "exit 2 at point 11"); #endif exit(2); } while (up[i++]) if (i == uplen) { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "exit 2 at point 12"); #endif exit(2); } if (! login || ! password) { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "sorry, NULL login or password, cannot proceed"); #endif exit(2); } else { #if SYSLOG_LEVEL >= 9 syslog(SYSLOG_DEBUG, "debug: login = %s, pass = %s", login, password); #endif } login = strdup(login); password = strdup(password); /* Clear input username/passwd stack. */ for (i = 0; i < sizeof(up); ++i) up[i] = 0; if (main_sys(argc, argv) < 0) { /* System login failed. We are going to try user defined login. */ #if SYSLOG_LEVEL >= 5 syslog(SYSLOG_INFO, "system login failed, trying user login"); #endif if (main_user(argc, argv, envp) < 0) { #if SYSLOG_LEVEL >= 5 syslog(SYSLOG_INFO, "user login failed, aborting"); #endif /* sleep() to 1. allow syslog to work and 2. hinder pop3 brute force hacks */ sleep(SLEEP); } else { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "execvp() failure in user login"); #endif } } else { #if SYSLOG_LEVEL >= 1 syslog(SYSLOG_ERROR, "pathexec()/execve() failure in system login"); #endif } nuke_dynamic_string(&login); nuke_dynamic_string(&password); exit(111); /* We should never reach this. */ return 0; } /* }}} */ void atexit_function0(void) /* {{{ */ { #if SYSLOG_LEVEL >= 1 closelog(); #endif } /* }}} */ void nuke_dynamic_string(char **str) /* {{{ */ { if (str != NULL || *str != NULL) { register char *s; for (s = *str; *s != '\0'; s++) *s = '\0'; free(*str); *str = NULL; } } /* }}} */ /* Modeline for ViM {{{ * vim:set ts=4: * vim600:fdm=marker fdl=0 fdc=0: * }}} */