boolean ber_read_integer(STREAM* s, uint32* value) { int length; ber_read_universal_tag(s, BER_TAG_INTEGER, false); ber_read_length(s, &length); if (value == NULL) { stream_seek(s, length); return true; } if (length == 1) stream_read_uint8(s, *value); else if (length == 2) stream_read_uint16_be(s, *value); else if (length == 3) { uint8 byte; stream_read_uint8(s, byte); stream_read_uint16_be(s, *value); *value += (byte << 16); } else if (length == 4) stream_read_uint32_be(s, *value); else return false; return true; }
int krb_tgsrep_recv(KRB_CONTEXT* krb_ctx) { int totlen, tmp, len; int errcode; STREAM* s; KrbTGSREP* krb_tgsrep; KrbKDCREP* kdc_rep; errcode = -1; s = stream_new(2048); krb_tcp_recv(krb_ctx, s->data, s->size); stream_read_uint32_be(s, totlen); if(totlen >= 2044) // MALFORMED PACKET goto finish; if(((len = krb_decode_application_tag(s, KRB_TAG_TGSREP, &tmp)) == 0) || (tmp != (totlen - len))) //NOT AN TGS-REP { krb_ctx->state = KRB_PACKET_ERROR; goto finish; } else /* TGS-REP process */ { totlen -= len; krb_tgsrep = xnew(KrbTGSREP); krb_ctx->tgskey = xnew(KrbENCKey); if(krb_decode_kdc_rep(s, &(krb_tgsrep->kdc_rep), totlen) == 0) { krb_ctx->state = KRB_PACKET_ERROR; goto finish; } kdc_rep = &(krb_tgsrep->kdc_rep); if(krb_verify_kdcrep(krb_ctx, kdc_rep, KRB_TAG_TGSREP) == 0) krb_ctx->state = KRB_TGSREP_OK; else krb_ctx->state = KRB_PACKET_ERROR; /* clean up */ krb_free_tgsrep(krb_tgsrep); xfree(krb_tgsrep); goto finish; } finish: stream_free(s); return errcode; }
int krb_asrep_recv(KRB_CONTEXT* krb_ctx) { int totlen, tmp, len; int errcode; STREAM* s; KrbERROR* krb_err; KrbASREP* krb_asrep; KrbKDCREP* kdc_rep; errcode = -1; s = stream_new(2048); krb_tcp_recv(krb_ctx, s->data, s->size); stream_read_uint32_be(s, totlen); if(totlen >= 2044) // MALFORMED PACKET goto finish; if(((len = krb_decode_application_tag(s, KRB_TAG_ASREP, &tmp)) == 0) || (tmp != (totlen - len))) //NOT AN AS-REP { if(((len = krb_decode_application_tag(s, KRB_TAG_ERROR, &tmp)) == 0) || (tmp != (totlen - len))) // NOT AN KRB-ERROR { krb_ctx->state = KRB_PACKET_ERROR; goto finish; } else { totlen -= len; krb_err = xnew(KrbERROR); if((totlen <= 0) || ((len = krb_decode_krb_error(s, krb_err, totlen)) == 0)) { krb_ctx->state = KRB_PACKET_ERROR; xfree(krb_err); goto finish; } /* ERROR CODE */ errcode = krb_err->errcode; if(errcode == KRB_AP_ERR_SKEW) { krb_ctx->state = KRB_ASREP_ERR; goto errclean; } else if(errcode == KDC_ERR_PREAUTH_REQ) { /* should parse PA-ENC-TYPE-INFO2 */ krb_ctx->state = KRB_ASREP_ERR; goto errclean; } else if(errcode == KDC_ERR_C_PRINCIPAL_UNKNOWN) { printf("KDC_ERR_C_PRINCIPAL_UNKNOWN\n"); krb_ctx->state = KRB_ASREP_ERR; goto errclean; } else { krb_ctx->state = KRB_PACKET_ERROR; goto errclean; } errclean: krb_free_krb_error(krb_err); xfree(krb_err); goto finish; } } else /* AS-REP process */ { totlen -= len; krb_asrep = xnew(KrbASREP); if(krb_decode_kdc_rep(s, &(krb_asrep->kdc_rep), totlen) == 0) { krb_ctx->state = KRB_PACKET_ERROR; goto finish; } kdc_rep = &(krb_asrep->kdc_rep); if(krb_verify_kdcrep(krb_ctx, kdc_rep, KRB_TAG_ASREP) == 0) krb_ctx->state = KRB_ASREP_OK; else krb_ctx->state = KRB_PACKET_ERROR; /* clean up */ krb_free_asrep(krb_asrep); xfree(krb_asrep); goto finish; } finish: stream_free(s); return errcode; }