From 4e98ead2b7b37629705795b99d9a1dade2ae3b4b Mon Sep 17 00:00:00 2001 From: Jameson Little Date: Tue, 24 May 2011 19:59:33 -0600 Subject: [PATCH 1/1] Initial commit --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ buildPam.sh | 7 ++++++ buildTest.sh | 3 +++ src/mypam.c | 35 ++++++++++++++++++++++++++++ src/test.c | 51 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+) create mode 100644 README.md create mode 100755 buildPam.sh create mode 100755 buildTest.sh create mode 100644 src/mypam.c create mode 100644 src/test.c diff --git a/README.md b/README.md new file mode 100644 index 0000000..b57c893 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +Intro +===== + +This is just a simple PAM module and test code for it. There really isn't much to it, but it does make a good example of how to get started with a PAM module. + +To build, either use the build scripts or use these commands: + +**Build the PAM module** + +`gcc -fPIC -fno-stack-protector -c src/mypam.c` + +`sudo ld -x --shared -o /lib/security/mypam.so mypam.o` + +The first command builds the object file in the current directory and the second links it with PAM. Since it's a shared library, PAM can use it on the fly without having to restart. + +**Build Test** + +`g++ -o pam_test src/test.c -lpam -lpam_misc` + +OR + +`gcc -o pam_test src/test.c -lpam -lpam_misc` + +The test program is valid C, so it could be compiled using gcc or g++. I like g++ better because I'll probably want to extend it and I like C++ better. + +Simple Usage +------------ + +The build scripts will take care of putting your module where it needs to be, `/lib/security`, so the next thing to do is edit config files. + +The config files are located in `/etc/pam.d/` and the one I edited was `/etc/pam.d/common-auth`. + +The test application tests auth and account functionality (although account isn't very interesting). At the top of the pam file (or anywhere), put these lines: + + auth sufficient mypam.so + account sufficient mypam.so + +I think the account part should technically go in `/etc/pam.d/common-account`, but I put mine in the same place so I'd remember to take them out later. + +To run the test program, just do: `pam_test backdoor` and you should get some messages saying that you're authenticated! Maybe this is how Sam Flynn 'hacked' his father's computer in TRON Legacy =D. + +Resources +========= + +I found these resources especially helpful: + +O'Reilly Guides: +---------------- + +These guides give brief overviews about PAM and how to write modules. This is useful if you already have a little knowledge. + +* [Writing PAM Modules, Part One](http://linuxdevcenter.com/pub/a/linux/2002/05/02/pam_modules.html) +* [Writing PAM Modules, Part Two](http://linuxdevcenter.com/pub/a/linux/2002/05/23/pam_modules.html) +* [Writing PAM Modules, Part Three](http://linuxdevcenter.com/pub/a/linux/2002/05/30/pam_modules.html) + +Others +------ + +Good example for simple authentication. I adapted this one in my simple PAM module. + +[2-factor authentication & writing PAM modules](http://ben.akrin.com/?p=1068) + +Gives an example program that uses PAM. I adapted this for testing my PAM module. + +[Example PAM application](http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/adg-example.html) diff --git a/buildPam.sh b/buildPam.sh new file mode 100755 index 0000000..b16477c --- /dev/null +++ b/buildPam.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +gcc -fPIC -fno-stack-protector -c src/mypam.c + +sudo ld -x --shared -o /lib/security/mypam.so mypam.o + +rm mypam.o diff --git a/buildTest.sh b/buildTest.sh new file mode 100755 index 0000000..f143d1c --- /dev/null +++ b/buildTest.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +g++ -o pam_test src/test.c -lpam -lpam_misc diff --git a/src/mypam.c b/src/mypam.c new file mode 100644 index 0000000..31b3247 --- /dev/null +++ b/src/mypam.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +/* expected hook */ +PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv ) { + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { + printf("Acct mgmt\n"); + return PAM_SUCCESS; +} + +/* expected hook, this is where custom stuff happens */ +PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv ) { + int retval; + + const char* pUsername; + retval = pam_get_user(pamh, &pUsername, "Username: "); + + printf("Welcome %s\n", pUsername); + + if (retval != PAM_SUCCESS) { + return retval; + } + + if (strcmp(pUsername, "backdoor") != 0) { + return PAM_AUTH_ERR; + } + + return PAM_SUCCESS; +} diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..3ea1662 --- /dev/null +++ b/src/test.c @@ -0,0 +1,51 @@ +#include +#include +#include + +const struct pam_conv conv = { + misc_conv, + NULL +}; + +int main(int argc, char *argv[]) { + pam_handle_t* pamh = NULL; + int retval; + const char* user = "nobody"; + + if(argc != 2) { + printf("Usage: app [username]\n"); + exit(1); + } + + user = argv[1]; + + retval = pam_start("check_user", user, &conv, &pamh); + + // Are the credentials correct? + if (retval == PAM_SUCCESS) { + printf("Credentials accepted.\n"); + retval = pam_authenticate(pamh, 0); + } + + // Can the accound be used at this time? + if (retval == PAM_SUCCESS) { + printf("Account is valid.\n"); + retval = pam_acct_mgmt(pamh, 0); + } + + // Did everything work? + if (retval == PAM_SUCCESS) { + printf("Authenticated\n"); + } else { + printf("Not Authenticated\n"); + } + + // close PAM (end session) + if (pam_end(pamh, retval) != PAM_SUCCESS) { + pamh = NULL; + printf("check_user: failed to release authenticator\n"); + exit(1); + } + + return retval == PAM_SUCCESS ? 0 : 1; +} -- 2.30.2