authfile works (except strtok)
authorEugene Crosser <crosser@average.org>
Tue, 3 Dec 2013 22:12:23 +0000 (02:12 +0400)
committerEugene Crosser <crosser@average.org>
Tue, 3 Dec 2013 22:12:23 +0000 (02:12 +0400)
authfile.c
pam_cr_setup.c

index 9b1313c85ce63e6aa1964043d703bfbcd7c8fdcb..f7daa60eec5f0c3de4b8596b3bbf481a610f7c89 100644 (file)
@@ -33,27 +33,41 @@ void authfile_template(char *str)
        template = str;
 }
 
        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;
 {
        const char *usub;
-       char *path;
        char *p, *q;
        struct passwd *pw;
 
        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 (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;
        }
                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 '~':
        q = path;
        for (p = template; *p; p++) switch (*p) {
        case '~':
@@ -69,7 +83,6 @@ static char *make_path(const char *tokenid, const char *userid)
                break;
        }
        *q = '\0';
                break;
        }
        *q = '\0';
-       return path;
 }
 
 struct _auth_obj authfile(const char *tokenid,
 }
 
 struct _auth_obj authfile(const char *tokenid,
@@ -81,10 +94,12 @@ struct _auth_obj authfile(const char *tokenid,
                                                const int csize))
 {
        struct _auth_obj ret = {0};
                                                const int csize))
 {
        struct _auth_obj ret = {0};
+       mode_t oldmask;
        FILE *fp = NULL;
        char *fn;
        FILE *fp = NULL;
        char *fn;
+       int fnl;
        char *buf = NULL;
        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;
        const char *hablob = NULL;
        unsigned char *ablob = NULL;
        int blobsize = 0;
@@ -92,12 +107,13 @@ struct _auth_obj authfile(const char *tokenid,
        int nonsize;
        struct _auth_obj ao;
 
        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;
        }
                ret.err = "authfile path impossible to build";
                return ret;
        }
+       fn = alloca(fnl);
+       make_path(fn, tokenid, userid);
        fp = fopen(fn, "r");
        fp = fopen(fn, "r");
-       free(fn);
        if (fp) {
                struct stat st;
                int fd = fileno(fp);
        if (fp) {
                struct stat st;
                int fd = fileno(fp);
@@ -159,6 +175,7 @@ struct _auth_obj authfile(const char *tokenid,
                return ret;
        }
 
                return ret;
        }
 
+       oldmask = umask(077);
        if ((fp = fopen(fn, "w"))) {
                int i;
 
        if ((fp = fopen(fn, "w"))) {
                int i;
 
@@ -176,6 +193,7 @@ struct _auth_obj authfile(const char *tokenid,
        } else {
                ret.err = strerror(errno);
        }
        } else {
                ret.err = strerror(errno);
        }
+       (void)umask(oldmask);
 
        if (!ret.err) {
                int bufsize = (wuserid?strlen(wuserid)+1:0) + ao.paylsize;
 
        if (!ret.err) {
                int bufsize = (wuserid?strlen(wuserid)+1:0) + ao.paylsize;
index e0fb52a61d992cffa912cde3de482d39d7431902..8a42a74e3886c5128b3a925e795933d75da93a6a 100644 (file)
@@ -7,72 +7,89 @@
 #include <unistd.h>
 #include <errno.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <errno.h>
 #include <stdarg.h>
+#include "authobj.h"
 #include "authfile.h"
 #include "pcsc_cr.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"
                "    -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"
                "    -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[])
 {
                , cmd);
 }
 
 int main(int argc, char *argv[])
 {
+       struct _auth_obj ao;
        int c;
        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 *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 *tokenid = NULL;
-       char *id = getlogin();
-       char *payload = "";
+       char *userid = getlogin();
+       char *payload = NULL;
        char *password = "";
 
        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)) {
            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':
                        exit(EXIT_FAILURE);
                }
                break;
        case 'f':
-               fn = optarg;
+               authfile_template(optarg);
                break;
        case 'a':
                if (!secfn) {
                        hsecret = optarg;
                } else {
                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;
                        exit(EXIT_FAILURE);
                }
                break;
@@ -80,7 +97,7 @@ int main(int argc, char *argv[])
                if (!hsecret) {
                        secfn = optarg;
                } else {
                if (!hsecret) {
                        secfn = optarg;
                } else {
-                       eprint("-A and -a are mutually exclusive");
+                       fprintf(stderr, "-A and -a are mutually exclusive");
                        exit(EXIT_FAILURE);
                }
                break;
                        exit(EXIT_FAILURE);
                }
                break;
@@ -88,7 +105,7 @@ int main(int argc, char *argv[])
                tokenid = optarg;
                break;
        case 'n':
                tokenid = optarg;
                break;
        case 'n':
-               nonce = optarg;
+               mynonce = optarg;
                break;
        case 'l':
                payload = optarg;
                break;
        case 'l':
                payload = optarg;
@@ -96,18 +113,25 @@ int main(int argc, char *argv[])
        case 'p':
                password = optarg;
                break;
        case 'p':
                password = optarg;
                break;
+       case 'v':
+               verbose = 1;
+               break;
        default:
                usage(argv[0]);
                exit(EXIT_FAILURE);
        }
        if (optind == (argc - 1)) {
        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);
        }
                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 (secfn) {
                FILE *sfp;
                char *p;
@@ -115,12 +139,12 @@ int main(int argc, char *argv[])
                if (!strcmp(secfn, "-")) sfp = stdin;
                else sfp = fopen(secfn, "r");
                if (!sfp) {
                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)) {
                                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);
                }
                                secfn, strerror(errno));
                        exit(EXIT_FAILURE);
                }
@@ -130,10 +154,6 @@ int main(int argc, char *argv[])
                fclose(sfp);
                hsecret = secbuf;
        }
                fclose(sfp);
                hsecret = secbuf;
        }
-       if (!id) {
-               eprint("cannot determine userid");
-               exit(EXIT_FAILURE);
-       }
        if (hsecret) {
                if (strlen(hsecret) != 40) {
                        fprintf(stderr,
        if (hsecret) {
                if (strlen(hsecret) != 40) {
                        fprintf(stderr,
@@ -149,7 +169,18 @@ int main(int argc, char *argv[])
                        sscanf(hsecret + i * 2, "%2hhx", &bsecret[i]);
                secret = bsecret;
        }
                        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;
 }
 }