The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rlm_securid.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 029bbf9761a16ff22b69b4ec9a01e0746cc8ad2f $
19  * @file rlm_securid.c
20  * @brief Supports auth against SecurID servers using OTP h/w tokens.
21  *
22  * Supports "next-token code" and "new-pin" modes.
23  *
24  * @copyright 2012 The FreeRADIUS server project
25  * @copyright 2012 Alan DeKok (aland@networkradius.com)
26  */
27 #define "rlm_securid - "
28 
29 #include <freeradius-devel/server/base.h>
30 #include <freeradius-devel/server/module_rlm.h>
31 #include <ctype.h>
32 
33 #include "rlm_securid.h"
34 
35 typedef enum {
36  RC_SECURID_AUTH_SUCCESS = 0,
37  RC_SECURID_AUTH_FAILURE = -3,
38  RC_SECURID_AUTH_ACCESS_DENIED_FAILURE = -4,
39  RC_SECURID_AUTH_INVALID_SERVER_FAILURE = -5,
40  RC_SECURID_AUTH_CHALLENGE = -17
41 } SECURID_AUTH_RC;
42 
43 
44 static const conf_parser_t module_config[] = {
45  { FR_CONF_OFFSET("timer_expire", rlm_securid_t, timer_limit), .dflt = "600" },
46  { FR_CONF_OFFSET("max_sessions", rlm_securid_t, max_sessions), .dflt = "2048" },
47  { FR_CONF_OFFSET("max_trips_per_session", rlm_securid_t, max_trips_per_session) },
48  { FR_CONF_OFFSET("max_round_trips", rlm_securid_t, max_trips_per_session), .dflt = "6" },
50 };
51 
52 static fr_dict_t const *dict_radius;
53 
54 extern fr_dict_autoload_t mem_dict[];
55 fr_dict_autoload_t mem_dict[] = {
56  { .out = &dict_radius, .proto = "radius" },
57  { NULL }
58 };
59 
65 
66 extern fr_dict_attr_autoload_t mem_dict_attr[];
67 fr_dict_attr_autoload_t mem_dict_attr[] = {
68  { .out = &attr_prompt, .name = "Prompt", .type = FR_TYPE_UINT32, .dict = &dict_radius },
69  { .out = &attr_reply_message, .name = "Reply-Message", .type = FR_TYPE_STRING, .dict = &dict_radius },
70  { .out = &attr_state, .name = "State", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
71  { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius },
72  { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
73  { NULL }
74 };
75 
76 static SD_CHAR empty_pin[] = "";
77 
78 /* comparison function to find session in the tree */
79 static int securid_session_cmp(void const *a, void const *b)
80 {
81  int ret;
82  SECURID_SESSION const *one = a;
83  SECURID_SESSION const *two = b;
84 
85  fr_assert(one != NULL);
86  fr_assert(two != NULL);
87 
88  ret = fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr);
89  if (ret != 0) return ret;
90 
91  return memcmp(one->state, two->state, sizeof(one->state));
92 }
93 
94 
95 static SECURID_AUTH_RC securidAuth(void *instance, request_t *request,
96  char const *username,
97  char const *passcode,
98  char *replyMsgBuffer, size_t replyMsgBufferSize)
99 {
100  rlm_securid_t *inst = (rlm_securid_t *) instance;
101  int acm_ret;
102  SD_PIN pin_params;
103  char new_pin[10];
104  char format[30];
105  SECURID_SESSION *securid_session = NULL;
106  int rc = -1;
107 
108  SD_CHAR *securid_user, *securid_pass;
109 
110  if (!username) {
111  ERROR("SecurID username is NULL");
112  return RC_SECURID_AUTH_FAILURE;
113  }
114 
115  if (!passcode) {
116  ERROR("SecurID passcode is NULL for %s user", username);
117  return RC_SECURID_AUTH_FAILURE;
118  }
119 
120  memcpy(&securid_user, &username, sizeof(securid_user));
121  memcpy(&securid_pass, &passcode, sizeof(securid_pass));
122 
123  *replyMsgBuffer = '\0';
124 
125  securid_session = securid_sessionlist_find(inst, request);
126  if (!securid_session) {
127  /* securid session not found */
128  SDI_HANDLE sdiHandle = SDI_HANDLE_NONE;
129 
130  acm_ret = SD_Init(&sdiHandle);
131  if (acm_ret != ACM_OK) {
132  RERROR("Cannot communicate with the ACE/Server");
133  return -1;
134  }
135 
136  acm_ret = SD_Lock(sdiHandle, securid_user);
137  if (acm_ret != ACM_OK) {
138  REDEBUG("SecurID: Access denied. Name [%s] lock failed", username);
139  return -2;
140  }
141 
142  acm_ret = SD_Check(sdiHandle, securid_pass, securid_user);
143  switch (acm_ret) {
144  case ACM_OK:
145  /* we are in now */
146  RDEBUG2("SecurID authentication successful for %s", username);
147  SD_Close(sdiHandle);
148 
149  return RC_SECURID_AUTH_SUCCESS;
150 
151  case ACM_ACCESS_DENIED:
152  /* not this time */
153  RDEBUG2("SecurID Access denied for %s", username);
154  SD_Close(sdiHandle);
155  return RC_SECURID_AUTH_ACCESS_DENIED_FAILURE;
156 
157  case ACM_INVALID_SERVER:
158  RERROR("SecurID: Invalid ACE server");
159  return RC_SECURID_AUTH_INVALID_SERVER_FAILURE;
160 
161  case ACM_NEW_PIN_REQUIRED:
162  RDEBUG2("SecurID new pin required for %s", username);
163 
164  /* create a new session */
165  securid_session = securid_session_alloc();
166  securid_session->sdiHandle = sdiHandle; /* save ACE handle for future use */
167  securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE;
168  securid_session->identity = talloc_typed_strdup(securid_session, username);
169 
170  /* Get PIN requirements */
171  acm_ret = AceGetPinParams(sdiHandle, &pin_params);
172 
173  /* If a system-generated PIN is required */
174  if (pin_params.Selectable == CANNOT_CHOOSE_PIN) {
175  /* Prompt user to accept a system generated PIN */
176  snprintf(replyMsgBuffer, replyMsgBufferSize,
177  "\r\nAre you prepared to accept a new system-generated PIN [y/n]?");
179 
180  } else if (pin_params.Selectable == USER_SELECTABLE) { //may be returned by AM 6.x servers.
181  snprintf(replyMsgBuffer, replyMsgBufferSize,
182  "\r\nPress 'y' to generate a new PIN\r\nOR\r\n'n'to enter a new PIN yourself [y/n]");
184 
185  } else {
186  if (pin_params.Alphanumeric) {
187  strcpy(format, "alphanumeric characters");
188  } else {
189  strcpy(format, "digits");
190  }
191  snprintf(replyMsgBuffer, replyMsgBufferSize,
192  " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:",
193  pin_params.Min, pin_params.Max, format);
194  }
195 
196  /* insert new session in the session list */
197  securid_sessionlist_add(inst, request, securid_session);
198 
199  return RC_SECURID_AUTH_CHALLENGE;
200 
201  case ACM_NEXT_CODE_REQUIRED:
202  RDEBUG2("Next securid token code required for %s",
203  username);
204 
205  /* create a new session */
206  securid_session = securid_session_alloc();
207  securid_session->sdiHandle = sdiHandle;
209  securid_session->identity = talloc_typed_strdup(securid_session, username);
210 
211  /* insert new session in the session list */
212  securid_sessionlist_add(inst, request, securid_session);
213 
214  strlcpy(replyMsgBuffer, "\r\nPlease Enter the Next Code from Your Token:", replyMsgBufferSize);
215  return RC_SECURID_AUTH_CHALLENGE;
216 
217  default:
218  ERROR("SecurID: Unexpected error from ACE/Agent API acm_ret=%d", acm_ret);
219  securid_session_free(inst, request, securid_session);
220  return RC_SECURID_AUTH_FAILURE;
221 
222 
223  }
224  } else {
225  /* existing session found */
226  RDEBUG2("Continuing previous session found for user [%s]", username);
227 
228  /* continue previous session */
229  switch (securid_session->securidSessionState) {
231  DEBUG2("Securid NEXT_CODE_REQUIRED_STATE: User [%s]", username);
232  /* next token code mode */
233 
234  acm_ret = SD_Next(securid_session->sdiHandle, securid_pass);
235  if (acm_ret == ACM_OK) {
236  INFO("Next SecurID token accepted for [%s].", securid_session->identity);
237  rc = RC_SECURID_AUTH_SUCCESS;
238 
239  } else {
240  INFO("SecurID: Next token rejected for [%s].", securid_session->identity);
241  rc = RC_SECURID_AUTH_FAILURE;
242  }
243 
244  /* deallocate session */
245  securid_session_free(inst, request, securid_session);
246  return rc;
247 
249  RDEBUG2("SecurID NEW_PIN_REQUIRED_STATE for %s",
250  username);
251 
252  /* save the previous pin */
253  if (securid_session->pin) TALLOC_FREE(securid_session->pin);
254  securid_session->pin = talloc_typed_strdup(securid_session, passcode);
255 
256  strlcpy(replyMsgBuffer, "\r\n Please re-enter new PIN:", replyMsgBufferSize);
257 
258  /* set next state */
260 
261  /* insert the updated session in the session list */
262  securid_sessionlist_add(inst, request, securid_session);
263  return RC_SECURID_AUTH_CHALLENGE;
264 
266  RDEBUG2("SecurID NEW_PIN_USER_CONFIRM_STATE: User [%s]", username);
267  /* compare previous pin and current pin */
268  if (!securid_session->pin || strcmp(securid_session->pin, passcode)) {
269  RDEBUG2("Pin confirmation failed. Pins do not match [%s] and [%s]",
270  SAFE_STR(securid_session->pin), securid_pass);
271  /* pins do not match */
272 
273  /* challenge the user again */
274  AceGetPinParams(securid_session->sdiHandle, &pin_params);
275  if (pin_params.Alphanumeric) {
276  strcpy(format, "alphanumeric characters");
277  } else {
278  strcpy(format, "digits");
279  }
280  snprintf(replyMsgBuffer, replyMsgBufferSize,
281  " \r\n Pins do not match--Please try again.\r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:",
282  pin_params.Min, pin_params.Max, format);
283 
284  securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE;
285 
286  /* insert the updated session in the session list */
287  securid_sessionlist_add(inst, request, securid_session);
288  rc = RC_SECURID_AUTH_CHALLENGE;
289 
290  } else {
291  /* pins match */
292  RDEBUG2("Pin confirmation succeeded. Pins match");
293  acm_ret = SD_Pin(securid_session->sdiHandle, securid_pass);
294  if (acm_ret == ACM_NEW_PIN_ACCEPTED) {
295  RDEBUG2("New SecurID pin accepted for %s.", securid_session->identity);
296 
298 
299  /* insert the updated session in the session list */
300  securid_sessionlist_add(inst, request, securid_session);
301 
302  rc = RC_SECURID_AUTH_CHALLENGE;
303  strlcpy(replyMsgBuffer, " \r\n\r\nWait for the code on your card to change, then enter new PIN and TokenCode\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
304  } else {
305  RDEBUG2("SecurID: New SecurID pin rejected for %s.", securid_session->identity);
306  SD_Pin(securid_session->sdiHandle, &empty_pin[0]); /* cancel PIN */
307 
308 
309  rc = RC_SECURID_AUTH_FAILURE;
310 
311  /* deallocate session */
312  securid_session_free(inst, request, securid_session);
313  }
314  }
315  return rc;
317  acm_ret = SD_Check(securid_session->sdiHandle, securid_pass, securid_user);
318  if (acm_ret == ACM_OK) {
319  RDEBUG2("New SecurID passcode accepted for %s", securid_session->identity);
320  rc = RC_SECURID_AUTH_SUCCESS;
321 
322  } else {
323  INFO("SecurID: New passcode rejected for [%s]", securid_session->identity);
324  rc = RC_SECURID_AUTH_FAILURE;
325  }
326 
327  /* deallocate session */
328  securid_session_free(inst, request, securid_session);
329 
330  return rc;
332  if (!strcmp(passcode, "y")) {
333  AceGetSystemPin(securid_session->sdiHandle, new_pin);
334 
335  /* Save the PIN for the next session
336  * continuation */
337  if (securid_session->pin) TALLOC_FREE(securid_session->pin);
338  securid_session->pin = talloc_typed_strdup(securid_session, new_pin);
339 
340  snprintf(replyMsgBuffer, replyMsgBufferSize,
341  "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?",
342  new_pin);
344 
345  /* insert the updated session in the
346  * session list */
347  securid_sessionlist_add(inst, request, securid_session);
348 
349  rc = RC_SECURID_AUTH_CHALLENGE;
350 
351  } else {
352  SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN
353 
354  /* deallocate session */
355  securid_session_free(inst, request, securid_session);
356  rc = RC_SECURID_AUTH_FAILURE;
357  }
358 
359  return rc;
360 
362  acm_ret = SD_Pin(securid_session->sdiHandle, (SD_CHAR*)securid_session->pin);
363  if (acm_ret == ACM_NEW_PIN_ACCEPTED) {
364  strlcpy(replyMsgBuffer, " \r\n\r\nPin Accepted. Wait for the code on your card to change, then enter new PIN and TokenCode\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
366  /* insert the updated session in the session list */
367  securid_sessionlist_add(inst, request, securid_session);
368  rc = RC_SECURID_AUTH_CHALLENGE;
369 
370  } else {
371  SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN
372  strlcpy(replyMsgBuffer, " \r\n\r\nPin Rejected. Wait for the code on your card to change, then try again.\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
373  /* deallocate session */
374  securid_session_free(inst, request, securid_session);
375  rc = RC_SECURID_AUTH_FAILURE;
376  }
377 
378  return rc;
379 
380  /* USER_SELECTABLE state should be implemented to preserve compatibility with AM 6.x servers, which can return this state */
382  if (!strcmp(passcode, "y")) {
383  /* User has opted for a system-generated PIN */
384  AceGetSystemPin(securid_session->sdiHandle, new_pin);
385  snprintf(replyMsgBuffer, replyMsgBufferSize,
386  "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?",
387  new_pin);
389 
390  /* insert the updated session in the session list */
391  securid_sessionlist_add(inst, request,
392  securid_session);
393  rc = RC_SECURID_AUTH_CHALLENGE;
394 
395  } else {
396  /* User has opted for a user-defined PIN */
397  AceGetPinParams(securid_session->sdiHandle,
398  &pin_params);
399  if (pin_params.Alphanumeric) {
400  strcpy(format, "alphanumeric characters");
401  } else {
402  strcpy(format, "digits");
403  }
404 
405  snprintf(replyMsgBuffer, replyMsgBufferSize,
406  " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:",
407  pin_params.Min, pin_params.Max, format);
408  securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE;
409 
410  /* insert the updated session in the session list */
411  securid_sessionlist_add(inst, request,
412  securid_session);
413  rc = RC_SECURID_AUTH_CHALLENGE;
414  }
415 
416  return rc;
417 
418  default:
419  ERROR("Invalid session state %d for user \"%s\"", securid_session->securidSessionState,
421  break;
422  }
423  }
424 
425  return 0;
426 
427 }
428 
429 /******************************************/
431 {
432  rlm_securid_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_securid_t);
433 
434  /* delete session tree */
435  if (inst->session_tree) {
436  talloc_free(inst->session_tree);
437  inst->session_tree = NULL;
438  }
439 
440  pthread_mutex_destroy(&(inst->session_mutex));
441 
442  return 0;
443 }
444 
445 
446 static int mod_instantiate(module_inst_ctx_t const *mctx)
447 {
448  rlm_securid_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_securid_t);
449 
450  /*
451  * Lookup sessions in the tree. We don't free them in
452  * the tree, as that's taken care of elsewhere...
453  */
454  inst->session_tree = fr_rb_inline_talloc_alloc(NULL, SECURID_SESSION, node, securid_session_cmp, NULL);
455  if (!inst->session_tree) {
456  ERROR("Cannot initialize session tree");
457  return -1;
458  }
459 
460  pthread_mutex_init(&(inst->session_mutex), NULL);
461  return 0;
462 }
463 
464 
465 /*
466  * Authenticate the user via one of any well-known password.
467  */
468 static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
469 {
470  int rcode;
472  char buffer[FR_MAX_STRING_LEN]="";
473  fr_pair_t *username, *password;
474  fr_pair_t *vp;
475 
476  username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name);
477  password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
478 
479  /*
480  * We can only authenticate user requests which HAVE
481  * a User-Name attribute.
482  */
483  if (!username) {
484  REDEBUG("Attribute \"User-Name\" is required for authentication");
486  }
487 
488  if (!password) {
489  REDEBUG("Attribute \"User-Password\" is required for authentication");
491  }
492 
493  /*
494  * The user MUST supply a non-zero-length password.
495  */
496  if (password->vp_length == 0) {
497  REDEBUG("Password should not be empty");
499  }
500 
501  if (RDEBUG_ENABLED3) {
502  RDEBUG3("Login attempt with password \"%pV\"", &password->data);
503  } else {
504  RDEBUG2("Login attempt with password");
505  }
506 
507  rcode = securidAuth(inst, request, username->vp_strvalue, password->vp_strvalue,
508  buffer, sizeof(buffer));
509 
510  switch (rcode) {
511  case RC_SECURID_AUTH_SUCCESS:
512  rcode = RLM_MODULE_OK;
513  break;
514 
515  case RC_SECURID_AUTH_CHALLENGE:
516  /* reply with Access-challenge message code (11) */
517 
518  /* Generate Prompt attribute */
520  vp->vp_uint32 = 0; /* no echo */
521 
522  /* Mark the packet as a Acceess-Challenge Packet */
523  request->reply->code = FR_RADIUS_CODE_ACCESS_CHALLENGE;
524  RDEBUG2("Sending Access-Challenge");
525  rcode = RLM_MODULE_HANDLED;
526  break;
527 
528  case RC_SECURID_AUTH_FAILURE:
529  case RC_SECURID_AUTH_ACCESS_DENIED_FAILURE:
530  case RC_SECURID_AUTH_INVALID_SERVER_FAILURE:
531  default:
532  rcode = RLM_MODULE_REJECT;
533  break;
534  }
535 
536  if (*buffer) {
538  fr_pair_value_strdup(vp, buffer, false);
539  }
540  RETURN_MODULE_RCODE(rcode);
541 }
542 
543 
544 /*
545  * The module name should be the only globally exported symbol.
546  * That is, everything else should be 'static'.
547  *
548  * If the module needs to temporarily modify it's instantiation
549  * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
550  * The server will then take care of ensuring that the module
551  * is single-threaded.
552  */
555  .common = {
556  .magic = MODULE_MAGIC_INIT,
557  .name = "securid",
558  .inst_size = sizeof(rlm_securid_t),
561  .detach = mod_detach
562  },
563  .method_names = (module_method_name_t[]){
564  { .name1 = "authenticate", .name2 = CF_IDENT_ANY, .method = mod_authenticate },
566  }
567 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
static int const char char buffer[256]
Definition: acutest.h:574
strcpy(log_entry->msg, buffer)
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
#define CF_IDENT_ANY
Definition: cf_util.h:78
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition: defs.h:43
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
dl_module_inst_t const * inst
Definition: dl_module.h:87
HIDDEN fr_dict_attr_t const * attr_reply_message
Definition: rlm_eap_ttls.c:94
int8_t fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
Compare two ip addresses.
Definition: inet.c:1332
HIDDEN fr_dict_attr_t const * attr_state
Definition: base.c:96
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition: log.h:335
#define RDEBUG3(fmt,...)
Definition: log.h:343
#define RERROR(fmt,...)
Definition: log.h:298
talloc_free(reap)
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:52
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:51
Specifies a module method identifier.
Definition: module_method.c:36
int securid_sessionlist_add(rlm_securid_t *inst, request_t *request, SECURID_SESSION *session)
Definition: mem.c:83
SECURID_SESSION * securid_session_alloc(void)
Definition: mem.c:32
void securid_session_free(UNUSED rlm_securid_t *inst, request_t *request, SECURID_SESSION *session)
Definition: mem.c:42
SECURID_SESSION * securid_sessionlist_find(rlm_securid_t *inst, request_t *request)
Definition: mem.c:172
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition: pair.c:688
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition: pair.c:2631
static const conf_parser_t config[]
Definition: base.c:188
static fr_dict_attr_t const * attr_user_password
Definition: radclient-ng.c:126
static fr_dict_t const * dict_radius
Definition: radclient-ng.c:102
static fr_dict_attr_t const * attr_user_name
Definition: radclient-ng.c:125
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define INFO(fmt,...)
Definition: radict.c:54
static const conf_parser_t module_config[]
Definition: radwho.c:59
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition: rb.h:246
#define RETURN_MODULE_RCODE(_rcode)
Definition: rcode.h:64
#define RETURN_MODULE_INVALID
Definition: rcode.h:59
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
@ RLM_MODULE_OK
The module is OK, continue.
Definition: rcode.h:43
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition: rcode.h:41
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition: rcode.h:44
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1312
username
Definition: rlm_securid.c:420
#define rlm_securid
Definition: rlm_securid.c:27
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_securid.c:468
static int mod_detach(module_detach_ctx_t *mctx)
Definition: rlm_securid.c:430
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_securid.c:446
fr_ipaddr_t src_ipaddr
Definition: rlm_securid.h:45
SDI_HANDLE sdiHandle
Definition: rlm_securid.h:40
SECURID_SESSION_STATE securidSessionState
Definition: rlm_securid.h:41
@ NEW_PIN_SYSTEM_CONFIRM_STATE
Definition: rlm_securid.h:17
@ NEW_PIN_REQUIRED_STATE
Definition: rlm_securid.h:13
@ NEW_PIN_USER_SELECT_STATE
Definition: rlm_securid.h:18
@ NEW_PIN_AUTH_VALIDATE_STATE
Definition: rlm_securid.h:15
@ NEW_PIN_SYSTEM_ACCEPT_STATE
Definition: rlm_securid.h:16
@ NEXT_CODE_REQUIRED_STATE
Definition: rlm_securid.h:12
@ NEW_PIN_USER_CONFIRM_STATE
Definition: rlm_securid.h:14
HIDDEN fr_dict_attr_t const * attr_prompt
char state[SECURID_STATE_LEN]
Definition: rlm_securid.h:43
#define SAFE_STR(s)
Definition: rlm_securid.h:8
#define MODULE_NAME_TERMINATOR
Definition: module.h:135
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
Definition: pair.h:129
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:34
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:333
#define talloc_get_type_abort_const
Definition: talloc.h:270
#define FR_MAX_STRING_LEN
Definition: value.h:30
int nonnull(2, 5))
int format(printf, 5, 0))