cram-md5/server.c

Go to the documentation of this file.
00001 /* server.c --- SASL CRAM-MD5 server side functions.
00002  * Copyright (C) 2002, 2003, 2004, 2006  Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with GNU SASL Library; if not, write to the Free
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #if HAVE_CONFIG_H
00024 # include "config.h"
00025 #endif
00026 
00027 /* Get specification. */
00028 #include "cram-md5.h"
00029 
00030 /* Get malloc, free. */
00031 #include <stdlib.h>
00032 
00033 /* Get memcpy, strdup, strlen. */
00034 #include <string.h>
00035 
00036 /* Get cram_md5_challenge. */
00037 #include "challenge.h"
00038 
00039 /* Get cram_md5_digest. */
00040 #include "digest.h"
00041 
00042 #define MD5LEN 16
00043 
00044 int
00045 _gsasl_cram_md5_server_start (Gsasl_session * sctx, void **mech_data)
00046 {
00047   char *challenge;
00048 
00049   challenge = malloc (CRAM_MD5_CHALLENGE_LEN);
00050   if (challenge == NULL)
00051     return GSASL_MALLOC_ERROR;
00052 
00053   cram_md5_challenge (challenge);
00054 
00055   *mech_data = challenge;
00056 
00057   return GSASL_OK;
00058 }
00059 
00060 int
00061 _gsasl_cram_md5_server_step (Gsasl_session * sctx,
00062                              void *mech_data,
00063                              const char *input, size_t input_len,
00064                              char **output, size_t * output_len)
00065 {
00066   char *challenge = mech_data;
00067   char hash[CRAM_MD5_DIGEST_LEN];
00068   const char *password;
00069   char *username = NULL;
00070   int res = GSASL_OK;
00071   char *normkey;
00072 
00073   if (input_len == 0)
00074     {
00075       *output_len = strlen (challenge);
00076       *output = strdup (challenge);
00077 
00078       return GSASL_NEEDS_MORE;
00079     }
00080 
00081   if (input_len <= MD5LEN * 2)
00082     return GSASL_MECHANISM_PARSE_ERROR;
00083 
00084   if (input[input_len - MD5LEN * 2 - 1] != ' ')
00085     return GSASL_MECHANISM_PARSE_ERROR;
00086 
00087   username = calloc (1, input_len - MD5LEN * 2);
00088   if (username == NULL)
00089     return GSASL_MALLOC_ERROR;
00090 
00091   memcpy (username, input, input_len - MD5LEN * 2 - 1);
00092 
00093   gsasl_property_set (sctx, GSASL_AUTHID, username);
00094 
00095   free (username);
00096 
00097   password = gsasl_property_get (sctx, GSASL_PASSWORD);
00098   if (!password)
00099     return GSASL_NO_PASSWORD;
00100 
00101   /* FIXME: Use SASLprep here?  Treat string as storage string?
00102      Specification is unclear. */
00103   res = gsasl_saslprep (password, 0, &normkey, NULL);
00104   if (res != GSASL_OK)
00105     return res;
00106 
00107   cram_md5_digest (challenge, strlen (challenge),
00108                    normkey, strlen (normkey), hash);
00109 
00110   free (normkey);
00111 
00112   if (memcmp (&input[input_len - MD5LEN * 2], hash, 2 * MD5LEN) == 0)
00113     res = GSASL_OK;
00114   else
00115     res = GSASL_AUTHENTICATION_ERROR;
00116 
00117   *output_len = 0;
00118   *output = NULL;
00119 
00120   return res;
00121 }
00122 
00123 void
00124 _gsasl_cram_md5_server_finish (Gsasl_session * sctx, void *mech_data)
00125 {
00126   char *challenge = mech_data;
00127 
00128   if (challenge)
00129     free (challenge);
00130 }

Generated on Tue Aug 22 12:06:06 2006 for gsasl by  doxygen 1.4.7