📄 kerberos.c
字号:
/* $OpenBSD: kerberos.c,v 1.2 2003/06/02 19:38:25 millert Exp $ *//*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * This source code is no longer held under any constraint of USA * `cryptographic laws' since it was exported legally. The cryptographic * functions were removed from the code and a "Bones" distribution was * made. A Commodity Jurisdiction Request #012-94 was filed with the * USA State Department, who handed it to the Commerce department. The * code was determined to fall under General License GTDA under ECCN 5D96G, * and hence exportable. The cryptographic interfaces were re-added by Eric * Young, and then KTH proceeded to maintain the code in the free world. * *//* * Copyright (C) 1990 by the Massachusetts Institute of Technology * * Export of this software from the United States of America is assumed * to require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. *//* $KTH: kerberos.c,v 1.50 2000/11/23 02:28:06 joda Exp $" */#ifdef KRB4#include <sys/types.h>#include <sys/socket.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <netinet/in.h>#include <resolv.h>#include <arpa/telnet.h>#include <des.h>#include <kerberosIV/krb.h>#include <pwd.h>#include <syslog.h>#include <err.h>#include "encrypt.h"#include "auth.h"#include "misc.h"int kerberos4_cksum (unsigned char *, int);extern int auth_debug_mode;static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0, AUTHTYPE_KERBEROS_V4, };#define KRB_AUTH 0 /* Authentication data follows */#define KRB_REJECT 1 /* Rejected (reason might follow) */#define KRB_ACCEPT 2 /* Accepted */#define KRB_CHALLENGE 3 /* Challenge for mutual auth. */#define KRB_RESPONSE 4 /* Response for mutual auth. */#define KRB_FORWARD 5 /* */#define KRB_FORWARD_ACCEPT 6 /* */#define KRB_FORWARD_REJECT 7 /* */#define KRB_SERVICE_NAME "rcmd"static KTEXT_ST auth;static char name[ANAME_SZ];static AUTH_DAT adat;static des_cblock session_key;static des_cblock cred_session;static des_key_schedule sched;static des_cblock challenge;static int auth_done; /* XXX */static int pack_cred(CREDENTIALS *cred, unsigned char *buf);static int unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred);intcheck_krb4_tickets() { int ret; int retval = 0; char *file; krb_principal princ; file = getenv("KRBTKFILE"); if(file == NULL) file = TKT_FILE; ret = krb_get_tf_realm(file, princ.realm); switch(ret) { case NO_TKT_FIL: retval = 0; goto done; case 0: retval = 1; goto done; default: errx(1, "krb_get_tf_realm: %d", ret); } done: return retval;}static intData(Authenticator *ap, int type, const void *d, int c){ unsigned char *p = str_data + 4; const unsigned char *cd = (const unsigned char *)d; if (c == -1) c = strlen((const char *)cd); if (auth_debug_mode) { printf("%s:%d: [%d] (%d)", str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", str_data[3], type, c); printd(d, c); printf("\r\n"); } *p++ = ap->type; *p++ = ap->way; *p++ = type; while (c-- > 0) { if ((*p++ = *cd++) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; if (str_data[3] == TELQUAL_IS) printsub('>', &str_data[2], p - (&str_data[2])); return(telnet_net_write(str_data, p - str_data));}intkerberos4_init(Authenticator *ap, int server){ FILE *fp; if (server) { str_data[3] = TELQUAL_REPLY; if ((fp = fopen(KEYFILE, "r")) == NULL) return(0); fclose(fp); } else { str_data[3] = TELQUAL_IS; } return(1);}char dst_realm_buf[REALM_SZ], *dest_realm = NULL;int dst_realm_sz = REALM_SZ;static intkerberos4_send(char *name, Authenticator *ap){ KTEXT_ST auth; char instance[INST_SZ]; char *realm; CREDENTIALS cred; int r; if(check_krb4_tickets() != 1) return 0; if (!UserNameRequested) { if (auth_debug_mode) { printf("Kerberos V4: no user name supplied\r\n"); } return(0); } memset(instance, 0, sizeof(instance)); strlcpy (instance, krb_get_phost(RemoteHostName), INST_SZ); realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName); if (!realm) { printf("Kerberos V4: no realm for %s\r\n", RemoteHostName); return(0); } printf("[ Trying %s (%s.%s@%s) ... ]\r\n", name, KRB_SERVICE_NAME, instance, realm); r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L); if (r) { printf("mk_req failed: %s\r\n", krb_get_err_text(r)); return(0); } r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); if (r) { printf("get_cred failed: %s\r\n", krb_get_err_text(r)); return(0); } if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { if (auth_debug_mode) printf("Not enough room for user name\r\n"); return(0); } if (auth_debug_mode) printf("Sent %d bytes of authentication data\r\n", auth.length); if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) { if (auth_debug_mode) printf("Not enough room for authentication data\r\n"); return(0); }#ifdef ENCRYPTION /* create challenge */ if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) { int i; des_key_sched(&cred.session, sched); memcpy (&cred_session, &cred.session, sizeof(cred_session)); des_init_random_number_generator(&cred.session); des_new_random_key(&session_key); des_ecb_encrypt(&session_key, &session_key, sched, 0); des_ecb_encrypt(&session_key, &challenge, sched, 0); /* old code Some CERT Advisory thinks this is a bad thing... des_init_random_number_generator(&cred.session); des_new_random_key(&challenge); des_ecb_encrypt(&challenge, &session_key, sched, 1); */ /* * Increment the challenge by 1, and encrypt it for * later comparison. */ for (i = 7; i >= 0; --i) if(++challenge[i] != 0) /* No carry! */ break; des_ecb_encrypt(&challenge, &challenge, sched, 1); }#endif if (auth_debug_mode) { printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); printf("Sent Kerberos V4 credentials to server\r\n"); } return(1);}intkerberos4_send_mutual(Authenticator *ap){ return kerberos4_send("mutual KERBEROS4", ap);}intkerberos4_send_oneway(Authenticator *ap){ return kerberos4_send("KERBEROS4", ap);}voidkerberos4_is(Authenticator *ap, unsigned char *data, int cnt){ struct sockaddr_in addr; char realm[REALM_SZ]; char instance[INST_SZ]; int r; socklen_t addr_len; if (cnt-- < 1) return; switch (*data++) { case KRB_AUTH: if (krb_get_lrealm(realm, 1) != KSUCCESS) { Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1); auth_finished(ap, AUTH_REJECT); if (auth_debug_mode) printf("No local realm\r\n"); return; } memmove(auth.dat, data, auth.length = cnt); if (auth_debug_mode) { printf("Got %d bytes of authentication data\r\n", cnt); printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); } k_getsockinst(0, instance, sizeof(instance)); addr_len = sizeof(addr); if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) { if(auth_debug_mode) printf("getpeername failed\r\n"); Data(ap, KRB_REJECT, "getpeername failed", -1); auth_finished(ap, AUTH_REJECT); return; } if (addr.sin_family != AF_INET) { if (auth_debug_mode) printf("unknown address family: %d\r\n", addr.sin_family); Data(ap, KRB_REJECT, "bad address family", -1); auth_finished(ap, AUTH_REJECT); return; } r = krb_rd_req(&auth, KRB_SERVICE_NAME, instance, addr.sin_addr.s_addr, &adat, ""); if (r) { if (auth_debug_mode) printf("Kerberos failed him as %s\r\n", name); Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1); auth_finished(ap, AUTH_REJECT); return; } /* save the session key */ memmove(session_key, adat.session, sizeof(adat.session)); krb_kntoln(&adat, name); if (UserNameRequested && !kuserok(&adat, UserNameRequested)){ char ts[MAXPATHLEN]; struct passwd *pw = getpwnam(UserNameRequested); if(pw){ snprintf(ts, sizeof(ts), "%s%u", TKT_ROOT, (unsigned)pw->pw_uid); esetenv("KRBTKFILE", ts, 1); if (pw->pw_uid == 0) syslog(LOG_INFO|LOG_AUTH, "ROOT Kerberos login from %s on %s", krb_unparse_name_long(adat.pname, adat.pinst, adat.prealm), RemoteHostName); } Data(ap, KRB_ACCEPT, NULL, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -