static krb5_error_code encode_rx_header (struct rx_header *h, krb5_storage *sp) { krb5_error_code ret; ret = krb5_store_uint32(sp, h->epoch); if (ret) return ret; ret = krb5_store_uint32(sp, h->connid); if (ret) return ret; ret = krb5_store_uint32(sp, h->callid); if (ret) return ret; ret = krb5_store_uint32(sp, h->seqno); if (ret) return ret; ret = krb5_store_uint32(sp, h->serialno); if (ret) return ret; ret = krb5_store_uint8(sp, h->type); if (ret) return ret; ret = krb5_store_uint8(sp, h->flags); if (ret) return ret; ret = krb5_store_uint8(sp, h->status); if (ret) return ret; ret = krb5_store_uint8(sp, h->secindex); if (ret) return ret; ret = krb5_store_uint16(sp, h->reserved); if (ret) return ret; ret = krb5_store_uint16(sp, h->serviceid); if (ret) return ret; return 0; }
static int make_result (krb5_data *data, uint16_t result_code, const char *expl) { krb5_error_code ret; krb5_storage *sp; sp = krb5_storage_emem(); if (sp == NULL) goto out; ret = krb5_store_uint16(sp, result_code); if (ret) goto out; ret = krb5_store_stringz(sp, expl); if (ret) goto out; ret = krb5_storage_to_data(sp, data); if (ret) goto out; krb5_storage_free(sp); return 0; out: if (sp) krb5_storage_free(sp); krb5_warnx (context, "Out of memory generating error reply"); return 1; }
static void test_uint16(krb5_context context, krb5_storage *sp) { krb5_error_code ret; int i; uint16_t val[] = { 0, 1, 65535 }, v; krb5_storage_truncate(sp, 0); for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { ret = krb5_store_uint16(sp, val[i]); if (ret) krb5_err(context, 1, ret, "krb5_store_uint16"); krb5_storage_seek(sp, 0, SEEK_SET); ret = krb5_ret_uint16(sp, &v); if (ret) krb5_err(context, 1, ret, "krb5_ret_uint16"); if (v != val[i]) krb5_errx(context, 1, "store and ret mismatch"); } }
static krb5_error_code build_logon_name(krb5_context context, time_t authtime, krb5_const_principal principal, krb5_data *logon) { krb5_error_code ret; krb5_storage *sp; uint64_t t; char *s, *s2; size_t i, len; t = unix2nttime(authtime); krb5_data_zero(logon); sp = krb5_storage_emem(); if (sp == NULL) return krb5_enomem(context); krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); CHECK(ret, krb5_store_uint32(sp, t & 0xffffffff), out); CHECK(ret, krb5_store_uint32(sp, t >> 32), out); ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &s); if (ret) goto out; len = strlen(s); CHECK(ret, krb5_store_uint16(sp, len * 2), out); #if 1 /* cheat for now */ s2 = malloc(len * 2); if (s2 == NULL) { ret = krb5_enomem(context); free(s); goto out; } for (i = 0; i < len; i++) { s2[i * 2] = s[i]; s2[i * 2 + 1] = 0; } free(s); #else /* write libwind code here */ #endif ret = krb5_storage_write(sp, s2, len * 2); free(s2); if (ret != len * 2) { ret = krb5_enomem(context); goto out; } ret = krb5_storage_to_data(sp, logon); if (ret) goto out; krb5_storage_free(sp); return 0; out: krb5_storage_free(sp); return ret; }
static krb5_error_code chgpw_prexmit(krb5_context context, int proto, void *ctx, rk_socket_t fd, krb5_data *data) { struct request *request = ctx; krb5_data ap_req_data, krb_priv_data, passwd_data; krb5_storage *sp = NULL; krb5_error_code ret; krb5_ssize_t slen; size_t len; krb5_data_zero(&ap_req_data); krb5_data_zero(&krb_priv_data); ret = krb5_auth_con_genaddrs(context, request->ac, fd, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR); if (ret) goto out; ret = krb5_mk_req_extended(context, &request->ac, AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY, NULL, request->creds, &ap_req_data); if (ret) goto out; passwd_data.data = rk_UNCONST(request->password); passwd_data.length = strlen(request->password); ret = krb5_mk_priv(context, request->ac, &passwd_data, &krb_priv_data, NULL); if (ret) goto out; sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; goto out; } len = 6 + ap_req_data.length + krb_priv_data.length; ret = krb5_store_uint16(sp, len); if (ret) goto out; ret = krb5_store_uint16(sp, 1); if (ret) goto out; ret = krb5_store_uint16(sp, ap_req_data.length); if (ret) goto out; slen = krb5_storage_write(sp, ap_req_data.data, ap_req_data.length); if (slen != ap_req_data.length) { ret = EINVAL; goto out; } slen = krb5_storage_write(sp, krb_priv_data.data, krb_priv_data.length); if (slen != krb_priv_data.length) { ret = EINVAL; goto out; } ret = krb5_storage_to_data(sp, data); out: if (ret) _krb5_debugx(context, 10, "chgpw_prexmit failed with: %d", ret); if (sp) krb5_storage_free(sp); krb5_data_free(&krb_priv_data); krb5_data_free(&ap_req_data); return ret; }
static krb5_error_code setpw_prexmit(krb5_context context, int proto, void *ctx, int fd, krb5_data *data) { struct request *request = ctx; krb5_data ap_req_data, krb_priv_data, pwd_data; krb5_error_code ret; ChangePasswdDataMS chpw; krb5_storage *sp = NULL; ssize_t slen; size_t len; krb5_data_zero(&ap_req_data); krb5_data_zero(&krb_priv_data); krb5_data_zero(&pwd_data); ret = krb5_auth_con_genaddrs(context, request->ac, fd, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR); if (ret) goto out; ret = krb5_mk_req_extended(context, &request->ac, AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY, NULL, request->creds, &ap_req_data); if (ret) goto out; chpw.newpasswd.length = strlen(request->password); chpw.newpasswd.data = rk_UNCONST(request->password); if (request->target) { chpw.targname = &request->target->name; chpw.targrealm = &request->target->realm; } else { chpw.targname = NULL; chpw.targrealm = NULL; } ASN1_MALLOC_ENCODE(ChangePasswdDataMS, pwd_data.data, pwd_data.length, &chpw, &len, ret); if (ret) goto out; if(pwd_data.length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); ret = krb5_mk_priv (context, request->ac, &pwd_data, &krb_priv_data, NULL); if (ret) goto out; sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; goto out; } len = 6 + ap_req_data.length + krb_priv_data.length; ret = krb5_store_uint16(sp, len); if (ret) goto out; ret = krb5_store_uint16(sp, 0xff80); if (ret) goto out; ret = krb5_store_uint16(sp, ap_req_data.length); if (ret) goto out; slen = krb5_storage_write(sp, ap_req_data.data, ap_req_data.length); if (slen != ap_req_data.length) { ret = EINVAL; goto out; } slen = krb5_storage_write(sp, krb_priv_data.data, krb_priv_data.length); if (slen != krb_priv_data.length) { ret = EINVAL; goto out; } ret = krb5_storage_to_data(sp, data); out: if (ret) _krb5_debugx(context, 10, "setpw_prexmit failed with %d", ret); if (sp) krb5_storage_free(sp); krb5_data_free(&krb_priv_data); krb5_data_free(&ap_req_data); krb5_data_free(&pwd_data); return ret; }
static krb5_error_code build_logon_name(krb5_context context, time_t authtime, krb5_const_principal principal, krb5_data *logon) { krb5_error_code ret; krb5_storage *sp; uint64_t t; char *s, *s2; size_t s2_len; t = unix2nttime(authtime); krb5_data_zero(logon); sp = krb5_storage_emem(); if (sp == NULL) return krb5_enomem(context); krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); CHECK(ret, krb5_store_uint32(sp, t & 0xffffffff), out); CHECK(ret, krb5_store_uint32(sp, t >> 32), out); ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM | KRB5_PRINCIPAL_UNPARSE_DISPLAY, &s); if (ret) goto out; { size_t ucs2_len; uint16_t *ucs2; unsigned int flags; ret = wind_utf8ucs2_length(s, &ucs2_len); if (ret) { krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s); free(s); return ret; } ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len); if (ucs2 == NULL) { free(s); return krb5_enomem(context); } ret = wind_utf8ucs2(s, ucs2, &ucs2_len); if (ret) { free(ucs2); krb5_set_error_message(context, ret, "Principal %s is not valid UTF-8", s); free(s); return ret; } else free(s); s2_len = (ucs2_len + 1) * 2; s2 = malloc(s2_len); if (s2 == NULL) { free(ucs2); return krb5_enomem(context); } flags = WIND_RW_LE; ret = wind_ucs2write(ucs2, ucs2_len, &flags, s2, &s2_len); free(ucs2); if (ret) { free(s2); krb5_set_error_message(context, ret, "Failed to write to UCS-2 buffer"); return ret; } /* * we do not want zero termination */ s2_len = ucs2_len * 2; } CHECK(ret, krb5_store_uint16(sp, s2_len), out); ret = krb5_storage_write(sp, s2, s2_len); free(s2); if (ret != (int)s2_len) { ret = krb5_enomem(context); goto out; } ret = krb5_storage_to_data(sp, logon); if (ret) goto out; krb5_storage_free(sp); return 0; out: krb5_storage_free(sp); return ret; }