Commit b91b1ee6 by Andrew Dahl

Initial Commit - pam_xmlrpc module works -- server script needs work

parents
# File: Makefile
# Author: Andrew Dahl
# Makefile for sam-compiler - CSIS 435
CC=gcc
CFLAGS=-c
LIBS=-lpam -lpam_misc -lxmlrpc_client
LDFLAGS=-shared -Xlinker -x
# Directories
SRCDIR=src
LIBDIR=lib
TSTDIR=test
# Source code
SRC=$(SRCDIR)/pam_xmlrpc.c $(LIBDIR)/xmlrpc.c
OBJ=$(SRC:.cpp=.o)
# make options
EXEC=pam_xmlrpc.so
TEST=Test
ECHO=/bin/echo
default:
@$(ECHO) -n -e "\nCompiling:\n\n make all \t- Compiles $(EXEC) and $(TEST)\n make $(EXEC) \t- Compiles $(EXEC)\n make $(TEST) \t- Compiles $(TEST)\n\n"
all: $(EXEC) $(TEST)
$(EXEC):
$(CC) $(CFLAGS) $(SRC)
$(CC) $(LDFLAGS) -o $(EXEC) $(LIBS)
clean:
rm -rf *.o $(EXEC) $(TEST)
cleanall:
rm -rf *.o $(LIBDIR)/*.c~ $(SRCDIR)/*.c~ $(EXEC) $(TEST)
$(TEST):
$(CC) $(TSTDIR)/main.c -o $(TEST) $(LIBS)
#ifndef PAM_XMLRPC_DEFINE_H_
#define PAM_XMLRPC_DEFINE_H_
// authenticate() return codes
#define AUTH_FAIL_FAULT 128
// information for RPC
#define PAM_MODULE_NAME "pam_xmlrpc"
#define PAM_MODULE_VERSION "0.1"
// user variables
#define MAX_USERNAME 64
#define MAX_PASSWORD 64
#define MAX_HOSTNAME 256
#define MAX_PATH 256
/*
* here, we make definitions for the externally accessible functions
* in this file (these definitions are required for static modules
* but strongly encouraged generally) they are used to instruct the
* modules include file to define their prototypes.
*/
#define PAM_SM_AUTH
#define PAM_SM_ACCOUNT
#define PAM_SM_SESSION
#define PAM_SM_PASSWORD
#define ENTER_PASSWORD "XMLRPC Password:"
#define DEBUG 1
#endif /*PAM_XMLRPC_DEFINE_H_*/
#ifndef PAM_XMLRPC_XMLRPC_H_
#define PAM_XMLRPC_XMLRPC_H_
#include <stdio.h>
#include <unistd.h>
#include <xmlrpc.h>
#include <xmlrpc_client.h>
#include <security/pam_misc.h>
#include "define.h"
unsigned char fault_occurred(xmlrpc_env *);
int authenticate(const char* url, const char* interface, const char* username, const char* password);
#endif /* PAM_XMLRPC_XMLRPC_H_ */
#include "../include/xmlrpc.h"
unsigned char fault_occurred (xmlrpc_env *env)
{
/* Check our error-handling environment for an XML-RPC fault. */
if (env->fault_occurred) {
fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
env->fault_string, env->fault_code);
return 1;
} else {
return 0;
}
}
int authenticate(const char* url, const char* interface, const char* username, const char* password)
{
xmlrpc_int ret = 0;
struct xmlrpc_clientparms clientParms;
struct xmlrpc_curl_xportparms curlParms;
curlParms.network_interface = interface;
curlParms.no_ssl_verifypeer = 1;
curlParms.no_ssl_verifyhost = 1;
curlParms.user_agent = "pam_xmlrpc/0.1";
// TODO: cainfo
// curlParms.cainfo = "cacert.pem\0";
clientParms.transport = "curl";
clientParms.transportparmsP = (void*)&curlParms;
clientParms.transportparm_size = XMLRPC_CXPSIZE(user_agent);
xmlrpc_env env;
xmlrpc_client* clientP;
xmlrpc_value* result;
xmlrpc_env_init(&env);
xmlrpc_client_setup_global_const(&env);
xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, PAM_MODULE_NAME, PAM_MODULE_VERSION);
xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, PAM_MODULE_NAME, PAM_MODULE_VERSION, &clientParms, XMLRPC_CPSIZE(transportparm_size), &clientP);
xmlrpc_client_call2f(&env, clientP, url, "authenticate", &result, "(ss)", username, password);
if( fault_occurred(&env) )
return AUTH_FAIL_FAULT;
/* Parse our result value. */
xmlrpc_read_int(&env, result, &ret);
if( fault_occurred(&env) )
return AUTH_FAIL_FAULT;
/* Dispose of our result value. */
xmlrpc_DECREF(result);
/* Shutdown our XML-RPC client library. */
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
switch((int)ret) {
case 0:
return PAM_SUCCESS;
case 2:
return PAM_AUTH_ERR;
default:
return PAM_CRED_INSUFFICIENT;
}
}
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <errno.h>
#include <security/pam_modules.h>
#include <security/pam_misc.h>
#include "../include/xmlrpc.h"
#include "../include/define.h"
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv)
{
int retval, i;
const char *user;
char *passwd;
passwd = NULL;
/* Get User */
if ((retval = pam_get_user (pamh, &user, NULL)) != PAM_SUCCESS || user == NULL) {
syslog (LOG_ERR, "pam_xmlrpc: no user specified");
return PAM_USER_UNKNOWN;
}
// Reset password if not NULL
if (passwd != NULL)
pam_set_item(pamh, PAM_AUTHTOK, (const void**) &passwd);
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &passwd);
if ( passwd == NULL )
getPassword(pamh);
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &passwd);
if ( passwd == NULL )
return PAM_AUTHINFO_UNAVAIL;
// pam_passwd = passwd;
if ( strcmp(passwd, "") == 0 )
return PAM_AUTH_ERR;
retval = authenticate("https://home.drewdahl.com/RPC2/index.php","eth0",user,passwd);
#ifdef DEBUG
printf("server_connect() returned: %d ", retval);
/* Some extra debug info... this is a common error */
switch( retval )
{
case PAM_SUCCESS:
printf("PAM_SUCCESS");
break;
case PAM_AUTH_ERR:
printf("PAM_AUTH_ERR - Issue with Server");
break;
case AUTH_FAIL_FAULT:
printf("AUTH_FAIL_FAULT - Auth failed due to XMLRPC Fault");
break;
case PAM_CRED_INSUFFICIENT:
printf("PAM_CRED_INSUFFICIENT - Login failure");
break;
}
printf("\n");
#endif
if (retval == PAM_AUTH_ERR)
{
return PAM_AUTH_ERR;
}
else if ( retval == AUTH_FAIL_FAULT )
{ /* XMLRPC failed on our side... */
return PAM_AUTH_ERR;
}
else if ( retval == PAM_CRED_INSUFFICIENT)
{ /* user/pass wasn't right */
return PAM_AUTH_ERR;
}
else
{ /* login success. Add to cache and return success */
#ifdef DEBUG
printf("pam_sm_authenticate: returning PAM_SUCCESS\n");
#endif
return PAM_SUCCESS;
}
#ifdef DEBUG
printf("pam_sm_authenticate: returning PAM_AUTH_ERR\n");
#endif
return PAM_AUTH_ERR;
}/* end pam_sm_authenticate */
int converse(pam_handle_t *pamh, int nargs, struct pam_message **message, struct pam_response **response)
{
int retval;
struct pam_conv *conv;
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);
if ((retval != PAM_SUCCESS) && (retval != PAM_CONV_AGAIN))
{
syslog(LOG_DEBUG, "pam_xmlrpc: conversation failure [%s]",
pam_strerror(pamh, retval));
}
}
else
{
syslog(LOG_ERR, "pam_xmlrpc: couldn't obtain coversation function [%s]",
pam_strerror(pamh, retval));
}
return retval; /* propagate error status */
}
int getPassword(pam_handle_t *pamh)
{
struct pam_message msg[3], *mesg[3];
struct pam_response *resp=NULL;
char *prompt = NULL;
int i=0;
int retval;
msg[i].msg = ENTER_PASSWORD;
msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
mesg[i] = &msg[0];
retval = converse(pamh, ++i, mesg, &resp);
if (prompt)
{
_pam_overwrite(prompt);
_pam_drop(prompt);
}
if (retval != PAM_SUCCESS)
{
if (resp != NULL)
_pam_drop_reply(resp,i);
return ((retval == PAM_CONV_AGAIN) ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL);
}
/* we have a password so set AUTHTOK */
return pam_set_item(pamh, PAM_AUTHTOK, resp->resp);
}
/* These all return success... for now. TODO: Add functionality on server */
PAM_EXTERN int pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, int argc, const char **argv)
{
#ifdef DEBUG
syslog (LOG_INFO, "pam_xmlrpc: acct_mgmt not implemented.");
#endif
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
#ifdef DEBUG
syslog(LOG_INFO, "pam_xmlrpc: setcred not implemented.");
#endif
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
#ifdef DEBUG
syslog(LOG_INFO, "pam_xmlrpc: chauthtok not implemented.");
#endif
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
#ifdef DEBUG
syslog(LOG_INFO, "pam_xmlrpc: open_session not implemented.");
#endif
return PAM_SUCCESS;
}
PAM_EXTERN
int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
#ifdef DEBUG
syslog(LOG_INFO, "pam_xmlrpc: close_session not implemented.");
#endif
return PAM_SUCCESS;
}
/* end of module definition */
#ifdef PAM_STATIC
/* static module data */
struct pam_module _pam_permit_modstruct = {
"pam_permit",
pam_sm_authenticate,
pam_sm_setcred,
pam_sm_acct_mgmt,
pam_sm_open_session,
pam_sm_close_session,
pam_sm_chauthtok
};
#endif
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <errno.h>
#include <xmlrpc.h>
#include <xmlrpc_client.h>
#include <security/pam_modules.h>
#include <security/pam_misc.h>
#define PAM_MODULE_NAME "pam_xmlrpc"
#define PAM_MODULE_VERSION "0.1"
unsigned char fault_occurred (xmlrpc_env *env)
{
/* Check our error-handling environment for an XML-RPC fault. */
if (env->fault_occurred) {
fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
env->fault_string, env->fault_code);
return 1;
} else {
return 0;
}
}
int main(int argc, char** argv)
{
char* url = "https://home.drewdahl.com/RPC2/index.php";
char* username = "hi";
char* password = "two";
xmlrpc_int ret = 0;
struct xmlrpc_clientparms clientParms;
struct xmlrpc_curl_xportparms curlParms;
curlParms.network_interface = "eth0";
curlParms.no_ssl_verifypeer = 1;
curlParms.no_ssl_verifyhost = 1;
curlParms.user_agent = "pam_xmlrpc/0.1";
// TODO: cainfo
// curlParms.cainfo = "cacert.pem\0";
clientParms.transport = "curl";
clientParms.transportparmsP = (void*)&curlParms;
clientParms.transportparm_size = XMLRPC_CXPSIZE(user_agent);
xmlrpc_env env;
xmlrpc_client* clientP;
xmlrpc_value* result;
xmlrpc_env_init(&env);
xmlrpc_client_setup_global_const(&env);
xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, PAM_MODULE_NAME, PAM_MODULE_VERSION);
xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, PAM_MODULE_NAME, PAM_MODULE_VERSION, &clientParms, XMLRPC_CPSIZE(transportparm_size), &clientP);
xmlrpc_client_call2f(&env, clientP, url, "authenticate", &result, "(ss)", username, password);
if( fault_occurred(&env) )
return 20;
/* Parse our result value. */
xmlrpc_read_int(&env, result, &ret);
if( fault_occurred(&env) )
return 21;
/* Dispose of our result value. */
xmlrpc_DECREF(result);
/* Shutdown our XML-RPC client library. */
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
return ret;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment