summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/popper/pop_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/popper/pop_auth.c')
-rw-r--r--crypto/heimdal/appl/popper/pop_auth.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/crypto/heimdal/appl/popper/pop_auth.c b/crypto/heimdal/appl/popper/pop_auth.c
new file mode 100644
index 0000000..525beaa
--- /dev/null
+++ b/crypto/heimdal/appl/popper/pop_auth.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <popper.h>
+#include <base64.h>
+RCSID("$Id: pop_auth.c,v 1.2 2000/04/12 15:37:45 assar Exp $");
+
+#ifdef KRB4
+
+enum {
+ NO_PROT = 1,
+ INT_PROT = 2,
+ PRIV_PROT = 4
+};
+
+static int
+auth_krb4(POP *p)
+{
+ int ret;
+ des_cblock key;
+ u_int32_t nonce, nonce_reply;
+ u_int32_t max_client_packet;
+ int protocols = NO_PROT | INT_PROT | PRIV_PROT;
+ char data[8];
+ int len;
+ char *s;
+ char instance[INST_SZ];
+ KTEXT_ST authent;
+ des_key_schedule schedule;
+ struct passwd *pw;
+
+ /* S -> C: 32 bit nonce in MSB base64 */
+
+ des_new_random_key(&key);
+ nonce = (key[0] | (key[1] << 8) | (key[2] << 16) | (key[3] << 24)
+ | key[4] | (key[5] << 8) | (key[6] << 16) | (key[7] << 24));
+ krb_put_int(nonce, data, 4, 8);
+ len = base64_encode(data, 4, &s);
+
+ pop_msg(p, POP_CONTINUE, "%s", s);
+ free(s);
+
+ /* C -> S: ticket and authenticator */
+
+ ret = sch_readline(p->input, &s);
+ if (ret <= 0 || strcmp (s, "*") == 0)
+ return pop_msg(p, POP_FAILURE,
+ "authentication aborted by client");
+ len = strlen(s);
+ if (len > sizeof(authent.dat)) {
+ return pop_msg(p, POP_FAILURE, "data packet too long");
+ }
+
+ authent.length = base64_decode(s, authent.dat);
+
+ k_getsockinst (0, instance, sizeof(instance));
+ ret = krb_rd_req(&authent, "pop", instance,
+ p->in_addr.sin_addr.s_addr,
+ &p->kdata, NULL);
+ if (ret != 0) {
+ return pop_msg(p, POP_FAILURE, "rd_req: %s",
+ krb_get_err_text(ret));
+ }
+ if (p->kdata.checksum != nonce) {
+ return pop_msg(p, POP_FAILURE, "data stream modified");
+ }
+
+ /* S -> C: nonce + 1 | bit | max segment */
+
+ krb_put_int(nonce + 1, data, 4, 7);
+ data[4] = protocols;
+ krb_put_int(1024, data + 5, 3, 3); /* XXX */
+ des_key_sched(&p->kdata.session, schedule);
+ des_pcbc_encrypt((des_cblock*)data,
+ (des_cblock*)data, 8,
+ schedule,
+ &p->kdata.session,
+ DES_ENCRYPT);
+ len = base64_encode(data, 8, &s);
+ pop_msg(p, POP_CONTINUE, "%s", s);
+
+ free(s);
+
+ /* C -> S: nonce | bit | max segment | username */
+
+ ret = sch_readline(p->input, &s);
+ if (ret <= 0 || strcmp (s, "*") == 0)
+ return pop_msg(p, POP_FAILURE,
+ "authentication aborted");
+ len = strlen(s);
+ if (len > sizeof(authent.dat)) {
+ return pop_msg(p, POP_FAILURE, "data packet too long");
+ }
+
+ authent.length = base64_decode(s, authent.dat);
+
+ if (authent.length % 8 != 0) {
+ return pop_msg(p, POP_FAILURE, "reply is not a multiple of 8 bytes");
+ }
+
+ des_key_sched(&p->kdata.session, schedule);
+ des_pcbc_encrypt((des_cblock*)authent.dat,
+ (des_cblock*)authent.dat,
+ authent.length,
+ schedule,
+ &p->kdata.session,
+ DES_DECRYPT);
+
+ krb_get_int(authent.dat, &nonce_reply, 4, 0);
+ if (nonce_reply != nonce) {
+ return pop_msg(p, POP_FAILURE, "data stream modified");
+ }
+ protocols &= authent.dat[4];
+ krb_get_int(authent.dat + 5, &max_client_packet, 3, 0);
+ if(authent.dat[authent.length - 1] != '\0') {
+ return pop_msg(p, POP_FAILURE, "bad format of username");
+ }
+ strncpy (p->user, authent.dat + 8, sizeof(p->user));
+ pw = k_getpwnam(p->user);
+ if (pw == NULL) {
+ return (pop_msg(p,POP_FAILURE,
+ "Password supplied for \"%s\" is incorrect.",
+ p->user));
+ }
+
+ 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);
+ ret = pop_login(p, pw);
+ if (protocols & PRIV_PROT)
+ ;
+ else if (protocols & INT_PROT)
+ ;
+ else
+ ;
+
+ return ret;
+}
+#endif /* KRB4 */
+
+#ifdef KRB5
+static int
+auth_gssapi(POP *p)
+{
+
+}
+#endif /* KRB5 */
+
+/*
+ * auth: RFC1734
+ */
+
+static struct {
+ const char *name;
+ int (*func)(POP *);
+} methods[] = {
+#ifdef KRB4
+ {"KERBEROS_V4", auth_krb4},
+#endif
+#ifdef KRB5
+ {"GSSAPI", auth_gssapi},
+#endif
+ {NULL, NULL}
+};
+
+int
+pop_auth (POP *p)
+{
+ int i;
+
+ for (i = 0; methods[i].name != NULL; ++i)
+ if (strcasecmp(p->pop_parm[1], methods[i].name) == 0)
+ return (*methods[i].func)(p);
+ return pop_msg(p, POP_FAILURE,
+ "Authentication method %s unknown", p->pop_parm[1]);
+}
OpenPOWER on IntegriCloud