template = str;
}
-static char *make_path(const char *tokenid, const char *userid)
+static int path_size(const char *tokenid, const char *userid)
{
const char *usub;
- char *path;
char *p, *q;
struct passwd *pw;
- if ((p = strchr(template, '~')) != strrchr(template, '~')) return NULL;
- if ((q = strchr(template, '?')) != strrchr(template, '?')) return NULL;
- if (p && !userid) return NULL;
- if (q && !tokenid) return NULL;
+ if ((p = strchr(template, '~')) != strrchr(template, '~')) return 0;
+ if ((q = strchr(template, '?')) != strrchr(template, '?')) return 0;
+ if (p && !userid) return 0;
+ if (q && !tokenid) return 0;
if (p == template) {
pw = getpwnam(userid);
- if (!pw) return NULL;
+ if (!pw) return 0;
+ usub = pw->pw_dir;
+ } else {
+ usub = userid;
+ }
+ return strlen(template) + p?strlen(usub):0 + q?strlen(tokenid):0 + 1;
+}
+
+static void
+make_path(char * const path, const char *tokenid, const char *userid)
+{
+ const char *usub;
+ char *p, *q;
+ struct passwd *pw;
+
+ path[0] = '\0';
+ if (template[0] == '~') {
+ pw = getpwnam(userid);
+ if (!pw) return;
usub = pw->pw_dir;
} else {
usub = userid;
}
- path = malloc(strlen(template) + p?strlen(usub):0 +
- q?strlen(tokenid):0 + 1);
- if (!path) return NULL;
q = path;
for (p = template; *p; p++) switch (*p) {
case '~':
break;
}
*q = '\0';
- return path;
}
struct _auth_obj authfile(const char *tokenid,
const int csize))
{
struct _auth_obj ret = {0};
+ mode_t oldmask;
FILE *fp = NULL;
char *fn;
+ int fnl;
char *buf = NULL;
- const char *wtokenid = NULL, *wuserid = NULL, *wnonce = NULL;
+ const char *wtokenid = "", *wuserid = NULL, *wnonce = NULL;
const char *hablob = NULL;
unsigned char *ablob = NULL;
int blobsize = 0;
int nonsize;
struct _auth_obj ao;
- if ((fn = make_path(tokenid, userid)) == NULL) {
+ if ((fnl = path_size(tokenid, userid)) == 0) {
ret.err = "authfile path impossible to build";
return ret;
}
+ fn = alloca(fnl);
+ make_path(fn, tokenid, userid);
fp = fopen(fn, "r");
- free(fn);
if (fp) {
struct stat st;
int fd = fileno(fp);
return ret;
}
+ oldmask = umask(077);
if ((fp = fopen(fn, "w"))) {
int i;
} else {
ret.err = strerror(errno);
}
+ (void)umask(oldmask);
if (!ret.err) {
int bufsize = (wuserid?strlen(wuserid)+1:0) + ao.paylsize;
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
+#include "authobj.h"
#include "authfile.h"
#include "pcsc_cr.h"
-int eprint(const char *format, ...)
+static struct _auth_chunk
+token_key(const unsigned char *challenge, const int challengesize)
{
- va_list ap;
- char *nfmt;
+ struct _auth_chunk ho = {0};
+ long rc;
+ int keysize = sizeof(ho.data);
- nfmt = alloca(strlen(format)+2);
- strcpy(nfmt, format);
- strcat(nfmt, "\n");
- va_start(ap, format);
- return vfprintf(stderr, nfmt, ap);
- va_end(ap);
+ if ((rc = pcsc_cr(challenge, challengesize, ho.data, &keysize))) {
+ ho.err = pcsc_errstr(rc);
+ }
+ return ho;
+}
+
+static char *mynonce = NULL;
+
+static void update_nonce(char *nonce, const int nonsize)
+{
+ if (mynonce) {
+ snprintf(nonce, nonsize, "%s", mynonce);
+ } else {
+ int n = 0;
+
+ sscanf(nonce, "%d", &n);
+ snprintf(nonce, nonsize, "%d", n+1);
+ }
}
-static void usage(const char const *cmd)
+static void usage(const char * const cmd)
{
- eprint( "usage: %s [options] [username]\n"
+ fprintf(stderr,
+ "usage: %s [options] [username]\n"
" -h - show this help and exit\n"
" -o backend-option - token option \"backend:key=val\"\n"
- " -f auth-file - auth state file to read/write\n"
+ " -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"
+ " -p password - login password\n"
+ " -v - show returned data\n"
, cmd);
}
int main(int argc, char *argv[])
{
+ struct _auth_obj ao;
int c;
- char *fn = NULL;
+ int verbose = 0;
char *hsecret = NULL;
char *secfn = NULL;
char secbuf[43];
unsigned char bsecret[20];
unsigned char *secret = NULL;
int i;
- char *nonce = NULL;
char *tokenid = NULL;
- char *id = getlogin();
- char *payload = "";
+ char *userid = getlogin();
+ char *payload = NULL;
char *password = "";
- while ((c = getopt(argc, argv, "ho:f:a:A:s:n:l:p:")) != -1)
+ while ((c = getopt(argc, argv, "ho:f:a:A:s:n:l:p:v")) != -1)
switch (c) {
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
case 'o':
if (pcsc_option(optarg)) {
- eprint("Option \"%s\" bad", optarg);
+ fprintf(stderr, "Option \"%s\" bad", optarg);
exit(EXIT_FAILURE);
}
break;
case 'f':
- fn = optarg;
+ authfile_template(optarg);
break;
case 'a':
if (!secfn) {
hsecret = optarg;
} else {
- eprint("-a and -A are mutually exclusive");
+ fprintf(stderr, "-a and -A are mutually exclusive");
exit(EXIT_FAILURE);
}
break;
if (!hsecret) {
secfn = optarg;
} else {
- eprint("-A and -a are mutually exclusive");
+ fprintf(stderr, "-A and -a are mutually exclusive");
exit(EXIT_FAILURE);
}
break;
tokenid = optarg;
break;
case 'n':
- nonce = optarg;
+ mynonce = optarg;
break;
case 'l':
payload = optarg;
case 'p':
password = optarg;
break;
+ case 'v':
+ verbose = 1;
+ break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
if (optind == (argc - 1)) {
- id = argv[optind];
+ userid = argv[optind];
optind++;
}
if (optind != argc) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
+ if (!userid) {
+ fprintf(stderr, "cannot determine userid");
+ exit(EXIT_FAILURE);
+ }
if (secfn) {
FILE *sfp;
char *p;
if (!strcmp(secfn, "-")) sfp = stdin;
else sfp = fopen(secfn, "r");
if (!sfp) {
- eprint("cannot open \"%s\": %s",
+ fprintf(stderr, "cannot open \"%s\": %s",
secfn, strerror(errno));
exit(EXIT_FAILURE);
}
if (!fgets(secbuf, sizeof(secbuf), sfp)) {
- eprint("cannot read \"%s\": %s",
+ fprintf(stderr, "cannot read \"%s\": %s",
secfn, strerror(errno));
exit(EXIT_FAILURE);
}
fclose(sfp);
hsecret = secbuf;
}
- if (!id) {
- eprint("cannot determine userid");
- exit(EXIT_FAILURE);
- }
if (hsecret) {
if (strlen(hsecret) != 40) {
fprintf(stderr,
sscanf(hsecret + i * 2, "%2hhx", &bsecret[i]);
secret = bsecret;
}
- return update_authfile(fn, tokenid, id, password, nonce,
- secret, sizeof(bsecret),
- (unsigned char *)payload, strlen(payload));
+ ao = authfile(tokenid, userid, password, update_nonce,
+ secret, secret ? sizeof(bsecret) : 0,
+ (unsigned char *)payload, payload ? strlen(payload) : 0,
+ token_key);
+ memset(bsecret, 0, sizeof(bsecret));
+ if (ao.err) {
+ fprintf(stderr, "%s\n", ao.err);
+ exit(EXIT_FAILURE);
+ } else if (verbose) {
+ printf("userid : \"%.*s\"\n", ao.datasize, ao.data);
+ printf("payload: \"%.*s\"\n", ao.paylsize, ao.payload);
+ }
+ if (ao.buffer) free(ao.buffer);
+ return 0;
}