1 /* server.c --- SASL CRAM-MD5 server side functions.
2 * Copyright (C) 2002, 2003, 2004, 2006 Simon Josefsson
4 * This file is part of GNU SASL Library.
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.
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.
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.
27 /* Get specification. */
30 /* Get malloc, free. */
33 /* Get memcpy, strdup, strlen. */
36 /* Get cram_md5_challenge. */
37 #include "challenge.h"
39 /* Get cram_md5_digest. */
45 _gsasl_cram_md5_server_start (Gsasl_session
* sctx
, void **mech_data
)
49 challenge
= malloc (CRAM_MD5_CHALLENGE_LEN
);
50 if (challenge
== NULL
)
51 return GSASL_MALLOC_ERROR
;
53 cram_md5_challenge (challenge
);
55 *mech_data
= challenge
;
61 _gsasl_cram_md5_server_step (Gsasl_session
* sctx
,
63 const char *input
, size_t input_len
,
64 char **output
, size_t * output_len
)
66 char *challenge
= mech_data
;
67 char hash
[CRAM_MD5_DIGEST_LEN
];
69 char *username
= NULL
;
75 *output_len
= strlen (challenge
);
76 *output
= strdup (challenge
);
78 return GSASL_NEEDS_MORE
;
81 if (input_len
<= MD5LEN
* 2)
82 return GSASL_MECHANISM_PARSE_ERROR
;
84 if (input
[input_len
- MD5LEN
* 2 - 1] != ' ')
85 return GSASL_MECHANISM_PARSE_ERROR
;
87 username
= calloc (1, input_len
- MD5LEN
* 2);
89 return GSASL_MALLOC_ERROR
;
91 memcpy (username
, input
, input_len
- MD5LEN
* 2 - 1);
93 gsasl_property_set (sctx
, GSASL_AUTHID
, username
);
97 password
= gsasl_property_get (sctx
, GSASL_PASSWORD
);
99 return GSASL_NO_PASSWORD
;
101 /* FIXME: Use SASLprep here? Treat string as storage string?
102 Specification is unclear. */
103 res
= gsasl_saslprep (password
, 0, &normkey
, NULL
);
107 cram_md5_digest (challenge
, strlen (challenge
),
108 normkey
, strlen (normkey
), hash
);
112 if (memcmp (&input
[input_len
- MD5LEN
* 2], hash
, 2 * MD5LEN
) == 0)
115 res
= GSASL_AUTHENTICATION_ERROR
;
124 _gsasl_cram_md5_server_finish (Gsasl_session
* sctx
, void *mech_data
)
126 char *challenge
= mech_data
;