Packaging: clean spec file
[platform/upstream/libgsasl.git] / securid / server.c
1 /* server.c --- SASL mechanism SECURID from RFC 2808, server side.
2  * Copyright (C) 2002-2012 Simon Josefsson
3  *
4  * This file is part of GNU SASL Library.
5  *
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.
10  *
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.
15  *
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.
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 /* Get specification. */
28 #include "securid.h"
29
30 /* Get malloc, free. */
31 #include <stdlib.h>
32
33 /* Get memchr, strdup, strlen. */
34 #include <string.h>
35
36 #define PASSCODE "passcode"
37 #define PIN "pin"
38
39 int
40 _gsasl_securid_server_step (Gsasl_session * sctx,
41                             void *mech_data,
42                             const char *input, size_t input_len,
43                             char **output, size_t * output_len)
44 {
45   const char *authorization_id = NULL;
46   const char *authentication_id = NULL;
47   const char *passcode = NULL;
48   const char *suggestedpin;
49   char *pin = NULL;
50   int res;
51   size_t len;
52
53   if (input_len == 0)
54     {
55       *output_len = 0;
56       *output = NULL;
57       return GSASL_NEEDS_MORE;
58     }
59
60   authorization_id = input;
61   authentication_id = memchr (input, '\0', input_len - 1);
62   if (authentication_id)
63     {
64       authentication_id++;
65       passcode = memchr (authentication_id, '\0',
66                          input_len - strlen (authorization_id) - 1 - 1);
67       if (passcode)
68         {
69           passcode++;
70           pin = memchr (passcode, '\0', input_len -
71                         strlen (authorization_id) - 1 -
72                         strlen (authentication_id) - 1 - 1);
73           if (pin)
74             {
75               pin++;
76               if (pin && !*pin)
77                 pin = NULL;
78             }
79         }
80     }
81
82   if (passcode == NULL)
83     return GSASL_MECHANISM_PARSE_ERROR;
84
85   gsasl_property_set (sctx, GSASL_AUTHID, authentication_id);
86   gsasl_property_set (sctx, GSASL_AUTHZID, authorization_id);
87   gsasl_property_set (sctx, GSASL_PASSCODE, passcode);
88   if (pin)
89     gsasl_property_set (sctx, GSASL_PIN, pin);
90   else
91     gsasl_property_set (sctx, GSASL_PIN, NULL);
92
93   res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SECURID);
94   switch (res)
95     {
96     case GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE:
97       *output = strdup (PASSCODE);
98       if (!*output)
99         return GSASL_MALLOC_ERROR;
100       *output_len = strlen (PASSCODE);
101       res = GSASL_NEEDS_MORE;
102       break;
103
104     case GSASL_SECURID_SERVER_NEED_NEW_PIN:
105       suggestedpin = gsasl_property_get (sctx, GSASL_SUGGESTED_PIN);
106       if (suggestedpin)
107         len = strlen (suggestedpin);
108       else
109         len = 0;
110       *output_len = strlen (PIN) + len;
111       *output = malloc (*output_len);
112       if (!*output)
113         return GSASL_MALLOC_ERROR;
114       memcpy (*output, PIN, strlen (PIN));
115       if (suggestedpin)
116         memcpy (*output + strlen (PIN), suggestedpin, len);
117       res = GSASL_NEEDS_MORE;
118       break;
119
120     default:
121       *output_len = 0;
122       *output = NULL;
123       break;
124     }
125
126   return res;
127 }