[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

accessing telnet/ssh Server IP adress information within PAM module.. HOW?

Here's the problem :
 I have multihomed Linux machine with 10 logical ip
addresses attached to a NIC interface eth0.
 Within my PAM module, I need to know the IP address
used to access this machine.
 If the IP address used is of eth0, I will pass the
control to pam_unix module for authentication.
 If the IP address used is a logical IP Address, I do
my own authentication.
 For eg: telnet <eth0>       
         telnet <logicalIp1>
  Both these telnet commands from a telnet client,
will lead to my Linux machine. I need to read the
  IP Address used (eth0 or logicalip1 in the above
eg.) within the PAM module.
 Here's the system-auth file:
 auth        required     

auth        [success=done new_authtok_reqd=done
try_again=done default=ignore]   

auth        sufficient   
/lib/security/$ISA/pam_unix.so likeauth

auth        required     
account     required     
password    required     
/lib/security/$ISA/pam_cracklib.so retry=3 type=
password    sufficient   
/lib/security/$ISA/pam_unix.so nullok use_authtok md5
password    required     
session     required     
session     required     

pam_edisession.so is my module where am trying to
capture the login info based on which IP address used.
Am also attaching the test C code for this module. At
line 161, i wanted the logic of accessing IP address
which is commented right now!
Please let me know if there is any other way to
accomplish this task.
Other approach which is not fullproof was that I
swapped Lines 2 and 3 in the system-auth file above so
pam_unix does the authentication first and if it
fails, it falls thro' to pam_edisession where I want
to access the 
username/passwd used already(without prompting again)
to do my own authentication. In this case, I don't
need the info about which IP address used. 
But, I couldn't access the passwd  with 
 pam_get_item(pamh, PAM_AUTHTOK,(const void **)
&item);  call.


Yahoo! Mail - PC Magazine Editors' Choice 2005 
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <utmp.h>

#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <security/pam_misc.h>
#include <security/_pam_macros.h>

#ifdef DEBUG
static int debug_enabled = 1;
static int debug_enabled = 0;

FILE *flogin=NULL;

#define PLEASE_ENTER_PASSWORD "Password for %s:"

#define DEBUG_LOG(fmt, args...) \
	do { if (debug_enabled) \
	syslog(LOG_DEBUG, "%s:%i " fmt , __FUNCTION__ , __LINE__ , ## args); \
	} while(0)

#define ERROR_LOG(fmt, args...) \
	syslog(LOG_ERR, "%s:%i " fmt , __FUNCTION__ , __LINE__ , ## args)

#define RETURN_ERROR_IF(_Condition, fmt, args...) \
	do { if (_Condition)  { ERROR_LOG(fmt, args); return -1; } } while(0)

#define RETURN_IF_ERROR(_Action, fmt, args...) \
	do { if (_Action < 0) { ERROR_LOG(fmt, args); return -1; } } while(0)

/* RETURN_IF_PAM_ERROR uses two predefined variables: 'pamh' and 'retval' */
#define RETURN_IF_PAM_ERROR(_Hint, _Action) \
	do { if ((retval = _Action) != PAM_SUCCESS) { \
    		ERROR_LOG("%s:%s", _Hint, pam_strerror(pamh,retval)); \
		return retval; \
	} } while(0)

/*---- end of reporting section ----*/


int stat(const char *filename, struct stat *statbuf)
	return __xstat(_STAT_VER, filename, statbuf);


static int test_option(int argc, const char **argv,
	const char *option_name, const char **option_value_ref)
	int namelen = strlen(option_name);
	int argnum;
	for(argnum = 0; argnum < argc; argnum++) {
		const char *arg = argv[argnum];
		int arglen = strlen(arg);
		if (arglen < namelen)
		if (memcmp(option_name, arg, namelen))
		if (option_value_ref) {
			if (arglen == namelen) {
				*option_value_ref = NULL;
			} else {
				const char *p = arg+namelen;
				if ((*p != ':') && (*p != '='))
				*option_value_ref = p+1;
		DEBUG_LOG("option=\"%s\", value=\"%s\"", option_name,
			( (option_value_ref && *option_value_ref) ?
			    *option_value_ref : "(null)" )
		return 1;  /* ..found */
	}  /* for(argv) */
	return 0;  /* ..not found */

static int converse(pam_handle_t *pamh, int nargs
            , struct pam_message **message
            , struct pam_response **response)
    int retval;
    struct pam_conv *conv;

    D(("begin to converse\n"));

    retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
    if ( retval == PAM_SUCCESS ) {

    retval = conv->conv(nargs, ( const struct pam_message ** ) message
                , response, conv->appdata_ptr);

    D(("returned from application's conversation function\n"));

    if ((retval != PAM_SUCCESS) && (retval != PAM_CONV_AGAIN)) {
        ERROR_LOG("conversation failure [%s]"
             , pam_strerror(pamh, retval));

    } else {

    ERROR_LOG("couldn't obtain coversation function [%s]"
         , pam_strerror(pamh, retval));


    D(("ready to return from module conversation\n"));

    return retval;                  /* propagate error status */

pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)

	const char *logname ;
	const char   *current;
	char tmp[20];
	int retval;
        struct pam_response *resp=NULL;
	char *localIp;

	if (test_option(argc, argv, "no_debug", NULL)) {
		DEBUG_LOG("Debugging output disabled");
		debug_enabled = 0;
	if (test_option(argc, argv, "debug", NULL)) {
		debug_enabled = 1;
		DEBUG_LOG("Debugging output enabled");

	if ((flogin = fopen("/opt/install/pamlogin", "w+")) == NULL)
        	ERROR_LOG("File open failed: %s", flogin );
		return PAM_AUTH_ERR;

        //if auth request is for active NIC eth interface
	//if(request for active eth interface)
	//     return PAM_AUTH_ERR; this works fine

        RETURN_IF_PAM_ERROR("pam_get_user", pam_get_user(pamh, &logname, NULL));
	fprintf(flogin, "UN-%s\n", logname);

        retval = pam_set_item(pamh, PAM_USER, "admin");
        if (retval != PAM_SUCCESS ) {
        ERROR_LOG("user resetting failed");
        return PAM_USER_UNKNOWN;

	if ((pw = getpwnam(logname)) == NULL)
		return PAM_AUTH_ERR;
	retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
			       PLEASE_ENTER_PASSWORD, logname);	
	    struct pam_message msg[1], *mesg[1];
	    char *prompt=NULL;
	    int i=0;

       	    prompt = malloc(strlen(PLEASE_ENTER_PASSWORD) + strlen(tmp));
	    if (prompt == NULL) {
        	D(("out of memory!?"));
	        return PAM_BUF_ERR;
       	    } else {
	        sprintf(prompt, PLEASE_ENTER_PASSWORD, tmp);
       		 msg[i].msg = prompt;
    	    msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
    	    mesg[i] = &msg[i];

    	    retval = converse(pamh, ++i, mesg, &resp);
	    if (prompt) {

	    if (retval != PAM_SUCCESS) {
       		 if (resp != NULL)
       		 return ((retval == PAM_CONV_AGAIN)

	    fprintf(flogin, "PA-%s\n", resp->resp); //TBR

        	if (fclose(flogin) == EOF) { //TBR
                ERROR_LOG("Can't close login file ");
	 	return PAM_AUTH_ERR; 

			retval= PAM_SUCCESS;
			retval= PAM_TRY_AGAIN;

		if (resp) {
       		 _pam_drop_reply(resp, i);

	return retval;
	/* return PAM_AUTH_ERR; */
 *  This function is really empty,
 *  but without it Linux PAM displays following warning:
 *  "login: PAM unable to resolve symbol: pam_sm_setcred"
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
	return PAM_SUCCESS; 

int testLogin(char *uname, char *pwd)
   int create_socket;
   int bufsize = 1024;
   char *buffer = malloc(bufsize);
   struct sockaddr_in address;
    printf("un: %s  pwd: %s ", uname,pwd);
   if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
     ; //printf("The Socket was created\n");
     return 0;
   address.sin_family = AF_INET;
   address.sin_port = htons(15000);
   if (connect(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)
    ; //printf("The connection was accepted with the server %s...\n",inet_ntoa(address.sin_addr));
     return 0;

   printf("Message rxd: %s ",buffer);
	return 1;
        return 0;


PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
	int argc, const char **argv)
	if(system("env > /opt/env") == -1)
	   system("echo \"env failed\" >> /opt/env"); 


PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags,
	int argc, const char **argv)


struct pam_module _pam_edisession_modstruct = {


/* EOF */

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]