2 Copyright (c) 2013 Eugene Crosser
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must
13 not claim that you wrote the original software. If you use this
14 software in a product, an acknowledgment in the product documentation
15 would be appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must
18 not be misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source
37 static struct _auth_chunk
38 token_key(const unsigned char *challenge, const size_t challengesize)
40 struct _auth_chunk ho = {0};
42 size_t keysize = sizeof(ho.data);
44 if ((rc = pcsc_cr(challenge, challengesize, ho.data, &keysize))) {
45 ho.err = pcsc_errstr(rc);
50 static char *mynonce = NULL;
52 static void update_nonce(char *nonce, const size_t nonsize)
55 snprintf(nonce, nonsize, "%s", mynonce);
59 sscanf(nonce, "%d", &n);
60 snprintf(nonce, nonsize, "%d", n+1);
64 static void usage(const char * const cmd)
67 "usage: %s [options] [username]\n"
68 " -h - show this help and exit\n"
69 " -o backend-option - token option \"backend:key=val\"\n"
70 " -f template - template for auth state filepath\n"
71 " -a secret | -A file-with-secret | -A -\n"
72 " - 40-character hexadecimal secret\n"
73 " -n nonce - initial nonce\n"
74 " -l payload - keyring unlock password\n"
75 " -p password - login password\n"
76 " -v - show returned data\n"
80 int main(int argc, char *argv[])
88 unsigned char bsecret[20];
89 unsigned char *secret = NULL;
91 char *userid = getlogin();
95 while ((c = getopt(argc, argv, "ho:f:a:A:n:l:p:v")) != -1)
101 if (pcsc_option(optarg)) {
102 fprintf(stderr, "Option \"%s\" bad", optarg);
107 authfile_template(optarg);
113 fprintf(stderr, "-a and -A are mutually exclusive");
121 fprintf(stderr, "-A and -a are mutually exclusive");
141 if (optind == (argc - 1)) {
142 userid = argv[optind];
145 if (optind != argc) {
150 fprintf(stderr, "cannot determine userid");
157 if (!strcmp(secfn, "-")) sfp = stdin;
158 else sfp = fopen(secfn, "r");
160 fprintf(stderr, "cannot open \"%s\": %s",
161 secfn, strerror(errno));
164 if (!fgets(secbuf, sizeof(secbuf), sfp)) {
165 fprintf(stderr, "cannot read \"%s\": %s",
166 secfn, strerror(errno));
169 for (p = secbuf + strlen(secbuf) - 1;
170 *p == '\n' || *p == '\r'; p--) *p = '\n';
176 if (strlen(hsecret) != 40) {
178 "secret wrong, must be exactly 40 chars\n");
181 if (strspn(hsecret, "0123456789abcdefABCDEF") != 40) {
183 "secret wrong, must be hexadecimal string\n");
186 for (i = 0; i < 20; i++)
187 sscanf(hsecret + i * 2, "%2hhx", &bsecret[i]);
190 ao = authfile(userid, password, update_nonce,
191 secret, secret ? sizeof(bsecret) : 0,
192 (unsigned char *)payload, payload ? strlen(payload) : 0,
194 memset(bsecret, 0, sizeof(bsecret));
196 fprintf(stderr, "%s\n", ao.err);
198 } else if (verbose) {
199 printf("version: %s\n", VERSION);
200 printf("userid : \"%.*s\"\n", (int)ao.datasize, ao.data);
201 printf("payload: \"%.*s\"\n", (int)ao.paylsize, ao.payload);
203 if (ao.buffer) free(ao.buffer);