diff options
author | Loïc Collignon <loic.collignon@iot.bzh> | 2017-10-26 16:27:49 +0200 |
---|---|---|
committer | Loïc Collignon <loic.collignon@iot.bzh> | 2017-10-26 16:28:29 +0200 |
commit | f8b3ccaa4edd4836885dc3e22062b69e80883f36 (patch) | |
tree | f3278c3046acdb884fcb1bce89219cf862fcdd6b /pam_agl/pam_agl_nfc.c | |
parent | f014ffc2223d1b3bd80a14df7698a6b19a08df35 (diff) |
add nfc pam module
Change-Id: Icc42361f64948e2c2ab082fa973793f19737df2d
Signed-off-by: Loïc Collignon <loic.collignon@iot.bzh>
Diffstat (limited to 'pam_agl/pam_agl_nfc.c')
-rw-r--r-- | pam_agl/pam_agl_nfc.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/pam_agl/pam_agl_nfc.c b/pam_agl/pam_agl_nfc.c new file mode 100644 index 0000000..b25ba5c --- /dev/null +++ b/pam_agl/pam_agl_nfc.c @@ -0,0 +1,152 @@ +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <uuid/uuid.h> +#include <json-c/json.h> + +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD +#include <security/pam_modules.h> +#include <security/pam_appl.h> + +#include <security/pam_client.h> +#include <security/pam_ext.h> +#include <security/pam_filter.h> +#include <security/pam_misc.h> +#include <security/pam_modutil.h> + +#define DATABASE_FILE "/etc/agl/keys.json" + +int authenticate(pam_handle_t* pamh, const char* uid) +{ + struct json_object* database; + struct json_object* nfc; + struct json_object* key; + + database = json_object_from_file(DATABASE_FILE); + if (!database) + { + printf("[PAM DEBUG] Failed to parse the database\n"); + return PAM_SERVICE_ERR; + } + + if (json_object_object_get_ex(database, "nfc", &nfc)) + { + if (json_object_object_get_ex(nfc, uid, &key)) + { + printf("[PAM] Key found!\n"); + printf("[PAM DEBUG] pam_set_item(\"%s\")\n", uid); + pam_set_item(pamh, PAM_USER, uid); + + const char* pam_authtok; + if (pam_get_item(pamh, PAM_AUTHTOK, (const void**)&pam_authtok) == PAM_SUCCESS && !pam_authtok) + pam_set_item(pamh, PAM_AUTHTOK, uid); + + json_object_put(database); + return PAM_SUCCESS; + } + } + + printf("[PAM] Key not found!\n"); + if (database) json_object_put(database); + return PAM_AUTH_ERR; +} + +int check_device(pam_handle_t* pamh, const char* device) +{ + char* idkey; + int ret; + + ret = read_device(device, &idkey); + if (ret != PAM_SUCCESS) return ret; + + printf("[PAM DEBUG] Data read:\n%s\n", idkey); + + json_object* idkey_json = json_tokener_parse(idkey); + if (!idkey_json) + { + free(idkey); + printf("[PAM DEBUG] Failed to parse json data!\n"); + return PAM_SERVICE_ERR; + } + + json_object* uuid_json; + if(!json_object_object_get_ex(idkey_json, "uuid", &uuid_json)) + { + free(idkey); + printf("[PAM DEBUG] The json does not contains a valid uuid\n"); + return PAM_SERVICE_ERR; + } + + const char* uuid = json_object_get_string(uuid_json); + printf("[PAM DEBUG] uuid: %s\n", uuid); + + ret = authenticate(pamh, uuid); + free(idkey); + json_object_put(idkey_json); + return ret; +} + +void log_pam(const char* fname, int flags, int argc, const char** argv, const char* device) +{ + printf("[PAM DEBUG] ---------- %s ----------\n", fname); + printf("[PAM DEBUG] flags: %d\n", flags); + for(int i = 0; i < argc; ++i) + { + printf("[PAM DEBUG] argv[%d]: %s\n", i, argv[i]); + } + printf("[PAM DEBUG] device: %s\n", device); + printf("[PAM DEBUG] ----------------------------------------\n"); +} + +/*! + @brief The pam_sm_authenticate function is the service module's implementation + of the pam_authenticate(3) interface. + This function performs the task of authenticating the user. + + @param[in] pamh Unknown. + @param[in] flags PAM_SILENT and/or PAM_DISALLOW_NULL_AUTHTOK. + @return PAM_SUCCESS if ok. +*/ +PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + const char* uid = pam_getenv(pamh, "UID"); + log_pam("pam_sm_authenticate", flags, argc, argv, uid); + return authenticate(pamh, uid); +} + +PAM_EXTERN int pam_sm_setcred(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + log_pam("pam_sm_setcred", flags, argc, argv, pam_getenv(pamh, "DEVICE")); + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + log_pam("pam_sm_acct_mgmt", flags, argc, argv, pam_getenv(pamh, "DEVICE")); + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + log_pam("pam_sm_open_session", flags, argc, argv, pam_getenv(pamh, "DEVICE")); + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + log_pam("pam_sm_close_session", flags, argc, argv, pam_getenv(pamh, "DEVICE")); + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_chauthtok(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + log_pam("pam_sm_chauthtok", flags, argc, argv, pam_getenv(pamh, "DEVICE")); + return PAM_SUCCESS; +} |