summaryrefslogtreecommitdiffstats
path: root/sqwebmail/auth.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /sqwebmail/auth.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'sqwebmail/auth.c')
-rw-r--r--sqwebmail/auth.c326
1 files changed, 326 insertions, 0 deletions
diff --git a/sqwebmail/auth.c b/sqwebmail/auth.c
new file mode 100644
index 0000000..5a3b9e7
--- /dev/null
+++ b/sqwebmail/auth.c
@@ -0,0 +1,326 @@
+/*
+** Copyright 1998 - 2006 Double Precision, Inc. See COPYING for
+** distribution information.
+*/
+
+
+/*
+*/
+
+#include "sqwebmail.h"
+#include "config.h"
+
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <courierauth.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#include "maildir/loginexec.h"
+#include "courierauthdebug.h"
+#include "auth.h"
+#include "htmllibdir.h"
+
+extern int check_sqwebpass(const char *);
+
+extern char *sqwebmail_content_charset, *sqwebmail_system_charset;
+#include "unicode/unicode.h"
+
+const char *myhostname()
+{
+char buf[512];
+static char *my_hostname=0;
+FILE *f;
+
+ if (my_hostname == 0)
+ {
+ buf[0]=0;
+ if ((f=fopen(HOSTNAMEFILE, "r")) != 0)
+ {
+ char *p;
+
+ if (fgets(buf, sizeof(buf), f) == NULL)
+ buf[0]=0;
+
+ fclose(f);
+
+ if ((p=strchr(buf, '\n')) != 0)
+ *p=0;
+ }
+
+ if (buf[0] == 0 && gethostname(buf, sizeof(buf)-1))
+ strcpy(buf, "localhost");
+
+ if ((my_hostname=malloc(strlen(buf)+1)) == 0)
+ enomem();
+ strcpy(my_hostname, buf);
+ }
+ return (my_hostname);
+}
+
+static int login_maildir(const char *maildir)
+{
+ if (!maildir || !*maildir)
+ maildir=getenv("MAILDIRPATH");
+ if (!maildir || !*maildir)
+ maildir="Maildir";
+ if (chdir(maildir)) return (-1);
+ maildir_loginexec();
+ return (0);
+}
+
+static int doauthlogin(struct authinfo *a, void *vp)
+{
+ const char *p=auth_getoption(a->options ? a->options:"",
+ "disablewebmail");
+ const char *c=(const char *)vp;
+
+ static char *authaddr=NULL;
+ static char *authfullname=NULL;
+ static char *authoptions=NULL;
+ static char *authenticated=NULL;
+ const char *n;
+ char *b;
+ int rc;
+
+
+ if (p && atoi(p))
+ return -1;
+
+ if ((rc = auth_callback_default(a)) != 0)
+ {
+ if (rc > 0)
+ perror("ERR: authentication error");
+ return -1;
+ }
+
+ if (login_maildir(a->maildir))
+ {
+ error("Unable to open the maildir for this account -- the maildir doesn't exist or has incorrect ownership or permissions.");
+ return (-1);
+ }
+
+ b=malloc(sizeof("AUTHADDR=")+strlen(c));
+
+ if (!b)
+ enomem();
+ strcat(strcpy(b, "AUTHADDR="), c);
+ putenv(b);
+ if (authaddr)
+ free(authaddr);
+ authaddr=b;
+
+
+ n=a->fullname;
+ if (!n) n="";
+ b=malloc(sizeof("AUTHFULLNAME=")+strlen(n));
+
+ if (!b)
+ enomem();
+ strcat(strcpy(b, "AUTHFULLNAME="), n);
+ putenv(b);
+ if (authfullname)
+ free(authfullname);
+ authfullname=b;
+
+ n=a->options;
+ if (!n) n="";
+
+ b=malloc(sizeof("OPTIONS=")+strlen(n));
+
+ if (!b)
+ enomem();
+ strcat(strcpy(b, "OPTIONS="), n);
+ putenv(b);
+ if (authoptions)
+ free(authoptions);
+ authoptions=b;
+
+ n=a->address;
+ if (!n) n="";
+
+ b=malloc(sizeof("AUTHENTICATED=")+strlen(n));
+
+ if (!b)
+ enomem();
+ strcat(strcpy(b, "AUTHENTICATED="), n);
+ putenv(b);
+ if (authenticated)
+ free(authenticated);
+ authenticated=b;
+
+ return (0);
+}
+
+const char *do_login(const char *u, const char *p, const char *ip)
+{
+ if (auth_login("webmail", u, p, doauthlogin, (void *)u))
+ {
+ courier_safe_printf("INFO: LOGIN FAILED, user=%s, ip=[%s]",
+ u?u:"", ip);
+ return NULL;
+ }
+
+ fprintf(stderr, "INFO: LOGIN, user=%s, ip=[%s]\n", u, ip);
+ return u;
+}
+
+int nochangepass()
+{
+ if (auth_getoptionenvint("wbnochangepass")) return 1;
+ if (access(SQWEBPASSWD, X_OK)) return 1;
+ return 0;
+}
+
+/*
+** login_changepwd tries to call the password change function for the
+** authentication module.
+**
+** Returns -1 if authentication module does not have a password change
+** function.
+**
+** Returns 0 if the authentication module has a password change function.
+**
+** *rc is set to 0 if password was changed, non-zero otherwise
+*/
+
+int login_changepwd(const char *u, const char *oldpwd, const char *newpwd,
+ int *rc)
+{
+ if (nochangepass())
+ return -1;
+
+ *rc= -1;
+
+ if (changepw("webmail", u, oldpwd, newpwd) == 0)
+ {
+ *rc=0;
+ }
+ return 0;
+}
+
+int prelogin(const char *u)
+{
+ return auth_getuserinfo("webmail", u, doauthlogin, (void *)u);
+}
+
+const char *login_returnaddr()
+{
+ static char *addrbuf=0;
+ const char *p, *domain="";
+
+ if ((p=getenv("AUTHENTICATED")) == NULL || *p == 0)
+ p=getenv("AUTHADDR");
+ if (!p) p="";
+ if (strchr(p, '@') == 0)
+ domain=myhostname();
+
+ if (addrbuf) free(addrbuf);
+ addrbuf=malloc(strlen(domain)+strlen(p)+2);
+ if (!addrbuf) enomem();
+
+ strcpy(addrbuf, p);
+ if (*domain)
+ strcat(strcat(addrbuf, "@"), domain);
+ return (addrbuf);
+}
+
+const char *login_fromhdr()
+{
+const char *address=login_returnaddr();
+const char *fullname=getenv("AUTHFULLNAME");
+int l;
+const char *p;
+char *q;
+
+static char *hdrbuf=0;
+
+FILE *fp;
+char authcharset[128];
+char *ufullname=0;
+static char *uhdrbuf=0;
+
+ if (!fullname || !*fullname)
+ return (address); /* That was easy */
+
+ authcharset[0] = 0;
+ if ((fp=fopen(AUTHCHARSET, "r")))
+ {
+ char *p;
+ if (fgets(authcharset, sizeof(authcharset), fp) == NULL)
+ authcharset[0]=0;
+ fclose(fp);
+
+ if ((p=strchr(authcharset, '\n')))
+ *p = '\0';
+ }
+
+ if (authcharset[0] == 0
+ && sqwebmail_system_charset && *sqwebmail_system_charset
+ && strcasecmp(sqwebmail_system_charset, "ASCII"))
+ strncat(authcharset, sqwebmail_system_charset,
+ sizeof(authcharset)-1);
+
+ if (authcharset[0]
+ && sqwebmail_content_charset && *sqwebmail_content_charset
+ && (ufullname=libmail_u_convert_toutf8(fullname, authcharset,NULL)))
+ fullname = ufullname;
+
+ l=sizeof("\"\" <>")+strlen(address)+strlen(fullname);
+
+ for (p=fullname; *p; p++)
+ if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
+ *p == '<' || *p == '>') ++l;
+
+ for (p=address; *p; p++)
+ if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
+ *p == '<' || *p == '>') ++l;
+
+ if (hdrbuf) free(hdrbuf);
+ hdrbuf=malloc(l);
+ if (!hdrbuf) enomem();
+ q=hdrbuf;
+ *q++='"';
+ for (p=fullname; *p; p++)
+ {
+ if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
+ *p == '<' || *p == '>') *q++ = '\\';
+ *q++= *p;
+ }
+ *q++='"';
+ *q++=' ';
+ *q++='<';
+ for (p=address; *p; p++)
+ {
+ if (*p == '"' || *p == '\\' || *p == '(' || *p == ')' ||
+ *p == '<' || *p == '>') *q++ = '\\';
+ *q++= *p;
+ }
+ *q++='>';
+ *q=0;
+
+ if (ufullname) free(ufullname);
+ if (uhdrbuf) free(uhdrbuf);
+ if ((uhdrbuf=libmail_u_convert_fromutf8(hdrbuf,
+ sqwebmail_content_charset,
+ NULL)) != NULL)
+ return (uhdrbuf);
+
+ return (hdrbuf);
+}
+