static void generate_random_pw(krb5_context context, char *buf, size_t bufsiz) { unsigned char x[512], *p; size_t i; memset(x, 0, sizeof(x)); krb5_generate_random_block(x, sizeof(x)); p = x; for (i = 0; i < bufsiz; i++) { while (isprint(*p) == 0) p++; if (p - x >= sizeof(x)) { krb5_generate_random_block(x, sizeof(x)); p = x; } buf[i] = (char)*p++; } buf[bufsiz - 1] = '\0'; memset(x, 0, sizeof(x)); }
/* * NIST guidance in Section 5.1 of [SP800-132] requires that a portion * of the salt of at least 128 bits shall be randomly generated. */ static krb5_error_code add_random_to_salt(krb5_context context, krb5_salt *in, krb5_salt *out) { krb5_error_code ret; char *p; unsigned char random[16]; char *s; int slen; krb5_generate_random_block(random, sizeof(random)); slen = rk_base64_encode(random, sizeof(random), &s); if (slen < 0) return ENOMEM; ret = krb5_data_alloc(&out->saltvalue, slen + in->saltvalue.length); if (ret) { free(s); return ret; } p = out->saltvalue.data; memcpy(p, s, slen); memcpy(&p[slen], in->saltvalue.data, in->saltvalue.length); out->salttype = in->salttype; free(s); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL _krb5_des_checksum(krb5_context context, const EVP_MD *evp_md, struct _krb5_key_data *key, const void *data, size_t len, Checksum *cksum) { struct _krb5_evp_schedule *ctx = key->schedule->data; EVP_MD_CTX *m; DES_cblock ivec; unsigned char *p = cksum->checksum.data; krb5_generate_random_block(p, 8); m = EVP_MD_CTX_create(); if (m == NULL) return krb5_enomem(context); EVP_DigestInit_ex(m, evp_md, NULL); EVP_DigestUpdate(m, p, 8); EVP_DigestUpdate(m, data, len); EVP_DigestFinal_ex (m, p + 8, NULL); EVP_MD_CTX_destroy(m); memset (&ivec, 0, sizeof(ivec)); EVP_CipherInit_ex(&ctx->ectx, NULL, NULL, NULL, (void *)&ivec, -1); EVP_Cipher(&ctx->ectx, p, p, 24); return 0; }
krb5_error_code _krb5_des_checksum(krb5_context context, CCDigestAlg alg, struct _krb5_key_data *key, const void *data, size_t len, Checksum *cksum) { struct _krb5_evp_schedule *ctx = key->schedule->data; CCDigestRef m; unsigned char ivec[8]; unsigned char *p = cksum->checksum.data; krb5_generate_random_block(p, 8); m = CCDigestCreate(alg); if (m == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } CCDigestUpdate(m, p, 8); CCDigestUpdate(m, data, len); CCDigestFinal(m, p + 8); CCDigestDestroy(m); memset (&ivec, 0, sizeof(ivec)); EVP_CipherInit_ex(&ctx->ectx, NULL, NULL, NULL, (void *)ivec, -1); EVP_Cipher(&ctx->ectx, p, p, 24); return 0; }
/* return a random value in range 0-127 */ static int RND(unsigned char *key, int keylen, int *left) { if(*left == 0) { krb5_generate_random_block(key, keylen); *left = keylen; } (*left)--; return ((unsigned char*)key)[*left]; }
static void DES3_random_key(krb5_context context, krb5_keyblock *key) { DES_cblock *k = key->keyvalue.data; do { krb5_generate_random_block(k, 3 * sizeof(DES_cblock)); DES_set_odd_parity(&k[0]); DES_set_odd_parity(&k[1]); DES_set_odd_parity(&k[2]); } while(DES_is_weak_key(&k[0]) || DES_is_weak_key(&k[1]) || DES_is_weak_key(&k[2])); }
static void DES3_random_key(krb5_context context, krb5_keyblock *key) { uint8_t *k = key->keyvalue.data; do { krb5_generate_random_block(key->keyvalue.data, key->keyvalue.length); CCDesSetOddParity(&k[0], 8); CCDesSetOddParity(&k[8], 8); CCDesSetOddParity(&k[16], 8); } while(CCDesIsWeakKey(&k[0], 8) || CCDesIsWeakKey(&k[8], 8) || CCDesIsWeakKey(&k[16], 8)); }
void random_password(char *pw, size_t len) { #ifdef OTP_STYLE { OtpKey newkey; krb5_generate_random_block(&newkey, sizeof(newkey)); otp_print_stddict (newkey, pw, len); strlwr(pw); } #else char *pass; generate_password(&pass, 3, "abcdefghijklmnopqrstuvwxyz", 7, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2, "@$%&*()-+=:,/<>1234567890", 1); strlcpy(pw, pass, len); memset(pass, 0, strlen(pass)); free(pass); #endif }
krb5_error_code KRB5_LIB_FUNCTION krb5_init_creds_init(krb5_context context, krb5_principal client, krb5_prompter_fct prompter, void *prompter_data, krb5_deltat start_time, krb5_get_init_creds_opt *options, krb5_init_creds_context *rctx) { krb5_init_creds_context ctx; krb5_error_code ret; *rctx = NULL; ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } ret = get_init_creds_common(context, client, start_time, options, ctx); if (ret) { free(ctx); return ret; } /* Set a new nonce. */ krb5_generate_random_block (&ctx->nonce, sizeof(ctx->nonce)); ctx->nonce &= 0x7fffffff; /* XXX these just needs to be the same when using Windows PK-INIT */ ctx->pk_nonce = ctx->nonce; ctx->prompter = prompter; ctx->prompter_data = prompter_data; *rctx = ctx; return ret; }
static krb5_error_code get_cred_kdc(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, krb5_addresses *addresses, krb5_creds *in_creds, krb5_creds *krbtgt, krb5_principal impersonate_principal, Ticket *second_ticket, krb5_creds *out_creds) { TGS_REQ req; krb5_data enc; krb5_data resp; krb5_kdc_rep rep; KRB_ERROR error; krb5_error_code ret; unsigned nonce; krb5_keyblock *subkey = NULL; size_t len; Ticket second_ticket_data; METHOD_DATA padata; krb5_data_zero(&resp); krb5_data_zero(&enc); padata.val = NULL; padata.len = 0; krb5_generate_random_block(&nonce, sizeof(nonce)); nonce &= 0xffffffff; if(flags.b.enc_tkt_in_skey && second_ticket == NULL){ ret = decode_Ticket(in_creds->second_ticket.data, in_creds->second_ticket.length, &second_ticket_data, &len); if(ret) return ret; second_ticket = &second_ticket_data; } if (impersonate_principal) { krb5_crypto crypto; PA_S4U2Self self; krb5_data data; void *buf; size_t size; self.name = impersonate_principal->name; self.realm = impersonate_principal->realm; self.auth = estrdup("Kerberos"); ret = _krb5_s4u2self_to_checksumdata(context, &self, &data); if (ret) { free(self.auth); goto out; } ret = krb5_crypto_init(context, &krbtgt->session, 0, &crypto); if (ret) { free(self.auth); krb5_data_free(&data); goto out; } ret = krb5_create_checksum(context, crypto, KRB5_KU_OTHER_CKSUM, 0, data.data, data.length, &self.cksum); krb5_crypto_destroy(context, crypto); krb5_data_free(&data); if (ret) { free(self.auth); goto out; } ASN1_MALLOC_ENCODE(PA_S4U2Self, buf, len, &self, &size, ret); free(self.auth); free_Checksum(&self.cksum); if (ret) goto out; if (len != size) krb5_abortx(context, "internal asn1 error"); ret = krb5_padata_add(context, &padata, KRB5_PADATA_FOR_USER, buf, len); if (ret) goto out; } ret = init_tgs_req (context, id, addresses, flags, second_ticket, in_creds, krbtgt, nonce, &padata, &subkey, &req); if (ret) goto out; ASN1_MALLOC_ENCODE(TGS_REQ, enc.data, enc.length, &req, &len, ret); if (ret) goto out; if(enc.length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); /* don't free addresses */ req.req_body.addresses = NULL; free_TGS_REQ(&req); /* * Send and receive */ { krb5_sendto_ctx stctx; ret = krb5_sendto_ctx_alloc(context, &stctx); if (ret) return ret; krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL); ret = krb5_sendto_context (context, stctx, &enc, krbtgt->server->name.name_string.val[1], &resp); krb5_sendto_ctx_free(context, stctx); } if(ret) goto out; memset(&rep, 0, sizeof(rep)); if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0) { unsigned eflags = 0; ret = krb5_copy_principal(context, in_creds->client, &out_creds->client); if(ret) goto out2; ret = krb5_copy_principal(context, in_creds->server, &out_creds->server); if(ret) goto out2; /* this should go someplace else */ out_creds->times.endtime = in_creds->times.endtime; /* XXX should do better testing */ if (flags.b.constrained_delegation || impersonate_principal) eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; ret = _krb5_extract_ticket(context, &rep, out_creds, &krbtgt->session, NULL, 0, &krbtgt->addresses, nonce, eflags, decrypt_tkt_with_subkey, subkey); out2: krb5_free_kdc_rep(context, &rep); } else if(krb5_rd_error(context, &resp, &error) == 0) { ret = krb5_error_from_rd_error(context, &error, in_creds); krb5_free_error_contents(context, &error); } else if(resp.length > 0 && ((char*)resp.data)[0] == 4) { ret = KRB5KRB_AP_ERR_V4_REPLY; krb5_clear_error_message(context); } else { ret = KRB5KRB_AP_ERR_MSG_TYPE; krb5_clear_error_message(context); } out: if (second_ticket == &second_ticket_data) free_Ticket(&second_ticket_data); free_METHOD_DATA(&padata); krb5_data_free(&resp); krb5_data_free(&enc); if(subkey) krb5_free_keyblock(context, subkey); return ret; }
static krb5_error_code tkt_referral_send(krb5_context context, krb5_tkt_creds_context ctx, krb5_data *in, krb5_data *out, krb5_realm *realm, unsigned int *flags) { krb5_error_code ret; TGS_REQ req; size_t len; METHOD_DATA padata; padata.val = NULL; padata.len = 0; krb5_generate_random_block(&ctx->nonce, sizeof(ctx->nonce)); ctx->nonce &= 0xffffffff; if (_krb5_have_debug(context, 10)) { char *sname, *tgtname; krb5_unparse_name(context, ctx->tgt.server, &tgtname); krb5_unparse_name(context, ctx->next.server, &sname); _krb5_debugx(context, 10, "sending TGS-REQ for %s using %s", sname, tgtname); } ret = _krb5_init_tgs_req(context, ctx->ccache, ctx->addreseses, ctx->kdc_flags, ctx->impersonate_principal, NULL, &ctx->next, &ctx->tgt, ctx->nonce, &padata, &ctx->subkey, &req); if (ret) goto out; ASN1_MALLOC_ENCODE(TGS_REQ, out->data, out->length, &req, &len, ret); if (ret) goto out; if(out->length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); /* don't free addresses */ req.req_body.addresses = NULL; free_TGS_REQ(&req); *realm = ctx->tgt.server->name.name_string.val[1]; *flags |= KRB5_TKT_STATE_CONTINUE; ctx->error = 0; ctx->state = tkt_referral_recv; return 0; out: ctx->error = ret; ctx->state = NULL; return ret; }
OM_uint32 _gssapi_wrap_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int * conf_state, gss_buffer_t output_message_buffer, krb5_keyblock *key) { u_char Klocaldata[16], k6_data[16], *p, *p0; size_t len, total_len, datalen; krb5_keyblock Klocal; krb5_error_code ret; int32_t seq_number; if (conf_state) *conf_state = 0; datalen = input_message_buffer->length; if (IS_DCE_STYLE(context_handle)) { len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); total_len += datalen; } else { datalen += 1; /* padding */ len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE; _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); } output_message_buffer->length = total_len; output_message_buffer->value = malloc (total_len); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } p0 = _gssapi_make_mech_header(output_message_buffer->value, len, GSS_KRB5_MECHANISM); p = p0; *p++ = 0x02; /* TOK_ID */ *p++ = 0x01; *p++ = 0x11; /* SGN_ALG */ *p++ = 0x00; if (conf_req_flag) { *p++ = 0x10; /* SEAL_ALG */ *p++ = 0x00; } else { *p++ = 0xff; /* SEAL_ALG */ *p++ = 0xff; } *p++ = 0xff; /* Filler */ *p++ = 0xff; p = NULL; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); _gss_mg_encode_be_uint32(seq_number, p0 + 8); krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (p0 + 8 + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4); krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */ /* p points to data */ p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE; memcpy(p, input_message_buffer->value, input_message_buffer->length); if (!IS_DCE_STYLE(context_handle)) p[input_message_buffer->length] = 1; /* padding */ ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SEAL, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ p0 + 24, 8, /* Confounder */ p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); if (ret) { *minor_status = ret; _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } { int i; Klocal.keytype = key->keytype; Klocal.keyvalue.data = Klocaldata; Klocal.keyvalue.length = sizeof(Klocaldata); for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } ret = arcfour_mic_key(context, &Klocal, p0 + 8, 4, /* SND_SEQ */ k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } if(conf_req_flag) { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen); EVP_CIPHER_CTX_cleanup(&rc4_key); } memset(k6_data, 0, sizeof(k6_data)); ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } if (conf_state) *conf_state = conf_req_flag; *minor_status = 0; return GSS_S_COMPLETE; }
static krb5_error_code create_reply_ticket (krb5_context context, struct rx_header *hdr, Key *skey, char *name, char *instance, char *realm, struct sockaddr_in *addr, int life, int kvno, int32_t max_seq_len, const char *sname, const char *sinstance, uint32_t challenge, const char *label, krb5_keyblock *key, krb5_data *reply) { krb5_error_code ret; krb5_data ticket; krb5_keyblock session; krb5_storage *sp; krb5_data enc_data; struct rx_header reply_hdr; char zero[8]; size_t pad; unsigned fyrtiosjuelva; /* create the ticket */ krb5_generate_random_keyblock(context, ETYPE_DES_PCBC_NONE, &session); _krb5_krb_create_ticket(context, 0, name, instance, realm, addr->sin_addr.s_addr, &session, life, kdc_time, sname, sinstance, &skey->key, &ticket); /* create the encrypted part of the reply */ sp = krb5_storage_emem (); krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva)); fyrtiosjuelva &= 0xffffffff; krb5_store_int32 (sp, fyrtiosjuelva); krb5_store_int32 (sp, challenge); krb5_storage_write (sp, session.keyvalue.data, 8); krb5_free_keyblock_contents(context, &session); krb5_store_int32 (sp, kdc_time); krb5_store_int32 (sp, kdc_time + _krb5_krb_life_to_time (0, life)); krb5_store_int32 (sp, kvno); krb5_store_int32 (sp, ticket.length); krb5_store_stringz (sp, name); krb5_store_stringz (sp, instance); #if 1 /* XXX - Why shouldn't the realm go here? */ krb5_store_stringz (sp, ""); #else krb5_store_stringz (sp, realm); #endif krb5_store_stringz (sp, sname); krb5_store_stringz (sp, sinstance); krb5_storage_write (sp, ticket.data, ticket.length); krb5_storage_write (sp, label, strlen(label)); /* pad to DES block */ memset (zero, 0, sizeof(zero)); pad = (8 - krb5_storage_seek (sp, 0, SEEK_CUR) % 8) % 8; krb5_storage_write (sp, zero, pad); krb5_storage_to_data (sp, &enc_data); krb5_storage_free (sp); if (enc_data.length > max_seq_len) { krb5_data_free (&enc_data); make_error_reply (hdr, KAANSWERTOOLONG, reply); return 0; } /* encrypt it */ { DES_key_schedule schedule; DES_cblock deskey; memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); DES_set_key_unchecked (&deskey, &schedule); DES_pcbc_encrypt (enc_data.data, enc_data.data, enc_data.length, &schedule, &deskey, DES_ENCRYPT); memset (&schedule, 0, sizeof(schedule)); memset (&deskey, 0, sizeof(deskey)); } /* create the reply packet */ init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST); sp = krb5_storage_emem (); ret = encode_rx_header (&reply_hdr, sp); krb5_store_int32 (sp, max_seq_len); krb5_store_xdr_data (sp, enc_data); krb5_data_free (&enc_data); krb5_storage_to_data (sp, reply); krb5_storage_free (sp); return 0; }
static krb5_error_code get_cred_kdc_usage(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, krb5_addresses *addresses, krb5_creds *in_creds, krb5_creds *krbtgt, krb5_creds *out_creds, krb5_key_usage usage) { TGS_REQ req; krb5_data enc; krb5_data resp; krb5_kdc_rep rep; KRB_ERROR error; krb5_error_code ret; unsigned nonce; krb5_keyblock *subkey = NULL; size_t len; Ticket second_ticket; int send_to_kdc_flags = 0; krb5_data_zero(&resp); krb5_data_zero(&enc); krb5_generate_random_block(&nonce, sizeof(nonce)); nonce &= 0xffffffff; if(flags.b.enc_tkt_in_skey){ ret = decode_Ticket(in_creds->second_ticket.data, in_creds->second_ticket.length, &second_ticket, &len); if(ret) return ret; } ret = init_tgs_req (context, id, addresses, flags, flags.b.enc_tkt_in_skey ? &second_ticket : NULL, in_creds, krbtgt, nonce, &subkey, &req, usage); if(flags.b.enc_tkt_in_skey) free_Ticket(&second_ticket); if (ret) goto out; ASN1_MALLOC_ENCODE(TGS_REQ, enc.data, enc.length, &req, &len, ret); if (ret) goto out; if(enc.length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); /* don't free addresses */ req.req_body.addresses = NULL; free_TGS_REQ(&req); /* * Send and receive */ again: ret = krb5_sendto_kdc_flags (context, &enc, &krbtgt->server->name.name_string.val[1], &resp, send_to_kdc_flags); if(ret) goto out; memset(&rep, 0, sizeof(rep)); if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0){ ret = krb5_copy_principal(context, in_creds->client, &out_creds->client); if(ret) goto out; ret = krb5_copy_principal(context, in_creds->server, &out_creds->server); if(ret) goto out; /* this should go someplace else */ out_creds->times.endtime = in_creds->times.endtime; ret = _krb5_extract_ticket(context, &rep, out_creds, &krbtgt->session, NULL, KRB5_KU_TGS_REP_ENC_PART_SESSION, &krbtgt->addresses, nonce, TRUE, flags.b.request_anonymous, decrypt_tkt_with_subkey, subkey); krb5_free_kdc_rep(context, &rep); } else if(krb5_rd_error(context, &resp, &error) == 0) { ret = krb5_error_from_rd_error(context, &error, in_creds); krb5_free_error_contents(context, &error); if (ret == KRB5KRB_ERR_RESPONSE_TOO_BIG && !(send_to_kdc_flags & KRB5_KRBHST_FLAGS_LARGE_MSG)) { send_to_kdc_flags |= KRB5_KRBHST_FLAGS_LARGE_MSG; krb5_data_free(&resp); goto again; } } else if(resp.data && ((char*)resp.data)[0] == 4) { ret = KRB5KRB_AP_ERR_V4_REPLY; krb5_clear_error_string(context); } else { ret = KRB5KRB_AP_ERR_MSG_TYPE; krb5_clear_error_string(context); } out: krb5_data_free(&resp); krb5_data_free(&enc); if(subkey){ krb5_free_keyblock_contents(context, subkey); free(subkey); } return ret; }
int create_and_write_cookie (char *file, size_t file_size, u_char *cookie_buf, size_t cookie_sz) { Xauth auth; char tmp[64]; int fd; FILE *f; char hostname[MaxHostNameLen]; int saved_errno; gethostname (hostname, sizeof(hostname)); auth.family = FamilyLocal; auth.address = hostname; auth.address_length = strlen(auth.address); snprintf (tmp, sizeof(tmp), "%d", display_num); auth.number_length = strlen(tmp); auth.number = tmp; auth.name = COOKIE_TYPE; auth.name_length = strlen(auth.name); auth.data_length = cookie_sz; auth.data = (char*)cookie_buf; #ifdef KRB5 krb5_generate_random_block (cookie_buf, cookie_sz); #else krb_generate_random_block (cookie_buf, cookie_sz); #endif strlcpy(file, "/tmp/AXXXXXX", file_size); fd = mkstemp(file); if(fd < 0) { saved_errno = errno; syslog(LOG_ERR, "create_and_write_cookie: mkstemp: %m"); return saved_errno; } f = fdopen(fd, "r+"); if(f == NULL){ saved_errno = errno; close(fd); return errno; } if(XauWriteAuth(f, &auth) == 0) { saved_errno = errno; fclose(f); return saved_errno; } /* * I would like to write a cookie for localhost:n here, but some * stupid code in libX11 will not look for cookies of that type, * so we are forced to use FamilyWild instead. */ auth.family = FamilyWild; auth.address_length = 0; if (XauWriteAuth(f, &auth) == 0) { saved_errno = errno; fclose (f); return saved_errno; } if(fclose(f)) return errno; return 0; }
krb5_error_code KRB5_LIB_FUNCTION krb5_get_in_cred(krb5_context context, krb5_flags options, const krb5_addresses *addrs, const krb5_enctype *etypes, const krb5_preauthtype *ptypes, const krb5_preauthdata *preauth, krb5_key_proc key_proc, krb5_const_pointer keyseed, krb5_decrypt_proc decrypt_proc, krb5_const_pointer decryptarg, krb5_creds *creds, krb5_kdc_rep *ret_as_reply) { krb5_error_code ret; AS_REQ a; krb5_kdc_rep rep; krb5_data req, resp; size_t len; krb5_salt salt; krb5_keyblock *key; size_t size; KDCOptions opts; PA_DATA *pa; krb5_enctype etype; krb5_preauthdata *my_preauth = NULL; unsigned nonce; int done; opts = int2KDCOptions(options); krb5_generate_random_block (&nonce, sizeof(nonce)); nonce &= 0xffffffff; do { done = 1; ret = init_as_req (context, opts, creds, addrs, etypes, ptypes, preauth, key_proc, keyseed, nonce, &a); if (my_preauth) { free_ETYPE_INFO(&my_preauth->val[0].info); free (my_preauth->val); my_preauth = NULL; } if (ret) return ret; ASN1_MALLOC_ENCODE(AS_REQ, req.data, req.length, &a, &len, ret); free_AS_REQ(&a); if (ret) return ret; if(len != req.length) krb5_abortx(context, "internal error in ASN.1 encoder"); ret = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp); krb5_data_free(&req); if (ret) return ret; memset (&rep, 0, sizeof(rep)); ret = decode_AS_REP(resp.data, resp.length, &rep.kdc_rep, &size); if(ret) { /* let's try to parse it as a KRB-ERROR */ KRB_ERROR error; int ret2; ret2 = krb5_rd_error(context, &resp, &error); if(ret2 && resp.data && ((char*)resp.data)[0] == 4) ret = KRB5KRB_AP_ERR_V4_REPLY; krb5_data_free(&resp); if (ret2 == 0) { ret = krb5_error_from_rd_error(context, &error, creds); /* if no preauth was set and KDC requires it, give it one more try */ if (!ptypes && !preauth && ret == KRB5KDC_ERR_PREAUTH_REQUIRED #if 0 || ret == KRB5KDC_ERR_BADOPTION #endif && set_ptypes(context, &error, &ptypes, &my_preauth)) { done = 0; preauth = my_preauth; krb5_free_error_contents(context, &error); krb5_clear_error_string(context); continue; } if(ret_as_reply) ret_as_reply->error = error; else free_KRB_ERROR (&error); return ret; } return ret; } krb5_data_free(&resp); } while(!done); pa = NULL; etype = rep.kdc_rep.enc_part.etype; if(rep.kdc_rep.padata){ int i = 0; pa = krb5_find_padata(rep.kdc_rep.padata->val, rep.kdc_rep.padata->len, KRB5_PADATA_PW_SALT, &i); if(pa == NULL) { i = 0; pa = krb5_find_padata(rep.kdc_rep.padata->val, rep.kdc_rep.padata->len, KRB5_PADATA_AFS3_SALT, &i); } } if(pa) { salt.salttype = pa->padata_type; salt.saltvalue = pa->padata_value; ret = (*key_proc)(context, etype, salt, keyseed, &key); } else { /* make a v5 salted pa-data */ ret = krb5_get_pw_salt (context, creds->client, &salt); if (ret) goto out; ret = (*key_proc)(context, etype, salt, keyseed, &key); krb5_free_salt(context, salt); } if (ret) goto out; { unsigned flags = 0; if (opts.request_anonymous) flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; ret = _krb5_extract_ticket(context, &rep, creds, key, keyseed, KRB5_KU_AS_REP_ENC_PART, NULL, nonce, flags, decrypt_proc, decryptarg); } memset (key->keyvalue.data, 0, key->keyvalue.length); krb5_free_keyblock_contents (context, key); free (key); out: if (ret == 0 && ret_as_reply) *ret_as_reply = rep; else krb5_free_kdc_rep (context, &rep); return ret; }