asetkey-with-heimdal-20070104
[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 <stdio.h>
11 #include <sys/types.h>
12 #include <netinet/in.h>
13 #include <netdb.h>
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17 #ifdef HAVE_STDLIB_H
18 #include <stdlib.h>
19 #endif
20 #ifdef HAVE_MEMORY_H
21 #include <memory.h>
22 #endif /* HAVE_MEMORY_H */
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #else /* HAVE_STRING_H */
26 #ifdef HAVE_STRINGS_H
27 #include <strings.h>
28 #endif /* HAVE_STRINGS_H */
29 #endif /* HAVE_STRING_H */
30
31 #include <afs/stds.h>
32 #include <krb5.h>
33
34 #include <afs/com_err.h>
35 #include <afs/cellconfig.h>
36 #include <afs/keys.h>
37 #include <afs/dirpath.h>
38
39 #ifdef HAVE_KRB5_CREDS_KEYBLOCK
40 #define USING_MIT 1
41 #endif
42 #ifdef HAVE_KRB5_CREDS_SESSION
43 #define USING_HEIMDAL 1
44 #endif
45
46 int
47 main(int argc, char *argv[])
48 {
49     struct afsconf_dir *tdir;
50     register long code;
51     const char *confdir;
52
53     if (argc == 1) {
54         fprintf(stderr, "%s: usage is '%s <opcode> options, e.g.\n",
55                 argv[0], argv[0]);
56         fprintf(stderr, "\t%s add <kvno> <keyfile> <princ>\n", argv[0]);
57         fprintf(stderr, "\t%s delete <kvno>\n", argv[0]);
58         fprintf(stderr, "\t%s list\n", argv[0]);
59         exit(1);
60     }
61
62     confdir = AFSDIR_SERVER_ETC_DIRPATH;
63
64     tdir = afsconf_Open(confdir);
65     if (!tdir) {
66         fprintf(stderr, "%s: can't initialize conf dir '%s'\n", argv[0],
67                 confdir);
68         exit(1);
69     }
70     if (strcmp(argv[1], "add")==0) {
71         krb5_context context;
72         krb5_principal principal;
73         krb5_keyblock *key;
74         krb5_error_code retval;
75         int kvno;
76
77         if (argc != 5) {
78             fprintf(stderr, "%s add: usage is '%s add <kvno> <keyfile> "
79                     "<princ>\n", argv[0], argv[0]);
80             exit(1);
81         }
82
83         krb5_init_context(&context);
84
85         kvno = atoi(argv[2]);
86         retval = krb5_parse_name(context, argv[4], &principal);
87         if (retval != 0) {
88                 com_err(argv[0], retval, "while parsing AFS principal");
89                 exit(1);
90         }
91         retval = krb5_kt_read_service_key(context, argv[3], principal, kvno,
92                                           ENCTYPE_DES_CBC_CRC, &key);
93         if (retval != 0) {
94                 com_err(argv[0], retval, "while extracting AFS service key");
95                 exit(1);
96         }
97
98 #ifdef USING_HEIMDAL
99 #define deref_key_length(key) \
100           key->keyvalue.length
101
102 #define deref_key_contents(key) \
103         key->keyvalue.data
104 #else
105 #define deref_key_length(key) \
106           key->length
107
108 #define deref_key_contents(key) \
109         key->contents
110 #endif
111         if (deref_key_length(key) != 8) {
112                 fprintf(stderr, "Key length should be 8, but is really %d!\n",
113                         deref_key_length(key));
114                 exit(1);
115         }
116
117         code = afsconf_AddKey(tdir, kvno, (char *) deref_key_contents(key), 1);
118         if (code) {
119             fprintf(stderr, "%s: failed to set key, code %d.\n", argv[0], code);
120             exit(1);
121         }
122         krb5_free_principal(context, principal);
123         krb5_free_keyblock(context, key);
124     }
125     else if (strcmp(argv[1], "delete")==0) {
126         long kvno;
127         if (argc != 3) {
128             fprintf(stderr, "%s delete: usage is '%s delete <kvno>\n",
129                     argv[0], argv[0]);
130             exit(1);
131         }
132         kvno = atoi(argv[2]);
133         code = afsconf_DeleteKey(tdir, kvno);
134         if (code) {
135             fprintf(stderr, "%s: failed to delete key %d, (code %d)\n",
136                     argv[0], kvno, code);
137             exit(1);
138         }
139     }
140     else if (strcmp(argv[1], "list") == 0) {
141         struct afsconf_keys tkeys;
142         register int i, j;
143         
144         code = afsconf_GetKeys(tdir, &tkeys);
145         if (code) {
146             fprintf(stderr, "%s: failed to get keys, code %d\n", argv[0], code);
147             exit(1);
148         }
149         for(i=0;i<tkeys.nkeys;i++) {
150             if (tkeys.key[i].kvno != -1) {
151                 printf("kvno %4d: key is: ", tkeys.key[i].kvno);
152                 for (j = 0; j < 8; j++)
153                         printf("%02x", (unsigned char) tkeys.key[i].key[j]);
154                 printf("\n");
155             }
156         }
157         printf("All done.\n");
158     }
159     else {
160         fprintf(stderr, "%s: unknown operation '%s', type '%s' for "
161                 "assistance\n", argv[0], argv[1], argv[0]);
162         exit(1);
163     }
164     exit(0);
165 }