Packaging: clean spec file
[platform/upstream/libgsasl.git] / securid / client.c
1 /* client.c --- SASL mechanism SECURID from RFC 2808, client 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 strdup, strlen. */
34 #include <string.h>
35
36 #define PASSCODE "passcode"
37 #define PIN "pin"
38
39 int
40 _gsasl_securid_client_start (Gsasl_session * sctx, void **mech_data)
41 {
42   int *step;
43
44   step = (int *) malloc (sizeof (*step));
45   if (step == NULL)
46     return GSASL_MALLOC_ERROR;
47
48   *step = 0;
49
50   *mech_data = step;
51
52   return GSASL_OK;
53 }
54
55 int
56 _gsasl_securid_client_step (Gsasl_session * sctx,
57                             void *mech_data,
58                             const char *input,
59                             size_t input_len,
60                             char **output, size_t * output_len)
61 {
62   int *step = mech_data;
63   const char *authzid = NULL, *authid = NULL, *passcode = NULL, *pin = NULL;
64   size_t authzidlen, authidlen, passcodelen, pinlen = 0;
65   int do_pin = 0;
66   int res;
67
68   switch (*step)
69     {
70     case 1:
71       if (input_len == strlen (PASSCODE) &&
72           memcmp (input, PASSCODE, strlen (PASSCODE)) == 0)
73         {
74           *step = 0;
75         }
76       else if (input_len >= strlen (PIN) &&
77                memcmp (input, PIN, strlen (PIN)) == 0)
78         {
79           do_pin = 1;
80           *step = 0;
81         }
82       else
83         {
84           *output_len = 0;
85           res = GSASL_OK;
86           break;
87         }
88       /* fall through */
89
90     case 0:
91       authzid = gsasl_property_get (sctx, GSASL_AUTHZID);
92       if (authzid)
93         authzidlen = strlen (authzid);
94       else
95         authzidlen = 0;
96
97       authid = gsasl_property_get (sctx, GSASL_AUTHID);
98       if (!authid)
99         return GSASL_NO_AUTHID;
100       authidlen = strlen (authid);
101
102       passcode = gsasl_property_get (sctx, GSASL_PASSCODE);
103       if (!passcode)
104         return GSASL_NO_PASSCODE;
105       passcodelen = strlen (passcode);
106
107       if (do_pin)
108         {
109           if (input_len > strlen (PIN))
110             gsasl_property_set_raw (sctx, GSASL_SUGGESTED_PIN,
111                                     &input[strlen (PIN)],
112                                     input_len - strlen (PIN));
113
114           pin = gsasl_property_get (sctx, GSASL_PIN);
115           if (!pin)
116             return GSASL_NO_PIN;
117           pinlen = strlen (pin);
118         }
119
120       *output_len = authzidlen + 1 + authidlen + 1 + passcodelen + 1;
121       if (do_pin)
122         *output_len += pinlen + 1;
123       *output = malloc (*output_len);
124       if (*output == NULL)
125         return GSASL_MALLOC_ERROR;
126
127       if (authzid)
128         memcpy (*output, authzid, authzidlen);
129       (*output)[authzidlen] = '\0';
130       memcpy (*output + authzidlen + 1, authid, authidlen);
131       (*output)[authzidlen + 1 + authidlen] = '\0';
132       memcpy (*output + authzidlen + 1 + authidlen + 1, passcode,
133               passcodelen);
134       (*output)[authzidlen + 1 + authidlen + 1 + passcodelen] = '\0';
135       if (do_pin)
136         {
137           memcpy (*output + authzidlen + 1 + authidlen + 1 + passcodelen + 1,
138                   pin, pinlen);
139           (*output)[authzidlen + 1 + authidlen + 1 + passcodelen + 1 +
140                     pinlen] = '\0';
141         }
142
143       (*step)++;
144       res = GSASL_OK;
145       break;
146
147     case 2:
148       *output_len = 0;
149       *output = NULL;
150       (*step)++;
151       res = GSASL_OK;
152       break;
153
154     default:
155       res = GSASL_MECHANISM_CALLED_TOO_MANY_TIMES;
156       break;
157     }
158
159   return res;
160 }
161
162 void
163 _gsasl_securid_client_finish (Gsasl_session * sctx, void *mech_data)
164 {
165   int *step = mech_data;
166
167   free (step);
168 }