sasl: Moved ntlm authentication message handling from smtp.c
[platform/upstream/curl.git] / lib / curl_sasl.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * RFC4616 PLAIN authentication
22  *
23  ***************************************************************************/
24
25 #include "setup.h"
26
27 #include <curl/curl.h>
28 #include "urldata.h"
29
30 #include "curl_base64.h"
31 #include "curl_ntlm_msgs.h"
32 #include "curl_sasl.h"
33
34 /* The last #include file should be: */
35 #include "memdebug.h"
36
37 /*
38  * Curl_sasl_create_plain_message()
39  *
40  * This is used to generate an already encoded plain message ready
41  * for sending to the recipient.
42  *
43  * Parameters:
44  *
45  * data    [in]     - The session handle.
46  * userp   [in]     - The user name.
47  * passdwp [in]     - The user's password.
48  * outptr  [in/out] - The address where a pointer to newly allocated memory
49  *                    holding the result will be stored upon completion.
50  * outlen  [out]    - The length of the output message.
51  *
52  * Returns CURLE_OK on success.
53  */
54 CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
55                                         const char* userp,
56                                         const char* passwdp,
57                                         char **outptr, size_t *outlen)
58 {
59   char plainauth[2 * MAX_CURL_USER_LENGTH + MAX_CURL_PASSWORD_LENGTH];
60   size_t ulen;
61   size_t plen;
62
63   ulen = strlen(userp);
64   plen = strlen(passwdp);
65
66   if(2 * ulen + plen + 2 > sizeof(plainauth)) {
67     *outlen = 0;
68     *outptr = NULL;
69     return CURLE_OUT_OF_MEMORY; /* plainauth too small */
70   }
71
72   memcpy(plainauth, userp, ulen);
73   plainauth[ulen] = '\0';
74   memcpy(plainauth + ulen + 1, userp, ulen);
75   plainauth[2 * ulen + 1] = '\0';
76   memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
77
78   return Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
79                             outlen);
80 }
81
82 /*
83  * Curl_sasl_create_login_message()
84  *
85  * This is used to generate an already encoded login message containing the
86  * user name or password ready for sending to the recipient.
87  *
88  * Parameters:
89  *
90  * data    [in]     - The session handle.
91  * userp   [in]     - The user name.
92  * outptr  [in/out] - The address where a pointer to newly allocated memory
93  *                    holding the result will be stored upon completion.
94  * outlen  [out]    - The length of the output message.
95  *
96  * Returns CURLE_OK on success.
97  */
98 CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
99                                         const char* valuep, char **outptr,
100                                         size_t *outlen)
101 {
102   size_t vlen = strlen(valuep);
103
104   if(!vlen) {
105     *outptr = strdup("=");
106     if(*outptr) {
107       *outlen = (size_t) 1;
108       return CURLE_OK;
109     }
110
111     *outlen = 0;
112     return CURLE_OUT_OF_MEMORY;
113   }
114
115   return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
116 }
117
118 #ifdef USE_NTLM
119 /*
120  * Curl_sasl_create_ntlm_type1_message()
121  *
122  * This is used to generate an already encoded NTLM type-1 message ready for
123  * sending to the recipient.
124  *
125  * Note: This is a simple wrapper of the NTLM function which means that any
126  * SASL based protocols don't have to include the NTLM functions directly.
127  *
128  * Parameters:
129  *
130  * userp   [in]     - The user name in the format User or Domain\User.
131  * passdwp [in]     - The user's password.
132  * ntlm    [in/out] - The ntlm data struct being used and modified.
133  * outptr  [in/out] - The address where a pointer to newly allocated memory
134  *                    holding the result will be stored upon completion.
135  * outlen  [out]    - The length of the output message.
136  *
137  * Returns CURLE_OK on success.
138  */
139 CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
140                                              const char *passwdp,
141                                              struct ntlmdata *ntlm,
142                                              char **outptr, size_t *outlen)
143 {
144   return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr,
145                                         outlen);
146 }
147
148 /*
149  * Curl_sasl_decode_ntlm_type2_message()
150  *
151  * This is used to decode a ntlm type-2 message received from a recipient and
152  * generate the already encoded NTLM type-3 message ready for sending back.
153  *
154  * Parameters:
155  *
156  * data    [in]     - Pointer to session handle.
157  * header  [in]     - Pointer to the input buffer.
158  * userp   [in]     - The user name in the format User or Domain\User.
159  * passdwp [in]     - The user's password.
160  * ntlm    [in/out] - The ntlm data struct being used and modified.
161  * outptr  [in/out] - The address where a pointer to newly allocated memory
162  *                    holding the result will be stored upon completion.
163  * outlen  [out]    - The length of the output message.
164  *
165  * Returns CURLE_OK on success.
166  */
167 CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
168                                              const char *header,
169                                              const char *userp,
170                                              const char *passwdp,
171                                              struct ntlmdata *ntlm,
172                                              char **outptr, size_t *outlen)
173 {
174   CURLcode result = Curl_ntlm_decode_type2_message(data, header, ntlm);
175
176   if(!result)
177     result = Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm,
178                                             outptr, outlen);
179
180   return result;
181 }
182 #endif /* USE_NTLM */
183
184 /*
185  * Curl_sasl_cleanup()
186  *
187  * This is used to cleanup any libraries or curl modules used by the sasl
188  * functions.
189  *
190  * Parameters:
191  *
192  * conn     [in]     - Pointer to the connection data.
193  * authused [in]     - The authentication mechanism used.
194  */
195 void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
196 {
197 #ifdef USE_NTLM
198   /* Cleanup the ntlm structure */
199   if(authused == SASL_AUTH_NTLM) {
200     Curl_ntlm_sspi_cleanup(&conn->ntlm);
201   }
202 #else
203   /* Reserved for future use */
204   (void)conn;
205   (void)authused;
206 #endif
207 }