Parent Directory
|
Revision Log
|
Revision Graph
Extra lines removed.
//$Header: /hl/cvsroots/e3ft_gpl01/e3ft_gpl01/nixprojs/cron/2006/php_rsa_auth_20061228/rsa_securid_auth.c,v 1.2 2006/12/28 21:58:18 dashley Exp $
//
//rsa_securid_auth.c : Authenticates a userid and Securid FOB value
// passed via the command-line.
//
// Designed to be called via a PHP script with
// UID/GID apch443a.
//
//Invocation:
// - rsa_securid_auth username fobvalue
// Attempts to authenticate the username with the FOB value.
//
// - rsa_securid_auth username fobvalue1 fobvalue2
// This invocation form will be used if a previous invocation
// has indicated that the next FOB value is required. It was
// determined empirically that the software has a wide enough
// window that using two successive FOB values (i.e. no "next"
// sequence, i.e. the first FOB value is "late") will work
// fine to cover this case. This makes for easier web
// programming.
//
//Return values:
// All information is passed back in the exit code. Possible
// values:
// 0 : Authentication successful (either with one or two FOB
// codes).
// 1 : Next code invocation required.
// 2 : Authentication failed due to return values from the
// RSA software indicating authentication failure.
// 3 : Authentication failed because the RSA software indicated
// an error condition.
// 4 : Authentication failed because this program detected
// an error condition (most likely ill-formed parameters).
//
#ifdef WIN32
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <termio.h>
#include <fcntl.h>
#endif
// in NT this allows using the aceclnt.lib file for linking
#define USE_ACE_AGENT_API_PROTOTYPES
#include "acexport.h"
#ifndef WIN32
int sd_echo_off(void);
int sd_echo_on(void);
#endif
//If the passed character is an upper-case letter, converts it to lower-case.
//all other data is left unchanged.
//
static char char_to_lower_case(char char_in)
{
switch(char_in)
{
default:
return(char_in);
break;
case 'A':
return('a');
break;
case 'B':
return('b');
break;
case 'C':
return('c');
break;
case 'D':
return('d');
break;
case 'E':
return('e');
break;
case 'F':
return('f');
break;
case 'G':
return('g');
break;
case 'H':
return('h');
break;
case 'I':
return('I');
break;
case 'J':
return('j');
break;
case 'K':
return('k');
break;
case 'L':
return('l');
break;
case 'M':
return('m');
break;
case 'N':
return('n');
break;
case 'O':
return('o');
break;
case 'P':
return('p');
break;
case 'Q':
return('q');
break;
case 'R':
return('r');
break;
case 'S':
return('s');
break;
case 'T':
return('t');
break;
case 'U':
return('u');
break;
case 'V':
return('v');
break;
case 'W':
return('w');
break;
case 'X':
return('x');
break;
case 'Y':
return('y');
break;
case 'Z':
return('z');
break;
}
}
//Returns 1 if the passed character is a digit, or 0 otherwise.
//
static int is_a_digit(char char_in)
{
switch(char_in)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return(1);
break;
default:
return(0);
break;
}
}
//Returns 1 if the passed character is a lower-case letter, or 0 otherwise.
//
static int is_a_lc_letter(char char_in)
{
switch(char_in)
{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
return(1);
break;
default:
return(0);
break;
}
}
//Returns 1 if the passed character is a valid first character of a username
//or 0 otherwise.
//
static int is_valid_username_first_char(char char_in)
{
return(is_a_lc_letter(char_in));
}
//Returns 1 if the passed character is a non-first character of a username
//or 0 otherwise.
//
static int is_valid_username_non_first_char(char char_in)
{
return(is_a_lc_letter(char_in) | is_a_digit(char_in));
}
//Copies a string from src to dst, up to a maximum of n characters.
//The n characters exceed the zero terminator. If the limit is exceeded
//the string is truncated.
//
static void str_guarded_copy(char *dst, const char *src, int n)
{
int i;
for (i=0; (i<(n-1)) && (src[i]); i++)
{
dst[i] = src[i];
}
dst[i] = 0;
}
// a simple main() to drive this program
int main(int argc, char* argv[])
{
SDI_HANDLE aceHdl;
SD_CHAR resp[128];
SD_CHAR prompt[512];
SD_I32 promptLen;
SD_I32 nextRespLen;
SD_I32 respTimeout;
SD_BOOL moreFlag;
SD_BOOL noechoFlag;
SD_I32 AuthStatus;
int i;
int ret;
int rv;
char username [100];
char passcode1[100];
char passcode2[100];
if ((argc != 3) && (argc != 4))
{
exit(4);
}
//Copy over the username. It has to be 20 characters or less, all letters and numbers,
//starting with a letter.
str_guarded_copy(username, argv[1], sizeof(username));
//The username must be at least one character.
if (! strlen(username))
exit(4);
//Convert all characters of the username to lower-case if they are upper.
for (i=0; i<strlen(username); i++)
username[i] = char_to_lower_case(username[i]);
//The first character of the username must be valid for a user name.
if (! is_valid_username_first_char(username[0]))
exit(4);
//Subsequent characters of the username must be valid.
for (i=1; i<strlen(username); i++)
if (! is_valid_username_non_first_char(username[i]))
exit(4);
//The first passcode must be exactly six digits and must be all digits.
str_guarded_copy(passcode1, argv[2], sizeof(passcode1));
if (strlen(passcode1) != 6)
return(4);
for (i=0; i<strlen(passcode1); i++)
if (! is_a_digit(passcode1[i]))
exit(4);
//The second passcode, if supplied, must be exactly six digits and must be all digits.
if (argc >= 4)
{
str_guarded_copy(passcode2, argv[3], sizeof(passcode2));
if (strlen(passcode2) != 6)
return(4);
for (i=0; i<strlen(passcode2); i++)
if (! is_a_digit(passcode2[i]))
exit(4);
}
if (!AceInitializeEx(/* "/etc/rsaauthmgr/ace/data/" */ "/etc/rsa_securid_apch443a_auth", NULL, 0))
{
exit(3);
}
if (SD_Init(&aceHdl) != ACM_OK) /* initialize socket */
{
exit(3);
}
ret = SD_Lock(aceHdl, username);
if (ret != ACM_OK)
{
exit(3);
}
ret = SD_Check(aceHdl, passcode1, username);
switch (ret)
{
case ACM_OK:
rv = 0;
break;
case ACM_ACCESS_DENIED:
rv = 2;
break;
case ACE_UNDEFINED_PASSCODE:
rv = 2;
break;
case ACE_UNDEFINED_USERNAME:
rv = 2;
break;
case ACE_ERR_INVALID_HANDLE:
rv = 2;
break;
case ACM_NEXT_CODE_REQUIRED:
if (argc == 4)
{
ret = SD_Next(aceHdl, passcode2);
if (ret == ACM_OK)
{
rv = 0;
}
else
{
rv = 2;
}
}
else
{
rv = 1;
}
break;
case ACM_NEW_PIN_REQUIRED:
rv = 2;
break;
default:
rv = 2;
break;
}
SD_Close(aceHdl); /* Shutdown the network connection */
return(rv);
}
//$Log: rsa_securid_auth.c,v $
//Revision 1.2 2006/12/28 21:58:18 dashley
//Extra lines removed.
//
//Revision 1.1 2006/12/28 21:57:49 dashley
//Initial checkin.
| David T. Ashley | ViewVC Help |
| Powered by ViewVC 1.0.5 |