1 | /* client.c --- SASL CRAM-MD5 client side functions. |
2 | * Copyright (C) 2002-2012 Simon Josefsson |
3 | * |
4 | * This file is part of GNU SASL Library. |
5 | * |
6 | * GNU SASL Library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public License |
8 | * as published by the Free Software Foundation; either version 2.1 of |
9 | * the License, or (at your option) any later version. |
10 | * |
11 | * GNU SASL Library 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. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with GNU SASL Library; if not, write to the Free |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | * Boston, MA 02110-1301, USA. |
20 | * |
21 | */ |
22 | |
23 | #ifdef HAVE_CONFIG_H |
24 | #include "config.h" |
25 | #endif |
26 | |
27 | /* Get specification. */ |
28 | #include "cram-md5.h" |
29 | |
30 | /* Get malloc, free. */ |
31 | #include <stdlib.h> |
32 | |
33 | /* Get memcpy, strlen. */ |
34 | #include <string.h> |
35 | |
36 | /* Get cram_md5_digest. */ |
37 | #include "digest.h" |
38 | |
39 | int |
40 | _gsasl_cram_md5_client_step (Gsasl_session * sctx, |
41 | void *mech_data, |
42 | const char *input, size_t input_len, |
43 | char **output, size_t * output_len) |
44 | { |
45 | char response[CRAM_MD5_DIGEST_LEN]; |
46 | const char *p; |
47 | size_t len; |
48 | char *tmp; |
49 | char *authid; |
50 | int rc; |
51 | |
52 | if (input_len == 0) |
53 | { |
54 | *output_len = 0; |
55 | *output = NULL; |
56 | return GSASL_NEEDS_MORE; |
57 | } |
58 | |
59 | p = gsasl_property_get (sctx, GSASL_AUTHID); |
60 | if (!p) |
61 | return GSASL_NO_AUTHID; |
62 | |
63 | /* XXX Use query strings here? Specification is unclear. */ |
64 | rc = gsasl_saslprep (p, GSASL_ALLOW_UNASSIGNED, &authid, NULL); |
65 | if (rc != GSASL_OK) |
66 | return rc; |
67 | |
68 | p = gsasl_property_get (sctx, GSASL_PASSWORD); |
69 | if (!p) |
70 | { |
71 | free (authid); |
72 | return GSASL_NO_PASSWORD; |
73 | } |
74 | |
75 | /* XXX Use query strings here? Specification is unclear. */ |
76 | rc = gsasl_saslprep (p, GSASL_ALLOW_UNASSIGNED, &tmp, NULL); |
77 | if (rc != GSASL_OK) |
78 | { |
79 | free (authid); |
80 | return rc; |
81 | } |
82 | |
83 | cram_md5_digest (input, input_len, tmp, strlen (tmp), response); |
84 | |
85 | free (tmp); |
86 | |
87 | len = strlen (authid); |
88 | |
89 | *output_len = len + strlen (" " ) + CRAM_MD5_DIGEST_LEN; |
90 | *output = malloc (*output_len); |
91 | if (!*output) |
92 | { |
93 | free (authid); |
94 | return GSASL_MALLOC_ERROR; |
95 | } |
96 | |
97 | memcpy (*output, authid, len); |
98 | (*output)[len++] = ' '; |
99 | memcpy (*output + len, response, CRAM_MD5_DIGEST_LEN); |
100 | |
101 | free (authid); |
102 | |
103 | return GSASL_OK; |
104 | } |
105 | |