1
2 /*
3 * Copyright (c) 1989 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by the University of California, Berkeley. The name of the
12 * University may not be used to endorse or promote products derived
13 * from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19 #ifndef lint
20 static char sccsid[] = "@(#)registerd.c 1.4 (Berkeley) 05/17/89";
21 #endif /* not lint */
22
23 #include <sys/types.h>
24 #include <sys/time.h>
25 #include <sys/signal.h>
26 #include <sys/resource.h>
27 #include <sys/param.h>
28 #include <sys/file.h>
29 #include <netinet/in.h>
30 #include <stdio.h>
31 #include <syslog.h>
32 #include <kerberos/krb.h>
33 #include <kerberos/krb_db.h>
34 #include "register_proto.h"
35
36 #define SKEYFILE "/kerberos/update.key%s"
37 #define KBUFSIZ (sizeof(struct keyfile_data))
38 #define CRYPT 0x00
39 #define CLEAR 0x01
40
41 char *progname;
42 struct sockaddr_in sin;
43 char msgbuf[BUFSIZ];
44
45 int die();
46
main(argc,argv)47 main(argc, argv)
48 char **argv;
49 {
50 int kf;
51 char keyfile[MAXPATHLEN];
52 static Key_schedule schedule;
53 u_char code;
54 char keybuf[KBUFSIZ];
55 int retval, sval;
56 struct keyfile_data *kfile;
57 static struct rlimit rl = { 0, 0 };
58
59 openlog("registerd", LOG_PID, LOG_AUTH);
60
61 progname = argv[0];
62
63 signal(SIGHUP, SIG_IGN);
64 signal(SIGINT, SIG_IGN);
65 signal(SIGTSTP, SIG_IGN);
66 signal(SIGPIPE, die);
67 if(setrlimit(RLIMIT_CORE, &rl) < 0) {
68 syslog(LOG_ERR, "setrlimit: %m");
69 exit(1);
70 }
71
72
73 /* figure out who we are talking to */
74
75 sval = sizeof(sin);
76 if(getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
77 syslog(LOG_ERR, "getpeername: %m");
78 exit(1);
79 }
80
81 /* get encryption key */
82
83 (void) sprintf(keyfile, SKEYFILE, inet_ntoa(sin.sin_addr));
84 if((kf = open(keyfile, O_RDONLY)) < 0) {
85 syslog(LOG_ERR, "error opening Kerberos update keyfile (%s): %m", keyfile);
86 (void) sprintf(msgbuf, "couldn't open session keyfile for your host");
87 send_packet(msgbuf, CLEAR);
88 exit(1);
89 }
90
91 if(read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
92 syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
93 (void) sprintf(msgbuf,
94 "couldn't read session key from your host's keyfile");
95 send_packet(msgbuf, CLEAR);
96 exit(1);
97 }
98 (void) sprintf(msgbuf, GOTKEY_MSG);
99 send_packet(msgbuf, CLEAR);
100 kfile = (struct keyfile_data *) keybuf;
101 key_sched(kfile->kf_key, schedule);
102 des_set_key(kfile->kf_key, schedule);
103
104 /* read the command code byte */
105
106 if(des_read(0, &code, 1) == 1) {
107
108 switch(code) {
109 case APPEND_DB:
110 retval = do_append();
111 break;
112 case ABORT:
113 cleanup();
114 close(0);
115 exit(0);
116 default:
117 retval = KFAILURE;
118 syslog(LOG_NOTICE,
119 "invalid command code on db update (0x%x)", code);
120 }
121
122 } else {
123 retval = KFAILURE;
124 syslog(LOG_ERR, "couldn't read command code on Kerberos update");
125 }
126
127 code = (u_char) retval;
128 if(code != KSUCCESS) {
129 (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
130 send_packet(msgbuf,CRYPT);
131 } else {
132 (void) sprintf(msgbuf, "Update complete.");
133 send_packet(msgbuf, CRYPT);
134 }
135 cleanup();
136 close(0);
137 exit(0);
138 }
139
140 #define MAX_PRINCIPAL 10
141 static Principal principal_data[MAX_PRINCIPAL];
142 static C_Block key, master_key;
143 static Key_schedule master_key_schedule;
144 int
do_append()145 do_append()
146 {
147 Principal default_princ;
148 char input_name[ANAME_SZ];
149 char input_instance[INST_SZ];
150 int j,n, more;
151 long mkeyversion;
152
153
154
155 /* get master key from MKEYFILE */
156 if(kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
157 syslog(LOG_ERR, "couldn't get master key");
158 return(KFAILURE);
159 }
160
161 mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
162 if(mkeyversion < 0) {
163 syslog(LOG_ERR, "couldn't validate master key");
164 return(KFAILURE);
165 }
166
167 n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
168 &default_princ, 1, &more);
169
170 if(n != 1) {
171 syslog(LOG_ERR, "couldn't get default principal");
172 return(KFAILURE);
173 }
174
175 /*
176 * get principal name, instance, and password from network.
177 * convert password to key and store it
178 */
179
180 if(net_get_principal(input_name, input_instance, key) != 0) {
181 return(KFAILURE);
182 }
183
184
185 j = kerb_get_principal(
186 input_name,
187 input_instance,
188 principal_data,
189 MAX_PRINCIPAL,
190 &more
191 );
192
193 if(j != 0) {
194 /* already in database, no update */
195 syslog(LOG_NOTICE, "attempt to add duplicate entry for principal %s.%s",
196 input_name, input_instance);
197 return(KDC_PR_N_UNIQUE);
198 }
199
200 /*
201 * set up principal's name, instance
202 */
203
204 strcpy(principal_data[0].name, input_name);
205 strcpy(principal_data[0].instance, input_instance);
206 principal_data[0].old = NULL;
207
208
209 /* and the expiration date and version #s */
210
211 principal_data[0].exp_date = default_princ.exp_date;
212 strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
213 principal_data[0].max_life = default_princ.max_life;
214 principal_data[0].attributes = default_princ.attributes;
215 principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
216
217
218 /* and the key */
219
220 kdb_encrypt_key(key, key, master_key, master_key_schedule,
221 ENCRYPT);
222 bcopy(key, &principal_data[0].key_low, 4);
223 bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
224 bzero(key, sizeof(key));
225
226 principal_data[0].key_version = 1; /* 1st entry */
227 if(kerb_put_principal(&principal_data[0], 1)) {
228 syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
229 return(KFAILURE);
230 }
231
232 syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
233 principal_data[0].name,
234 principal_data[0].instance,
235 inet_ntoa(sin.sin_addr)
236 );
237
238 return(KSUCCESS);
239
240 }
241
send_packet(msg,flag)242 send_packet(msg,flag)
243 char *msg;
244 int flag;
245 {
246 int len = strlen(msg);
247 msg[len++] = '\n';
248 msg[len] = '\0';
249 if (len > sizeof(msgbuf)) {
250 syslog(LOG_ERR, "send_packet: invalid msg size");
251 return;
252 }
253 if (flag == CRYPT) {
254 if (des_write(0, msg, len) != len)
255 syslog(LOG_ERR, "couldn't write reply message");
256 } else if (flag == CLEAR) {
257 if (write(0, msg, len) != len)
258 syslog(LOG_ERR, "couldn't write reply message");
259 } else
260 syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
261
262 }
263
net_get_principal(pname,iname,keyp)264 net_get_principal(pname, iname, keyp)
265 char *pname, *iname;
266 C_Block *keyp;
267 {
268 int cc;
269 static char password[255];
270
271 cc = des_read(0, pname, ANAME_SZ);
272 if(cc != ANAME_SZ) {
273 syslog(LOG_ERR, "couldn't get principal name");
274 return(-1);
275 }
276
277 cc = des_read(0, iname, INST_SZ);
278 if(cc != INST_SZ) {
279 syslog(LOG_ERR, "couldn't get instance name");
280 return(-1);
281 }
282
283 cc = des_read(0, password, 255);
284 if(cc != 255) {
285 syslog(LOG_ERR, "couldn't get password");
286 bzero(password, 255);
287 return(-1);
288 }
289
290 string_to_key(password, *keyp);
291 bzero(password, 255);
292 return(0);
293 }
294
cleanup()295 cleanup()
296 {
297 bzero(master_key, sizeof(master_key));
298 bzero(key, sizeof(key));
299 bzero(master_key_schedule, sizeof(master_key_schedule));
300 }
301
die()302 die()
303 {
304 syslog(LOG_ERR, "remote end died (SIGPIPE)");
305 cleanup();
306 exit(1);
307 }
308