📄 kerberos.c
字号:
instance = ptr + strlen(service) + 1; rpkt = &rpkt_st; klog(L_INI_REQ, "Initial ticket request Host: %s User: \"%s\" \"%s\"", inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); if (i = check_princ(req_name_ptr, req_inst_ptr, 0, &a_name_data)) { kerb_err_reply(client, pkt, i, lt); return; } tk->length = 0; /* init */ if (strcmp(service, "krbtgt")) klog(L_NTGT_INTK, "INITIAL request from %s.%s for %s.%s", req_name_ptr, req_inst_ptr, service, instance, 0); /* this does all the checking */ if (i = check_princ(service, instance, lifetime, &s_name_data)) { kerb_err_reply(client, pkt, i, lt); return; } /* Bound requested lifetime with service and user */ lifetime = min(req_life, ((u_long) s_name_data.max_life)); lifetime = min(lifetime, ((u_long) a_name_data.max_life));#ifdef NOENCRYPTION bzero(session_key, sizeof(C_Block));#else /* random session key */ random_key(session_key);#endif /* unseal server's key from master key */ bcopy(&s_name_data.key_low, key, 4); bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); /* construct and seal the ticket */ krb_create_ticket(tk, k_flags, a_name_data.name, a_name_data.instance, local_realm, client_host.s_addr, session_key, lifetime, kerb_time.tv_sec, s_name_data.name, s_name_data.instance, key); bzero(key, sizeof(key)); bzero(key_s, sizeof(key_s)); /* * get the user's key, unseal it from the server's key, and * use it to seal the cipher */ /* a_name_data.key_low a_name_data.key_high */ bcopy(&a_name_data.key_low, key, 4); bcopy(&a_name_data.key_high, ((long *) key) + 1, 4); /* unseal the a_name key from the master key */ kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); create_ciph(ciph, session_key, s_name_data.name, s_name_data.instance, local_realm, lifetime, s_name_data.key_version, tk, kerb_time.tv_sec, key); /* clear session key */ bzero(session_key, sizeof(session_key)); bzero(key, sizeof(key)); /* always send a reply packet */ rpkt = create_auth_reply(req_name_ptr, req_inst_ptr, req_realm_ptr, req_time_ws, 0, a_name_data.exp_date, a_name_data.key_version, ciph); sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *)client, S_AD_SZ); bzero(&a_name_data, sizeof(a_name_data)); bzero(&s_name_data, sizeof(s_name_data)); break; } case AUTH_MSG_APPL_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 */ char tktrlm[REALM_SZ]; n_appl_req++; tk->length = 0; k_flags = 0; /* various kerberos flags */ auth->length = 4 + strlen(pkt->dat + 3); auth->length += (int) *(pkt->dat + auth->length) + (int) *(pkt->dat + auth->length + 1) + 2; bcopy(pkt->dat, auth->dat, auth->length); strncpy(tktrlm, auth->dat + 3, REALM_SZ); if (set_tgtkey(tktrlm)) { lt = klog(L_ERR_UNK, "FAILED realm %s unknown. Host: %s ", tktrlm, inet_ntoa(client_host)); kerb_err_reply(client, pkt, kerno, lt); return; } kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr, ad, 0); if (kerno) { klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s", inet_ntoa(client_host), krb_err_txt[kerno]); kerb_err_reply(client, pkt, kerno, "krb_rd_req failed"); return; } ptr = (char *) pkt->dat + auth->length; bcopy(ptr, &time_ws, 4); ptr += 4; req_life = (u_long) (*ptr++); service = ptr; instance = ptr + strlen(service) + 1; klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s", ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host), service, instance, 0); if (strcmp(ad->prealm, tktrlm)) { kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, "Can't hop realms"); return; } if (!strcmp(service, "changepw")) { kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN, "Can't authorize password changed based on TGT"); return; } kerno = check_princ(service, instance, req_life, &s_name_data); if (kerno) { kerb_err_reply(client, pkt, kerno, lt); return; } /* Bound requested lifetime with service and user */ lifetime = min(req_life, (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300))); lifetime = min(lifetime, ((u_long) s_name_data.max_life)); /* unseal server's key from master key */ bcopy(&s_name_data.key_low, key, 4); bcopy(&s_name_data.key_high, ((long *) key) + 1, 4); kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); /* construct and seal the ticket */#ifdef NOENCRYPTION bzero(session_key, sizeof(C_Block));#else /* random session key */ random_key(session_key);#endif krb_create_ticket(tk, k_flags, ad->pname, ad->pinst, ad->prealm, client_host.s_addr, session_key, lifetime, kerb_time.tv_sec, s_name_data.name, s_name_data.instance, key); bzero(key, sizeof(key)); bzero(key_s, sizeof(key_s)); create_ciph(ciph, session_key, service, instance, local_realm, lifetime, s_name_data.key_version, tk, kerb_time.tv_sec, ad->session); /* clear session key */ bzero(session_key, sizeof(session_key)); bzero(ad->session, sizeof(ad->session)); rpkt = create_auth_reply(ad->pname, ad->pinst, ad->prealm, time_ws, 0, 0, 0, ciph); sendto(f, rpkt->dat, rpkt->length, 0, (struct sockaddr *)client, S_AD_SZ); bzero(&s_name_data, sizeof(s_name_data)); break; }#ifdef notdef_DIE case AUTH_MSG_DIE: { lt = klog(L_DEATH_REQ, "Host: %s User: \"%s\" \"%s\" Kerberos killed", inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0); exit(0); }#endif notdef_DIE default: { lt = klog(L_KRB_PERR, "Unknown message type: %d from %s port %u", req_msg_type, inet_ntoa(client_host), ntohs(client->sin_port)); break; } }}/* * setup_disc * * disconnect all descriptors, remove ourself from the process * group that spawned us. */setup_disc(){ int s; for (s = 0; s < 3; s++) { (void) close(s); } (void) open("/dev/null", 0); (void) dup2(0, 1); (void) dup2(0, 2); s = open("/dev/tty", 2); if (s >= 0) { ioctl(s, TIOCNOTTY, (struct sgttyb *) 0); (void) close(s); } (void) chdir("/tmp"); return;}/* * kerb_er_reply creates an error reply packet and sends it to the * client. */kerb_err_reply(client, pkt, err, string) struct sockaddr_in *client; KTEXT pkt; long err; char *string;{ static KTEXT_ST e_pkt_st; KTEXT e_pkt = &e_pkt_st; static char e_msg[128]; strcpy(e_msg, "\nKerberos error -- "); strcat(e_msg, string); cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr, req_time_ws, err, e_msg); sendto(f, e_pkt->dat, e_pkt->length, 0, (struct sockaddr *)client, S_AD_SZ);}/* * Make sure that database isn't stale. * * Exit if it is; we don't want to tell lies. */static void check_db_age(){ long age; if (max_age != -1) { /* Requires existance of kerb_get_db_age() */ gettimeofday(&kerb_time, 0); age = kerb_get_db_age(); if (age == 0) { klog(L_KRB_PERR, "Database currently being updated!"); hang(); } if ((age + max_age) < kerb_time.tv_sec) { klog(L_KRB_PERR, "Database out of date!"); hang(); /* NOTREACHED */ } }}check_princ(p_name, instance, lifetime, p) char *p_name; char *instance; unsigned lifetime; Principal *p;{ static int n; static int more; long trans; n = kerb_get_principal(p_name, instance, p, 1, &more); klog(L_ALL_REQ, "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d", p_name, instance, lifetime, n, 0); if (n < 0) { lt = klog(L_KRB_PERR, "Database unavailable!"); hang(); } /* * if more than one p_name, pick one, randomly create a session key, * compute maximum lifetime, lookup authorizations if applicable, * and stuff into cipher. */ if (n == 0) { /* service unknown, log error, skip to next request */ lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name, instance, 0); return KERB_ERR_PRINCIPAL_UNKNOWN; } if (more) { /* not unique, log error */ lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"", p_name, instance, 0); return KERB_ERR_PRINCIPAL_NOT_UNIQUE; } /* If the user's key is null, we want to return an error */ if ((p->key_low == 0) && (p->key_high == 0)) { /* User has a null key */ lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, instance, 0); return KERB_ERR_NULL_KEY; } if (master_key_version != p->kdc_key_ver) { /* log error reply */ lt = klog(L_ERR_MKV, "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d", master_key_version, p->name, p->instance, p->kdc_key_ver, 0); return KERB_ERR_NAME_MAST_KEY_VER; } /* make sure the service hasn't expired */ if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) { /* service did expire, log it */ lt = klog(L_ERR_SEXP, "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance, stime(&(p->exp_date)), 0); return KERB_ERR_NAME_EXP; } /* ok is zero */ return 0;}/* Set the key for krb_rd_req so we can check tgt */set_tgtkey(r) char *r; /* Realm for desired key */{ int n; static char lastrealm[REALM_SZ]; Principal p_st; Principal *p = &p_st; C_Block key; if (!strcmp(lastrealm, r)) return (KSUCCESS); log("Getting key for %s", r); n = kerb_get_principal("krbtgt", r, p, 1, &more); if (n == 0) return (KFAILURE); /* unseal tgt key from master key */ bcopy(&p->key_low, key, 4); bcopy(&p->key_high, ((long *) key) + 1, 4); kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); krb_set_key(key, 0); strcpy(lastrealm, r); return (KSUCCESS);}static voidhang(){ if (pause_int == -1) { klog(L_KRB_PERR, "Kerberos will pause so as not to loop init"); for (;;) pause(); } else { char buf[256]; sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int); klog(L_KRB_PERR, buf); sleep(pause_int); klog(L_KRB_PERR, "Do svedania....\n"); exit(1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -