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