introcude authfile module
[pam_pcsc_cr.git] / pam_cr_setup.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <stdarg.h>
10 #include "authfile.h"
11 #include "pcsc_cr.h"
12
13 int eprint(const char *format, ...)
14 {
15         va_list ap;
16
17         va_start(ap, format);
18         return vfprintf(stderr, format, ap);
19         va_end(ap);
20 }
21
22 static void usage(const char const *cmd)
23 {
24         eprint( "usage: %s [options] [username]\n"
25                 "    -h                - show this help and exit\n"
26                 "    -o backend-option - token option \"backend:key=val\"\n"
27                 "    -f auth-file      - auth state file to read/write\n"
28                 "    -a secret | -A file-with-secret | -A -\n"
29                 "                      - 40-character hexadecimal secret\n"
30                 "    -s token-serial   - public I.D. of the token\n"
31                 "    -n nonce          - initial nonce\n"
32                 "    -l payload        - keyring unlock password\n"
33                 "    -p password       - login password\n"
34                 , cmd);
35 }
36
37 int main(int argc, char *argv[])
38 {
39         int c;
40         char *fn = NULL;
41         char *hsecret = NULL;
42         char *secfn = NULL;
43         char secbuf[43];
44         unsigned char bsecret[20];
45         unsigned char *secret = NULL;
46         int i;
47         char *nonce = "1";
48         char *tokenid = "";
49         char *id = getlogin();
50         char *payload = "";
51         char *password = "";
52
53         while ((c = getopt(argc, argv, "ho:f:a:A:s:n:l:p:")) != -1)
54             switch (c) {
55         case 'h':
56                 usage(argv[0]);
57                 exit(EXIT_SUCCESS);
58         case 'o':
59                 if (pcsc_option(optarg)) {
60                         eprint("Option \"%s\" bad\n", optarg);
61                         exit(EXIT_FAILURE);
62                 }
63                 break;
64         case 'f':
65                 fn = optarg;
66                 break;
67         case 'a':
68                 if (!secfn) {
69                         hsecret = optarg;
70                 } else {
71                         eprint("-a and -A are mutually exclusive\n");
72                         exit(EXIT_FAILURE);
73                 }
74                 break;
75         case 'A':
76                 if (!hsecret) {
77                         secfn = optarg;
78                 } else {
79                         eprint("-A and -a are mutually exclusive\n");
80                         exit(EXIT_FAILURE);
81                 }
82                 break;
83         case 's':
84                 tokenid = optarg;
85                 break;
86         case 'n':
87                 nonce = optarg;
88                 break;
89         case 'l':
90                 payload = optarg;
91                 break;
92         case 'p':
93                 password = optarg;
94                 break;
95         default:
96                 usage(argv[0]);
97                 exit(EXIT_FAILURE);
98         }
99         if (optind == (argc - 1)) {
100                 id = argv[optind];
101                 optind++;
102         }
103         if (optind != argc) {
104                 usage(argv[0]);
105                 exit(EXIT_FAILURE);
106         }
107         if (secfn) {
108                 FILE *sfp;
109                 char *p;
110
111                 if (!strcmp(secfn, "-")) sfp = stdin;
112                 else sfp = fopen(secfn, "r");
113                 if (!sfp) {
114                         eprint("cannot open \"%s\": %s\n",
115                                 secfn, strerror(errno));
116                         exit(EXIT_FAILURE);
117                 }
118                 if (!fgets(secbuf, sizeof(secbuf), sfp)) {
119                         eprint("cannot read \"%s\": %s\n",
120                                 secfn, strerror(errno));
121                         exit(EXIT_FAILURE);
122                 }
123                 for (p = secbuf + strlen(secbuf) - 1;
124                         *p == '\n' || *p == '\r'; p--) *p = '\n';
125
126                 fclose(sfp);
127                 hsecret = secbuf;
128         }
129         if (!id) {
130                 eprint("cannot determine userid\n");
131                 exit(EXIT_FAILURE);
132         }
133         if (hsecret) {
134                 if (strlen(hsecret) != 40) {
135                         fprintf(stderr,
136                                 "secret wrong, must be exactly 40 chars\n");
137                         exit(EXIT_FAILURE);
138                 }
139                 if (strspn(hsecret, "0123456789abcdefABCDEF") != 40) {
140                         fprintf(stderr,
141                                 "secret wrong, must be hexadecimal string\n");
142                         exit(EXIT_FAILURE);
143                 }
144                 for (i = 0; i < 20; i++)
145                         sscanf(hsecret + i * 2, "%2hhx", &bsecret[i]);
146                 secret = bsecret;
147         }
148         return update_authfile(fn, tokenid, id, password, nonce,
149                                 secret, sizeof(bsecret),
150                                 (unsigned char *)payload, strlen(payload));
151 }