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