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; }
krb5_error_code KRB5_LIB_FUNCTION krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) { int i; int ret; int32_t tmp; ret = krb5_ret_int32(sp, &tmp); if(ret) return ret; adr->len = tmp; ALLOC(adr->val, adr->len); if (adr->val == NULL && adr->len != 0) return ENOMEM; for(i = 0; i < adr->len; i++){ ret = krb5_ret_address(sp, &adr->val[i]); if(ret) break; } return ret; }
OM_uint32 gss_import_sec_context ( OM_uint32 * minor_status, const gss_buffer_t interprocess_token, gss_ctx_id_t * context_handle ) { OM_uint32 ret = GSS_S_FAILURE; krb5_error_code kret; krb5_storage *sp; krb5_auth_context ac; krb5_address local, remote; krb5_address *localp, *remotep; krb5_data data; gss_buffer_desc buffer; krb5_keyblock keyblock; int32_t tmp; int32_t flags; OM_uint32 minor; int is_cfx = 0; GSSAPI_KRB5_INIT (); localp = remotep = NULL; sp = krb5_storage_from_mem (interprocess_token->value, interprocess_token->length); if (sp == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } *context_handle = malloc(sizeof(**context_handle)); if (*context_handle == NULL) { *minor_status = ENOMEM; krb5_storage_free (sp); return GSS_S_FAILURE; } memset (*context_handle, 0, sizeof(**context_handle)); HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); kret = krb5_auth_con_init (gssapi_krb5_context, &(*context_handle)->auth_context); if (kret) { gssapi_krb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } /* flags */ *minor_status = 0; if (krb5_ret_int32 (sp, &flags) != 0) goto failure; /* retrieve the auth context */ ac = (*context_handle)->auth_context; krb5_ret_int32 (sp, &ac->flags); if (flags & SC_LOCAL_ADDRESS) { if (krb5_ret_address (sp, localp = &local) != 0) goto failure; } if (flags & SC_REMOTE_ADDRESS) { if (krb5_ret_address (sp, remotep = &remote) != 0) goto failure; } krb5_auth_con_setaddrs (gssapi_krb5_context, ac, localp, remotep); if (localp) krb5_free_address (gssapi_krb5_context, localp); if (remotep) krb5_free_address (gssapi_krb5_context, remotep); localp = remotep = NULL; if (krb5_ret_int16 (sp, &ac->local_port) != 0) goto failure; if (krb5_ret_int16 (sp, &ac->remote_port) != 0) goto failure; if (flags & SC_KEYBLOCK) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; krb5_auth_con_setkey (gssapi_krb5_context, ac, &keyblock); krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock); } if (flags & SC_LOCAL_SUBKEY) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; krb5_auth_con_setlocalsubkey (gssapi_krb5_context, ac, &keyblock); krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock); } if (flags & SC_REMOTE_SUBKEY) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; krb5_auth_con_setremotesubkey (gssapi_krb5_context, ac, &keyblock); krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock); } if (krb5_ret_int32 (sp, &ac->local_seqnumber)) goto failure; if (krb5_ret_int32 (sp, &ac->remote_seqnumber)) goto failure; if (krb5_ret_int32 (sp, &tmp) != 0) goto failure; ac->keytype = tmp; if (krb5_ret_int32 (sp, &tmp) != 0) goto failure; ac->cksumtype = tmp; /* names */ if (krb5_ret_data (sp, &data)) goto failure; buffer.value = data.data; buffer.length = data.length; ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, &(*context_handle)->source); if (ret) { ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID, &(*context_handle)->source); if (ret) { krb5_data_free (&data); goto failure; } } krb5_data_free (&data); if (krb5_ret_data (sp, &data) != 0) goto failure; buffer.value = data.data; buffer.length = data.length; ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, &(*context_handle)->target); if (ret) { ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID, &(*context_handle)->target); if (ret) { krb5_data_free (&data); goto failure; } } krb5_data_free (&data); if (krb5_ret_int32 (sp, &tmp)) goto failure; (*context_handle)->flags = tmp; if (krb5_ret_int32 (sp, &tmp)) goto failure; (*context_handle)->more_flags = tmp; if (krb5_ret_int32 (sp, &tmp) == 0) (*context_handle)->lifetime = tmp; else (*context_handle)->lifetime = GSS_C_INDEFINITE; gsskrb5_is_cfx(*context_handle, &is_cfx); ret = _gssapi_msg_order_create(minor_status, &(*context_handle)->order, _gssapi_msg_order_f((*context_handle)->flags), 0, 0, is_cfx); if (ret) goto failure; krb5_storage_free (sp); return GSS_S_COMPLETE; failure: krb5_auth_con_free (gssapi_krb5_context, (*context_handle)->auth_context); if ((*context_handle)->source != NULL) gss_release_name(&minor, &(*context_handle)->source); if ((*context_handle)->target != NULL) gss_release_name(&minor, &(*context_handle)->target); if (localp) krb5_free_address (gssapi_krb5_context, localp); if (remotep) krb5_free_address (gssapi_krb5_context, remotep); if((*context_handle)->order) _gssapi_msg_order_destroy(&(*context_handle)->order); HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); krb5_storage_free (sp); free (*context_handle); *context_handle = GSS_C_NO_CONTEXT; return ret; }
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; }
OM_uint32 GSSAPI_CALLCONV _gsskrb5_import_sec_context ( OM_uint32 * minor_status, const gss_buffer_t interprocess_token, gss_ctx_id_t * context_handle ) { OM_uint32 ret = GSS_S_FAILURE; krb5_context context; krb5_error_code kret; krb5_storage *sp; krb5_auth_context ac; krb5_address local, remote; krb5_address *localp, *remotep; krb5_data data; gss_buffer_desc buffer; krb5_keyblock keyblock; int32_t flags, tmp; gsskrb5_ctx ctx; gss_name_t name; GSSAPI_KRB5_INIT (&context); *context_handle = GSS_C_NO_CONTEXT; localp = remotep = NULL; sp = krb5_storage_from_mem (interprocess_token->value, interprocess_token->length); if (sp == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) { *minor_status = ENOMEM; krb5_storage_free (sp); return GSS_S_FAILURE; } HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); kret = krb5_auth_con_init (context, &ctx->auth_context); if (kret) { *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } /* flags */ *minor_status = 0; if (krb5_ret_int32 (sp, &flags) != 0) goto failure; /* retrieve the auth context */ ac = ctx->auth_context; if (krb5_ret_int32 (sp, &tmp) != 0) goto failure; ac->flags = tmp; if (flags & SC_LOCAL_ADDRESS) { if (krb5_ret_address (sp, localp = &local) != 0) goto failure; } if (flags & SC_REMOTE_ADDRESS) { if (krb5_ret_address (sp, remotep = &remote) != 0) goto failure; } krb5_auth_con_setaddrs (context, ac, localp, remotep); if (localp) krb5_free_address (context, localp); if (remotep) krb5_free_address (context, remotep); localp = remotep = NULL; if (krb5_ret_int16 (sp, &ac->local_port) != 0) goto failure; if (krb5_ret_int16 (sp, &ac->remote_port) != 0) goto failure; if (flags & SC_KEYBLOCK) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; krb5_auth_con_setkey (context, ac, &keyblock); krb5_free_keyblock_contents (context, &keyblock); } if (flags & SC_LOCAL_SUBKEY) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; krb5_auth_con_setlocalsubkey (context, ac, &keyblock); krb5_free_keyblock_contents (context, &keyblock); } if (flags & SC_REMOTE_SUBKEY) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; krb5_auth_con_setremotesubkey (context, ac, &keyblock); krb5_free_keyblock_contents (context, &keyblock); } if (krb5_ret_uint32 (sp, &ac->local_seqnumber)) goto failure; if (krb5_ret_uint32 (sp, &ac->remote_seqnumber)) goto failure; if (krb5_ret_int32 (sp, &tmp) != 0) goto failure; ac->keytype = tmp; if (krb5_ret_int32 (sp, &tmp) != 0) goto failure; ac->cksumtype = tmp; /* names */ if (krb5_ret_data (sp, &data)) goto failure; buffer.value = data.data; buffer.length = data.length; ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, &name); if (ret) { ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID, &name); if (ret) { krb5_data_free (&data); goto failure; } } ctx->source = (krb5_principal)name; krb5_data_free (&data); if (krb5_ret_data (sp, &data) != 0) goto failure; buffer.value = data.data; buffer.length = data.length; ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, &name); if (ret) { ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID, &name); if (ret) { krb5_data_free (&data); goto failure; } } ctx->target = (krb5_principal)name; krb5_data_free (&data); if (krb5_ret_int32 (sp, &tmp)) goto failure; ctx->flags = tmp; if (krb5_ret_int32 (sp, &tmp)) goto failure; ctx->more_flags = tmp; if (krb5_ret_int32 (sp, &tmp)) goto failure; ctx->endtime = tmp; ret = _gssapi_msg_order_import(minor_status, sp, &ctx->gk5c.order); if (ret) goto failure; krb5_storage_free (sp); _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0); *context_handle = (gss_ctx_id_t)ctx; return GSS_S_COMPLETE; failure: krb5_auth_con_free (context, ctx->auth_context); if (ctx->source != NULL) krb5_free_principal(context, ctx->source); if (ctx->target != NULL) krb5_free_principal(context, ctx->target); if (localp) krb5_free_address (context, localp); if (remotep) krb5_free_address (context, remotep); if(ctx->gk5c.order) _gssapi_msg_order_destroy(&ctx->gk5c.order); HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); krb5_storage_free (sp); free (ctx); *context_handle = GSS_C_NO_CONTEXT; return ret; }