Branch data Line data Source code
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 : 18 : _gsasl_securid_client_start (Gsasl_session * sctx, void **mech_data)
41 : : {
42 : : int *step;
43 : :
44 : 18 : step = (int *) malloc (sizeof (*step));
45 [ - + ]: 18 : if (step == NULL)
46 : 0 : return GSASL_MALLOC_ERROR;
47 : :
48 : 18 : *step = 0;
49 : :
50 : 18 : *mech_data = step;
51 : :
52 : 18 : return GSASL_OK;
53 : : }
54 : :
55 : : int
56 : 25 : _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 : 25 : int *step = mech_data;
63 : 25 : const char *authzid = NULL, *authid = NULL, *passcode = NULL, *pin = NULL;
64 : 25 : size_t authzidlen, authidlen, passcodelen, pinlen = 0;
65 : 25 : int do_pin = 0;
66 : : int res;
67 : :
68 [ + + - - ]: 25 : switch (*step)
69 : : {
70 : : case 1:
71 [ + + ][ + - ]: 10 : if (input_len == strlen (PASSCODE) &&
72 : 4 : memcmp (input, PASSCODE, strlen (PASSCODE)) == 0)
73 : : {
74 : 4 : *step = 0;
75 : : }
76 [ + - ][ + - ]: 6 : else if (input_len >= strlen (PIN) &&
77 : 6 : memcmp (input, PIN, strlen (PIN)) == 0)
78 : : {
79 : 6 : do_pin = 1;
80 : 6 : *step = 0;
81 : : }
82 : : else
83 : : {
84 : 0 : *output_len = 0;
85 : 0 : res = GSASL_OK;
86 : 0 : break;
87 : : }
88 : : /* fall through */
89 : :
90 : : case 0:
91 : 25 : authzid = gsasl_property_get (sctx, GSASL_AUTHZID);
92 [ + + ]: 25 : if (authzid)
93 : 20 : authzidlen = strlen (authzid);
94 : : else
95 : 5 : authzidlen = 0;
96 : :
97 : 25 : authid = gsasl_property_get (sctx, GSASL_AUTHID);
98 [ + + ]: 25 : if (!authid)
99 : 5 : return GSASL_NO_AUTHID;
100 : 20 : authidlen = strlen (authid);
101 : :
102 : 20 : passcode = gsasl_property_get (sctx, GSASL_PASSCODE);
103 [ - + ]: 20 : if (!passcode)
104 : 0 : return GSASL_NO_PASSCODE;
105 : 20 : passcodelen = strlen (passcode);
106 : :
107 [ + + ]: 20 : if (do_pin)
108 : : {
109 [ + + ]: 6 : if (input_len > strlen (PIN))
110 : 4 : gsasl_property_set_raw (sctx, GSASL_SUGGESTED_PIN,
111 : : &input[strlen (PIN)],
112 : : input_len - strlen (PIN));
113 : :
114 : 6 : pin = gsasl_property_get (sctx, GSASL_PIN);
115 [ - + ]: 6 : if (!pin)
116 : 0 : return GSASL_NO_PIN;
117 : 6 : pinlen = strlen (pin);
118 : : }
119 : :
120 : 20 : *output_len = authzidlen + 1 + authidlen + 1 + passcodelen + 1;
121 [ + + ]: 20 : if (do_pin)
122 : 6 : *output_len += pinlen + 1;
123 : 20 : *output = malloc (*output_len);
124 [ - + ]: 20 : if (*output == NULL)
125 : 0 : return GSASL_MALLOC_ERROR;
126 : :
127 [ + - ]: 20 : if (authzid)
128 : 20 : memcpy (*output, authzid, authzidlen);
129 : 20 : (*output)[authzidlen] = '\0';
130 : 20 : memcpy (*output + authzidlen + 1, authid, authidlen);
131 : 20 : (*output)[authzidlen + 1 + authidlen] = '\0';
132 : 20 : memcpy (*output + authzidlen + 1 + authidlen + 1, passcode,
133 : : passcodelen);
134 : 20 : (*output)[authzidlen + 1 + authidlen + 1 + passcodelen] = '\0';
135 [ + + ]: 20 : if (do_pin)
136 : : {
137 : 6 : memcpy (*output + authzidlen + 1 + authidlen + 1 + passcodelen + 1,
138 : : pin, pinlen);
139 : 6 : (*output)[authzidlen + 1 + authidlen + 1 + passcodelen + 1 +
140 : 6 : pinlen] = '\0';
141 : : }
142 : :
143 : 20 : (*step)++;
144 : 20 : res = GSASL_OK;
145 : 20 : break;
146 : :
147 : : case 2:
148 : 0 : *output_len = 0;
149 : 0 : *output = NULL;
150 : 0 : (*step)++;
151 : 0 : res = GSASL_OK;
152 : 0 : break;
153 : :
154 : : default:
155 : 0 : res = GSASL_MECHANISM_CALLED_TOO_MANY_TIMES;
156 : 0 : break;
157 : : }
158 : :
159 : 25 : return res;
160 : : }
161 : :
162 : : void
163 : 18 : _gsasl_securid_client_finish (Gsasl_session * sctx, void *mech_data)
164 : : {
165 : 18 : int *step = mech_data;
166 : :
167 : 18 : free (step);
168 : 18 : }
|