static OM_uint32 kdc_type2(OM_uint32 *minor_status, void *ctx, uint32_t flags, const char *hostname, const char *domain, uint32_t *ret_flags, struct ntlm_buf *out) { struct ntlmkrb5 *c = ctx; krb5_error_code ret; struct ntlm_type2 type2; krb5_data challange; struct ntlm_buf data; krb5_data ti; memset(&type2, 0, sizeof(type2)); /* * Request data for type 2 packet from the KDC. */ ret = krb5_ntlm_init_request(c->context, c->ntlm, NULL, c->id, flags, hostname, domain); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } /* * */ ret = krb5_ntlm_init_get_opaque(c->context, c->ntlm, &c->opaque); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } /* * */ ret = krb5_ntlm_init_get_flags(c->context, c->ntlm, &type2.flags); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } *ret_flags = type2.flags; ret = krb5_ntlm_init_get_challange(c->context, c->ntlm, &challange); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } if (challange.length != sizeof(type2.challange)) { *minor_status = EINVAL; return GSS_S_FAILURE; } memcpy(type2.challange, challange.data, sizeof(type2.challange)); krb5_data_free(&challange); ret = krb5_ntlm_init_get_targetname(c->context, c->ntlm, &type2.targetname); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } ret = krb5_ntlm_init_get_targetinfo(c->context, c->ntlm, &ti); if (ret) { free(type2.targetname); *minor_status = ret; return GSS_S_FAILURE; } type2.targetinfo.data = ti.data; type2.targetinfo.length = ti.length; ret = heim_ntlm_encode_type2(&type2, &data); free(type2.targetname); krb5_data_free(&ti); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } out->data = data.data; out->length = data.length; return GSS_S_COMPLETE; }
int ntlm_server_init(struct ntlm_server_init_options *opt, int argc, char ** argv) { krb5_error_code ret; krb5_ntlm ntlm; struct ntlm_type2 type2; krb5_data challange, opaque; struct ntlm_buf data; char *s; memset(&type2, 0, sizeof(type2)); ret = krb5_ntlm_alloc(context, &ntlm); if (ret) krb5_err(context, 1, ret, "krb5_ntlm_alloc"); ret = krb5_ntlm_init_request(context, ntlm, opt->kerberos_realm_string, id, NTLM_NEG_UNICODE|NTLM_NEG_NTLM, "NUTCRACKER", "L"); if (ret) krb5_err(context, 1, ret, "krb5_ntlm_init_request"); /* * */ ret = krb5_ntlm_init_get_challange(context, ntlm, &challange); if (ret) krb5_err(context, 1, ret, "krb5_ntlm_init_get_challange"); if (challange.length != sizeof(type2.challange)) krb5_errx(context, 1, "ntlm challange have wrong length"); memcpy(type2.challange, challange.data, sizeof(type2.challange)); krb5_data_free(&challange); ret = krb5_ntlm_init_get_flags(context, ntlm, &type2.flags); if (ret) krb5_err(context, 1, ret, "krb5_ntlm_init_get_flags"); krb5_ntlm_init_get_targetname(context, ntlm, &type2.targetname); type2.targetinfo.data = "\x00\x00"; type2.targetinfo.length = 2; ret = heim_ntlm_encode_type2(&type2, &data); if (ret) krb5_errx(context, 1, "heim_ntlm_encode_type2"); free(type2.targetname); /* * */ base64_encode(data.data, data.length, &s); free(data.data); printf("type2=%s\n", s); free(s); /* * */ ret = krb5_ntlm_init_get_opaque(context, ntlm, &opaque); if (ret) krb5_err(context, 1, ret, "krb5_ntlm_init_get_opaque"); base64_encode(opaque.data, opaque.length, &s); krb5_data_free(&opaque); printf("opaque=%s\n", s); free(s); /* * */ krb5_ntlm_free(context, ntlm); return 0; }