📄 kerberos5.c
字号:
if (UserNameRequested && krb5_kuserok (telnet_context, ticket->enc_part2->client, UserNameRequested)) { /* FIXME: Check buffer length */ strcpy (name, UserNameRequested); return AUTH_VALID; } return AUTH_USER;}intkerberos5_is_auth (TN_Authenticator *ap, unsigned char *data, int cnt, char *errbuf, int errbuflen){ int r = 0; krb5_keytab keytabid = 0; krb5_authenticator *authenticator; char *name; krb5_data outbuf; krb5_keyblock *newkey = NULL; krb5_principal server; #ifdef ENCRYPTION Session_Key skey;#endif auth.data = (char *)data; auth.length = cnt; if (!r && !auth_context) r = krb5_auth_con_init (telnet_context, &auth_context); if (!r) { krb5_rcache rcache; r = krb5_auth_con_getrcache (telnet_context, auth_context, &rcache); if (!r && !rcache) { r = krb5_sname_to_principal(telnet_context, 0, 0, KRB5_NT_SRV_HST, &server); if (!r) { r = krb5_get_server_rcache(telnet_context, krb5_princ_component (telnet_context, server, 0), &rcache); krb5_free_principal (telnet_context, server); } } if (!r) r = krb5_auth_con_setrcache (telnet_context, auth_context, rcache); } if (!r && telnet_srvtab) r = krb5_kt_resolve (telnet_context, telnet_srvtab, &keytabid); if (!r) r = krb5_rd_req (telnet_context, &auth_context, &auth, NULL, keytabid, NULL, &ticket); if (r) { snprintf (errbuf, errbuflen, "krb5_rd_req failed: %s", error_message (r)); return r; } /* 256 bytes should be much larger than any reasonable first component of a service name especially since the default is of length 4. */ if (krb5_princ_component (telnet_context,ticket->server,0)->length < 256) { char princ[256]; strncpy (princ, krb5_princ_component (telnet_context, ticket->server,0)->data, krb5_princ_component (telnet_context, ticket->server,0)->length); princ[krb5_princ_component (telnet_context, ticket->server,0)->length] = '\0'; if (strcmp ("host", princ)) { snprintf(errbuf, errbuflen, "incorrect service name: \"%s\" != \"host\"", princ); return 1; } } else { strncpy (errbuf, "service name too long", errbuflen); return 1; } r = krb5_auth_con_getauthenticator (telnet_context, auth_context, &authenticator); if (r) { snprintf (errbuf, errbuflen, "krb5_auth_con_getauthenticator failed: %s", error_message (r)); return 1; }#ifdef AUTH_ENCRYPT_MASK if ((ap->way & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON && !authenticator->checksum) { snprintf (errbuf, errbuflen, "authenticator is missing required checksum"); return 1; }#endif if (authenticator->checksum) { char type_check[2]; krb5_checksum *cksum = authenticator->checksum; krb5_keyblock *key; type_check[0] = ap->type; type_check[1] = ap->way; r = krb5_auth_con_getkey (telnet_context, auth_context, &key); if (r) { snprintf (errbuf, errbuflen, "krb5_auth_con_getkey failed: %s", error_message (r)); return 1; } r = krb5_verify_checksum (telnet_context, cksum->checksum_type, cksum, &type_check, 2, key->contents, key->length); if (r) { snprintf (errbuf, errbuflen, "checksum verification failed: %s", error_message (r)); return 1; } krb5_free_keyblock (telnet_context, key); } krb5_free_authenticator (telnet_context, authenticator); if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { if ((r = krb5_mk_rep (telnet_context, auth_context, &outbuf))) { snprintf (errbuf, errbuflen, "Make reply failed: %s", error_message(r)); return 1; } Data (ap, KRB_RESPONSE, outbuf.data, outbuf.length); } if (krb5_unparse_name (telnet_context, ticket->enc_part2 ->client, &name)) name = 0; Data (ap, KRB_ACCEPT, name, name ? -1 : 0); DEBUG(("telnetd: Kerberos5 identifies him as ``%s''\r\n", name ? name : "")); auth_finished (ap, AUTH_USER); if (name) free (name); krb5_auth_con_getremotesubkey (telnet_context, auth_context, &newkey); if (session_key) { krb5_free_keyblock (telnet_context, session_key); session_key = 0; } if (newkey) { krb5_copy_keyblock (telnet_context, newkey, &session_key); krb5_free_keyblock (telnet_context, newkey); } else { krb5_copy_keyblock (telnet_context, ticket->enc_part2->session, &session_key); } telnet_encrypt_key (&skey); return 0;}#ifdef FORWARDintkerberos5_is_forward (TN_Authenticator *ap, unsigned char *data, int cnt, char *errbuf, int errbuflen){ int r = 0; krb5_data inbuf; inbuf.length = cnt; inbuf.data = (char *)data; if ((r = krb5_auth_con_genaddrs (telnet_context, auth_context, net, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) || (r = rd_and_store_for_creds(telnet_context, auth_context, &inbuf, ticket))) { snprintf (errbuf, errbuflen, "Read forwarded creds failed: %s", error_message (r)); Data (ap, KRB_FORWARD_REJECT, errbuf, -1); DEBUG(("Could not read forwarded credentials\r\n")); } else { Data(ap, KRB_FORWARD_ACCEPT, 0, 0); DEBUG(("Forwarded credentials obtained\r\n")); } return r;}#else# define kerberos5_is_forward(ap,data,cnt,errbuf,errbuflen) 0#endif voidkerberos5_is (TN_Authenticator *ap, unsigned char *data, int cnt){ int r = 0; char errbuf[512]; if (cnt-- < 1) return; errbuf[0] = 0; switch (*data++) { case KRB_AUTH: r = kerberos5_is_auth (ap, data, cnt, errbuf, sizeof errbuf); break; case KRB_FORWARD: r = kerberos5_is_forward (ap, data, cnt, errbuf, sizeof errbuf); break; default: DEBUG(("Unknown Kerberos option %d\r\n", data[-1])); Data(ap, KRB_REJECT, 0, 0); break; } if (r) { if (!errbuf[0]) snprintf (errbuf, sizeof errbuf, "kerberos_is: %s", error_message(r)); Data (ap, KRB_REJECT, errbuf, -1); DEBUG(("%s\r\n", errbuf)); syslog (LOG_ERR, "%s", errbuf); if (auth_context) { krb5_auth_con_free (telnet_context, auth_context); auth_context = 0; } }} static char *req_type_str (int type){ switch (type) { case KRB_REJECT: return "REJECT"; case KRB_ACCEPT: return "ACCEPT"; case KRB_AUTH: return "AUTH"; case KRB_RESPONSE: return "RESPONSE"; case KRB_FORWARD: return "FORWARD"; case KRB_FORWARD_ACCEPT: return "FORWARD_ACCEPT"; case KRB_FORWARD_REJECT: return "FORWARD_REJECT"; } return NULL;} #define ADDC(p,l,c) if ((l) > 0) {*(p)++ = (c); --(l);}voidkerberos5_printsub (unsigned char *data, int cnt, unsigned char *buf, int buflen){ char *p; int i; buf[buflen-1] = '\0'; /* make sure its NULL terminated */ buflen -= 1; p = req_type_str (data[3]); if (!p) { int l = snprintf (buf, buflen, " %d (unknown)", data[3]); buf += l; buflen -= l; } else { while (buflen > 0 && (*buf++ = *p++) != 0) buflen--; } switch (data[3]) { case KRB_REJECT: /* Rejected (reason might follow) */ case KRB_ACCEPT: /* Accepted (username might follow) */ if (cnt <= 4) break; ADDC(buf, buflen, '"'); for (i = 4; i < cnt; i++) ADDC(buf, buflen, data[i]); ADDC(buf, buflen, '"'); ADDC(buf, buflen, '\0'); break; case KRB_AUTH: case KRB_RESPONSE: case KRB_FORWARD: case KRB_FORWARD_ACCEPT: case KRB_FORWARD_REJECT: for (i = 4; buflen > 0 && i < cnt; i++) { int l = snprintf (buf, buflen, " %d", data[i]); buf += l; buflen -= l; } }} #ifdef FORWARDvoidkerberos5_forward (TN_Authenticator *ap){ krb5_error_code r; krb5_ccache ccache; krb5_principal client = 0; krb5_principal server = 0; krb5_data forw_creds; forw_creds.data = 0; if ((r = krb5_cc_default (telnet_context, &ccache))) { DEBUG(("Kerberos V5: could not get default ccache - %s\r\n", error_message(r))); return; } for (;;) /* Fake loop */ { if ((r = krb5_cc_get_principal (telnet_context, ccache, &client))) { DEBUG(("Kerberos V5: could not get default principal - %s\r\n", error_message(r))); break; } if ((r = krb5_sname_to_principal (telnet_context, RemoteHostName, "host", KRB5_NT_SRV_HST, &server))) { DEBUG(("Kerberos V5: could not make server principal - %s\r\n", error_message(r))); break; } if ((r = krb5_auth_con_genaddrs (telnet_context, auth_context, net, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) { DEBUG(("Kerberos V5: could not gen local full address - %s\r\n", error_message(r))); break; } if ((r = krb5_fwd_tgt_creds (telnet_context, auth_context, 0, client, server, ccache, forward_flags & OPTS_FORWARDABLE_CREDS, &forw_creds))) { DEBUG(("Kerberos V5: error getting forwarded creds - %s\r\n", error_message(r))); break; } /* Send forwarded credentials */ if (!Data(ap, KRB_FORWARD, forw_creds.data, forw_creds.length)) { DEBUG(("Not enough room for authentication data\r\n")); } else { DEBUG(("Forwarded local Kerberos V5 credentials to server\r\n")); } break; } if (client) krb5_free_principal(telnet_context, client); if (server) krb5_free_principal(telnet_context, server); if (forw_creds.data) free(forw_creds.data); krb5_cc_close(telnet_context, ccache);}#endif #endif /* KRB5 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -