aklog: Fix some format warnings
[openafs.git] / src / aklog / asetkey.c
1 /*
2  * $Id$
3  *
4  * asetkey - Manipulates an AFS KeyFile
5  *
6  * Updated for Kerberos 5
7  */
8
9 #include <afsconfig.h>
10 #include <sys/types.h>
11 #include <netinet/in.h>
12 #include <netdb.h>
13 #include <stdio.h>
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17 #include <stdlib.h>
18 #ifdef HAVE_MEMORY_H
19 #include <memory.h>
20 #endif /* HAVE_MEMORY_H */
21 #include <string.h>
22
23 #include <afs/stds.h>
24 #include <krb5.h>
25
26 #ifndef HAVE_KERBEROSV_HEIM_ERR_H
27 #include <afs/com_err.h>
28 #endif
29 #include <afs/cellconfig.h>
30 #include <afs/keys.h>
31 #include <afs/dirpath.h>
32
33 #ifdef HAVE_KRB5_CREDS_KEYBLOCK
34 #define USING_MIT 1
35 #endif
36 #ifdef HAVE_KRB5_CREDS_SESSION
37 #define USING_HEIMDAL 1
38 #endif
39
40 static int
41 char2hex(char c)
42 {
43   if (c >= '0' && c <= '9')
44     return (c - 48);
45   if ((c >= 'a') && (c <= 'f'))
46     return (c - 'a' + 10);
47
48   if ((c >= 'A') && (c <= 'F'))
49     return (c - 'A' + 10);
50
51   return -1;
52 }
53
54 int
55 main(int argc, char *argv[])
56 {
57     struct afsconf_dir *tdir;
58     long code;
59     const char *confdir;
60
61     if (argc == 1) {
62         fprintf(stderr, "%s: usage is '%s <opcode> options, e.g.\n",
63                 argv[0], argv[0]);
64         fprintf(stderr, "\t%s add <kvno> <keyfile> <princ>\n", argv[0]);
65         fprintf(stderr, "\tOR\n\t%s add <kvno> <key>\n", argv[0]);
66         fprintf(stderr, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv[0]);
67         fprintf(stderr, "\t%s delete <kvno>\n", argv[0]);
68         fprintf(stderr, "\t%s list\n", argv[0]);
69         exit(1);
70     }
71
72     confdir = AFSDIR_SERVER_ETC_DIRPATH;
73
74     tdir = afsconf_Open(confdir);
75     if (!tdir) {
76         fprintf(stderr, "%s: can't initialize conf dir '%s'\n", argv[0],
77                 confdir);
78         exit(1);
79     }
80     if (strcmp(argv[1], "add")==0) {
81         krb5_context context;
82         krb5_principal principal;
83         krb5_keyblock *key;
84         krb5_error_code retval;
85         int kvno, keymode = 0;
86
87         if (argc != 5) {
88             if (argc == 4)
89                 keymode = 1;
90             else {
91                 fprintf(stderr, "%s add: usage is '%s add <kvno> <keyfile> "
92                         "<princ>\n", argv[0], argv[0]);
93                 fprintf(stderr, "\tOR\n\t%s add <kvno> <key>\n", argv[0]);
94                 fprintf(stderr, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv[0]);
95                 exit(1);
96             }
97         }
98
99         kvno = atoi(argv[2]);
100         if (keymode) {
101             char tkey[8];
102             int i;
103             char *cp;
104             if (strlen(argv[3]) != 16) {
105                 printf("key %s is not in right format\n", argv[3]);
106                 printf(" <key> should be an 8byte hex representation \n");
107                 printf("  Ex: setkey add 0 \"80b6a7cd7a9dadb6\"\n");
108                 exit(1);
109             }
110             memset(tkey, 0, sizeof(tkey));
111             for (i = 7, cp = argv[3] + 15; i >= 0; i--, cp -= 2)
112                 tkey[i] = char2hex(*cp) + char2hex(*(cp - 1)) * 16;
113             code = afsconf_AddKey(tdir, kvno, tkey, 1);
114         } else {
115             krb5_init_context(&context);
116
117             retval = krb5_parse_name(context, argv[4], &principal);
118             if (retval != 0) {
119                 afs_com_err(argv[0], retval, "while parsing AFS principal");
120                 exit(1);
121             }
122             retval = krb5_kt_read_service_key(context, argv[3], principal, kvno,
123                                               ENCTYPE_DES_CBC_CRC, &key);
124             if (retval != 0) {
125                 afs_com_err(argv[0], retval, "while extracting AFS service key");
126                 exit(1);
127             }
128
129 #ifdef USING_HEIMDAL
130 #define deref_key_length(key)                   \
131             key->keyvalue.length
132
133 #define deref_key_contents(key)                 \
134             key->keyvalue.data
135 #else
136 #define deref_key_length(key)                   \
137             key->length
138
139 #define deref_key_contents(key)                 \
140             key->contents
141 #endif
142             if (deref_key_length(key) != 8) {
143                 fprintf(stderr, "Key length should be 8, but is really %u!\n",
144                         (unsigned int)deref_key_length(key));
145                 exit(1);
146             }
147             code = afsconf_AddKey(tdir, kvno, (char *) deref_key_contents(key), 1);
148         }
149
150         if (code) {
151             fprintf(stderr, "%s: failed to set key, code %ld.\n", argv[0], code);
152             exit(1);
153         }
154         if (keymode == 0) {
155             krb5_free_principal(context, principal);
156             krb5_free_keyblock(context, key);
157         }
158     }
159     else if (strcmp(argv[1], "delete")==0) {
160         long kvno;
161         if (argc != 3) {
162             fprintf(stderr, "%s delete: usage is '%s delete <kvno>\n",
163                     argv[0], argv[0]);
164             exit(1);
165         }
166         kvno = atoi(argv[2]);
167         code = afsconf_DeleteKey(tdir, kvno);
168         if (code) {
169             fprintf(stderr, "%s: failed to delete key %ld, (code %ld)\n",
170                     argv[0], kvno, code);
171             exit(1);
172         }
173     }
174     else if (strcmp(argv[1], "list") == 0) {
175         struct afsconf_keys tkeys;
176         int i, j;
177
178         code = afsconf_GetKeys(tdir, &tkeys);
179         if (code) {
180             fprintf(stderr, "%s: failed to get keys, code %ld\n", argv[0], code);
181             exit(1);
182         }
183         for(i=0;i<tkeys.nkeys;i++) {
184             if (tkeys.key[i].kvno != -1) {
185                 printf("kvno %4d: key is: ", tkeys.key[i].kvno);
186                 for (j = 0; j < 8; j++)
187                         printf("%02x", (unsigned char) tkeys.key[i].key[j]);
188                 printf("\n");
189             }
190         }
191         printf("All done.\n");
192     }
193     else {
194         fprintf(stderr, "%s: unknown operation '%s', type '%s' for "
195                 "assistance\n", argv[0], argv[1], argv[0]);
196         exit(1);
197     }
198     exit(0);
199 }