summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/popper/pop_pass.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/popper/pop_pass.c')
-rw-r--r--crypto/heimdal/appl/popper/pop_pass.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/crypto/heimdal/appl/popper/pop_pass.c b/crypto/heimdal/appl/popper/pop_pass.c
new file mode 100644
index 0000000..cebd780
--- /dev/null
+++ b/crypto/heimdal/appl/popper/pop_pass.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#include <popper.h>
+RCSID("$Id: pop_pass.c,v 1.41 2000/04/12 15:37:46 assar Exp $");
+
+#ifdef KRB4
+static int
+krb4_verify_password (POP *p)
+{
+ int status;
+ char lrealm[REALM_SZ];
+ char tkt[MaxPathLen];
+
+ status = krb_get_lrealm(lrealm,1);
+ if (status == KFAILURE) {
+ pop_log(p, POP_PRIORITY, "%s: (%s.%s@%s) %s", p->client,
+ p->kdata.pname, p->kdata.pinst, p->kdata.prealm,
+ krb_get_err_text(status));
+ return 1;
+ }
+ snprintf(tkt, sizeof(tkt), "%s_popper.%u", TKT_ROOT, (unsigned)getpid());
+ krb_set_tkt_string (tkt);
+
+ status = krb_verify_user(p->user, "", lrealm,
+ p->pop_parm[1], KRB_VERIFY_SECURE, "pop");
+ dest_tkt(); /* no point in keeping the tickets */
+ return status;
+}
+#endif /* KRB4 */
+
+#ifdef KRB5
+static int
+krb5_verify_password (POP *p)
+{
+ krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
+ krb5_get_init_creds_opt get_options;
+ krb5_verify_init_creds_opt verify_options;
+ krb5_error_code ret;
+ krb5_principal client, server;
+ krb5_creds creds;
+
+ krb5_get_init_creds_opt_init (&get_options);
+
+ krb5_get_init_creds_opt_set_preauth_list (&get_options,
+ pre_auth_types,
+ 1);
+
+ krb5_verify_init_creds_opt_init (&verify_options);
+
+ ret = krb5_parse_name (p->context, p->user, &client);
+ if (ret) {
+ pop_log(p, POP_PRIORITY, "krb5_parse_name: %s",
+ krb5_get_err_text (p->context, ret));
+ return 1;
+ }
+
+ ret = krb5_get_init_creds_password (p->context,
+ &creds,
+ client,
+ p->pop_parm[1],
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ &get_options);
+ if (ret) {
+ pop_log(p, POP_PRIORITY,
+ "krb5_get_init_creds_password: %s",
+ krb5_get_err_text (p->context, ret));
+ return 1;
+ }
+
+ ret = krb5_sname_to_principal (p->context,
+ p->myhost,
+ "pop",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (ret) {
+ pop_log(p, POP_PRIORITY,
+ "krb5_get_init_creds_password: %s",
+ krb5_get_err_text (p->context, ret));
+ return 1;
+ }
+
+ ret = krb5_verify_init_creds (p->context,
+ &creds,
+ server,
+ NULL,
+ NULL,
+ &verify_options);
+ krb5_free_principal (p->context, client);
+ krb5_free_principal (p->context, server);
+ krb5_free_creds_contents (p->context, &creds);
+ return ret;
+}
+#endif
+/*
+ * pass: Obtain the user password from a POP client
+ */
+
+int
+pop_pass (POP *p)
+{
+ struct passwd *pw;
+ int i;
+ struct stat st;
+
+ /* Make one string of all these parameters */
+
+ for (i = 1; i < p->parm_count; ++i)
+ p->pop_parm[i][strlen(p->pop_parm[i])] = ' ';
+
+ /* Look for the user in the password file */
+ if ((pw = k_getpwnam(p->user)) == NULL)
+ return (pop_msg(p,POP_FAILURE,
+ "Password supplied for \"%s\" is incorrect.",
+ p->user));
+
+ if (p->kerberosp) {
+#ifdef KRB4
+ if (p->version == 4) {
+ if(kuserok (&p->kdata, p->user)) {
+ pop_log(p, POP_PRIORITY,
+ "%s: (%s.%s@%s) tried to retrieve mail for %s.",
+ p->client, p->kdata.pname, p->kdata.pinst,
+ p->kdata.prealm, p->user);
+ return(pop_msg(p,POP_FAILURE,
+ "Popping not authorized"));
+ }
+ pop_log(p, POP_INFO, "%s: %s.%s@%s -> %s",
+ p->ipaddr,
+ p->kdata.pname, p->kdata.pinst, p->kdata.prealm,
+ p->user);
+ } else
+#endif /* KRB4 */
+#ifdef KRB5
+ if (p->version == 5) {
+ char *name;
+
+ if (!krb5_kuserok (p->context, p->principal, p->user)) {
+ pop_log (p, POP_PRIORITY,
+ "krb5 permission denied");
+ return pop_msg(p, POP_FAILURE,
+ "Popping not authorized");
+ }
+ if(krb5_unparse_name (p->context, p->principal, &name) == 0) {
+ pop_log(p, POP_INFO, "%s: %s -> %s",
+ p->ipaddr, name, p->user);
+ free (name);
+ }
+ } else {
+ pop_log (p, POP_PRIORITY, "kerberos authentication failed");
+ return pop_msg (p, POP_FAILURE,
+ "kerberos authentication failed");
+ }
+#endif
+ { }
+ } else {
+ /* We don't accept connections from users with null passwords */
+ if (pw->pw_passwd == NULL)
+ return (pop_msg(p,
+ POP_FAILURE,
+ "Password supplied for \"%s\" is incorrect.",
+ p->user));
+
+#ifdef OTP
+ if (otp_verify_user (&p->otp_ctx, p->pop_parm[1]) == 0)
+ /* pass OK */;
+ else
+#endif
+ /* Compare the supplied password with the password file entry */
+ if (p->auth_level != AUTH_NONE)
+ return pop_msg(p, POP_FAILURE,
+ "Password supplied for \"%s\" is incorrect.",
+ p->user);
+ else if (!strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd))
+ /* pass OK */;
+ else {
+ int ret = -1;
+#ifdef KRB4
+ ret = krb4_verify_password (p);
+#endif
+#ifdef KRB5
+ if(ret)
+ ret = krb5_verify_password (p);
+#endif
+ if(ret)
+ return pop_msg(p, POP_FAILURE,
+ "Password incorrect");
+ }
+ }
+ pop_log(p, POP_INFO, "login from %s as %s",
+ p->ipaddr, p->user);
+
+ /* Build the name of the user's maildrop */
+ snprintf(p->drop_name, sizeof(p->drop_name), "%s/%s", POP_MAILDIR, p->user);
+
+ if(stat(p->drop_name, &st) < 0 || !S_ISDIR(st.st_mode)){
+ /* Make a temporary copy of the user's maildrop */
+ /* and set the group and user id */
+ if (pop_dropcopy(p, pw) != POP_SUCCESS) return (POP_FAILURE);
+
+ /* Get information about the maildrop */
+ if (pop_dropinfo(p) != POP_SUCCESS) return(POP_FAILURE);
+ } else {
+ if(changeuser(p, pw) != POP_SUCCESS) return POP_FAILURE;
+ if(pop_maildir_info(p) != POP_SUCCESS) return POP_FAILURE;
+ }
+ /* Initialize the last-message-accessed number */
+ p->last_msg = 0;
+
+ /* Authorization completed successfully */
+ return (pop_msg (p, POP_SUCCESS,
+ "%s has %d message(s) (%ld octets).",
+ p->user, p->msg_count, p->drop_size));
+}
OpenPOWER on IntegriCloud