| 1 /* This file is part of the Project Athena Zephyr Notification System. |
|
| 2 * It contains source for the ZMakeAuthentication function. |
|
| 3 * |
|
| 4 * Created by: Robert French |
|
| 5 * |
|
| 6 * Copyright (c) 1987 by the Massachusetts Institute of Technology. |
|
| 7 * For copying and distribution information, see the file |
|
| 8 * "mit-copyright.h". |
|
| 9 */ |
|
| 10 |
|
| 11 #include "internal.h" |
|
| 12 |
|
| 13 #ifndef ERROR_TABLE_BASE_krb |
|
| 14 #define ERROR_TABLE_BASE_krb (39525376L) |
|
| 15 #endif |
|
| 16 |
|
| 17 #ifdef ZEPHYR_USES_KERBEROS |
|
| 18 #ifdef WIN32 |
|
| 19 |
|
| 20 #else |
|
| 21 #include <krb_err.h> |
|
| 22 #endif |
|
| 23 static long last_authent_time = 0L; |
|
| 24 static KTEXT_ST last_authent; |
|
| 25 #endif |
|
| 26 |
|
| 27 #if 0 |
|
| 28 Code_t ZResetAuthentication () { |
|
| 29 #ifdef ZEPHYR_USES_KERBEROS |
|
| 30 last_authent_time = 0L; |
|
| 31 #endif |
|
| 32 return ZERR_NONE; |
|
| 33 } |
|
| 34 #endif |
|
| 35 |
|
| 36 Code_t ZMakeAuthentication(notice, buffer, buffer_len, len) |
|
| 37 register ZNotice_t *notice; |
|
| 38 char *buffer; |
|
| 39 int buffer_len; |
|
| 40 int *len; |
|
| 41 { |
|
| 42 #ifdef ZEPHYR_USES_KERBEROS |
|
| 43 int result; |
|
| 44 time_t now; |
|
| 45 KTEXT_ST authent; |
|
| 46 char *cstart, *cend; |
|
| 47 ZChecksum_t checksum; |
|
| 48 CREDENTIALS cred; |
|
| 49 extern unsigned long des_quad_cksum(); |
|
| 50 |
|
| 51 now = time(0); |
|
| 52 if (last_authent_time == 0 || (now - last_authent_time > 120)) { |
|
| 53 result = krb_mk_req(&authent, SERVER_SERVICE, |
|
| 54 SERVER_INSTANCE, __Zephyr_realm, 0); |
|
| 55 if (result != MK_AP_OK) { |
|
| 56 last_authent_time = 0; |
|
| 57 return (result+ERROR_TABLE_BASE_krb); |
|
| 58 } |
|
| 59 last_authent_time = now; |
|
| 60 last_authent = authent; |
|
| 61 } |
|
| 62 else { |
|
| 63 authent = last_authent; |
|
| 64 } |
|
| 65 notice->z_auth = 1; |
|
| 66 notice->z_authent_len = authent.length; |
|
| 67 notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3); |
|
| 68 /* zero length authent is an error, so malloc(0) is not a problem */ |
|
| 69 if (!notice->z_ascii_authent) |
|
| 70 return (ENOMEM); |
|
| 71 if ((result = ZMakeAscii(notice->z_ascii_authent, |
|
| 72 authent.length*3, |
|
| 73 authent.dat, |
|
| 74 authent.length)) != ZERR_NONE) { |
|
| 75 free(notice->z_ascii_authent); |
|
| 76 return (result); |
|
| 77 } |
|
| 78 result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart, |
|
| 79 &cend); |
|
| 80 free(notice->z_ascii_authent); |
|
| 81 notice->z_authent_len = 0; |
|
| 82 if (result) |
|
| 83 return(result); |
|
| 84 |
|
| 85 /* Compute a checksum over the header and message. */ |
|
| 86 if ((result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, |
|
| 87 __Zephyr_realm, &cred)) != 0) |
|
| 88 return result; |
|
| 89 checksum = des_quad_cksum(buffer, NULL, cstart - buffer, 0, (C_Block *)cred.session); |
|
| 90 checksum ^= des_quad_cksum(cend, NULL, buffer + *len - cend, 0, |
|
| 91 (C_Block *)cred.session); |
|
| 92 checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len, |
|
| 93 0, (C_Block *)cred.session); |
|
| 94 notice->z_checksum = checksum; |
|
| 95 ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum); |
|
| 96 |
|
| 97 return (ZERR_NONE); |
|
| 98 #else |
|
| 99 notice->z_checksum = 0; |
|
| 100 notice->z_auth = 1; |
|
| 101 notice->z_authent_len = 0; |
|
| 102 notice->z_ascii_authent = ""; |
|
| 103 return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL)); |
|
| 104 #endif |
|
| 105 } |
|