Init RSA repo.
[external/uw-imap-toolkit.git] / imap-2007e / c-client / auth_pla.c
1 /* ========================================================================
2  * Copyright 1988-2006 University of Washington
3  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
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 \f
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 \f
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 ("auth_plain_client : Server bug: non-empty initial PLAIN challenge 1",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
76     if (!pwd[0]) {              /* empty challenge or user requested abort */
77       (*responder) (stream,NIL,0);
78       *trial = 0;               /* cancel subsequent attempts */
79       ret = LONGT;              /* will get a BAD response back */
80     }
81     else {
82       unsigned long rlen = 
83         strlen (mb->authuser) + strlen (user) + strlen (pwd) + 2;
84       char *response = (char *) fs_get (rlen);
85       char *t = response;       /* copy authorization id */
86
87         memset(response, 0x00, rlen);
88
89       if (mb->authuser[0]) for (u = user; *u; *t++ = *u++);
90       *t++ = '\0';              /* delimiting NUL */
91
92                                 /* copy authentication id */
93       for (u = mb->authuser[0] ? mb->authuser : user; *u; *t++ = *u++);
94       *t++ = '\0';              /* delimiting NUL */
95
96                                 /* copy password */
97       for (u = pwd; *u; *t++ = *u++);
98                                 /* send credentials */
99         
100       if ((*responder) (stream,response,rlen)) {
101         if (challenge = (*challenger) (stream,&clen))
102         {
103           fs_give ((void **) &challenge);
104         }
105         else {
106           ++*trial;             /* can try again if necessary */
107           ret = LONGT;          /* check the authentication */
108         }
109       }
110       memset (response,0,rlen); /* erase credentials */
111       fs_give ((void **) &response);
112     }
113   }
114   else // [ Written by Kyuho Jo for AOL 2010/02/16
115   {
116         mm_log ("Enter section for handling emtpy challenge",WARN);
117     if (clen) 
118         {                       /* abort if challenge non-empty */
119       mm_log ("auth_plain_client : Server bug: non-empty initial PLAIN challenge 2",WARN);
120       (*responder) (stream,NIL,0);
121       ret = LONGT;              /* will get a BAD response back */
122     }
123     pwd[0] = NIL;               /* prompt user if empty challenge */
124
125         mm_login (mb,user,pwd,*trial);
126
127         if (pwd[0] == NULL) 
128     { /* empty challenge or user requested abort */
129       mm_log ("empty challenge or user requested abort",WARN);
130       (*responder) (stream,NIL,0);
131       *trial = 0;               /* cancel subsequent attempts */
132       ret = LONGT;              /* will get a BAD response back */
133     }
134     else 
135         {
136       unsigned long rlen = strlen (mb->authuser) + strlen (user) + strlen (pwd) + 2;
137       char *response = (char *) fs_get (rlen);
138       char *t = response;       /* copy authorization id */
139
140           mm_log ("copy authorization id ",WARN);
141
142           if (mb->authuser[0]) 
143                 for (u = user; *u; *t++ = *u++);
144           *t++ = '\0';          /* delimiting NUL */
145                                         /* copy authentication id */
146       for (u = mb->authuser[0] ? mb->authuser : user; *u; *t++ = *u++);
147       *t++ = '\0';              /* delimiting NUL */
148                                         /* copy password */
149       for (u = pwd; *u; *t++ = *u++); /* send credentials */
150
151           if ((*responder)(stream,response,rlen)) 
152           {
153             mm_log ("response ",WARN);
154             if (challenge = (*challenger) (stream,&clen))
155               fs_give ((void **) &challenge);
156             else 
157             {
158               mm_log ("Second emtpy challege  ",WARN);
159               ++*trial;         /* can try again if necessary */
160               ret = LONGT;              /* check the authentication */
161             }
162       }
163       memset (response,0,rlen); /* erase credentials */
164       fs_give ((void **) &response);
165     }
166         
167   }    // ] Written by Kyuho Jo for AOL 2010/02/16
168
169   memset (pwd,0,MAILTMPLEN);    /* erase password */
170   if (!ret) *trial = 65535;     /* don't retry if bad protocol */
171   return ret;
172 }
173 \f
174 /* Server authenticator
175  * Accepts: responder function
176  *          argument count
177  *          argument vector
178  * Returns: authenticated user name or NIL
179  */
180
181 char *auth_plain_server (authresponse_t responder,int argc,char *argv[])
182 {
183   char *ret = NIL;
184   char *user,*aid,*pass;
185   unsigned long len;
186                                 /* get user name */
187   if (aid = (*responder) ("",0,&len)) {
188                                 /* note: responders null-terminate */
189     if ((((unsigned long) ((user = aid + strlen (aid) + 1) - aid)) < len) &&
190         (((unsigned long) ((pass = user + strlen (user) + 1) - aid)) < len) &&
191         (((unsigned long) ((pass + strlen (pass)) - aid)) == len) &&
192         (*aid ? server_login (aid,pass,user,argc,argv) :
193          server_login (user,pass,NIL,argc,argv))) ret = myusername ();
194     fs_give ((void **) &aid);
195   }
196   return ret;
197 }