gsasl  1.8.0
cram-md5/client.c
Go to the documentation of this file.
00001 /* client.c --- SASL CRAM-MD5 client side functions.
00002  * Copyright (C) 2002-2012 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 #ifdef 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, strlen. */
00034 #include <string.h>
00035 
00036 /* Get cram_md5_digest. */
00037 #include "digest.h"
00038 
00039 int
00040 _gsasl_cram_md5_client_step (Gsasl_session * sctx,
00041                              void *mech_data,
00042                              const char *input, size_t input_len,
00043                              char **output, size_t * output_len)
00044 {
00045   char response[CRAM_MD5_DIGEST_LEN];
00046   const char *p;
00047   size_t len;
00048   char *tmp;
00049   char *authid;
00050   int rc;
00051 
00052   if (input_len == 0)
00053     {
00054       *output_len = 0;
00055       *output = NULL;
00056       return GSASL_NEEDS_MORE;
00057     }
00058 
00059   p = gsasl_property_get (sctx, GSASL_AUTHID);
00060   if (!p)
00061     return GSASL_NO_AUTHID;
00062 
00063   /* XXX Use query strings here?  Specification is unclear. */
00064   rc = gsasl_saslprep (p, GSASL_ALLOW_UNASSIGNED, &authid, NULL);
00065   if (rc != GSASL_OK)
00066     return rc;
00067 
00068   p = gsasl_property_get (sctx, GSASL_PASSWORD);
00069   if (!p)
00070     {
00071       free (authid);
00072       return GSASL_NO_PASSWORD;
00073     }
00074 
00075   /* XXX Use query strings here?  Specification is unclear. */
00076   rc = gsasl_saslprep (p, GSASL_ALLOW_UNASSIGNED, &tmp, NULL);
00077   if (rc != GSASL_OK)
00078     {
00079       free (authid);
00080       return rc;
00081     }
00082 
00083   cram_md5_digest (input, input_len, tmp, strlen (tmp), response);
00084 
00085   free (tmp);
00086 
00087   len = strlen (authid);
00088 
00089   *output_len = len + strlen (" ") + CRAM_MD5_DIGEST_LEN;
00090   *output = malloc (*output_len);
00091   if (!*output)
00092     {
00093       free (authid);
00094       return GSASL_MALLOC_ERROR;
00095     }
00096 
00097   memcpy (*output, authid, len);
00098   (*output)[len++] = ' ';
00099   memcpy (*output + len, response, CRAM_MD5_DIGEST_LEN);
00100 
00101   free (authid);
00102 
00103   return GSASL_OK;
00104 }