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
39int
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
55int
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
162void
163_gsasl_securid_client_finish (Gsasl_session * sctx, void *mech_data)
164{
165 int *step = mech_data;
166
167 free (step);
168}
169