9 #include <json-c/json.h>
12 #define PAM_SM_ACCOUNT
13 #define PAM_SM_SESSION
14 #define PAM_SM_PASSWORD
15 #include <security/pam_modules.h>
16 #include <security/pam_appl.h>
18 #include <security/pam_client.h>
19 #include <security/pam_ext.h>
20 #include <security/pam_filter.h>
21 #include <security/pam_misc.h>
22 #include <security/pam_modutil.h>
24 #define DATABASE_FILE "/etc/agl/keys.json"
26 int authenticate(pam_handle_t* pamh, const char* uid)
28 struct json_object* database;
29 struct json_object* nfc;
30 struct json_object* key;
32 database = json_object_from_file(DATABASE_FILE);
35 printf("[PAM DEBUG] Failed to parse the database\n");
36 return PAM_SERVICE_ERR;
39 if (json_object_object_get_ex(database, "nfc", &nfc))
41 if (json_object_object_get_ex(nfc, uid, &key))
43 printf("[PAM] Key found!\n");
44 printf("[PAM DEBUG] pam_set_item(\"%s\")\n", uid);
45 pam_set_item(pamh, PAM_USER, uid);
47 const char* pam_authtok;
48 if (pam_get_item(pamh, PAM_AUTHTOK, (const void**)&pam_authtok) == PAM_SUCCESS && !pam_authtok)
49 pam_set_item(pamh, PAM_AUTHTOK, uid);
51 json_object_put(database);
56 printf("[PAM] Key not found!\n");
57 if (database) json_object_put(database);
61 int check_device(pam_handle_t* pamh, const char* device)
66 ret = read_device(device, &idkey);
67 if (ret != PAM_SUCCESS) return ret;
69 printf("[PAM DEBUG] Data read:\n%s\n", idkey);
71 json_object* idkey_json = json_tokener_parse(idkey);
75 printf("[PAM DEBUG] Failed to parse json data!\n");
76 return PAM_SERVICE_ERR;
79 json_object* uuid_json;
80 if(!json_object_object_get_ex(idkey_json, "uuid", &uuid_json))
83 printf("[PAM DEBUG] The json does not contains a valid uuid\n");
84 return PAM_SERVICE_ERR;
87 const char* uuid = json_object_get_string(uuid_json);
88 printf("[PAM DEBUG] uuid: %s\n", uuid);
90 ret = authenticate(pamh, uuid);
92 json_object_put(idkey_json);
96 void log_pam(const char* fname, int flags, int argc, const char** argv, const char* device)
98 printf("[PAM DEBUG] ---------- %s ----------\n", fname);
99 printf("[PAM DEBUG] flags: %d\n", flags);
100 for(int i = 0; i < argc; ++i)
102 printf("[PAM DEBUG] argv[%d]: %s\n", i, argv[i]);
104 printf("[PAM DEBUG] device: %s\n", device);
105 printf("[PAM DEBUG] ----------------------------------------\n");
109 @brief The pam_sm_authenticate function is the service module's implementation
110 of the pam_authenticate(3) interface.
111 This function performs the task of authenticating the user.
113 @param[in] pamh Unknown.
114 @param[in] flags PAM_SILENT and/or PAM_DISALLOW_NULL_AUTHTOK.
115 @return PAM_SUCCESS if ok.
117 PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char** argv)
119 const char* uid = pam_getenv(pamh, "UID");
120 log_pam("pam_sm_authenticate", flags, argc, argv, uid);
121 return authenticate(pamh, uid);
124 PAM_EXTERN int pam_sm_setcred(pam_handle_t* pamh, int flags, int argc, const char** argv)
126 log_pam("pam_sm_setcred", flags, argc, argv, pam_getenv(pamh, "DEVICE"));
130 PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t* pamh, int flags, int argc, const char** argv)
132 log_pam("pam_sm_acct_mgmt", flags, argc, argv, pam_getenv(pamh, "DEVICE"));
136 PAM_EXTERN int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char** argv)
138 log_pam("pam_sm_open_session", flags, argc, argv, pam_getenv(pamh, "DEVICE"));
142 PAM_EXTERN int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char** argv)
144 log_pam("pam_sm_close_session", flags, argc, argv, pam_getenv(pamh, "DEVICE"));
148 PAM_EXTERN int pam_sm_chauthtok(pam_handle_t* pamh, int flags, int argc, const char** argv)
150 log_pam("pam_sm_chauthtok", flags, argc, argv, pam_getenv(pamh, "DEVICE"));