1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZMakeAuthentication function.
4 * Created by: Robert French
8 * Copyright (c) 1987 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file
16 static const char rcsid_ZMakeAuthentication_c[] = "$Id$";
23 #if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA
24 #define krb5_free_data(ctx, dat) free((dat)->data)
28 ZResetAuthentication(void)
34 ZMakeAuthentication(register ZNotice_t *notice,
40 return ZMakeZcodeAuthentication(notice, buffer, buffer_len, len/*?XXX*/);
51 result = krb_mk_req(&authent, SERVER_SERVICE,
52 SERVER_INSTANCE, __Zephyr_realm, 0);
53 if (result != MK_AP_OK)
54 return (result+krb_err_base);
55 result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE,
56 __Zephyr_realm, &cred);
57 if (result != KSUCCESS)
58 return (result+krb_err_base);
60 session = (C_Block *)cred.session;
63 notice->z_authent_len = authent.length;
64 notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3);
65 /* zero length authent is an error, so malloc(0) is not a problem */
66 if (!notice->z_ascii_authent)
68 if ((result = ZMakeAscii(notice->z_ascii_authent,
71 authent.length)) != ZERR_NONE) {
72 free(notice->z_ascii_authent);
75 result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart,
77 free(notice->z_ascii_authent);
78 notice->z_authent_len = 0;
82 /* Compute a checksum over the header and message. */
83 checksum = des_quad_cksum(buffer, NULL, cstart - buffer, 0, session);
84 checksum ^= des_quad_cksum(cend, NULL, buffer + *len - cend, 0,
86 checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
88 notice->z_checksum = checksum;
89 ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum);
93 notice->z_checksum = 0;
95 notice->z_authent_len = 0;
96 notice->z_ascii_authent = "";
97 return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL));
103 ZMakeZcodeAuthentication(register ZNotice_t *notice,
108 return ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
113 ZMakeZcodeRealmAuthentication(register ZNotice_t *notice,
120 krb5_error_code result;
122 krb5_keyblock *keyblock;
123 krb5_auth_context authctx;
125 char *cksum_start, *cstart, *cend;
126 int cksum_len, zcode_len, phdr_adj;
128 result = ZGetCredsRealm(&creds, realm);
133 /* Figure out what checksum type to use */
134 keyblock = Z_credskey(creds);
137 /* Create the authenticator */
138 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
140 krb5_free_creds(Z_krb5_ctx, creds);
144 authent = (krb5_data *)malloc(sizeof(krb5_data));
146 /* HOLDING: creds, authctx */
147 result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */,
148 0 /* in_data */, creds, authent);
149 krb5_auth_con_free(Z_krb5_ctx, authctx);
151 krb5_free_creds(Z_krb5_ctx, creds);
154 /* HOLDING: creds, authent */
156 /* Encode the authenticator */
158 notice->z_authent_len = authent->length;
159 zcode_len = authent->length * 2 + 2; /* 2x growth plus Z and null */
160 notice->z_ascii_authent = (char *)malloc(zcode_len);
161 if (!notice->z_ascii_authent) {
162 krb5_free_data(Z_krb5_ctx, authent);
163 krb5_free_creds(Z_krb5_ctx, creds);
166 /* HOLDING: creds, authent, notice->z_ascii_authent */
167 result = ZMakeZcode(notice->z_ascii_authent, zcode_len,
168 (unsigned char *)authent->data, authent->length);
169 krb5_free_data(Z_krb5_ctx, authent);
171 free(notice->z_ascii_authent);
172 krb5_free_creds(Z_krb5_ctx, creds);
175 /* HOLDING: creds, notice->z_ascii_authent */
177 /* format the notice header, with a zero checksum */
178 result = Z_NewFormatRawHeader(notice, buffer, buffer_len, phdr_len,
179 &cksum_start, &cksum_len, &cstart, &cend);
180 free(notice->z_ascii_authent);
181 notice->z_authent_len = 0;
183 krb5_free_creds(Z_krb5_ctx, creds);
186 result = Z_InsertZcodeChecksum(keyblock, notice, buffer, cksum_start,
187 cksum_len, cstart, cend, buffer_len,
189 krb5_free_creds(Z_krb5_ctx, creds);
193 *phdr_len += phdr_adj;
196 #endif /* HAVE_KRB5 */
201 ZGetCreds(krb5_creds **creds_out)
203 return ZGetCredsRealm(creds_out, __Zephyr_realm);
207 ZGetCredsRealm(krb5_creds **creds_out,
211 krb5_ccache ccache; /* XXX make this a global or static?*/
214 result = krb5_cc_default(Z_krb5_ctx, &ccache);
218 memset((char *)&creds_in, 0, sizeof(creds_in));
219 result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
222 SERVER_SERVICE, SERVER_INSTANCE, 0);
224 krb5_cc_close(Z_krb5_ctx, ccache);
228 result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
230 krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */
231 krb5_cc_close(Z_krb5_ctx, ccache);
235 #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
236 creds_in.keyblock.enctype = ENCTYPE_DES_CBC_CRC; /* XXX? */
238 creds_in.session.keytype = KEYTYPE_DES; /* XXX? */
241 result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out);
242 krb5_cc_close(Z_krb5_ctx, ccache);
243 krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */