1 /* plain.c implementation of SASL mechanism PLAIN as defined in RFC 2595
2 * Copyright (C) 2002 Simon Josefsson
4 * This file is part of libgsasl.
6 * Libgsasl is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * Libgsasl is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with libgsasl; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 _gsasl_plain_client_init (Gsasl_ctx
*ctx
)
33 _gsasl_plain_client_done (Gsasl_ctx
*ctx
)
39 _gsasl_plain_client_start (Gsasl_session_ctx
*cctx
,
45 ctx
= gsasl_client_ctx_get (cctx
);
47 return GSASL_CANNOT_GET_CTX
;
49 if (gsasl_client_callback_authorization_id_get (ctx
) == NULL
)
50 return GSASL_NEED_CLIENT_AUTHORIZATION_ID_CALLBACK
;
52 if (gsasl_client_callback_authentication_id_get (ctx
) == NULL
)
53 return GSASL_NEED_CLIENT_AUTHENTICATION_ID_CALLBACK
;
55 if (gsasl_client_callback_password_get (ctx
) == NULL
)
56 return GSASL_NEED_CLIENT_PASSWORD_CALLBACK
;
58 step
= (int*) malloc(sizeof(*step
));
60 return GSASL_MALLOC_ERROR
;
70 _gsasl_plain_client_step (Gsasl_session_ctx
*cctx
,
77 int *step
= mech_data
;
78 Gsasl_client_callback_authentication_id cb_authentication_id
;
79 Gsasl_client_callback_authorization_id cb_authorization_id
;
80 Gsasl_client_callback_password cb_password
;
89 ctx
= gsasl_client_ctx_get (cctx
);
91 return GSASL_CANNOT_GET_CTX
;
93 cb_authorization_id
= gsasl_client_callback_authorization_id_get (ctx
);
94 if (cb_authorization_id
== NULL
)
95 return GSASL_NEED_CLIENT_AUTHORIZATION_ID_CALLBACK
;
97 cb_authentication_id
= gsasl_client_callback_authentication_id_get (ctx
);
98 if (cb_authentication_id
== NULL
)
99 return GSASL_NEED_CLIENT_AUTHENTICATION_ID_CALLBACK
;
101 cb_password
= gsasl_client_callback_password_get (ctx
);
102 if (cb_password
== NULL
)
103 return GSASL_NEED_CLIENT_PASSWORD_CALLBACK
;
107 len
= *output_len
- (tmp
- output
);
108 res
= cb_authorization_id (cctx
, tmp
, &len
);
111 tmp2
= gsasl_utf8_nfkc_normalize (tmp
, len
);
113 return GSASL_UNICODE_NORMALIZATION_ERROR
;
114 if (*output_len
<= tmp
- output
+ strlen(tmp2
))
115 return GSASL_TOO_SMALL_BUFFER
;
116 memcpy(tmp
, tmp2
, strlen(tmp2
));
121 len
= *output_len
- (tmp
- output
);
122 res
= cb_authentication_id (cctx
, tmp
, &len
);
125 tmp2
= gsasl_utf8_nfkc_normalize (tmp
, len
);
127 return GSASL_UNICODE_NORMALIZATION_ERROR
;
128 if (*output_len
<= tmp
- output
+ strlen(tmp2
))
129 return GSASL_TOO_SMALL_BUFFER
;
130 memcpy(tmp
, tmp2
, strlen(tmp2
));
135 len
= *output_len
- (tmp
- output
);
136 res
= cb_password (cctx
, tmp
, &len
);
139 tmp2
= gsasl_utf8_nfkc_normalize (tmp
, len
);
141 return GSASL_UNICODE_NORMALIZATION_ERROR
;
142 if (*output_len
<= tmp
- output
+ strlen(tmp2
))
143 return GSASL_TOO_SMALL_BUFFER
;
144 memcpy(tmp
, tmp2
, strlen(tmp2
));
148 *output_len
= tmp
- output
;
152 return GSASL_NEEDS_MORE
;
156 _gsasl_plain_client_finish (Gsasl_session_ctx
*cctx
,
159 int *step
= mech_data
;
169 _gsasl_plain_server_init (Gsasl_ctx
*ctx
)
175 _gsasl_plain_server_done (Gsasl_ctx
*ctx
)
181 _gsasl_plain_server_start (Gsasl_session_ctx
*sctx
,
186 ctx
= gsasl_server_ctx_get (sctx
);
188 return GSASL_CANNOT_GET_CTX
;
190 if (gsasl_server_callback_validate_get (ctx
) == NULL
&&
191 gsasl_server_callback_retrieve_get (ctx
) == NULL
)
192 return GSASL_NEED_SERVER_VALIDATE_CALLBACK
;
198 _gsasl_plain_server_step (Gsasl_session_ctx
*sctx
,
205 Gsasl_server_callback_validate cb_validate
;
206 Gsasl_server_callback_retrieve cb_retrieve
;
207 char *authorization_id
= NULL
;
208 char *authentication_id
= NULL
;
209 char *passwordptr
= NULL
;
210 char *password
= NULL
;
217 return GSASL_NEEDS_MORE
;
220 authorization_id
= input
;
221 authentication_id
= memchr(input
, 0, input_len
);
222 if (authentication_id
)
225 passwordptr
= memchr(authentication_id
, 0,
226 input_len
- strlen(authorization_id
) - 1);
227 if (passwordptr
!= NULL
)
231 if (passwordptr
== NULL
)
232 return GSASL_MECHANISM_PARSE_ERROR
;
234 password
= malloc(input_len
- (passwordptr
- input
) + 1);
235 if (password
== NULL
)
236 return GSASL_MALLOC_ERROR
;
237 memcpy(password
, passwordptr
, input_len
- (passwordptr
- input
));
238 password
[input_len
- (passwordptr
- input
)] = '\0';
240 ctx
= gsasl_server_ctx_get (sctx
);
242 return GSASL_CANNOT_GET_CTX
;
244 cb_validate
= gsasl_server_callback_validate_get (ctx
);
245 cb_retrieve
= gsasl_server_callback_retrieve_get (ctx
);
246 if (cb_validate
== NULL
&& cb_retrieve
== NULL
)
247 return GSASL_NEED_SERVER_VALIDATE_CALLBACK
;
251 res
= cb_validate(sctx
, authorization_id
, authentication_id
, password
);
259 res
= cb_retrieve(sctx
, authentication_id
, authorization_id
, NULL
,
263 key
= malloc(keylen
);
265 return GSASL_MALLOC_ERROR
;
266 res
= cb_retrieve(sctx
, authentication_id
, authorization_id
, NULL
,
273 normkey
= gsasl_utf8_nfkc_normalize (key
, keylen
);
278 return GSASL_UNICODE_NORMALIZATION_ERROR
;
280 if (strlen(password
) == strlen(normkey
) &&
281 memcmp(normkey
, password
, strlen(normkey
)) == 0)
284 res
= GSASL_AUTHENTICATION_ERROR
;
292 _gsasl_plain_server_finish (Gsasl_session_ctx
*sctx
,
298 #endif /* USE_PLAIN */