]>
Commit | Line | Data |
---|---|---|
de56407f | 1 | /* |
2 | * $Source$ | |
3 | * $Header$ | |
4 | */ | |
546bc43b | 5 | /* (c) Copyright 1988 by the Massachusetts Institute of Technology. */ |
6 | /* For copying and distribution information, please see the file */ | |
7 | /* <mit-copyright.h>. */ | |
de56407f | 8 | |
9 | #ifndef lint | |
5df6ee25 | 10 | static char *rcsid_auth_002_c = "$Header$"; |
7da203a3 | 11 | #endif |
de56407f | 12 | |
546bc43b | 13 | #include <mit-copyright.h> |
de56407f | 14 | #include <stdio.h> |
8fd777cf | 15 | #include <string.h> |
1e8fd4c0 | 16 | #include <gdb.h> |
de56407f | 17 | #include <krb.h> |
b29ec86e | 18 | #include <krb_et.h> |
de56407f | 19 | #include <netinet/in.h> |
20 | #include <errno.h> | |
8fd777cf | 21 | #ifdef POSIX |
22 | #include <sys/utsname.h> | |
23 | #endif | |
de56407f | 24 | |
25 | extern char buf[BUFSIZ]; | |
26 | extern int have_authorization; | |
27 | extern struct sockaddr_in *client_address(); | |
28 | extern CONNECTION conn; | |
7da203a3 | 29 | extern int code; |
de56407f | 30 | extern char *PrincipalHostname(); |
1c6164bb | 31 | static char service[] = "rcmd"; |
32 | static char master[] = "sms"; | |
de56407f | 33 | static char qmark[] = "???"; |
5df6ee25 | 34 | extern C_Block session; |
de56407f | 35 | |
36 | /* | |
5df6ee25 | 37 | * authentication request auth_002: |
de56407f | 38 | * |
5df6ee25 | 39 | * >>> (STRING) "auth_002" |
de56407f | 40 | * <<< (int) 0 |
41 | * >>> (STRING) ticket | |
42 | * <<< (int) code | |
5df6ee25 | 43 | * <<< (STRING) nonce |
44 | * >>> (STRING) encrypted nonce | |
45 | * <<< (int) code | |
de56407f | 46 | * |
47 | */ | |
48 | ||
49 | int | |
5df6ee25 | 50 | auth_002(str) |
de56407f | 51 | char *str; |
52 | { | |
53 | STRING data; | |
c47daf21 | 54 | char host[BUFSIZ], realm[REALM_SZ]; |
55 | char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ]; | |
de56407f | 56 | AUTH_DAT ad; |
c47daf21 | 57 | char *p, *first, *config_lookup(); |
de56407f | 58 | KTEXT_ST ticket_st; |
8fd777cf | 59 | #ifdef POSIX |
60 | struct utsname name; | |
61 | #endif | |
5df6ee25 | 62 | des_key_schedule sched; |
63 | C_Block nonce, nonce2; | |
de56407f | 64 | |
65 | if (send_ok()) | |
5df6ee25 | 66 | lose("sending okay for authorization (auth_002)"); |
de56407f | 67 | code = receive_object(conn, (char *)&data, STRING_T); |
68 | if (code) { | |
69 | code = connection_errno(conn); | |
70 | lose("awaiting Kerberos authenticators"); | |
71 | } | |
8fd777cf | 72 | #ifdef POSIX |
73 | (void) uname(&name); | |
74 | strncpy(host, name.nodename, sizeof(host)); | |
75 | #else | |
76 | gethostname(host, sizeof(host)); | |
77 | #endif | |
de56407f | 78 | ticket_st.mbz = 0; |
79 | ticket_st.length = MAX_STRING_SIZE(data); | |
8fd777cf | 80 | memcpy(ticket_st.dat, STRING_DATA(data), MAX_STRING_SIZE(data)); |
1e8fd4c0 | 81 | code = krb_rd_req(&ticket_st, service, |
c47daf21 | 82 | krb_get_phost(host), 0, |
83 | &ad, KEYFILE); | |
de56407f | 84 | if (code) { |
b29ec86e | 85 | code += ERROR_TABLE_BASE_krb; |
de56407f | 86 | strcpy(ad.pname, qmark); |
87 | strcpy(ad.pinst, qmark); | |
88 | strcpy(ad.prealm, qmark); | |
89 | goto auth_failed; | |
90 | } | |
c47daf21 | 91 | |
92 | /* If there is an auth record in the config file matching the | |
93 | * authenticator we received, then accept it. If there's no | |
94 | * auth record, assume [master]@[local realm]. | |
95 | */ | |
96 | if (first = p = config_lookup("auth")) { | |
97 | do { | |
98 | kname_parse(aname, ainst, arealm, p); | |
99 | if (strcmp(aname, ad.pname) || | |
100 | strcmp(ainst, ad.pinst) || | |
101 | strcmp(arealm, ad.prealm)) | |
102 | p = config_lookup("auth"); | |
103 | else | |
104 | p = first; | |
105 | } while (p != first); | |
106 | } else { | |
107 | strcpy(aname, master); | |
108 | strcpy(ainst, ""); | |
109 | if (krb_get_lrealm(arealm,1)) | |
110 | strcpy(arealm, KRB_REALM); | |
111 | } | |
de56407f | 112 | code = EPERM; |
c47daf21 | 113 | if (strcmp(aname, ad.pname) || |
114 | strcmp(ainst, ad.pinst) || | |
115 | strcmp(arealm, ad.prealm)) | |
116 | goto auth_failed; | |
5df6ee25 | 117 | |
118 | if (send_ok()) | |
119 | lose("sending preliminary approval of authorization"); | |
120 | ||
121 | /* replay protection */ | |
122 | des_random_key(&nonce); | |
123 | STRING_DATA(data) = (char *)nonce; | |
124 | MAX_STRING_SIZE(data) = 8; | |
125 | if (send_object(conn, (char *)&data, STRING_T)) | |
126 | lose("sending nonce"); | |
127 | code = receive_object(conn, (char *)&data, STRING_T); | |
585b298c | 128 | if (code) { |
129 | code = connection_errno(conn); | |
130 | goto auth_failed; | |
131 | } | |
5df6ee25 | 132 | des_key_sched(&ad.session, &sched); |
133 | des_ecb_encrypt(STRING_DATA(data), nonce2, sched, 0); | |
134 | if (memcmp(nonce, nonce2, sizeof(nonce))) | |
135 | goto auth_failed; | |
136 | ||
de56407f | 137 | if (send_ok()) |
138 | lose("sending approval of authorization"); | |
139 | have_authorization = 1; | |
06c2568b | 140 | /* Stash away session key */ |
8fd777cf | 141 | memcpy(session, ad.session, sizeof(session)); |
de56407f | 142 | return(0); |
143 | auth_failed: | |
144 | sprintf(buf, "auth for %s.%s@%s failed: %s", | |
145 | ad.pname, ad.pinst, ad.prealm, error_message(code)); | |
146 | { | |
147 | register int rc; | |
148 | rc = send_object(conn, (char *)&code, INTEGER_T); | |
149 | code = rc; | |
150 | } | |
151 | if (code) | |
152 | lose("sending rejection of authenticator"); | |
153 | return(EPERM); | |
154 | } |