]>
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 | |
de56407f | 17 | #include <krb.h> |
7ac48069 | 18 | |
19 | RCSID("$Header$"); | |
de56407f | 20 | |
1c6164bb | 21 | static char service[] = "rcmd"; |
22 | static char master[] = "sms"; | |
de56407f | 23 | static char qmark[] = "???"; |
85330553 | 24 | extern des_cblock session; |
de56407f | 25 | |
26 | /* | |
5df6ee25 | 27 | * authentication request auth_002: |
de56407f | 28 | * |
5df6ee25 | 29 | * >>> (STRING) "auth_002" |
de56407f | 30 | * <<< (int) 0 |
31 | * >>> (STRING) ticket | |
32 | * <<< (int) code | |
5df6ee25 | 33 | * <<< (STRING) nonce |
34 | * >>> (STRING) encrypted nonce | |
35 | * <<< (int) code | |
de56407f | 36 | * |
37 | */ | |
38 | ||
85330553 | 39 | void auth_002(int conn, char *str) |
de56407f | 40 | { |
5eaef520 | 41 | char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ]; |
42 | AUTH_DAT ad; | |
85330553 | 43 | char *p, *first, *data; |
44 | size_t size; | |
5eaef520 | 45 | KTEXT_ST ticket_st; |
5eaef520 | 46 | des_key_schedule sched; |
85330553 | 47 | des_cblock nonce, nonce2; |
48 | long code; | |
de56407f | 49 | |
85330553 | 50 | send_ok(conn); |
51 | ||
52 | recv_string(conn, &data, &size); | |
53 | if (size > sizeof(ticket_st.dat)) | |
5eaef520 | 54 | { |
85330553 | 55 | code = KE_RD_AP_UNDEC; |
56 | com_err(whoami, code, ": authenticator too large"); | |
57 | send_int(conn, code); | |
58 | return; | |
de56407f | 59 | } |
85330553 | 60 | memcpy(ticket_st.dat, data, size); |
61 | free(data); | |
5eaef520 | 62 | ticket_st.mbz = 0; |
85330553 | 63 | ticket_st.length = size; |
64 | code = krb_rd_req(&ticket_st, service, krb_get_phost(hostname), 0, | |
5eaef520 | 65 | &ad, KEYFILE); |
66 | if (code) | |
67 | { | |
68 | code += ERROR_TABLE_BASE_krb; | |
69 | strcpy(ad.pname, qmark); | |
70 | strcpy(ad.pinst, qmark); | |
71 | strcpy(ad.prealm, qmark); | |
72 | goto auth_failed; | |
de56407f | 73 | } |
c47daf21 | 74 | |
5eaef520 | 75 | /* If there is an auth record in the config file matching the |
76 | * authenticator we received, then accept it. If there's no | |
77 | * auth record, assume [master]@[local realm]. | |
78 | */ | |
7ac48069 | 79 | if ((first = p = config_lookup("auth"))) |
5eaef520 | 80 | { |
81 | do | |
82 | { | |
83 | kname_parse(aname, ainst, arealm, p); | |
84 | if (strcmp(aname, ad.pname) || | |
85 | strcmp(ainst, ad.pinst) || | |
86 | strcmp(arealm, ad.prealm)) | |
87 | p = config_lookup("auth"); | |
88 | else | |
89 | p = first; | |
90 | } | |
91 | while (p != first); | |
c47daf21 | 92 | } |
5eaef520 | 93 | else |
94 | { | |
95 | strcpy(aname, master); | |
96 | strcpy(ainst, ""); | |
97 | if (krb_get_lrealm(arealm, 1)) | |
98 | strcpy(arealm, KRB_REALM); | |
99 | } | |
100 | code = EPERM; | |
101 | if (strcmp(aname, ad.pname) || | |
102 | strcmp(ainst, ad.pinst) || | |
103 | strcmp(arealm, ad.prealm)) | |
104 | goto auth_failed; | |
5df6ee25 | 105 | |
85330553 | 106 | send_ok(conn); |
5df6ee25 | 107 | |
5eaef520 | 108 | /* replay protection */ |
109 | des_random_key(&nonce); | |
85330553 | 110 | send_string(conn, (char *)nonce, sizeof(nonce)); |
111 | recv_string(conn, &data, &size); | |
5eaef520 | 112 | des_key_sched(ad.session, sched); |
85330553 | 113 | des_ecb_encrypt(data, nonce2, sched, 0); |
114 | free(data); | |
5eaef520 | 115 | if (memcmp(nonce, nonce2, sizeof(nonce))) |
116 | goto auth_failed; | |
85330553 | 117 | send_ok(conn); |
5df6ee25 | 118 | |
5eaef520 | 119 | have_authorization = 1; |
120 | /* Stash away session key */ | |
121 | memcpy(session, ad.session, sizeof(session)); | |
85330553 | 122 | return; |
123 | ||
de56407f | 124 | auth_failed: |
85330553 | 125 | com_err(whoami, code, "auth for %s.%s@%s failed", |
126 | ad.pname, ad.pinst, ad.prealm); | |
127 | send_int(conn, code); | |
de56407f | 128 | } |