gsasl  1.8.0
securid/server.c
Go to the documentation of this file.
00001 /* server.c --- SASL mechanism SECURID from RFC 2808, server side.
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 "securid.h"
00029 
00030 /* Get malloc, free. */
00031 #include <stdlib.h>
00032 
00033 /* Get memchr, strdup, strlen. */
00034 #include <string.h>
00035 
00036 #define PASSCODE "passcode"
00037 #define PIN "pin"
00038 
00039 int
00040 _gsasl_securid_server_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   const char *authorization_id = NULL;
00046   const char *authentication_id = NULL;
00047   const char *passcode = NULL;
00048   const char *suggestedpin;
00049   char *pin = NULL;
00050   int res;
00051   size_t len;
00052 
00053   if (input_len == 0)
00054     {
00055       *output_len = 0;
00056       *output = NULL;
00057       return GSASL_NEEDS_MORE;
00058     }
00059 
00060   authorization_id = input;
00061   authentication_id = memchr (input, '\0', input_len - 1);
00062   if (authentication_id)
00063     {
00064       authentication_id++;
00065       passcode = memchr (authentication_id, '\0',
00066                          input_len - strlen (authorization_id) - 1 - 1);
00067       if (passcode)
00068         {
00069           passcode++;
00070           pin = memchr (passcode, '\0', input_len -
00071                         strlen (authorization_id) - 1 -
00072                         strlen (authentication_id) - 1 - 1);
00073           if (pin)
00074             {
00075               pin++;
00076               if (pin && !*pin)
00077                 pin = NULL;
00078             }
00079         }
00080     }
00081 
00082   if (passcode == NULL)
00083     return GSASL_MECHANISM_PARSE_ERROR;
00084 
00085   gsasl_property_set (sctx, GSASL_AUTHID, authentication_id);
00086   gsasl_property_set (sctx, GSASL_AUTHZID, authorization_id);
00087   gsasl_property_set (sctx, GSASL_PASSCODE, passcode);
00088   if (pin)
00089     gsasl_property_set (sctx, GSASL_PIN, pin);
00090   else
00091     gsasl_property_set (sctx, GSASL_PIN, NULL);
00092 
00093   res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SECURID);
00094   switch (res)
00095     {
00096     case GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE:
00097       *output = strdup (PASSCODE);
00098       if (!*output)
00099         return GSASL_MALLOC_ERROR;
00100       *output_len = strlen (PASSCODE);
00101       res = GSASL_NEEDS_MORE;
00102       break;
00103 
00104     case GSASL_SECURID_SERVER_NEED_NEW_PIN:
00105       suggestedpin = gsasl_property_get (sctx, GSASL_SUGGESTED_PIN);
00106       if (suggestedpin)
00107         len = strlen (suggestedpin);
00108       else
00109         len = 0;
00110       *output_len = strlen (PIN) + len;
00111       *output = malloc (*output_len);
00112       if (!*output)
00113         return GSASL_MALLOC_ERROR;
00114       memcpy (*output, PIN, strlen (PIN));
00115       if (suggestedpin)
00116         memcpy (*output + strlen (PIN), suggestedpin, len);
00117       res = GSASL_NEEDS_MORE;
00118       break;
00119 
00120     default:
00121       *output_len = 0;
00122       *output = NULL;
00123       break;
00124     }
00125 
00126   return res;
00127 }