plain/server.c

Go to the documentation of this file.
00001 /* server.c --- SASL mechanism PLAIN as defined in RFC 2595, server side.
00002  * Copyright (C) 2002, 2003, 2004, 2005  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 "plain.h"
00029 
00030 /* Get memcpy, memchr, strlen. */
00031 #include <string.h>
00032 
00033 /* Get malloc, free. */
00034 #include <stdlib.h>
00035 
00036 int
00037 _gsasl_plain_server_step (Gsasl_session * sctx,
00038                           void *mech_data,
00039                           const char *input, size_t input_len,
00040                           char **output, size_t * output_len)
00041 {
00042   const char *authzidptr = input;
00043   char *authidptr = NULL;
00044   char *passwordptr = NULL;
00045   char *passwdz = NULL, *passprep = NULL, *authidprep = NULL;
00046   int res;
00047 
00048   *output_len = 0;
00049   *output = NULL;
00050 
00051   if (input_len == 0)
00052     return GSASL_NEEDS_MORE;
00053 
00054   /* Parse input. */
00055   {
00056     authidptr = memchr (input, 0, input_len - 1);
00057     if (authidptr)
00058       {
00059         authidptr++;
00060         passwordptr = memchr (authidptr, 0, input_len - strlen (input) - 1);
00061         if (passwordptr)
00062           passwordptr++;
00063         else
00064           return GSASL_MECHANISM_PARSE_ERROR;
00065       }
00066     else
00067       return GSASL_MECHANISM_PARSE_ERROR;
00068 
00069     /* As the NUL (U+0000) character is used as a deliminator, the NUL
00070        (U+0000) character MUST NOT appear in authzid, authcid, or passwd
00071        productions. */
00072     if (memchr (passwordptr, 0, input_len - (passwordptr - input)))
00073       return GSASL_MECHANISM_PARSE_ERROR;
00074   }
00075 
00076   /* Store authid, after preparing it... */
00077   {
00078     res = gsasl_saslprep (authidptr, GSASL_ALLOW_UNASSIGNED,
00079                           &authidprep, NULL);
00080     if (res != GSASL_OK)
00081       return res;
00082 
00083     gsasl_property_set (sctx, GSASL_AUTHID, authidprep);
00084 
00085     /* Store authzid, if absent, use SASLprep(authcid). */
00086     if (*authzidptr == '\0')
00087       gsasl_property_set (sctx, GSASL_AUTHZID, authidprep);
00088     else
00089       gsasl_property_set (sctx, GSASL_AUTHZID, authzidptr);
00090 
00091     free (authidprep);
00092   }
00093 
00094   /* Store passwd, after preparing it... */
00095   {
00096     /* Need to zero terminate password... */
00097     passwdz = malloc (input_len - (passwordptr - input) + 1);
00098     if (passwdz == NULL)
00099       return GSASL_MALLOC_ERROR;
00100     memcpy (passwdz, passwordptr, input_len - (passwordptr - input));
00101     passwdz[input_len - (passwordptr - input)] = '\0';
00102 
00103     res = gsasl_saslprep (passwdz, GSASL_ALLOW_UNASSIGNED,
00104                           &passprep, NULL);
00105     free (passwdz);
00106     if (res != GSASL_OK)
00107       return res;
00108 
00109     gsasl_property_set (sctx, GSASL_PASSWORD, passprep);
00110   }
00111 
00112   /* Authorization.  Let application verify credentials internally,
00113      but fall back to deal with it locally... */
00114   res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SIMPLE);
00115   if (res == GSASL_NO_CALLBACK)
00116     {
00117       const char *key;
00118       char *normkey;
00119 
00120       gsasl_property_set (sctx, GSASL_PASSWORD, NULL);
00121       key = gsasl_property_get (sctx, GSASL_PASSWORD);
00122       if (!key)
00123         {
00124           free (passprep);
00125           return GSASL_NO_PASSWORD;
00126         }
00127 
00128       /* Unassigned code points are not permitted. */
00129       res = gsasl_saslprep (key, 0, &normkey, NULL);
00130       if (res != GSASL_OK)
00131         {
00132           free (passprep);
00133           return res;
00134         }
00135 
00136       if (strcmp (normkey, passprep) == 0)
00137         res = GSASL_OK;
00138       else
00139         res = GSASL_AUTHENTICATION_ERROR;
00140       free (normkey);
00141     }
00142   free (passprep);
00143 
00144   return res;
00145 }

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