1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1990, 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 06/01/93";
16 #endif /* not lint */
17
18 #include <sys/types.h>
19 #include <sys/time.h>
20 #include <sys/signal.h>
21 #include <sys/resource.h>
22 #include <sys/param.h>
23 #include <sys/file.h>
24 #include <netinet/in.h>
25 #include <syslog.h>
26 #include <kerberosIV/des.h>
27 #include <kerberosIV/krb.h>
28 #include <kerberosIV/krb_db.h>
29 #include <stdio.h>
30 #include "register_proto.h"
31 #include "pathnames.h"
32
33 #define KBUFSIZ (sizeof(struct keyfile_data))
34 #define RCRYPT 0x00
35 #define CLEAR 0x01
36
37 char *progname, msgbuf[BUFSIZ];
38
main(argc,argv)39 main(argc, argv)
40 int argc;
41 char **argv;
42 {
43 static Key_schedule schedule;
44 static struct rlimit rl = { 0, 0 };
45 struct keyfile_data *kfile;
46 u_char code;
47 int kf, retval, sval;
48 struct sockaddr_in sin;
49 char keyfile[MAXPATHLEN], keybuf[KBUFSIZ];
50 void die();
51
52 progname = argv[0]; /* for the library routines */
53
54 openlog("registerd", LOG_PID, LOG_AUTH);
55
56 (void)signal(SIGHUP, SIG_IGN);
57 (void)signal(SIGINT, SIG_IGN);
58 (void)signal(SIGTSTP, SIG_IGN);
59 (void)signal(SIGPIPE, die);
60
61 if (setrlimit(RLIMIT_CORE, &rl) < 0) {
62 syslog(LOG_ERR, "setrlimit: %m");
63 exit(1);
64 }
65
66
67 /* figure out who we are talking to */
68
69 sval = sizeof(sin);
70 if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
71 syslog(LOG_ERR, "getpeername: %m");
72 exit(1);
73 }
74
75 /* get encryption key */
76
77 (void) sprintf(keyfile, "%s%s%s",
78 SERVER_KEYDIR,
79 CLIENT_KEYFILE,
80 inet_ntoa(sin.sin_addr));
81
82 if ((kf = open(keyfile, O_RDONLY)) < 0) {
83 syslog(LOG_ERR,
84 "error opening Kerberos update keyfile (%s): %m", keyfile);
85 (void) sprintf(msgbuf,
86 "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(&sin);
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)",
120 code);
121 }
122
123 } else {
124 retval = KFAILURE;
125 syslog(LOG_ERR,
126 "couldn't read command code on Kerberos update");
127 }
128
129 code = (u_char) retval;
130 if (code != KSUCCESS) {
131 (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
132 send_packet(msgbuf, RCRYPT);
133 } else {
134 (void) sprintf(msgbuf, "Update complete.");
135 send_packet(msgbuf, RCRYPT);
136 }
137 cleanup();
138 close(0);
139 exit(0);
140 }
141
142 #define MAX_PRINCIPAL 10
143 static Principal principal_data[MAX_PRINCIPAL];
144 static C_Block key, master_key;
145 static Key_schedule master_key_schedule;
146 int
do_append(sinp)147 do_append(sinp)
148 struct sockaddr_in *sinp;
149 {
150 Principal default_princ;
151 char input_name[ANAME_SZ];
152 char input_instance[INST_SZ];
153 int j,n, more;
154 long mkeyversion;
155
156
157
158 /* get master key from MKEYFILE */
159 if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
160 syslog(LOG_ERR, "couldn't get master key");
161 return(KFAILURE);
162 }
163
164 mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
165 if (mkeyversion < 0) {
166 syslog(LOG_ERR, "couldn't validate master key");
167 return(KFAILURE);
168 }
169
170 n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
171 &default_princ, 1, &more);
172
173 if (n != 1) {
174 syslog(LOG_ERR, "couldn't get default principal");
175 return(KFAILURE);
176 }
177
178 /*
179 * get principal name, instance, and password from network.
180 * convert password to key and store it
181 */
182
183 if (net_get_principal(input_name, input_instance, key) != 0) {
184 return(KFAILURE);
185 }
186
187
188 j = kerb_get_principal(
189 input_name,
190 input_instance,
191 principal_data,
192 MAX_PRINCIPAL,
193 &more
194 );
195
196 if (j != 0) {
197 /* already in database, no update */
198 syslog(LOG_NOTICE,
199 "attempt to add duplicate entry for principal %s.%s",
200 input_name, input_instance);
201 return(KDC_PR_N_UNIQUE);
202 }
203
204 /*
205 * set up principal's name, instance
206 */
207
208 strcpy(principal_data[0].name, input_name);
209 strcpy(principal_data[0].instance, input_instance);
210 principal_data[0].old = NULL;
211
212
213 /* and the expiration date and version #s */
214
215 principal_data[0].exp_date = default_princ.exp_date;
216 strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
217 principal_data[0].max_life = default_princ.max_life;
218 principal_data[0].attributes = default_princ.attributes;
219 principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
220
221
222 /* and the key */
223
224 kdb_encrypt_key(key, key, master_key, master_key_schedule,
225 ENCRYPT);
226 bcopy(key, &principal_data[0].key_low, 4);
227 bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
228 bzero(key, sizeof(key));
229
230 principal_data[0].key_version = 1; /* 1st entry */
231
232 /* and write it to the database */
233
234 if (kerb_put_principal(&principal_data[0], 1)) {
235 syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
236 return(KFAILURE);
237 }
238
239 syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
240 principal_data[0].name,
241 principal_data[0].instance,
242 inet_ntoa(sinp->sin_addr)
243 );
244
245 return(KSUCCESS);
246
247 }
248
send_packet(msg,flag)249 send_packet(msg,flag)
250 char *msg;
251 int flag;
252 {
253 int len = strlen(msg);
254 msg[len++] = '\n';
255 msg[len] = '\0';
256 if (len > sizeof(msgbuf)) {
257 syslog(LOG_ERR, "send_packet: invalid msg size");
258 return;
259 }
260 if (flag == RCRYPT) {
261 if (des_write(0, msg, len) != len)
262 syslog(LOG_ERR, "couldn't write reply message");
263 } else if (flag == CLEAR) {
264 if (write(0, msg, len) != len)
265 syslog(LOG_ERR, "couldn't write reply message");
266 } else
267 syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
268
269 }
270
net_get_principal(pname,iname,keyp)271 net_get_principal(pname, iname, keyp)
272 char *pname, *iname;
273 C_Block *keyp;
274 {
275 int cc;
276 static char password[255];
277
278 cc = des_read(0, pname, ANAME_SZ);
279 if (cc != ANAME_SZ) {
280 syslog(LOG_ERR, "couldn't get principal name");
281 return(-1);
282 }
283
284 cc = des_read(0, iname, INST_SZ);
285 if (cc != INST_SZ) {
286 syslog(LOG_ERR, "couldn't get instance name");
287 return(-1);
288 }
289
290 cc = des_read(0, password, 255);
291 if (cc != 255) {
292 syslog(LOG_ERR, "couldn't get password");
293 bzero(password, 255);
294 return(-1);
295 }
296
297 string_to_key(password, *keyp);
298 bzero(password, 255);
299 return(0);
300 }
301
cleanup()302 cleanup()
303 {
304 bzero(master_key, sizeof(master_key));
305 bzero(key, sizeof(key));
306 bzero(master_key_schedule, sizeof(master_key_schedule));
307 }
308
309 void
die()310 die()
311 {
312 syslog(LOG_ERR, "remote end died (SIGPIPE)");
313 cleanup();
314 exit(1);
315 }
316