1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2020, 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 https://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 * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
23 *
24 ***************************************************************************/
25
26 #include "curl_setup.h"
27
28 #if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
29 !defined(CURL_DISABLE_POP3)
30
31 #include <curl/curl.h>
32 #include "urldata.h"
33
34 #include "vauth/vauth.h"
35 #include "curl_base64.h"
36 #include "curl_md5.h"
37 #include "warnless.h"
38 #include "strtok.h"
39 #include "sendf.h"
40 #include "curl_printf.h"
41
42 /* The last #include files should be: */
43 #include "curl_memory.h"
44 #include "memdebug.h"
45
46 /*
47 * Curl_auth_create_plain_message()
48 *
49 * This is used to generate an already encoded PLAIN message ready
50 * for sending to the recipient.
51 *
52 * Parameters:
53 *
54 * data [in] - The session handle.
55 * authzid [in] - The authorization identity.
56 * authcid [in] - The authentication identity.
57 * passwd [in] - The password.
58 * outptr [in/out] - The address where a pointer to newly allocated memory
59 * holding the result will be stored upon completion.
60 * outlen [out] - The length of the output message.
61 *
62 * Returns CURLE_OK on success.
63 */
Curl_auth_create_plain_message(struct Curl_easy * data,const char * authzid,const char * authcid,const char * passwd,char ** outptr,size_t * outlen)64 CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
65 const char *authzid,
66 const char *authcid,
67 const char *passwd,
68 char **outptr, size_t *outlen)
69 {
70 CURLcode result;
71 char *plainauth;
72 size_t zlen;
73 size_t clen;
74 size_t plen;
75 size_t plainlen;
76
77 *outlen = 0;
78 *outptr = NULL;
79 zlen = (authzid == NULL ? 0 : strlen(authzid));
80 clen = strlen(authcid);
81 plen = strlen(passwd);
82
83 /* Compute binary message length. Check for overflows. */
84 if((zlen > SIZE_T_MAX/4) || (clen > SIZE_T_MAX/4) ||
85 (plen > (SIZE_T_MAX/2 - 2)))
86 return CURLE_OUT_OF_MEMORY;
87 plainlen = zlen + clen + plen + 2;
88
89 plainauth = malloc(plainlen);
90 if(!plainauth)
91 return CURLE_OUT_OF_MEMORY;
92
93 /* Calculate the reply */
94 if(zlen != 0)
95 memcpy(plainauth, authzid, zlen);
96 plainauth[zlen] = '\0';
97 memcpy(plainauth + zlen + 1, authcid, clen);
98 plainauth[zlen + clen + 1] = '\0';
99 memcpy(plainauth + zlen + clen + 2, passwd, plen);
100
101 /* Base64 encode the reply */
102 result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen);
103 free(plainauth);
104
105 return result;
106 }
107
108 /*
109 * Curl_auth_create_login_message()
110 *
111 * This is used to generate an already encoded LOGIN message containing the
112 * user name or password ready for sending to the recipient.
113 *
114 * Parameters:
115 *
116 * data [in] - The session handle.
117 * valuep [in] - The user name or user's password.
118 * outptr [in/out] - The address where a pointer to newly allocated memory
119 * holding the result will be stored upon completion.
120 * outlen [out] - The length of the output message.
121 *
122 * Returns CURLE_OK on success.
123 */
Curl_auth_create_login_message(struct Curl_easy * data,const char * valuep,char ** outptr,size_t * outlen)124 CURLcode Curl_auth_create_login_message(struct Curl_easy *data,
125 const char *valuep, char **outptr,
126 size_t *outlen)
127 {
128 size_t vlen = strlen(valuep);
129
130 if(!vlen) {
131 /* Calculate an empty reply */
132 *outptr = strdup("=");
133 if(*outptr) {
134 *outlen = (size_t) 1;
135 return CURLE_OK;
136 }
137
138 *outlen = 0;
139 return CURLE_OUT_OF_MEMORY;
140 }
141
142 /* Base64 encode the value */
143 return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
144 }
145
146 /*
147 * Curl_auth_create_external_message()
148 *
149 * This is used to generate an already encoded EXTERNAL message containing
150 * the user name ready for sending to the recipient.
151 *
152 * Parameters:
153 *
154 * data [in] - The session handle.
155 * user [in] - The user name.
156 * outptr [in/out] - The address where a pointer to newly allocated memory
157 * holding the result will be stored upon completion.
158 * outlen [out] - The length of the output message.
159 *
160 * Returns CURLE_OK on success.
161 */
Curl_auth_create_external_message(struct Curl_easy * data,const char * user,char ** outptr,size_t * outlen)162 CURLcode Curl_auth_create_external_message(struct Curl_easy *data,
163 const char *user, char **outptr,
164 size_t *outlen)
165 {
166 /* This is the same formatting as the login message */
167 return Curl_auth_create_login_message(data, user, outptr, outlen);
168 }
169
170 #endif /* if no users */
171