Am Sonntag, 7. Dezember 2008 schrieb Charles Sprickman:
> On Sun, 7 Dec 2008, John Stile wrote:
> > On Tue, 2008-11-04 at 23:05 +0100, Rolf Eike Beer wrote:
> >> Am Mittwoch, 22. Oktober 2008 schrieb Rolf Eike Beer:
> >>> Am Sonntag, 11. Mai 2008 schrieb Sam Varshavchik:
> >>>> Rolf Eike Beer writes:
> >>>>> Am Samstag, 10. Mai 2008 schrieb Sam Varshavchik:
> >>>>>> Bookworm writes:
> >>>>>>> I've been made aware that in the latest 60.4 changelog
> >>>>>>> (http://www.courier-mta.org/authlib/changelog.html), the authvchkpw
> >>>>>>> module has been dropped.
> >>>>>>> 
> >>>>>>> What needs to be done to have it put back in?    I'm assuming a
> >>>>>>> maintainer, but I'm sure there's a lot more to that.
> >>>>>> 
> >>>>>> Yes, someone need to take ownership of the code.
> >>>>> 
> >>>>> What needs to be done there?
> >>>> 
> >>>> Grab the authvchkpw code from the last version, verify that it build
> >>>> and compiles. Post a patch to restore the module to HEAD, put
> >>>> yourself down as the contact.
> >>> 
> >>> Ok, it had been a while. I'll be busy working on other things for at
> >>> least two more weeks but I would definitely do the task of keeping
> >>> this working.
> >>> 
> >>> To give me a easier start could you give me some hints where to start,
> >>> please? What exactly do I need to check out to get the lastest version
> >>> where this was in? Which modules (I assume only authlib) do I need to
> >>> monitor to see if anything changes? Have there been any problems (build
> >>> or runtime) prior to the remove I should know about?
> >> 
> >> Ping?
> > 
> > Hello Rolf,
> > 
> >  Has there been any progress on authvchkpw?
> 
> I'm curious as well.  I'm stuck on a very old version of Courier and while
> I'll likely be dumping the whole mail system for something entirely
> different late next year, for now I'd like to at least keep things up to
> date.  Courier 4.0.6(_1,1), courier-authlib-vchkpw 0.58(_2) - this is from
> FreeBSD ports, the numbers in parens indicate their revisions.
> 
> The problem I see here, and if I'm not mistaken, vpopmail support was
> dropped shortly after this version, is that the vpopmail auth module has a
> huge memory leak.  After about one week all my authdaemond processes grow
> to a few hundred MB in size.  Current solution?  Nightly cron job to
> restart the daemon. :(
> 
> There are a few very good people outside of Inter7 working on vpopmail.
> Both Bill Shupp and Tom Collins would probably be very helpful to anyone
> working on this.  Check out the sf.net page for their contact info.

Hi everyone,

it actually took my much longer than I wanted to. I thought the auth module in 
vpopmail would work and therefore not looked into it any more. Since I was 
forced to upgrade my server 3 days ago I needed to look into it again as 
things of course did not work afterwards :(

So the authvchkpw.c included in vpopmail is a standalone binary while courier-
authlib expects a shared library. I looked at the existing modules (the in-
header documentation on what to do could have been better to make me my things 
easier, but source good has worked to) and the authvchkpw.c from vpopmail and 
basically merged that together. I've no idea if I did everything right but at 
least I now can get my mails again.

Since I have no idea whatsoever of that autohell stuff I wroke a small cmake 
file to get everything compiled. My steps were basically as follows:

-install courier-authlib
-build vpopmail
-copy the two attached files into vpopmail source dir
-mkdir build
-cmake vpopmail/source/dir
-make
-copy libauthvchkpw.so to courier authlib directory

I'm sure all this could be a lot improved as this is really just an ugly 
hacked together first version. It may rape your dog, eat your kittens, or make 
your children become lawyers. You have been warned. I don't give any warranty 
for anything. But it works for me (at least for the last day or so) and I just 
wanted to share those with you.

Comments welcome.

Eike
PROJECT(authvchkpw)

ADD_LIBRARY(authvchkpw SHARED
		authvchkpw.c hmac_md5.c)

SET_TARGET_PROPERTIES(authvchkpw PROPERTIES COMPILE_FLAGS -DENABLE_AUTH_LOGGING)

TARGET_LINK_LIBRARIES(authvchkpw ${CMAKE_CURRENT_SOURCE_DIR}/libvpopmail.a)
/*
 * $Id: authvchkpw.c 706 2009-03-10 17:56:19Z volz0r $
 * Copyright (C) 1999-2009 Inter7 Internet Technologies, Inc.
 *
 * Revision 2.2  2008-08-24 17:43:44+05:30  Cprogrammer
 * added code to return error for password changes
 *
 * Revision 2.1  2008-08-24 14:44:56+05:30  Cprogrammer
 * courier-imap authmodule for IndiMail
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * The GNU General Public License does not permit incorporating your program
 * into proprietary programs.  If your program is a subroutine library, you
 * may consider it more useful to permit linking proprietary applications with
 * the library.  If this is what you want to do, use the GNU Lesser General
 * Public License instead of this License.  But first, please read
 * <http://www.gnu.org/philosophy/why-not-lgpl.html>.
 *
 */
#include "config.h"
#include "vpopmail.h"
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <pwd.h>
#include <string.h>
#include "md5.h"
#include "hmac_md5.h"
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "vauth.h"
#include <courierauth.h>
#include "authstaticlist.h"

#ifndef lint
static char     sccsid[] = "$Id: authvchkpw.c 706 2009-03-10 17:56:19Z volz0r $";
#endif
#ifdef AUTH_SIZE
#undef AUTH_SIZE
#define AUTH_SIZE 512
#else
#define AUTH_SIZE 512
#endif

int             authlen = AUTH_SIZE;
static int
exec_local(char *userid, char *TheDomain, struct vqpasswd *pw, const char *service,
		int (*callback_func)(struct authinfo *, void *),
		void *callback_arg);
static char     hextab[] = "0123456789abcdef";

static void
close_connection()
{
#ifdef PASSWD_CACHE
	if (!getenv("PASSWD_CACHE"))
		vclose();
#else /*- Not PASSWD_CACHE */
	vclose();
#endif
}

static int
pw_comp(char *testlogin, char *password, char *challenge, char *response)
{
	unsigned char   digest[16];
	unsigned char   digascii[33];
	char           *crypt_pass;
	unsigned char   h;
	int             j;

	if(!response || (response && !*response))
	{
		if (!(crypt_pass = crypt((char *) challenge, (char *) password)))
		{
			printf("454-%s (#4.3.0)\r\n", strerror(errno));
			fflush(stdout);
			_exit (111);
		}
		return(strncmp((const char *) crypt_pass, (const char *) password, (size_t) 14));
	}
	hmac_md5((unsigned char *) challenge, (int) strlen((const char *) challenge), (unsigned char *) password,
		(int) strlen((const char *) password), digest);
	digascii[32] = 0;
	for (j = 0; j < 16; j++)
	{
		h = digest[j] >> 4;
		digascii[2 * j] = hextab[h];
		h = digest[j] & 0x0f;
		digascii[(2 * j) + 1] = hextab[h];
	}
	return (strcmp((const char *) digascii, (const char *) response) && strcmp((const char *) password, (const char *) challenge));
}

/*
 * getEnvConfigStr
 */
static void
getEnvConfigStr(char **source, char *envname, char *defaultValue)
{
	if (!(*source = getenv(envname)))
		*source = defaultValue;
	return;
}

static int
Login_Tasks(pw, user, ServiceType)
	struct passwd  *pw;
	const char     *user;
	char           *ServiceType;
{
	char           *domain, *ptr;
	char            fqemail[MAX_BUFF];
#ifdef ENABLE_AUTH_LOGGING
#ifdef MIN_LOGIN_INTERVAL
	time_t          min_login_interval, last_time;
#endif
#ifdef USE_MAILDIRQUOTA	
	mdir_t          size_limit, count_limit;
#endif
#endif

	if (!pw)
		return(1);
	lowerit((char *) user);
	lowerit(pw->pw_name);
	if (!(ptr = strchr(user, '@')))
	{
		getEnvConfigStr(&domain, "DEFAULT_DOMAIN", DEFAULT_DOMAIN);
		lowerit(domain);
		snprintf(fqemail, MAX_BUFF, "%...@%s", user, domain);
	} else
	{
		domain = ptr + 1;
		strncpy(fqemail, user, MAX_BUFF);
		*ptr = 0;
	}
	if (access(pw->pw_dir, F_OK))
		vmake_maildir(domain, pw->pw_dir);
#ifdef POP_AUTH_OPEN_RELAY
	/*- open the relay to pop3/imap users */
	if (!getenv("NORELAY") && (pw->pw_gid & NO_RELAY) == 0)
		open_smtp_relay(pw->pw_name, domain);
#endif
#ifdef ENABLE_AUTH_LOGGING
#ifdef MIN_LOGIN_INTERVAL
	last_time = vget_lastauth(pw, domain);
#endif
	if (!(ptr = getenv("TCPERMOTEIP")))
		ptr = "0.0.0.0";
	vset_lastauth(pw->pw_name, domain, ptr);
#ifdef MIN_LOGIN_INTERVAL
  if(( vget_lastauth(vpw,TheDomain ) - last_time ) < MIN_LOGIN_INTERVAL ) { 
    vchkpw_exit(1);
  }
#endif
#endif /*- ENABLE_AUTH_LOGGING */
	return(0);
}

int
callauth(const char *service, char *login, char *pass,
		int (*callback_func)(struct authinfo *, void *),
		void *callback_arg)
{
	char           *buf, *tmpbuf, *challenge, *crypt_pass,
				   *prog_name, *service_type;
	char            user[AUTH_SIZE], domain[AUTH_SIZE], Email[MAX_BUFF];
	int             count, offset;
	uid_t           uid;
	gid_t           gid;
	struct vqpasswd  *pw;

	if (parse_email(login, user, domain, MAX_BUFF))
	{
		fprintf(stderr, "%s: could not parse email [%s]\n", prog_name, login);
		errno = EPERM;
		return -1;
	}
	if (!vget_assign(domain, 0, 0, &uid, &gid)) 
	{
		fprintf(stderr, "%s: domain %s does not exist\n", prog_name, domain);
		errno = EPERM;
		return -2;
	}
    if (vauth_open(0))
	{
		fprintf(stderr, "%s: inquery: %s\n", prog_name, strerror(errno));
		errno = EPERM;
		return -3;
	}
	pw = vauth_getpw(user, domain);
	if (!pw)
	{
		fprintf(stderr, "%s: inquery: %s\n", prog_name, strerror(errno));
		close_connection();
		return (1);
	}
	/*
	 * Look at what type of connection we are trying to auth.
	 * And then see if the user is permitted to make this type
	 * of connection
	 */
	if (strcmp("webmail", service) == 0)
	{
		if (pw->pw_gid & NO_WEBMAIL)
		{
			errno = EPERM;
			return -4;
		}
	} else
	if (strcmp("pop3", service) == 0)
	{
		if (pw->pw_gid & NO_POP)
		{
			errno = EPERM;
			return -5;
		}
	} else
	if (strcmp("imap", service) == 0)
	{
		if (pw->pw_gid & NO_IMAP)
		{
			errno = EPERM;
			return -6;
		}
	}
	crypt_pass = pw->pw_passwd;

	if (pw_comp(login, crypt_pass, pass, NULL))
	{
		errno = EPERM;
		return -7;
	}

	return exec_local(login, domain, pw, service, callback_func, callback_arg);
}

static int
exec_local(char *userid, char *TheDomain, struct vqpasswd *pw, const char *service,
		int (*callback_func)(struct authinfo *, void *),
		void *callback_arg)
{
	char            Maildir[MAX_BUFF], authenv2[MAX_BUFF],
	                authenv4[MAX_BUFF], TheUser[MAX_BUFF], TmpBuf[MAX_BUFF];
	char           *ptr, *cptr;
	int             status;
	uid_t uid;
#ifdef USE_MAILDIRQUOTA
	mdir_t          size_limit, count_limit;
#endif
	struct authinfo auth;

	memset(&auth, 0, sizeof(auth));

	for (cptr = TheUser, ptr = userid;*ptr && *ptr != '@';*cptr++ = *ptr++);
	*cptr = 0;
	strncpy(TmpBuf, service, MAX_BUFF);
	if ((ptr = strrchr(TmpBuf, ':')))
		*ptr = 0;
	status = Login_Tasks(pw, userid, TmpBuf);
	if (status == 2 && !strncasecmp(service, "imap", 4))
	{
		close_connection();
		return(17);
	}
	close_connection();
	snprintf(Maildir, MAX_BUFF, "/var/vpopmail/domains/%s/%s/.maildir/", TheDomain, TheUser);
	if (access(Maildir, F_OK) || chdir(Maildir))
	{
		return(42);
	}
	snprintf(authenv2, MAX_BUFF, "%...@%s", TheUser, TheDomain);
#ifdef USE_MAILDIRQUOTA
	size_limit = parse_quota(pw->pw_shell, &count_limit);
	snprintf(authenv4, MAX_BUFF, "%"PRIu64"S,%"PRIu64"C", size_limit, count_limit);
#else
	snprintf(authenv4, MAX_BUFF, "%sS", pw->pw_shell);
#endif

	if (!vget_assign(TheDomain, 0, 0, &uid, &auth.sysgroupid))
		return -1;
	

	auth.sysuserid = &uid;
	auth.homedir = pw->pw_dir;
	auth.address = authenv2;
	auth.fullname = pw->pw_gecos;
	auth.maildir = Maildir;
// 	auth.clearpasswd = pw->pw_passwd;
	auth.passwd = pw->pw_passwd;
// 	auth.quota = authenv4;

	if (auth.homedir == 0 || *auth.homedir == '\0')
		auth.homedir="/var/vpopmail";

	status = 0;

	if (uid == 0 || auth.sysgroupid == 0)
	{
		status = 1;
	}

	if (status == 0 && callback_func)
		status = (*callback_func)(&auth, callback_arg);

	return status;
}

int auth_vchkpw(const char *service, const char *authtype, char *authdata,
	      int (*callback_func)(struct authinfo *, void *),
	      void *callback_arg)
{
char buf[20];
	char *user, *pass;
	int ret = -1;

	if ((user=strtok(authdata, "\n")) == 0 ||
		(pass=strtok(0, "\n")) == 0)
	{
		DPRINTF("incomplete authentication data");
		errno=EPERM;
		return (-1);
	}

	if (strcmp(authtype, AUTHTYPE_LOGIN) != 0) {
		errno = EPERM;
		return -1;
	}

	ret = callauth(service, user, pass, callback_func, callback_arg);

	if (ret) {
		errno = EPERM;
		return -1;
	}

	return ret;
}

int auth_vchkpw_pre() { return -1; }
int auth_vchkpw_cleanup() { return 0; }
int auth_vchkpw_changepw() { return -1; }
int auth_vchkpw_enumerate() { return -1; }

static struct authstaticinfo authvchkpw_info={
	"authvchkpw",
	auth_vchkpw,
	auth_vchkpw_pre,
	auth_vchkpw_cleanup,
	NULL,
	auth_vchkpw_cleanup,
	NULL};

struct authstaticinfo *courier_authvchkpw_init()
{
	return &authvchkpw_info;
}

Attachment: signature.asc
Description: This is a digitally signed message part.

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Courier-imap mailing list
Courier-imap@lists.sourceforge.net
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-imap

Reply via email to