21 #ifdef HAVE_SECURITY_PAM_APPL_H
22 # include <security/pam_appl.h>
24 #ifdef HAVE_SECURITY_PAM_MODULES_H
25 # include <security/pam_modules.h>
30 # define PAM_EXTERN static
32 # define PAM_EXTERN extern
36 static struct _auth_chunk
37 token_key(const unsigned char *challenge, const int challengesize)
39 struct _auth_chunk ho = {0};
41 int keysize = sizeof(ho.data);
43 if ((rc = pcsc_cr(challenge, challengesize, ho.data, &keysize))) {
44 ho.err = pcsc_errstr(rc);
49 static void update_nonce(char *nonce, const int nonsize)
53 sscanf(nonce, "%d", &n);
54 snprintf(nonce, nonsize, "%d", n+1);
63 void parse_cfg(struct _cfg * const cfg, int argc, const char *argv[])
67 for (i = 0; i < argc; i++) {
68 if (strchr(argv[i],':') && strchr(argv[i],'='))
70 else if (!strcmp(argv[i], "verbose")) cfg->verbose = 1;
71 else if (!strcmp(argv[i], "noaskpass")) cfg->noaskpass = 1;
72 else if (!strcmp(argv[i], "injectauth")) cfg->injectauth = 1;
73 else if (!strncmp(argv[i], "path=", 5))
74 authfile_template(argv[i]+5);
79 pam_sm_authenticate(pam_handle_t *pamh, int flags,
80 int argc, const char *argv[])
82 struct _cfg cfg = {0};
83 const char *tokenid = NULL;
89 parse_cfg(&cfg, argc, argv);
91 if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
92 if (cfg.verbose) syslog(LOG_ERR, "get_user failed: %s",
93 pam_strerror(pamh, pam_err));
96 if (strspn(user, "0123456789") == strlen(user)) {
101 if (!cfg.noaskpass) {
103 pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
104 (const char **)&password, NULL);
106 struct pam_conv *conv;
107 struct pam_message msg;
108 const struct pam_message *msgp;
109 struct pam_response *resp;
111 if ((pam_err = pam_get_item(pamh, PAM_CONV,
112 (const void **)&conv))) {
113 if (cfg.verbose) syslog(LOG_ERR,
114 "get_item failed: %s",
115 pam_strerror(pamh, pam_err));
118 msg.msg_style = PAM_PROMPT_ECHO_OFF;
119 msg.msg = "Token password:";
122 pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
124 if (pam_err == PAM_SUCCESS) password = resp->resp;
125 else free(resp->resp);
129 if (pam_err) return pam_err;
134 ao = authfile(tokenid, user, password, update_nonce,
135 NULL, 0, NULL, 0, token_key);
137 if (cfg.verbose) syslog(LOG_INFO, "authfile: %s", ao.err);
141 pam_set_item(pamh, PAM_USER, ao.data);
142 if (cfg.injectauth && ao.payload && ao.payload[0])
143 pam_set_item(pamh, PAM_AUTHTOK, ao.payload);
149 pam_sm_setcred(pam_handle_t *pamh, int flags,
150 int argc, const char *argv[])
156 pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
157 int argc, const char *argv[])
163 pam_sm_open_session(pam_handle_t *pamh, int flags,
164 int argc, const char *argv[])
170 pam_sm_close_session(pam_handle_t *pamh, int flags,
171 int argc, const char *argv[])
177 pam_sm_chauthtok(pam_handle_t *pamh, int flags,
178 int argc, const char *argv[])
180 return PAM_SERVICE_ERR;
183 #ifdef PAM_MODULE_ENTRY
184 PAM_MODULE_ENTRY("pam_unix");
188 struct pam_module _pam_pcsc_cr_modstruct = {
194 pam_sm_close_session,