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