The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Functions | Variables
rlm_securid.c File Reference

Supports auth against SecurID servers using OTP h/w tokens. More...

Go to the source code of this file.

Macros

#define rlm_securid   - "#include <freeradius-devel/server/base.h>#include <freeradius-devel/server/module_rlm.h>#include <ctype.h>#include "rlm_securid.h"typedef enum { RC_SECURID_AUTH_SUCCESS = 0, RC_SECURID_AUTH_FAILURE = -3, RC_SECURID_AUTH_ACCESS_DENIED_FAILURE = -4, RC_SECURID_AUTH_INVALID_SERVER_FAILURE = -5, RC_SECURID_AUTH_CHALLENGE = -17} SECURID_AUTH_RC;static const conf_parser_t module_config[] = { { FR_CONF_OFFSET("timer_expire", rlm_securid_t, timer_limit), .dflt = "600" }, { FR_CONF_OFFSET("max_sessions", rlm_securid_t, max_sessions), .dflt = "2048" }, { FR_CONF_OFFSET("max_trips_per_session", rlm_securid_t, max_trips_per_session) }, { FR_CONF_OFFSET("max_round_trips", rlm_securid_t, max_trips_per_session), .dflt = "6" }, CONF_PARSER_TERMINATOR};static fr_dict_t const *dict_radius;extern fr_dict_autoload_t mem_dict[];fr_dict_autoload_t mem_dict[] = { { .out = &dict_radius, .proto = "radius" }, { NULL }};fr_dict_attr_t const *attr_prompt;fr_dict_attr_t const *attr_reply_message;fr_dict_attr_t const *attr_state;fr_dict_attr_t const *attr_user_name;fr_dict_attr_t const *attr_user_password;extern fr_dict_attr_autoload_t mem_dict_attr[];fr_dict_attr_autoload_t mem_dict_attr[] = { { .out = &attr_prompt, .name = "Prompt", .type = FR_TYPE_UINT32, .dict = &dict_radius }, { .out = &attr_reply_message, .name = "Reply-Message", .type = FR_TYPE_STRING, .dict = &dict_radius }, { .out = &attr_state, .name = "State", .type = FR_TYPE_OCTETS, .dict = &dict_radius }, { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius }, { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius }, { NULL }};static SD_CHAR empty_pin[] = "";/* comparison function to find session in the tree */static int securid_session_cmp(void const *a, void const *b){ int ret; SECURID_SESSION const *one = a; SECURID_SESSION const *two = b; fr_assert(one != NULL); fr_assert(two != NULL); ret = fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr); if (ret != 0) return ret; return memcmp(one->state, two->state, sizeof(one->state));}static SECURID_AUTH_RC securidAuth(void *instance, request_t *request, char const *username, char const *passcode, char *replyMsgBuffer, size_t replyMsgBufferSize){ rlm_securid_t *inst = (rlm_securid_t *) instance; int acm_ret; SD_PIN pin_params; char new_pin[10]; char format[30]; SECURID_SESSION *securid_session = NULL; int rc = -1; SD_CHAR *securid_user, *securid_pass; if (!username) { ERROR("SecurID username is NULL"); return RC_SECURID_AUTH_FAILURE; } if (!passcode) { ERROR("SecurID passcode is NULL for %s user", username); return RC_SECURID_AUTH_FAILURE; } memcpy(&securid_user, &username, sizeof(securid_user)); memcpy(&securid_pass, &passcode, sizeof(securid_pass)); *replyMsgBuffer = '\0'; securid_session = securid_sessionlist_find(inst, request); if (!securid_session) { /* securid session not found */ SDI_HANDLE sdiHandle = SDI_HANDLE_NONE; acm_ret = SD_Init(&sdiHandle); if (acm_ret != ACM_OK) { RERROR("Cannot communicate with the ACE/Server"); return -1; } acm_ret = SD_Lock(sdiHandle, securid_user); if (acm_ret != ACM_OK) { REDEBUG("SecurID: Access denied. Name [%s] lock failed", username); return -2; } acm_ret = SD_Check(sdiHandle, securid_pass, securid_user); switch (acm_ret) { case ACM_OK: /* we are in now */ RDEBUG2("SecurID authentication successful for %s", username); SD_Close(sdiHandle); return RC_SECURID_AUTH_SUCCESS; case ACM_ACCESS_DENIED: /* not this time */ RDEBUG2("SecurID Access denied for %s", username); SD_Close(sdiHandle); return RC_SECURID_AUTH_ACCESS_DENIED_FAILURE; case ACM_INVALID_SERVER: RERROR("SecurID: Invalid ACE server"); return RC_SECURID_AUTH_INVALID_SERVER_FAILURE; case ACM_NEW_PIN_REQUIRED: RDEBUG2("SecurID new pin required for %s", username); /* create a new session */ securid_session = securid_session_alloc(); securid_session->sdiHandle = sdiHandle; /* save ACE handle for future use */ securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE; securid_session->identity = talloc_typed_strdup(securid_session, username); /* Get PIN requirements */ acm_ret = AceGetPinParams(sdiHandle, &pin_params); /* If a system-generated PIN is required */ if (pin_params.Selectable == CANNOT_CHOOSE_PIN) { /* Prompt user to accept a system generated PIN */ snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nAre you prepared to accept a new system-generated PIN [y/n]?"); securid_session->securidSessionState = NEW_PIN_SYSTEM_ACCEPT_STATE; } else if (pin_params.Selectable == USER_SELECTABLE) { //may be returned by AM 6.x servers. snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nPress 'y' to generate a new PIN\r\nOR\r\n'n'to enter a new PIN yourself [y/n]"); securid_session->securidSessionState = NEW_PIN_USER_SELECT_STATE; } else { if (pin_params.Alphanumeric) { strcpy(format, "alphanumeric characters"); } else { strcpy(format, "digits"); } snprintf(replyMsgBuffer, replyMsgBufferSize, " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:", pin_params.Min, pin_params.Max, format); } /* insert new session in the session list */ securid_sessionlist_add(inst, request, securid_session); return RC_SECURID_AUTH_CHALLENGE; case ACM_NEXT_CODE_REQUIRED: RDEBUG2("Next securid token code required for %s", username); /* create a new session */ securid_session = securid_session_alloc(); securid_session->sdiHandle = sdiHandle; securid_session->securidSessionState = NEXT_CODE_REQUIRED_STATE; securid_session->identity = talloc_typed_strdup(securid_session, username); /* insert new session in the session list */ securid_sessionlist_add(inst, request, securid_session); strlcpy(replyMsgBuffer, "\r\nPlease Enter the Next Code from Your Token:", replyMsgBufferSize); return RC_SECURID_AUTH_CHALLENGE; default: ERROR("SecurID: Unexpected error from ACE/Agent API acm_ret=%d", acm_ret); securid_session_free(inst, request, securid_session); return RC_SECURID_AUTH_FAILURE; } } else { /* existing session found */ RDEBUG2("Continuing previous session found for user [%s]", username); /* continue previous session */ switch (securid_session->securidSessionState) { case NEXT_CODE_REQUIRED_STATE: DEBUG2("Securid NEXT_CODE_REQUIRED_STATE: User [%s]", username); /* next token code mode */ acm_ret = SD_Next(securid_session->sdiHandle, securid_pass); if (acm_ret == ACM_OK) { INFO("Next SecurID token accepted for [%s].", securid_session->identity); rc = RC_SECURID_AUTH_SUCCESS; } else { INFO("SecurID: Next token rejected for [%s].", securid_session->identity); rc = RC_SECURID_AUTH_FAILURE; } /* deallocate session */ securid_session_free(inst, request, securid_session); return rc; case NEW_PIN_REQUIRED_STATE: RDEBUG2("SecurID NEW_PIN_REQUIRED_STATE for %s", username); /* save the previous pin */ if (securid_session->pin) TALLOC_FREE(securid_session->pin); securid_session->pin = talloc_typed_strdup(securid_session, passcode); strlcpy(replyMsgBuffer, "\r\n Please re-enter new PIN:", replyMsgBufferSize); /* set next state */ securid_session->securidSessionState = NEW_PIN_USER_CONFIRM_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); return RC_SECURID_AUTH_CHALLENGE; case NEW_PIN_USER_CONFIRM_STATE: RDEBUG2("SecurID NEW_PIN_USER_CONFIRM_STATE: User [%s]", username); /* compare previous pin and current pin */ if (!securid_session->pin || strcmp(securid_session->pin, passcode)) { RDEBUG2("Pin confirmation failed. Pins do not match [%s] and [%s]", SAFE_STR(securid_session->pin), securid_pass); /* pins do not match */ /* challenge the user again */ AceGetPinParams(securid_session->sdiHandle, &pin_params); if (pin_params.Alphanumeric) { strcpy(format, "alphanumeric characters"); } else { strcpy(format, "digits"); } snprintf(replyMsgBuffer, replyMsgBufferSize, " \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:", pin_params.Min, pin_params.Max, format); securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { /* pins match */ RDEBUG2("Pin confirmation succeeded. Pins match"); acm_ret = SD_Pin(securid_session->sdiHandle, securid_pass); if (acm_ret == ACM_NEW_PIN_ACCEPTED) { RDEBUG2("New SecurID pin accepted for %s.", securid_session->identity); securid_session->securidSessionState = NEW_PIN_AUTH_VALIDATE_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; 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); } else { RDEBUG2("SecurID: New SecurID pin rejected for %s.", securid_session->identity); SD_Pin(securid_session->sdiHandle, &empty_pin[0]); /* cancel PIN */ rc = RC_SECURID_AUTH_FAILURE; /* deallocate session */ securid_session_free(inst, request, securid_session); } } return rc; case NEW_PIN_AUTH_VALIDATE_STATE: acm_ret = SD_Check(securid_session->sdiHandle, securid_pass, securid_user); if (acm_ret == ACM_OK) { RDEBUG2("New SecurID passcode accepted for %s", securid_session->identity); rc = RC_SECURID_AUTH_SUCCESS; } else { INFO("SecurID: New passcode rejected for [%s]", securid_session->identity); rc = RC_SECURID_AUTH_FAILURE; } /* deallocate session */ securid_session_free(inst, request, securid_session); return rc; case NEW_PIN_SYSTEM_ACCEPT_STATE: if (!strcmp(passcode, "y")) { AceGetSystemPin(securid_session->sdiHandle, new_pin); /* Save the PIN for the next session * continuation */ if (securid_session->pin) TALLOC_FREE(securid_session->pin); securid_session->pin = talloc_typed_strdup(securid_session, new_pin); snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?", new_pin); securid_session->securidSessionState = NEW_PIN_SYSTEM_CONFIRM_STATE; /* insert the updated session in the * session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN /* deallocate session */ securid_session_free(inst, request, securid_session); rc = RC_SECURID_AUTH_FAILURE; } return rc; case NEW_PIN_SYSTEM_CONFIRM_STATE: acm_ret = SD_Pin(securid_session->sdiHandle, (SD_CHAR*)securid_session->pin); if (acm_ret == ACM_NEW_PIN_ACCEPTED) { 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); securid_session->securidSessionState = NEW_PIN_AUTH_VALIDATE_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN 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); /* deallocate session */ securid_session_free(inst, request, securid_session); rc = RC_SECURID_AUTH_FAILURE; } return rc; /* USER_SELECTABLE state should be implemented to preserve compatibility with AM 6.x servers, which can return this state */ case NEW_PIN_USER_SELECT_STATE: if (!strcmp(passcode, "y")) { /* User has opted for a system-generated PIN */ AceGetSystemPin(securid_session->sdiHandle, new_pin); snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?", new_pin); securid_session->securidSessionState = NEW_PIN_SYSTEM_CONFIRM_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { /* User has opted for a user-defined PIN */ AceGetPinParams(securid_session->sdiHandle, &pin_params); if (pin_params.Alphanumeric) { strcpy(format, "alphanumeric characters"); } else { strcpy(format, "digits"); } snprintf(replyMsgBuffer, replyMsgBufferSize, " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:", pin_params.Min, pin_params.Max, format); securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } return rc; default: ERROR("Invalid session state %d for user \"%s\"", securid_session->securidSessionState,
 

Functions

static unlang_action_t mod_authenticate (rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
 
static int mod_detach (module_detach_ctx_t *mctx)
 
static int mod_instantiate (module_inst_ctx_t const *mctx)
 

Variables

 break
 
 return
 
module_rlm_t rlm_securid
 
 username
 

Detailed Description

Supports auth against SecurID servers using OTP h/w tokens.

Id
029bbf9761a16ff22b69b4ec9a01e0746cc8ad2f

Supports "next-token code" and "new-pin" modes.

Definition in file rlm_securid.c.

Macro Definition Documentation

◆ rlm_securid

module_rlm_t rlm_securid   - "#include <freeradius-devel/server/base.h>#include <freeradius-devel/server/module_rlm.h>#include <ctype.h>#include "rlm_securid.h"typedef enum { RC_SECURID_AUTH_SUCCESS = 0, RC_SECURID_AUTH_FAILURE = -3, RC_SECURID_AUTH_ACCESS_DENIED_FAILURE = -4, RC_SECURID_AUTH_INVALID_SERVER_FAILURE = -5, RC_SECURID_AUTH_CHALLENGE = -17} SECURID_AUTH_RC;static const conf_parser_t module_config[] = { { FR_CONF_OFFSET("timer_expire", rlm_securid_t, timer_limit), .dflt = "600" }, { FR_CONF_OFFSET("max_sessions", rlm_securid_t, max_sessions), .dflt = "2048" }, { FR_CONF_OFFSET("max_trips_per_session", rlm_securid_t, max_trips_per_session) }, { FR_CONF_OFFSET("max_round_trips", rlm_securid_t, max_trips_per_session), .dflt = "6" }, CONF_PARSER_TERMINATOR};static fr_dict_t const *dict_radius;extern fr_dict_autoload_t mem_dict[];fr_dict_autoload_t mem_dict[] = { { .out = &dict_radius, .proto = "radius" }, { NULL }};fr_dict_attr_t const *attr_prompt;fr_dict_attr_t const *attr_reply_message;fr_dict_attr_t const *attr_state;fr_dict_attr_t const *attr_user_name;fr_dict_attr_t const *attr_user_password;extern fr_dict_attr_autoload_t mem_dict_attr[];fr_dict_attr_autoload_t mem_dict_attr[] = { { .out = &attr_prompt, .name = "Prompt", .type = FR_TYPE_UINT32, .dict = &dict_radius }, { .out = &attr_reply_message, .name = "Reply-Message", .type = FR_TYPE_STRING, .dict = &dict_radius }, { .out = &attr_state, .name = "State", .type = FR_TYPE_OCTETS, .dict = &dict_radius }, { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius }, { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius }, { NULL }};static SD_CHAR empty_pin[] = "";/* comparison function to find session in the tree */static int securid_session_cmp(void const *a, void const *b){ int ret; SECURID_SESSION const *one = a; SECURID_SESSION const *two = b; fr_assert(one != NULL); fr_assert(two != NULL); ret = fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr); if (ret != 0) return ret; return memcmp(one->state, two->state, sizeof(one->state));}static SECURID_AUTH_RC securidAuth(void *instance, request_t *request, char const *username, char const *passcode, char *replyMsgBuffer, size_t replyMsgBufferSize){ rlm_securid_t *inst = (rlm_securid_t *) instance; int acm_ret; SD_PIN pin_params; char new_pin[10]; char format[30]; SECURID_SESSION *securid_session = NULL; int rc = -1; SD_CHAR *securid_user, *securid_pass; if (!username) { ERROR("SecurID username is NULL"); return RC_SECURID_AUTH_FAILURE; } if (!passcode) { ERROR("SecurID passcode is NULL for %s user", username); return RC_SECURID_AUTH_FAILURE; } memcpy(&securid_user, &username, sizeof(securid_user)); memcpy(&securid_pass, &passcode, sizeof(securid_pass)); *replyMsgBuffer = '\0'; securid_session = securid_sessionlist_find(inst, request); if (!securid_session) { /* securid session not found */ SDI_HANDLE sdiHandle = SDI_HANDLE_NONE; acm_ret = SD_Init(&sdiHandle); if (acm_ret != ACM_OK) { RERROR("Cannot communicate with the ACE/Server"); return -1; } acm_ret = SD_Lock(sdiHandle, securid_user); if (acm_ret != ACM_OK) { REDEBUG("SecurID: Access denied. Name [%s] lock failed", username); return -2; } acm_ret = SD_Check(sdiHandle, securid_pass, securid_user); switch (acm_ret) { case ACM_OK: /* we are in now */ RDEBUG2("SecurID authentication successful for %s", username); SD_Close(sdiHandle); return RC_SECURID_AUTH_SUCCESS; case ACM_ACCESS_DENIED: /* not this time */ RDEBUG2("SecurID Access denied for %s", username); SD_Close(sdiHandle); return RC_SECURID_AUTH_ACCESS_DENIED_FAILURE; case ACM_INVALID_SERVER: RERROR("SecurID: Invalid ACE server"); return RC_SECURID_AUTH_INVALID_SERVER_FAILURE; case ACM_NEW_PIN_REQUIRED: RDEBUG2("SecurID new pin required for %s", username); /* create a new session */ securid_session = securid_session_alloc(); securid_session->sdiHandle = sdiHandle; /* save ACE handle for future use */ securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE; securid_session->identity = talloc_typed_strdup(securid_session, username); /* Get PIN requirements */ acm_ret = AceGetPinParams(sdiHandle, &pin_params); /* If a system-generated PIN is required */ if (pin_params.Selectable == CANNOT_CHOOSE_PIN) { /* Prompt user to accept a system generated PIN */ snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nAre you prepared to accept a new system-generated PIN [y/n]?"); securid_session->securidSessionState = NEW_PIN_SYSTEM_ACCEPT_STATE; } else if (pin_params.Selectable == USER_SELECTABLE) { //may be returned by AM 6.x servers. snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nPress 'y' to generate a new PIN\r\nOR\r\n'n'to enter a new PIN yourself [y/n]"); securid_session->securidSessionState = NEW_PIN_USER_SELECT_STATE; } else { if (pin_params.Alphanumeric) { strcpy(format, "alphanumeric characters"); } else { strcpy(format, "digits"); } snprintf(replyMsgBuffer, replyMsgBufferSize, " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:", pin_params.Min, pin_params.Max, format); } /* insert new session in the session list */ securid_sessionlist_add(inst, request, securid_session); return RC_SECURID_AUTH_CHALLENGE; case ACM_NEXT_CODE_REQUIRED: RDEBUG2("Next securid token code required for %s", username); /* create a new session */ securid_session = securid_session_alloc(); securid_session->sdiHandle = sdiHandle; securid_session->securidSessionState = NEXT_CODE_REQUIRED_STATE; securid_session->identity = talloc_typed_strdup(securid_session, username); /* insert new session in the session list */ securid_sessionlist_add(inst, request, securid_session); strlcpy(replyMsgBuffer, "\r\nPlease Enter the Next Code from Your Token:", replyMsgBufferSize); return RC_SECURID_AUTH_CHALLENGE; default: ERROR("SecurID: Unexpected error from ACE/Agent API acm_ret=%d", acm_ret); securid_session_free(inst, request, securid_session); return RC_SECURID_AUTH_FAILURE; } } else { /* existing session found */ RDEBUG2("Continuing previous session found for user [%s]", username); /* continue previous session */ switch (securid_session->securidSessionState) { case NEXT_CODE_REQUIRED_STATE: DEBUG2("Securid NEXT_CODE_REQUIRED_STATE: User [%s]", username); /* next token code mode */ acm_ret = SD_Next(securid_session->sdiHandle, securid_pass); if (acm_ret == ACM_OK) { INFO("Next SecurID token accepted for [%s].", securid_session->identity); rc = RC_SECURID_AUTH_SUCCESS; } else { INFO("SecurID: Next token rejected for [%s].", securid_session->identity); rc = RC_SECURID_AUTH_FAILURE; } /* deallocate session */ securid_session_free(inst, request, securid_session); return rc; case NEW_PIN_REQUIRED_STATE: RDEBUG2("SecurID NEW_PIN_REQUIRED_STATE for %s", username); /* save the previous pin */ if (securid_session->pin) TALLOC_FREE(securid_session->pin); securid_session->pin = talloc_typed_strdup(securid_session, passcode); strlcpy(replyMsgBuffer, "\r\n Please re-enter new PIN:", replyMsgBufferSize); /* set next state */ securid_session->securidSessionState = NEW_PIN_USER_CONFIRM_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); return RC_SECURID_AUTH_CHALLENGE; case NEW_PIN_USER_CONFIRM_STATE: RDEBUG2("SecurID NEW_PIN_USER_CONFIRM_STATE: User [%s]", username); /* compare previous pin and current pin */ if (!securid_session->pin || strcmp(securid_session->pin, passcode)) { RDEBUG2("Pin confirmation failed. Pins do not match [%s] and [%s]", SAFE_STR(securid_session->pin), securid_pass); /* pins do not match */ /* challenge the user again */ AceGetPinParams(securid_session->sdiHandle, &pin_params); if (pin_params.Alphanumeric) { strcpy(format, "alphanumeric characters"); } else { strcpy(format, "digits"); } snprintf(replyMsgBuffer, replyMsgBufferSize, " \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:", pin_params.Min, pin_params.Max, format); securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { /* pins match */ RDEBUG2("Pin confirmation succeeded. Pins match"); acm_ret = SD_Pin(securid_session->sdiHandle, securid_pass); if (acm_ret == ACM_NEW_PIN_ACCEPTED) { RDEBUG2("New SecurID pin accepted for %s.", securid_session->identity); securid_session->securidSessionState = NEW_PIN_AUTH_VALIDATE_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; 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); } else { RDEBUG2("SecurID: New SecurID pin rejected for %s.", securid_session->identity); SD_Pin(securid_session->sdiHandle, &empty_pin[0]); /* cancel PIN */ rc = RC_SECURID_AUTH_FAILURE; /* deallocate session */ securid_session_free(inst, request, securid_session); } } return rc; case NEW_PIN_AUTH_VALIDATE_STATE: acm_ret = SD_Check(securid_session->sdiHandle, securid_pass, securid_user); if (acm_ret == ACM_OK) { RDEBUG2("New SecurID passcode accepted for %s", securid_session->identity); rc = RC_SECURID_AUTH_SUCCESS; } else { INFO("SecurID: New passcode rejected for [%s]", securid_session->identity); rc = RC_SECURID_AUTH_FAILURE; } /* deallocate session */ securid_session_free(inst, request, securid_session); return rc; case NEW_PIN_SYSTEM_ACCEPT_STATE: if (!strcmp(passcode, "y")) { AceGetSystemPin(securid_session->sdiHandle, new_pin); /* Save the PIN for the next session * continuation */ if (securid_session->pin) TALLOC_FREE(securid_session->pin); securid_session->pin = talloc_typed_strdup(securid_session, new_pin); snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?", new_pin); securid_session->securidSessionState = NEW_PIN_SYSTEM_CONFIRM_STATE; /* insert the updated session in the * session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN /* deallocate session */ securid_session_free(inst, request, securid_session); rc = RC_SECURID_AUTH_FAILURE; } return rc; case NEW_PIN_SYSTEM_CONFIRM_STATE: acm_ret = SD_Pin(securid_session->sdiHandle, (SD_CHAR*)securid_session->pin); if (acm_ret == ACM_NEW_PIN_ACCEPTED) { 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); securid_session->securidSessionState = NEW_PIN_AUTH_VALIDATE_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN 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); /* deallocate session */ securid_session_free(inst, request, securid_session); rc = RC_SECURID_AUTH_FAILURE; } return rc; /* USER_SELECTABLE state should be implemented to preserve compatibility with AM 6.x servers, which can return this state */ case NEW_PIN_USER_SELECT_STATE: if (!strcmp(passcode, "y")) { /* User has opted for a system-generated PIN */ AceGetSystemPin(securid_session->sdiHandle, new_pin); snprintf(replyMsgBuffer, replyMsgBufferSize, "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?", new_pin); securid_session->securidSessionState = NEW_PIN_SYSTEM_CONFIRM_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } else { /* User has opted for a user-defined PIN */ AceGetPinParams(securid_session->sdiHandle, &pin_params); if (pin_params.Alphanumeric) { strcpy(format, "alphanumeric characters"); } else { strcpy(format, "digits"); } snprintf(replyMsgBuffer, replyMsgBufferSize, " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:", pin_params.Min, pin_params.Max, format); securid_session->securidSessionState = NEW_PIN_REQUIRED_STATE; /* insert the updated session in the session list */ securid_sessionlist_add(inst, request, securid_session); rc = RC_SECURID_AUTH_CHALLENGE; } return rc; default: ERROR("Invalid session state %d for user \"%s\"", securid_session->securidSessionState,

Definition at line 27 of file rlm_securid.c.

Function Documentation

◆ mod_authenticate()

static unlang_action_t mod_authenticate ( rlm_rcode_t p_result,
module_ctx_t const *  mctx,
request_t request 
)
static

Definition at line 468 of file rlm_securid.c.

+ Here is the call graph for this function:

◆ mod_detach()

static int mod_detach ( module_detach_ctx_t mctx)
static

Definition at line 430 of file rlm_securid.c.

+ Here is the call graph for this function:

◆ mod_instantiate()

static int mod_instantiate ( module_inst_ctx_t const *  mctx)
static

Definition at line 446 of file rlm_securid.c.

Variable Documentation

◆ break

break

Definition at line 421 of file rlm_securid.c.

◆ return

return

Definition at line 425 of file rlm_securid.c.

◆ rlm_securid

module_rlm_t rlm_securid
Initial value:
= {
.common = {
.name = "securid",
.inst_size = sizeof(rlm_securid_t),
.detach = mod_detach
},
.method_names = (module_method_name_t[]){
{ .name1 = "authenticate", .name2 = CF_IDENT_ANY, .method = mod_authenticate },
}
}
#define CF_IDENT_ANY
Definition: cf_util.h:78
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
Specifies a module method identifier.
Definition: module_method.c:36
static const conf_parser_t config[]
Definition: base.c:188
static const conf_parser_t module_config[]
Definition: radwho.c:59
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1312
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
#define MODULE_NAME_TERMINATOR
Definition: module.h:135

Definition at line 554 of file rlm_securid.c.

◆ username

username

Definition at line 420 of file rlm_securid.c.