📄 kerberos.c
字号:
/* * $Source: /usr/src/kerberosIV/kerberos/RCS/kerberos.c,v $ * $Author: torek $ * * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute * of Technology. * * For copying and distribution information, please see the file * <mit-copyright.h>. */#ifndef lintstatic char *rcsid_kerberos_c ="$Header: /usr/src/kerberosIV/kerberos/RCS/kerberos.c,v 4.22 93/05/16 00:27:07 torek Exp $";#endif lint#include <mit-copyright.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <signal.h>#include <sgtty.h>#include <sys/ioctl.h>#include <sys/time.h>#include <sys/file.h>#include <ctype.h>#include <string.h>#include <des.h>#include <krb.h>#include <klog.h>#include <prot.h>#include <krb_db.h>#include <kdc.h>extern int errno;int f;/* XXX several files in libkdb know about this */char *progname;static Key_schedule master_key_schedule;static C_Block master_key;static struct timeval kerb_time;static Principal a_name_data; /* for requesting user */static Principal s_name_data; /* for services requested */static C_Block session_key;static C_Block user_key;static C_Block service_key;static u_char master_key_version;static char k_instance[INST_SZ];static char log_text[128];static char *lt;static int more;static int mflag; /* Are we invoked manually? */static int lflag; /* Have we set an alterate log file? */static char *log_file; /* name of alt. log file */static int nflag; /* don't check max age */static int rflag; /* alternate realm specified *//* fields within the received request packet */static u_char req_msg_type;static u_char req_version;static char *req_name_ptr;static char *req_inst_ptr;static char *req_realm_ptr;static u_char req_no_req;static u_long req_time_ws;int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */static char local_realm[REALM_SZ];/* statistics */static long q_bytes; /* current bytes remaining in queue */static long q_n; /* how many consecutive non-zero * q_bytes */static long max_q_bytes;static long max_q_n;static long n_auth_req;static long n_appl_req;static long n_packets;static long n_user;static long n_server;static long max_age = -1;static long pause_int = -1;static void check_db_age();static void hang();/* * Print usage message and exit. */static void usage(){ fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname, " [-a max_age] [-l log_file] [-r realm]" ," [database_pathname]" ); exit(1);}main(argc, argv) int argc; char **argv;{ struct sockaddr_in from; register int n; int on = 1; int child; struct servent *sp; int fromlen; static KTEXT_ST pkt_st; KTEXT pkt = &pkt_st; Principal *p; int more, kerror; C_Block key; int c; struct sockaddr_in sin; extern char *optarg; extern int optind; progname = argv[0]; while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) { switch(c) { case 's': /* * Set parameters to slave server defaults. */ if (max_age == -1 && !nflag) max_age = ONE_DAY; /* 24 hours */ if (pause_int == -1) pause_int = FIVE_MINUTES; /* 5 minutes */ if (lflag == 0) { log_file = KRBSLAVELOG; lflag++; } break; case 'n': max_age = -1; /* don't check max age. */ nflag++; break; case 'm': mflag++; /* running manually; prompt for master key */ break; case 'p': /* Set pause interval. */ if (!isdigit(optarg[0])) usage(); pause_int = atoi(optarg); if ((pause_int < 5) || (pause_int > ONE_HOUR)) { fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n"); usage(); } break; case 'a': /* Set max age. */ if (!isdigit(optarg[0])) usage(); max_age = atoi(optarg); if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) { fprintf(stderr, "max_age must be between one hour and three days, in seconds\n"); usage(); } break; case 'l': /* Set alternate log file */ lflag++; log_file = optarg; break; case 'r': /* Set realm name */ rflag++; strcpy(local_realm, optarg); break; default: usage(); break; } } if (optind == (argc-1)) { if (kerb_db_set_name(argv[optind]) != 0) { fprintf(stderr, "Could not set alternate database name\n"); exit(1); } optind++; } if (optind != argc) usage(); printf("Kerberos server starting\n"); if ((!nflag) && (max_age != -1)) printf("\tMaximum database age: %d seconds\n", max_age); if (pause_int != -1) printf("\tSleep for %d seconds on error\n", pause_int); else printf("\tSleep forever on error\n"); if (mflag) printf("\tMaster key will be entered manually\n"); printf("\tLog file is %s\n", lflag ? log_file : KRBLOG); if (lflag) kset_logfile(log_file); /* find our hostname, and use it as the instance */ if (gethostname(k_instance, INST_SZ)) { fprintf(stderr, "%s: gethostname error\n", progname); exit(1); } if ((sp = getservbyname("kerberos", "udp")) == 0) { fprintf(stderr, "%s: udp/kerberos unknown service\n", progname); exit(1); } bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = sp->s_port; if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "%s: Can't open socket\n", progname); exit(1); } if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname); if (bind(f, (struct sockaddr *)&sin, S_AD_SZ) < 0) { fprintf(stderr, "%s: Can't bind socket\n", progname); exit(1); } /* do all the database and cache inits */ if (n = kerb_init()) { if (mflag) { printf("Kerberos db and cache init "); printf("failed = %d ...exiting\n", n); exit(-1); } else { klog(L_KRB_PERR, "Kerberos db and cache init failed = %d ...exiting", n); hang(); } } /* Make sure database isn't stale */ check_db_age(); /* setup master key */ if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) { klog (L_KRB_PERR, "kerberos: couldn't get master key.\n"); exit (-1); } kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout); if (kerror < 0) { klog (L_KRB_PERR, "Can't verify master key."); bzero (master_key, sizeof (master_key)); bzero (master_key_schedule, sizeof (master_key_schedule)); exit (-1); } master_key_version = (u_char) kerror; fprintf(stdout, "\nCurrent Kerberos master key version is %d\n", master_key_version); if (!rflag) { /* Look up our local realm */ krb_get_lrealm(local_realm, 1); } fprintf(stdout, "Local realm: %s\n", local_realm); fflush(stdout); if (set_tgtkey(local_realm)) { /* Ticket granting service unknown */ klog(L_KRB_PERR, "Ticket granting ticket service unknown"); fprintf(stderr, "Ticket granting ticket service unknown\n"); exit(1); } if (mflag) { if ((child = fork()) != 0) { printf("Kerberos started, PID=%d\n", child); exit(0); } setup_disc(); } /* receive loop */ for (;;) { fromlen = S_AD_SZ; n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, (struct sockaddr *)&from, &fromlen); if (n > 0) { pkt->length = n; pkt->mbz = 0; /* force zeros to catch runaway strings */ /* see what is left in the input queue */ ioctl(f, FIONREAD, &q_bytes); gettimeofday(&kerb_time, NULL); q_n++; max_q_n = max(max_q_n, q_n); n_packets++; klog(L_NET_INFO, "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d", q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0); max_q_bytes = max(max_q_bytes, q_bytes); if (!q_bytes) q_n = 0; /* reset consecutive packets */ kerberos(&from, pkt); } else klog(L_NET_ERR, "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0); }}kerberos(client, pkt) struct sockaddr_in *client; KTEXT pkt;{ static KTEXT_ST rpkt_st; KTEXT rpkt = &rpkt_st; static KTEXT_ST ciph_st; KTEXT ciph = &ciph_st; static KTEXT_ST tk_st; KTEXT tk = &tk_st; static KTEXT_ST auth_st; KTEXT auth = &auth_st; AUTH_DAT ad_st; AUTH_DAT *ad = &ad_st; static struct in_addr client_host; static int msg_byte_order; static int swap_bytes; static u_char k_flags; char *p_name, *instance; u_long lifetime; int i; C_Block key; Key_schedule key_s; char *ptr; ciph->length = 0; client_host = client->sin_addr; /* eval macros and correct the byte order and alignment as needed */ req_version = pkt_version(pkt); /* 1 byte, version */ req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */ req_act_vno = req_version; /* check packet version */ if (req_version != KRB_PROT_VERSION) { lt = klog(L_KRB_PERR, "KRB prot version mismatch: KRB =%d request = %d", KRB_PROT_VERSION, req_version, 0); /* send an error reply */ kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt); return; } msg_byte_order = req_msg_type & 1; swap_bytes = 0; if (msg_byte_order != HOST_BYTE_ORDER) { swap_bytes++; } klog(L_KRB_PINFO, "Prot version: %d, Byte order: %d, Message type: %d", req_version, msg_byte_order, req_msg_type); switch (req_msg_type & ~1) { case AUTH_MSG_KDC_REQUEST: { u_long time_ws; /* Workstation time */ u_long req_life; /* Requested liftime */ char *service; /* Service name */ char *instance; /* Service instance */ int kerno; /* Kerberos error number */ n_auth_req++; tk->length = 0; k_flags = 0; /* various kerberos flags */ /* set up and correct for byte order and alignment */ req_name_ptr = (char *) pkt_a_name(pkt); req_inst_ptr = (char *) pkt_a_inst(pkt); req_realm_ptr = (char *) pkt_a_realm(pkt); bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws)); /* time has to be diddled */ if (swap_bytes) { swap_u_long(req_time_ws); } ptr = (char *) pkt_time_ws(pkt) + 4; req_life = (u_long) (*ptr++); service = ptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -