setup program (and must be the same, obviously). In the template string,
character '~' in the first position is substituted with the userid's
home directory, '~' in a position other than first - with the userid
-itself, and character '?' - with the "tokenid". This latter is just an
-arbitrary string that is not involved in the authentication process.
-But, if the template contains '?' but not '~', login process can start
-without the knowlege of the userid. Userid will be picked from the file
-and injected into the PAM environment, given that tokenid is known from
-the start.
+itself.
Default template string is `~/.pam_cr/auth`, i.e. the file lives in the
user's home directory, in the subdirectory `.pam_cr`.
* Template string may contain zero or one '~' and zero or one '?'.
* '~' at the beginning of the template string is substituted with
* the home directory of the userid. In any other position it is
- * substituted with the userid itself. '?' is substituted with the
- * tokenid. There is no way to make the resulting path contain '~'
- * or '?'. If there is more than one '~' or '?', or if the '~' is
- * at the beginning but userid does not resolve via getpwnam, or
- * the character to substitute is present but the argument is NULL,
- * NULL is returned. Otherwise, malloc()'ed area containg the path
- * string.
+ * substituted with the userid itself. There is no way to make the
+ * resulting path contain '~'. If there is more than one '~', or if
+ * the '~' is at the beginning but userid does not resolve via
+ * getpwnam, or '~' is present but the argument is NULL, path_size
+ * returns 0, and make_path returns 1.
*/
static const char *template = "~/.pam_cr/auth";
I like the alternatives even less. =ec
*/
-static int path_size(const char *tokenid, const struct passwd *pw)
+static int path_size(const struct passwd *pw)
{
- const char *usub;
- const char *p, *q;
+ const char *p;
if ((p = strchr(template, '~')) != strrchr(template, '~')) return 0;
- if ((q = strchr(template, '?')) != strrchr(template, '?')) return 0;
if (p && !pw) return 0;
- if (q && !tokenid) return 0;
- if (p == template) usub = pw->pw_dir;
- else usub = pw->pw_name;
- return strlen(template)+(p?strlen(usub):0)+(q?strlen(tokenid):0)+1;
+ if (p == template) return strlen(template)+strlen(pw->pw_dir)+1;
+ else return strlen(template)+strlen(pw->pw_name)+1;
}
static int
-make_path(char * const path, const char *tokenid, const struct passwd *pw)
+make_path(char * const path, const struct passwd *pw)
{
const char *p;
char *q;
else strcpy(q, pw->pw_name);
while (*q) q++;
break;
- case '?':
- if (!tokenid) return 1;
- strcpy(q, tokenid);
- while (*q) q++;
- break;
default:
*q++ = *p;
break;
return i != argc;
}
-struct _auth_obj authfile(const char *tokenid,
- const char *userid, const char *password,
+struct _auth_obj authfile(const char *userid, const char *password,
void (*update_nonce)(char *nonce, const int nonsize),
const unsigned char *secret, const int secsize,
const unsigned char *payload, const int paylsize,
struct stat st = {0};
char *buf = NULL;
struct {
- const char *tokenid;
const char *userid;
const char *nonce;
const char *hablob;
- } w = {"", NULL, NULL, NULL};
+ } w = {NULL, NULL, NULL};
unsigned char *ablob = NULL;
int blobsize = 0;
char *newnonce;
struct _auth_obj ao;
if (userid) pw = getpwnam(userid);
- if ((fnl = path_size(tokenid, pw)) == 0) {
+ if ((fnl = path_size(pw)) == 0) {
ret.err = "authfile path_size failed";
return ret;
}
fn = alloca(fnl);
- if (make_path(fn, tokenid, pw)) {
+ if (make_path(fn, pw)) {
ret.err = "authfile make_path failed";
return ret;
}
if (b64_encode(ao.data, ao.datasize, b64, &bsize)) {
ret.err = "error: could not encode auth string";
- } else if (fprintf(fp, "%s:%s:%s:%s\n",
- tokenid?tokenid:w.tokenid,
+ } else if (fprintf(fp, "%s:%s:%s\n",
userid?userid:w.userid, newnonce, b64) < 0) {
ret.err = strerror(errno);
}
void authfile_template(const char *template);
-struct _auth_obj authfile(const char *tokenid,
- const char *userid, const char *password,
+struct _auth_obj authfile(const char *userid, const char *password,
void (*update_nonce)(char *nonce, const int nonsize),
const unsigned char *secret, const int secsize,
const unsigned char *payload, const int paysize,
" -f template - template for auth state filepath\n"
" -a secret | -A file-with-secret | -A -\n"
" - 40-character hexadecimal secret\n"
- " -s token-serial - public I.D. of the token\n"
" -n nonce - initial nonce\n"
" -l payload - keyring unlock password\n"
" -p password - login password\n"
unsigned char bsecret[20];
unsigned char *secret = NULL;
int i;
- char *tokenid = NULL;
char *userid = getlogin();
char *payload = NULL;
char *password = "";
- while ((c = getopt(argc, argv, "ho:f:a:A:s:n:l:p:v")) != -1)
+ while ((c = getopt(argc, argv, "ho:f:a:A:n:l:p:v")) != -1)
switch (c) {
case 'h':
usage(argv[0]);
exit(EXIT_FAILURE);
}
break;
- case 's':
- tokenid = optarg;
- break;
case 'n':
mynonce = optarg;
break;
sscanf(hsecret + i * 2, "%2hhx", &bsecret[i]);
secret = bsecret;
}
- ao = authfile(tokenid, userid, password, update_nonce,
+ ao = authfile(userid, password, update_nonce,
secret, secret ? sizeof(bsecret) : 0,
(unsigned char *)payload, payload ? strlen(payload) : 0,
token_key);
int argc, const char *argv[])
{
struct _cfg cfg = {0};
- const char *tokenid = NULL;
const char *user;
const char *password;
struct _auth_obj ao;
pam_strerror(pamh, pam_err));
return pam_err;
}
- if (strspn(user, "0123456789") == strlen(user)) {
- tokenid = user;
- user = NULL;
- }
- if (cfg.verbose) syslog(LOG_DEBUG, "tokenid=\"%s\", user=\"%s\"",
- tokenid?tokenid:"<none>", user?user:"<none>");
+ if (cfg.verbose) syslog(LOG_DEBUG, "user=\"%s\"", user?user:"<none>");
if (!cfg.noaskpass) {
if ((pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
password = "";
}
- ao = authfile(tokenid, user, password, update_nonce,
+ ao = authfile(user, password, update_nonce,
NULL, 0, NULL, 0, token_key);
if (ao.err) {
if (cfg.verbose) syslog(LOG_INFO, "authfile: %s", ao.err);
return PAM_AUTH_ERR;
} else {
- if (!user)
- pam_set_item(pamh, PAM_USER, ao.data);
+ /* Just because we can. Probably not much use for that. */
+ /* Userid written in authfile may differ from the login one. */
+ pam_set_item(pamh, PAM_USER, ao.data);
if (cfg.injectauth && ao.payload && ao.payload[0])
pam_set_item(pamh, PAM_AUTHTOK, ao.payload);
if (cfg.verbose) syslog(LOG_DEBUG, "authenticated");