⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kerberos5.c

📁 inetutils的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2002 Free Software Foundation, Inc.   This file is part of GNU Inetutils.   GNU Inetutils is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   GNU Inetutils is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with GNU Inetutils; see the file COPYING.  If not, write to   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef KRB5#include <stdlib.h>#include <stdio.h>#include <arpa/telnet.h>#include <krb5.h>#include <assert.h>#include <com_err.h>#include <netdb.h>#include <ctype.h>#include <syslog.h>#ifdef  HAVE_STRING_H# include <string.h>#else# include <strings.h>#endif#include "auth.h"#include "misc.h"#ifndef KRB5_ENV_CCNAME# define KRB5_ENV_CCNAME "KRB5CCNAME"#endif#ifdef  ENCRYPTION#include "encrypt.h"#endif#ifdef  FORWARD/* FIXME: This is set directly from telnet/main.c */int forward_flags = 0;  extern int net; /*FIXME*/void kerberos5_forward ();#endif  /* FORWARD */static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0,					AUTHTYPE_KERBEROS_V5, };#define KRB_AUTH             0       /* Authentication data follows */#define KRB_REJECT           1       /* Rejected (reason might follow) */#define KRB_ACCEPT           2       /* Accepted */#define KRB_RESPONSE         3       /* Response for mutual auth. */#define KRB_FORWARD          4       /* Forwarded credentials follow */#define KRB_FORWARD_ACCEPT   5       /* Forwarded credentials accepted */#define KRB_FORWARD_REJECT   6       /* Forwarded credentials rejected */krb5_auth_context auth_context = 0;krb5_context telnet_context = 0;static  krb5_data auth; /* session key for telnet */static  krb5_ticket *ticket = NULL; /* telnet matches the AP_REQ and				       AP_REP with this */krb5_keyblock   *session_key = 0;char *telnet_srvtab = NULL;char *telnet_krb5_realm = NULL;#define DEBUG(c) if (auth_debug_mode) printf cstatic intData (TN_Authenticator *ap, int type, krb5_pointer d, int c){  unsigned char *p = str_data + 4;  unsigned char *cd = (unsigned char *) d;  if (c == -1)    c = strlen (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 (net_write (str_data, p - str_data));}/* FIXME: Reverse return code! */intkerberos5_init (TN_Authenticator *ap, int server){  str_data[3] = server ? TELQUAL_REPLY : TELQUAL_IS;  if (telnet_context == 0 && krb5_init_context(&telnet_context))    return 0;  return 1;}voidkerberos5_cleanup (){  krb5_ccache ccache;  char *ccname;  if (telnet_context == 0)    return;  ccname = getenv (KRB5_ENV_CCNAME);  if (ccname)    {      if (!krb5_cc_resolve (telnet_context, ccname, &ccache))	krb5_cc_destroy (telnet_context, ccache);  }  krb5_free_context (telnet_context);  telnet_context = 0;}#ifdef  ENCRYPTIONvoidencryption_init (krb5_creds *creds){  krb5_keyblock *newkey = 0;    krb5_auth_con_getlocalsubkey (telnet_context, auth_context, &newkey);  if (session_key)    {      krb5_free_keyblock (telnet_context, session_key);      session_key = 0;    }  if (newkey)    {      switch (newkey->enctype)	{	case ENCTYPE_DES_CBC_CRC:	case ENCTYPE_DES_CBC_MD5:	  krb5_copy_keyblock (telnet_context, newkey, &session_key);	  break;	default:	  switch (creds->keyblock.enctype)	    {	    case ENCTYPE_DES_CBC_CRC:	    case ENCTYPE_DES_CBC_MD5:	      krb5_copy_keyblock (telnet_context, &creds->keyblock,				  &session_key);	      break;	    default:	      DEBUG(("can't determine which keyblock to use"));	      /*FIXME: abort?*/	    }	}      krb5_free_keyblock(telnet_context, newkey);    }}#else# define encryption_init(c)#endifintkerberos5_send (TN_Authenticator *ap){  krb5_error_code r;  krb5_ccache ccache;  krb5_creds creds;   krb5_creds *new_creds = 0;  int ap_opts;  char type_check[2];  krb5_data check_data;  if (!UserNameRequested)    {      DEBUG(("telnet: Kerberos V5: no user name supplied\r\n"));      return 0;    }  if ((r = krb5_cc_default (telnet_context, &ccache)))    {      DEBUG(("telnet: Kerberos V5: could not get default ccache\r\n"));      return 0;    }  memset (&creds, 0, sizeof (creds));  if ((r = krb5_sname_to_principal (telnet_context, RemoteHostName,				    "host", KRB5_NT_SRV_HST,				    &creds.server)))    {      DEBUG(("telnet: Kerberos V5: error while constructing service name: %s\r\n",	     error_message(r)));      return 0;    }  if (telnet_krb5_realm)    {      krb5_data rdata;      rdata.length = strlen (telnet_krb5_realm);      rdata.data = malloc (rdata.length + 1);      assert (rdata.data);      strcpy (rdata.data, telnet_krb5_realm);      krb5_princ_set_realm (telnet_context, creds.server, &rdata);    }  if ((r = krb5_cc_get_principal (telnet_context, ccache,				  &creds.client)))    {      DEBUG(("telnet: Kerberos V5: failure on principal (%s)\r\n",	     error_message(r)));      krb5_free_cred_contents (telnet_context, &creds);      return 0;    }  creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;  if ((r = krb5_get_credentials (telnet_context, 0,				 ccache, &creds, &new_creds)))    {      DEBUG(("telnet: Kerberos V5: failure on credentials(%s)\r\n",	     error_message(r)));      krb5_free_cred_contents (telnet_context, &creds);      return 0;    }  if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)    ap_opts = AP_OPTS_MUTUAL_REQUIRED;  else    ap_opts = 0;#ifdef ENCRYPTION  ap_opts |= AP_OPTS_USE_SUBKEY;#endif   if (auth_context)    {      krb5_auth_con_free (telnet_context, auth_context);      auth_context = 0;    }    if ((r = krb5_auth_con_init (telnet_context, &auth_context)))    {      DEBUG(("Kerberos V5: failed to init auth_context (%s)\r\n",	     error_message(r)));      return 0;    }  krb5_auth_con_setflags (telnet_context, auth_context,			  KRB5_AUTH_CONTEXT_RET_TIME);  type_check[0] = ap->type;  type_check[1] = ap->way;  check_data.magic = KV5M_DATA;  check_data.length = 2;  check_data.data = (char *) &type_check;  r = krb5_mk_req_extended (telnet_context, &auth_context, ap_opts,			    &check_data, new_creds, &auth);  encryption_init (new_creds);    krb5_free_cred_contents (telnet_context, &creds);  krb5_free_creds (telnet_context, new_creds);  if (r)    {      DEBUG(("telnet: Kerberos V5: mk_req failed (%s)\r\n",	     error_message(r)));      return 0;    }  if (!auth_sendname (UserNameRequested, strlen (UserNameRequested)))    {      DEBUG(("telnet: Not enough room for user name\r\n"));      return 0;    }  if (!Data (ap, KRB_AUTH, auth.data, auth.length))    {      DEBUG(("telnet: Not enough room for authentication data\r\n"));      return 0;    }  DEBUG(("telnet: Sent Kerberos V5 credentials to server\r\n"));  return 1;}#ifdef ENCRYPTIONvoidtelnet_encrypt_key (Session_Key *skey){  if (session_key)    {      skey->type = SK_DES;      skey->length = 8;      skey->data = session_key->contents;      encrypt_session_key (skey, 0);    }}#else# define telnet_encrypt_key(s)#endifvoidkerberos5_reply (TN_Authenticator *ap, unsigned char *data, int cnt){#ifdef ENCRYPTION  Session_Key skey;#endif  static int mutual_complete = 0;  if (cnt-- < 1)    return;    switch (*data++)    {    case KRB_REJECT:      if (cnt > 0) 	printf ("[ Kerberos V5 refuses authentication because %.*s ]\r\n",	       cnt, data);      else	printf ("[ Kerberos V5 refuses authentication ]\r\n");      auth_send_retry();      return;    case KRB_ACCEPT:      if (!mutual_complete)	{	  if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)	    {	      printf ("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n");	      auth_send_retry ();	      break;	    }	  telnet_encrypt_key (&skey);	}      if (cnt)	printf ("[ Kerberos V5 accepts you as ``%.*s''%s ]\r\n", cnt, data,		mutual_complete ?		" (server authenticated)" : 		" (server NOT authenticated)");      else	printf ("[ Kerberos V5 accepts you ]\r\n");      auth_finished(ap, AUTH_USER);#ifdef  FORWARD      if (forward_flags & OPTS_FORWARD_CREDS)	kerberos5_forward (ap);#endif       break;    case KRB_RESPONSE:      if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)	{	  krb5_ap_rep_enc_part *reply;	  krb5_data inbuf;	  krb5_error_code r;	  inbuf.length = cnt;	  inbuf.data = (char *)data;	  if ((r = krb5_rd_rep (telnet_context, auth_context, &inbuf,				&reply)))	    {	      printf ("[ Mutual authentication failed: %s ]\r\n",		      error_message (r));	      auth_send_retry ();	      break;	    }	  	  krb5_free_ap_rep_enc_part (telnet_context, reply);	  telnet_encrypt_key (&skey);	  mutual_complete = 1;	}      break;#ifdef  FORWARD    case KRB_FORWARD_ACCEPT:      printf ("[ Kerberos V5 accepted forwarded credentials ]\r\n");      break;          case KRB_FORWARD_REJECT:      printf ("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n",	      cnt, data);      break;#endif  /* FORWARD */    default:      DEBUG(("Unknown Kerberos option %d\r\n", data[-1]));    }}intkerberos5_status (TN_Authenticator *ap, char *name, int level){  if (level < AUTH_USER)    return level;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -