static void print_addr(krb5_context context, const char *addr) { krb5_addresses addresses; krb5_error_code ret; char buf[38]; char buf2[1000]; size_t len; int i; ret = krb5_parse_address(context, addr, &addresses); if (ret) krb5_err(context, 1, ret, "krb5_parse_address"); if (addresses.len < 1) krb5_err(context, 1, ret, "too few addresses"); for (i = 0; i < addresses.len; i++) { krb5_print_address(&addresses.val[i], buf, sizeof(buf), &len); #if 0 printf("addr %d: %s (%d/%d)\n", i, buf, (int)len, (int)strlen(buf)); #endif if (strlen(buf) > sizeof(buf)) abort(); krb5_print_address(&addresses.val[i], buf2, sizeof(buf2), &len); #if 0 printf("addr %d: %s (%d/%d)\n", i, buf2, (int)len, (int)strlen(buf2)); #endif if (strlen(buf2) > sizeof(buf2)) abort(); } krb5_free_addresses(context, &addresses); }
static void truncated_addr(krb5_context context, const char *addr, size_t truncate_len, size_t outlen) { krb5_addresses addresses; krb5_error_code ret; char *buf; size_t len; buf = ecalloc(1, outlen + 1); ret = krb5_parse_address(context, addr, &addresses); if (ret) krb5_err(context, 1, ret, "krb5_parse_address"); if (addresses.len != 1) krb5_err(context, 1, ret, "addresses should be one"); krb5_print_address(&addresses.val[0], buf, truncate_len, &len); #if 0 printf("addr %s (%d/%d) should be %d\n", buf, (int)len, (int)strlen(buf), (int)outlen); #endif if (truncate_len > strlen(buf) + 1) krb5_err(context, 1, ret, "%s truncate_len %d larger then strlen %d source %s", buf, (int)truncate_len, (int)strlen(buf), addr); if (outlen != len) krb5_err(context, 1, ret, "%s: outlen %d != len %d", buf, (int)outlen, (int)strlen(buf)); krb5_print_address(&addresses.val[0], buf, outlen + 1, &len); #if 0 printf("addr %s (%d/%d)\n", buf, (int)len, (int)strlen(buf)); #endif if (len != outlen) abort(); if (strlen(buf) != len) abort(); krb5_free_addresses(context, &addresses); free(buf); }
static krb5_error_code compare_addrs(krb5_context context, krb5_address *a, krb5_address *b, const char *message) { char a_str[64], b_str[64]; size_t len; if(krb5_address_compare (context, a, b)) return 0; krb5_print_address (a, a_str, sizeof(a_str), &len); krb5_print_address (b, b_str, sizeof(b_str), &len); krb5_set_error_message(context, KRB5KRB_AP_ERR_BADADDR, "%s: %s != %s", message, b_str, a_str); return KRB5KRB_AP_ERR_BADADDR; }
khm_int32 KHMAPI addr_list_toString(const void *d, khm_size cb_d, wchar_t *buf, khm_size *pcb_buf, khm_int32 flags) { HostAddresses as; size_t len; size_t i; wchar_t wstr[2048] = L""; wchar_t *wstr_d = &wstr[0]; khm_size cch_wstr = ARRAYLENGTH(wstr); if ( decode_HostAddresses((const unsigned char *) d, cb_d, &as, &len) ) { assert(FALSE); return KHM_ERROR_INVALID_PARAM; } for (i=0; i < as.len; i++) { char buf[1024]; wchar_t wbuf[1024]; len = sizeof(buf); if (krb5_print_address(&as.val[i], buf, sizeof(buf), &len)) { assert(FALSE); continue; } AnsiStrToUnicode(wbuf, sizeof(wbuf), buf); if (FAILED(StringCchCatEx(wstr_d, cch_wstr, wbuf, &wstr_d, &cch_wstr, STRSAFE_NO_TRUNCATION))) { assert(FALSE); continue; } if (i + 1 < as.len) { if (FAILED(StringCchCatEx(wstr_d, cch_wstr, L",", &wstr_d, &cch_wstr, STRSAFE_NO_TRUNCATION))) { assert(FALSE); continue; } } } len = (ARRAYLENGTH(wstr) - cch_wstr) * sizeof(wchar_t); if (buf == NULL || *pcb_buf < len) { *pcb_buf = len; return KHM_ERROR_TOO_LONG; } StringCbCopy(buf, *pcb_buf, wstr); *pcb_buf = len; free_HostAddresses(&as); return KHM_ERROR_SUCCESS; }
static void print_addresses (krb5_context context, const krb5_addresses *addrs) { int i; char buf[256]; size_t len; for (i = 0; i < addrs->len; ++i) { krb5_print_address (&addrs->val[i], buf, sizeof(buf), &len); printf ("%s\n", buf); } }
static int arange_print_addr (const krb5_address *addr, char *str, size_t len) { struct arange *a; krb5_error_code ret; size_t l, size, ret_len; a = addr->address.data; l = strlcpy(str, "RANGE:", len); ret_len = l; if (l > len) l = len; size = l; ret = krb5_print_address (&a->low, str + size, len - size, &l); if (ret) return ret; ret_len += l; if (len - size > l) size += l; else size = len; l = strlcat(str + size, "-", len - size); ret_len += l; if (len - size > l) size += l; else size = len; ret = krb5_print_address (&a->high, str + size, len - size, &l); if (ret) return ret; ret_len += l; return ret_len; }
static int addrport_print_addr (const krb5_address *addr, char *str, size_t len) { krb5_error_code ret; krb5_address addr1, addr2; uint16_t port = 0; size_t ret_len = 0, l, size = 0; krb5_storage *sp; sp = krb5_storage_from_data((krb5_data*)rk_UNCONST(&addr->address)); if (sp == NULL) return ENOMEM; /* for totally obscure reasons, these are not in network byteorder */ krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE); krb5_storage_seek(sp, 2, SEEK_CUR); /* skip first two bytes */ krb5_ret_address(sp, &addr1); krb5_storage_seek(sp, 2, SEEK_CUR); /* skip two bytes */ krb5_ret_address(sp, &addr2); krb5_storage_free(sp); if(addr2.addr_type == KRB5_ADDRESS_IPPORT && addr2.address.length == 2) { unsigned long value; _krb5_get_int(addr2.address.data, &value, 2); port = value; } l = strlcpy(str, "ADDRPORT:", len); ret_len += l; if (len > l) size += l; else size = len; ret = krb5_print_address(&addr1, str + size, len - size, &l); if (ret) return ret; ret_len += l; if (len - size > l) size += l; else size = len; ret = snprintf(str + size, len - size, ",PORT=%u", port); if (ret < 0) return EINVAL; ret_len += ret; return ret_len; }
static int spawn_child(krb5_context contextp, int *socks, unsigned int num_socks, int this_sock) { int e; size_t i; struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; socklen_t sa_size = sizeof(__ss); krb5_socket_t s; pid_t pid; krb5_address addr; char buf[128]; size_t buf_len; s = accept(socks[this_sock], sa, &sa_size); if(rk_IS_BAD_SOCKET(s)) { krb5_warn(contextp, rk_SOCK_ERRNO, "accept"); return 1; } e = krb5_sockaddr2address(contextp, sa, &addr); if(e) krb5_warn(contextp, e, "krb5_sockaddr2address"); else { e = krb5_print_address (&addr, buf, sizeof(buf), &buf_len); if(e) krb5_warn(contextp, e, "krb5_print_address"); else krb5_warnx(contextp, "connection from %s", buf); krb5_free_address(contextp, &addr); } pid = fork(); if(pid == 0) { for(i = 0; i < num_socks; i++) rk_closesocket(socks[i]); dup2(s, STDIN_FILENO); dup2(s, STDOUT_FILENO); if(s != STDIN_FILENO && s != STDOUT_FILENO) rk_closesocket(s); return 0; } else { rk_closesocket(s); } return 1; }
static void write_stats(krb5_context context, slave *slaves, u_int32_t current_version) { char str[100]; rtbl_t tbl; time_t t = time(NULL); FILE *fp; fp = fopen(slave_stats_file, "w"); if (fp == NULL) return; krb5_format_time(context, t, str, sizeof(str), TRUE); fprintf(fp, "Status for slaves, last updated: %s\n\n", str); fprintf(fp, "Master version: %lu\n\n", (unsigned long)current_version); tbl = rtbl_create(); if (tbl == NULL) { fclose(fp); return; } rtbl_add_column(tbl, SLAVE_NAME, 0); rtbl_add_column(tbl, SLAVE_ADDRESS, 0); rtbl_add_column(tbl, SLAVE_VERSION, RTBL_ALIGN_RIGHT); rtbl_add_column(tbl, SLAVE_STATUS, 0); rtbl_add_column(tbl, SLAVE_SEEN, 0); rtbl_set_prefix(tbl, " "); rtbl_set_column_prefix(tbl, SLAVE_NAME, ""); while (slaves) { krb5_address addr; krb5_error_code ret; rtbl_add_column_entry(tbl, SLAVE_NAME, slaves->name); ret = krb5_sockaddr2address (context, (struct sockaddr*)&slaves->addr, &addr); if(ret == 0) { krb5_print_address(&addr, str, sizeof(str), NULL); krb5_free_address(context, &addr); rtbl_add_column_entry(tbl, SLAVE_ADDRESS, str); } else rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>"); snprintf(str, sizeof(str), "%u", (unsigned)slaves->version); rtbl_add_column_entry(tbl, SLAVE_VERSION, str); if (slaves->flags & SLAVE_F_DEAD) rtbl_add_column_entry(tbl, SLAVE_STATUS, "Down"); else rtbl_add_column_entry(tbl, SLAVE_STATUS, "Up"); ret = krb5_format_time(context, slaves->seen, str, sizeof(str), TRUE); rtbl_add_column_entry(tbl, SLAVE_SEEN, str); slaves = slaves->next; } rtbl_format(tbl, fp); rtbl_destroy(tbl); fclose(fp); }
static void print_cred_verbose(krb5_context context, krb5_creds *cred) { int j; char *str; krb5_error_code ret; krb5_timestamp sec; krb5_timeofday (context, &sec); ret = krb5_unparse_name(context, cred->server, &str); if(ret) exit(1); printf(N_("Server: %s\n", ""), str); free (str); ret = krb5_unparse_name(context, cred->client, &str); if(ret) exit(1); printf(N_("Client: %s\n", ""), str); free (str); { Ticket t; size_t len; char *s; decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len); ret = krb5_enctype_to_string(context, t.enc_part.etype, &s); printf(N_("Ticket etype: ", "")); if (ret == 0) { printf("%s", s); free(s); } else { printf(N_("unknown-enctype(%d)", ""), t.enc_part.etype); } if(t.enc_part.kvno) printf(N_(", kvno %d", ""), *t.enc_part.kvno); printf("\n"); if(cred->session.keytype != t.enc_part.etype) { ret = krb5_enctype_to_string(context, cred->session.keytype, &str); if(ret) krb5_warn(context, ret, "session keytype"); else { printf(N_("Session key: %s\n", "enctype"), str); free(str); } } free_Ticket(&t); printf(N_("Ticket length: %lu\n", ""), (unsigned long)cred->ticket.length); } printf(N_("Auth time: %s\n", ""), printable_time_long(cred->times.authtime)); if(cred->times.authtime != cred->times.starttime) printf(N_("Start time: %s\n", ""), printable_time_long(cred->times.starttime)); printf(N_("End time: %s", ""), printable_time_long(cred->times.endtime)); if(sec > cred->times.endtime) printf(N_(" (expired)", "")); printf("\n"); if(cred->flags.b.renewable) printf(N_("Renew till: %s\n", ""), printable_time_long(cred->times.renew_till)); { char flags[1024]; unparse_flags(TicketFlags2int(cred->flags.b), asn1_TicketFlags_units(), flags, sizeof(flags)); printf(N_("Ticket flags: %s\n", ""), flags); } printf(N_("Addresses: ", "")); if (cred->addresses.len != 0) { for(j = 0; j < cred->addresses.len; j++){ char buf[128]; size_t len; if(j) printf(", "); ret = krb5_print_address(&cred->addresses.val[j], buf, sizeof(buf), &len); if(ret == 0) printf("%s", buf); } } else { printf(N_("addressless", "")); } printf("\n\n"); }
int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_kdc_configuration *config; krb5_storage *sp; int fd, optidx = 0; setprogname(argv[0]); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if(help_flag) usage(0); if(version_flag){ print_version(NULL); exit(0); } ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed to parse configuration file"); ret = krb5_kdc_get_config(context, &config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_default_config"); kdc_openlog(context, "kdc-replay", config); ret = krb5_kdc_set_dbinfo(context, config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo"); #ifdef PKINIT if (config->enable_pkinit) { if (config->pkinit_kdc_identity == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); if (config->pkinit_kdc_anchors == NULL) krb5_errx(context, 1, "pkinit enabled but no X509 anchors"); krb5_kdc_pk_initialize(context, config, config->pkinit_kdc_identity, config->pkinit_kdc_anchors, config->pkinit_kdc_cert_pool, config->pkinit_kdc_revoke); } #endif /* PKINIT */ if (argc != 2) errx(1, "argc != 2"); printf("kdc replay\n"); fd = open(argv[1], O_RDONLY); if (fd < 0) err(1, "open: %s", argv[1]); sp = krb5_storage_from_fd(fd); if (sp == NULL) krb5_errx(context, 1, "krb5_storage_from_fd"); while(1) { struct sockaddr_storage sa; krb5_socklen_t salen = sizeof(sa); struct timeval tv; krb5_address a; krb5_data d, r; uint32_t t, clty, tag; char astr[80]; ret = krb5_ret_uint32(sp, &t); if (ret == HEIM_ERR_EOF) break; else if (ret) krb5_errx(context, 1, "krb5_ret_uint32(version)"); if (t != 1) krb5_errx(context, 1, "version not 1"); ret = krb5_ret_uint32(sp, &t); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(time)"); ret = krb5_ret_address(sp, &a); if (ret) krb5_errx(context, 1, "krb5_ret_address"); ret = krb5_ret_data(sp, &d); if (ret) krb5_errx(context, 1, "krb5_ret_data"); ret = krb5_ret_uint32(sp, &clty); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(class|type)"); ret = krb5_ret_uint32(sp, &tag); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(tag)"); ret = krb5_addr2sockaddr (context, &a, (struct sockaddr *)&sa, &salen, 88); if (ret == KRB5_PROG_ATYPE_NOSUPP) goto out; else if (ret) krb5_err(context, 1, ret, "krb5_addr2sockaddr"); ret = krb5_print_address(&a, astr, sizeof(astr), NULL); if (ret) krb5_err(context, 1, ret, "krb5_print_address"); printf("processing request from %s, %lu bytes\n", astr, (unsigned long)d.length); r.length = 0; r.data = NULL; tv.tv_sec = t; tv.tv_usec = 0; krb5_kdc_update_time(&tv); krb5_set_real_time(context, tv.tv_sec, 0); ret = krb5_kdc_process_request(context, config, d.data, d.length, &r, NULL, astr, (struct sockaddr *)&sa, 0); if (ret) krb5_err(context, 1, ret, "krb5_kdc_process_request"); if (r.length) { Der_class cl; Der_type ty; unsigned int tag2; ret = der_get_tag (r.data, r.length, &cl, &ty, &tag2, NULL); if (MAKE_TAG(cl, ty, 0) != clty) krb5_errx(context, 1, "class|type mismatch: %d != %d", (int)MAKE_TAG(cl, ty, 0), (int)clty); if (tag != tag2) krb5_errx(context, 1, "tag mismatch"); krb5_data_free(&r); } else { if (clty != 0xffffffff) krb5_errx(context, 1, "clty not invalid"); if (tag != 0xffffffff) krb5_errx(context, 1, "tag not invalid"); } out: krb5_data_free(&d); krb5_free_address(context, &a); } krb5_storage_free(sp); krb5_free_context(context); printf("done\n"); return 0; }
static int doit (krb5_keytab keytab, int port) { krb5_error_code ret; int *sockets; int maxfd; krb5_realm *realms; krb5_addresses addrs; krb5_address *my_addrp; unsigned n, i; fd_set real_fdset; struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; #ifdef INETD_SUPPORT int fdz; int from_inetd; socklen_t fromlen; krb5_address my_addr; struct sockaddr_storage __local; struct sockaddr *localsa = (struct sockaddr *)&__local; #endif ret = krb5_get_default_realms(context, &realms); if (ret) krb5_err (context, 1, ret, "krb5_get_default_realms"); #ifdef INETD_SUPPORT fromlen = sizeof __ss; from_inetd = (getsockname(0, sa, &fromlen) == 0); if (!from_inetd) { #endif if (explicit_addresses.len) { addrs = explicit_addresses; } else { ret = krb5_get_all_server_addrs (context, &addrs); if (ret) krb5_err (context, 1, ret, "krb5_get_all_server_addrs"); } n = addrs.len; sockets = malloc (n * sizeof(*sockets)); if (sockets == NULL) krb5_errx (context, 1, "out of memory"); maxfd = -1; FD_ZERO(&real_fdset); for (i = 0; i < n; ++i) { krb5_socklen_t sa_size = sizeof(__ss); krb5_addr2sockaddr (context, &addrs.val[i], sa, &sa_size, port); sockets[i] = socket (sa->sa_family, SOCK_DGRAM, 0); if (sockets[i] < 0) krb5_err (context, 1, errno, "socket"); if (bind (sockets[i], sa, sa_size) < 0) { char str[128]; size_t len; int save_errno = errno; ret = krb5_print_address (&addrs.val[i], str, sizeof(str), &len); if (ret) strlcpy(str, "unknown address", sizeof(str)); krb5_warn (context, save_errno, "bind(%s)", str); continue; } maxfd = max (maxfd, sockets[i]); if (maxfd >= FD_SETSIZE) krb5_errx (context, 1, "fd too large"); FD_SET(sockets[i], &real_fdset); } #ifdef INETD_SUPPORT } else { n = 1; maxfd = 0; fdz = 0; sockets = &fdz; FD_ZERO(&real_fdset); FD_SET(0, &real_fdset); } #endif if (maxfd == -1) krb5_errx (context, 1, "No sockets!"); while(exit_flag == 0) { krb5_ssize_t retx; fd_set fdset = real_fdset; retx = select (maxfd + 1, &fdset, NULL, NULL, NULL); if (retx < 0) { if (errno == EINTR) continue; else krb5_err (context, 1, errno, "select"); } for (i = 0; i < n; ++i) if (FD_ISSET(sockets[i], &fdset)) { u_char buf[BUFSIZ]; socklen_t addrlen = sizeof(__ss); retx = recvfrom(sockets[i], buf, sizeof(buf), 0, sa, &addrlen); if (retx < 0) { if(errno == EINTR) break; else krb5_err (context, 1, errno, "recvfrom"); } #ifdef INETD_SUPPORT if (from_inetd) { socklen_t loclen = sizeof(__local); int ret2; ret2 = get_local_addr(sa, addrlen, localsa, &loclen); if (ret2 < 0) krb5_errx (context, errno, "get_local_addr"); ret2 = krb5_sockaddr2address(context, localsa, &my_addr); if (ret2) krb5_errx (context, ret2, "krb5_sockaddr2address"); my_addrp = &my_addr; } else #endif my_addrp = &addrs.val[i]; process (realms, keytab, sockets[i], my_addrp, sa, addrlen, buf, retx); #ifdef INETD_SUPPORT if (from_inetd) { krb5_free_address(context, &my_addr); } #endif } #ifdef INETD_SUPPORT if (from_inetd) break; #endif } for (i = 0; i < n; ++i) close(sockets[i]); free(sockets); #ifdef INETD_SUPPORT if (!from_inetd) #endif krb5_free_addresses (context, &addrs); krb5_free_host_realm (context, realms); krb5_free_context (context); return 0; }