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; }
static int test_parse(void) { const char *user = "******", *domain = "mydomain", *password = "******", *target = "DOMAIN"; struct ntlm_type1 type1; struct ntlm_type2 type2; struct ntlm_type3 type3; struct ntlm_buf data; int ret, flags; memset(&type1, 0, sizeof(type1)); type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM; type1.domain = rk_UNCONST(domain); type1.hostname = NULL; type1.os[0] = 0; type1.os[1] = 0; ret = heim_ntlm_encode_type1(&type1, &data); if (ret) errx(1, "heim_ntlm_encode_type1"); memset(&type1, 0, sizeof(type1)); ret = heim_ntlm_decode_type1(&data, &type1); free(data.data); if (ret) errx(1, "heim_ntlm_encode_type1"); heim_ntlm_free_type1(&type1); /* * */ memset(&type2, 0, sizeof(type2)); flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN; type2.flags = flags; memset(type2.challenge, 0x7f, sizeof(type2.challenge)); type2.targetname = rk_UNCONST(target); type2.targetinfo.data = NULL; type2.targetinfo.length = 0; ret = heim_ntlm_encode_type2(&type2, &data); if (ret) errx(1, "heim_ntlm_encode_type2"); memset(&type2, 0, sizeof(type2)); ret = heim_ntlm_decode_type2(&data, &type2); free(data.data); if (ret) errx(1, "heim_ntlm_decode_type2"); heim_ntlm_free_type2(&type2); /* * */ memset(&type3, 0, sizeof(type3)); type3.flags = flags; type3.username = rk_UNCONST(user); type3.targetname = rk_UNCONST(target); type3.ws = rk_UNCONST("workstation"); { struct ntlm_buf key; heim_ntlm_nt_key(password, &key); heim_ntlm_calculate_ntlm1(key.data, key.length, type2.challenge, &type3.ntlm); free(key.data); } ret = heim_ntlm_encode_type3(&type3, &data); if (ret) errx(1, "heim_ntlm_encode_type3"); free(type3.ntlm.data); memset(&type3, 0, sizeof(type3)); ret = heim_ntlm_decode_type3(&data, 1, &type3); free(data.data); if (ret) errx(1, "heim_ntlm_decode_type3"); if (strcmp("workstation", type3.ws) != 0) errx(1, "type3 ws wrong"); if (strcmp(target, type3.targetname) != 0) errx(1, "type3 targetname wrong"); if (strcmp(user, type3.username) != 0) errx(1, "type3 username wrong"); heim_ntlm_free_type3(&type3); /* * NTLMv2 */ memset(&type2, 0, sizeof(type2)); flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN; type2.flags = flags; memset(type2.challenge, 0x7f, sizeof(type2.challenge)); type2.targetname = rk_UNCONST(target); type2.targetinfo.data = "\x00\x00"; type2.targetinfo.length = 2; ret = heim_ntlm_encode_type2(&type2, &data); if (ret) errx(1, "heim_ntlm_encode_type2"); memset(&type2, 0, sizeof(type2)); ret = heim_ntlm_decode_type2(&data, &type2); free(data.data); if (ret) errx(1, "heim_ntlm_decode_type2"); heim_ntlm_free_type2(&type2); return 0; }
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.challenge)) { *minor_status = EINVAL; return GSS_S_FAILURE; } memcpy(type2.challenge, challange.data, sizeof(type2.challenge)); 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; }