0
|
1 /* ========================================================================
|
|
2 * Copyright 1988-2006 University of Washington
|
|
3 *
|
|
4 * Licensed under the Apache License, Version 2.0 (the "License");
|
|
5 * you may not use this file except in compliance with the License.
|
|
6 * You may obtain a copy of the License at
|
|
7 *
|
|
8 * http://www.apache.org/licenses/LICENSE-2.0
|
|
9 *
|
|
10 *
|
|
11 * ========================================================================
|
|
12 */
|
|
13
|
|
14 /*
|
|
15 * Program: Plain authenticator
|
|
16 *
|
|
17 * Author: Mark Crispin
|
|
18 * Networks and Distributed Computing
|
|
19 * Computing & Communications
|
|
20 * University of Washington
|
|
21 * Administration Building, AG-44
|
|
22 * Seattle, WA 98195
|
|
23 * Internet: MRC@CAC.Washington.EDU
|
|
24 *
|
|
25 * Date: 22 September 1998
|
|
26 * Last Edited: 30 August 2006
|
|
27 */
|
|
28
|
|
29 long auth_plain_client (authchallenge_t challenger,authrespond_t responder,
|
|
30 char *service,NETMBX *mb,void *stream,
|
|
31 unsigned long *trial,char *user);
|
|
32 char *auth_plain_server (authresponse_t responder,int argc,char *argv[]);
|
|
33
|
|
34 AUTHENTICATOR auth_pla = {
|
|
35 AU_AUTHUSER | AU_HIDE, /* allow authuser, hidden */
|
|
36 "PLAIN", /* authenticator name */
|
|
37 NIL, /* always valid */
|
|
38 auth_plain_client, /* client method */
|
|
39 auth_plain_server, /* server method */
|
|
40 NIL /* next authenticator */
|
|
41 };
|
|
42
|
|
43 /* Client authenticator
|
|
44 * Accepts: challenger function
|
|
45 * responder function
|
|
46 * SASL service name
|
|
47 * parsed network mailbox structure
|
|
48 * stream argument for functions
|
|
49 * pointer to current trial count
|
|
50 * returned user name
|
|
51 * Returns: T if success, NIL otherwise, number of trials incremented if retry
|
|
52 */
|
|
53
|
|
54 long auth_plain_client (authchallenge_t challenger,authrespond_t responder,
|
|
55 char *service,NETMBX *mb,void *stream,
|
|
56 unsigned long *trial,char *user)
|
|
57 {
|
|
58 char *u,pwd[MAILTMPLEN];
|
|
59 void *challenge;
|
|
60 unsigned long clen;
|
|
61 long ret = NIL;
|
|
62 /* snarl if not SSL/TLS session */
|
|
63 if (!mb->sslflag && !mb->tlsflag)
|
|
64 mm_log ("SECURITY PROBLEM: insecure server advertised AUTH=PLAIN",WARN);
|
|
65 /* get initial (empty) challenge */
|
|
66 if (challenge = (*challenger) (stream,&clen)) {
|
|
67 fs_give ((void **) &challenge);
|
|
68 if (clen) { /* abort if challenge non-empty */
|
|
69 mm_log ("Server bug: non-empty initial PLAIN challenge",WARN);
|
|
70 (*responder) (stream,NIL,0);
|
|
71 ret = LONGT; /* will get a BAD response back */
|
|
72 }
|
|
73 pwd[0] = NIL; /* prompt user if empty challenge */
|
|
74 mm_login (mb,user,pwd,*trial);
|
|
75 if (!pwd[0]) { /* empty challenge or user requested abort */
|
|
76 (*responder) (stream,NIL,0);
|
|
77 *trial = 0; /* cancel subsequent attempts */
|
|
78 ret = LONGT; /* will get a BAD response back */
|
|
79 }
|
|
80 else {
|
|
81 unsigned long rlen =
|
|
82 strlen (mb->authuser) + strlen (user) + strlen (pwd) + 2;
|
|
83 char *response = (char *) fs_get (rlen);
|
|
84 char *t = response; /* copy authorization id */
|
|
85 if (mb->authuser[0]) for (u = user; *u; *t++ = *u++);
|
|
86 *t++ = '\0'; /* delimiting NUL */
|
|
87 /* copy authentication id */
|
|
88 for (u = mb->authuser[0] ? mb->authuser : user; *u; *t++ = *u++);
|
|
89 *t++ = '\0'; /* delimiting NUL */
|
|
90 /* copy password */
|
|
91 for (u = pwd; *u; *t++ = *u++);
|
|
92 /* send credentials */
|
|
93 if ((*responder) (stream,response,rlen)) {
|
|
94 if (challenge = (*challenger) (stream,&clen))
|
|
95 fs_give ((void **) &challenge);
|
|
96 else {
|
|
97 ++*trial; /* can try again if necessary */
|
|
98 ret = LONGT; /* check the authentication */
|
|
99 }
|
|
100 }
|
|
101 memset (response,0,rlen); /* erase credentials */
|
|
102 fs_give ((void **) &response);
|
|
103 }
|
|
104 }
|
|
105 memset (pwd,0,MAILTMPLEN); /* erase password */
|
|
106 if (!ret) *trial = 65535; /* don't retry if bad protocol */
|
|
107 return ret;
|
|
108 }
|
|
109
|
|
110 /* Server authenticator
|
|
111 * Accepts: responder function
|
|
112 * argument count
|
|
113 * argument vector
|
|
114 * Returns: authenticated user name or NIL
|
|
115 */
|
|
116
|
|
117 char *auth_plain_server (authresponse_t responder,int argc,char *argv[])
|
|
118 {
|
|
119 char *ret = NIL;
|
|
120 char *user,*aid,*pass;
|
|
121 unsigned long len;
|
|
122 /* get user name */
|
|
123 if (aid = (*responder) ("",0,&len)) {
|
|
124 /* note: responders null-terminate */
|
|
125 if ((((unsigned long) ((user = aid + strlen (aid) + 1) - aid)) < len) &&
|
|
126 (((unsigned long) ((pass = user + strlen (user) + 1) - aid)) < len) &&
|
|
127 (((unsigned long) ((pass + strlen (pass)) - aid)) == len) &&
|
|
128 (*aid ? server_login (aid,pass,user,argc,argv) :
|
|
129 server_login (user,pass,NIL,argc,argv))) ret = myusername ();
|
|
130 fs_give ((void **) &aid);
|
|
131 }
|
|
132 return ret;
|
|
133 }
|