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