d9dfb66acd7c8290d119f908ec48b0a6240c0121
[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 "authobj.h"
10 #if 0
11 #include "pcsc_cr.h"
12 #endif
13
14 static void usage(const char const *cmd)
15 {
16         fprintf(stderr,
17                 "usage: %s [-f filename] {-s hexstring40 | -S file} [-u username] [-n nonce] [-l payload] [-p password]\n",
18                 cmd);
19 }
20
21 int main(int argc, char *argv[])
22 {
23         int c;
24         char *fn = NULL;
25         FILE *fp;
26         char *hsecret = NULL;
27         char *secfn = NULL;
28         char secbuf[43];
29         unsigned char secret[20];
30         int i;
31         char *nonce = "1";
32         char *id = getlogin();
33         char *payload = "";
34         char *password = "";
35         int rc;
36         unsigned char authobj[256];
37         int authsize = sizeof(authobj);
38
39         while ((c = getopt(argc, argv, "h"
40 #if 0
41                                         "o:"
42 #endif
43                                         "f:s:S:u:n:l:p:")) != -1) switch (c) {
44         case 'h':
45                 usage(argv[0]);
46                 exit(EXIT_SUCCESS);
47 #if 0
48         case 'o':
49                 if (pcsc_option(optarg)) {
50                         fprintf(stderr, "Option \"%s\" bad\n", optarg);
51                         exit(EXIT_FAILURE);
52                 }
53                 break;
54 #endif
55         case 'f':
56                 fn = optarg;
57                 break;
58         case 's':
59                 if (!secfn) {
60                         hsecret = optarg;
61                 } else {
62                         fprintf(stderr, "-s and -S are mutually exclusive\n");
63                         exit(EXIT_FAILURE);
64                 }
65                 break;
66         case 'S':
67                 if (!hsecret) {
68                         secfn = optarg;
69                 } else {
70                         fprintf(stderr, "-S and -s are mutually exclusive\n");
71                         exit(EXIT_FAILURE);
72                 }
73                 break;
74         case 'u':
75                 id = optarg;
76                 break;
77         case 'n':
78                 nonce = optarg;
79                 break;
80         case 'l':
81                 payload = optarg;
82                 break;
83         case 'p':
84                 password = optarg;
85                 break;
86         default:
87                 usage(argv[0]);
88                 exit(EXIT_FAILURE);
89         }
90         if (optind == (argc - 1) && !secfn && !hsecret) {
91                 hsecret = argv[optind];
92                 optind++;
93         }
94         if (optind != argc) {
95                 usage(argv[0]);
96                 exit(EXIT_FAILURE);
97         }
98         if (secfn) {
99                 FILE *sfp;
100                 char *p;
101
102                 if (!strcmp(secfn, "-")) sfp = stdin;
103                 else sfp = fopen(secfn, "r");
104                 if (!sfp) {
105                         fprintf(stderr, "cannot open \"%s\": %s\n",
106                                 secfn, strerror(errno));
107                         exit(EXIT_FAILURE);
108                 }
109                 if (!fgets(secbuf, sizeof(secbuf), sfp)) {
110                         fprintf(stderr, "cannot read \"%s\": %s\n",
111                                 secfn, strerror(errno));
112                         exit(EXIT_FAILURE);
113                 }
114                 for (p = secbuf + strlen(secbuf) - 1;
115                         *p == '\n' || *p == '\r'; p--) *p = '\n';
116
117                 fclose(sfp);
118                 hsecret = secbuf;
119         }
120         if (!hsecret) {
121                 fprintf(stderr, "secret missing, specify -s or -S\n");
122                 exit(EXIT_FAILURE);
123         }
124         if (strlen(hsecret) != 40) {
125                 fprintf(stderr, "secret wrong, must be exactly 40 chars\n");
126                 exit(EXIT_FAILURE);
127         }
128         for (i = 0; i < 20; i++)
129             if (sscanf(hsecret + i * 2, "%2hhx", &secret[i]) != 1) {
130                 fprintf(stderr, "secret wrong, must be hexadecimal\n");
131                 exit(EXIT_FAILURE);
132         }
133         if (!id) {
134                 fprintf(stderr, "cannot determine userid\n");
135                 exit(EXIT_FAILURE);
136         }
137         rc = make_authobj(id, password, nonce, secret, sizeof(secret),
138                         (unsigned char *)payload, strlen(payload),
139                         authobj, &authsize);
140         if (rc) {
141                 fprintf(stderr, "error %d\n", rc);
142                 exit(EXIT_FAILURE);
143         }
144         fp = fopen(fn, "w");
145         if (!fp) {
146                 fprintf(stderr, "cannot open \"%s\": %s\n",
147                         fn, strerror(errno));
148                 exit(EXIT_FAILURE);
149         }
150         if (fprintf(fp, "%s:%s:%s:", "", id, nonce) < 0) {
151                 fprintf(stderr, "cannot write to \"%s\": %s\n",
152                         fn, strerror(errno));
153                 exit(EXIT_FAILURE);
154         }
155         for (i = 0; i < authsize; i++)
156             if (fprintf(fp, "%02x", authobj[i]) < 0) {
157                 fprintf(stderr, "cannot write to \"%s\": %s\n",
158                         fn, strerror(errno));
159                 exit(EXIT_FAILURE);
160         }
161         fprintf(fp, "\n");
162         if (fclose(fp) < 0) {
163                 fprintf(stderr, "cannot close \"%s\": %s\n",
164                         fn, strerror(errno));
165                 exit(EXIT_FAILURE);
166         }
167         return 0;
168 }