libwinpr-sspi: cleanup of data types
This commit is contained in:
parent
9fd0d13a1c
commit
45009824be
@ -50,6 +50,11 @@ wchar_t* _wcsdup(const wchar_t* strSource)
|
||||
|
||||
#if sun
|
||||
strDestination = wsdup(strSource);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
strDestination = malloc(wcslen(strSource));
|
||||
|
||||
if (strDestination != NULL)
|
||||
wcscpy(strDestination, strSource);
|
||||
#else
|
||||
strDestination = wcsdup(strSource);
|
||||
#endif
|
||||
|
@ -370,7 +370,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
|
||||
int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
{
|
||||
uint32 cbMaxToken;
|
||||
UINT32 cbMaxToken;
|
||||
ULONG fContextReq;
|
||||
ULONG pfContextAttr;
|
||||
SECURITY_STATUS status;
|
||||
@ -708,24 +708,24 @@ void credssp_read_ts_password_creds(rdpCredssp* credssp, STREAM* s)
|
||||
/* [0] domainName (OCTET STRING) */
|
||||
ber_read_contextual_tag(s, 0, &length, true);
|
||||
ber_read_octet_string_tag(s, &length);
|
||||
credssp->identity.DomainLength = (uint32) length;
|
||||
credssp->identity.Domain = (uint16*) malloc(length);
|
||||
credssp->identity.DomainLength = (UINT32) length;
|
||||
credssp->identity.Domain = (UINT16*) malloc(length);
|
||||
CopyMemory(credssp->identity.Domain, s->p, credssp->identity.DomainLength);
|
||||
stream_seek(s, credssp->identity.DomainLength);
|
||||
|
||||
/* [1] userName (OCTET STRING) */
|
||||
ber_read_contextual_tag(s, 1, &length, true);
|
||||
ber_read_octet_string_tag(s, &length);
|
||||
credssp->identity.UserLength = (uint32) length;
|
||||
credssp->identity.User = (uint16*) malloc(length);
|
||||
credssp->identity.UserLength = (UINT32) length;
|
||||
credssp->identity.User = (UINT16*) malloc(length);
|
||||
CopyMemory(credssp->identity.User, s->p, credssp->identity.UserLength);
|
||||
stream_seek(s, credssp->identity.UserLength);
|
||||
|
||||
/* [2] password (OCTET STRING) */
|
||||
ber_read_contextual_tag(s, 2, &length, true);
|
||||
ber_read_octet_string_tag(s, &length);
|
||||
credssp->identity.PasswordLength = (uint32) length;
|
||||
credssp->identity.Password = (uint16*) malloc(length);
|
||||
credssp->identity.PasswordLength = (UINT32) length;
|
||||
credssp->identity.Password = (UINT16*) malloc(length);
|
||||
CopyMemory(credssp->identity.Password, s->p, credssp->identity.PasswordLength);
|
||||
stream_seek(s, credssp->identity.PasswordLength);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ char* KRB_PACKAGE_NAME = "Kerberos";
|
||||
boolean tcp_is_ipaddr(const char* hostname)
|
||||
{
|
||||
char* s;
|
||||
uint8 dotcnt, digcnt;
|
||||
BYTE dotcnt, digcnt;
|
||||
char val;
|
||||
s = (char*)hostname;
|
||||
dotcnt = digcnt = 0;
|
||||
@ -115,7 +115,7 @@ time_t get_clock_skew(char* str)
|
||||
char* get_dns_queryname(char *host, char* protocol)
|
||||
{
|
||||
char* qname;
|
||||
uint32 buflen;
|
||||
UINT32 buflen;
|
||||
buflen = 0;
|
||||
|
||||
if(protocol)
|
||||
@ -255,12 +255,12 @@ int krb_tcp_connect(KRB_CONTEXT* krb_ctx, KDCENTRY* entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int krb_tcp_recv(KRB_CONTEXT* krb_ctx, uint8* data, uint32 length)
|
||||
int kerberos_tcp_recv(KRB_CONTEXT* krb_ctx, BYTE* data, UINT32 length)
|
||||
{
|
||||
return freerdp_tcp_read(krb_ctx->ksockfd, data, length);
|
||||
}
|
||||
|
||||
int krb_tcp_send(KRB_CONTEXT* krb_ctx, uint8* data, uint32 length)
|
||||
int krb_tcp_send(KRB_CONTEXT* krb_ctx, BYTE* data, UINT32 length)
|
||||
{
|
||||
return freerdp_tcp_write(krb_ctx->ksockfd, data, length);
|
||||
}
|
||||
@ -273,9 +273,8 @@ KRB_CONTEXT* kerberos_ContextNew()
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
context->enctype = ETYPE_RC4_HMAC; //choose enc type
|
||||
context->enctype = ETYPE_RC4_HMAC;
|
||||
context->state = KRB_STATE_INITIAL;
|
||||
context->uniconv = freerdp_uniconv_new();
|
||||
}
|
||||
|
||||
return context;
|
||||
@ -468,16 +467,16 @@ SECURITY_STATUS SEC_ENTRY kerberos_InitializeSecurityContextA(PCredHandle phCred
|
||||
break;
|
||||
case KRB_STATE_INITIAL:
|
||||
case KRB_ASREP_ERR:
|
||||
krb_asreq_send(krb_ctx, errcode);
|
||||
kerberos_asreq_send(krb_ctx, errcode);
|
||||
break;
|
||||
case KRB_ASREQ_OK:
|
||||
errcode = krb_asrep_recv(krb_ctx);
|
||||
errcode = kerberos_asrep_recv(krb_ctx);
|
||||
break;
|
||||
case KRB_ASREP_OK:
|
||||
krb_tgsreq_send(krb_ctx, 0);
|
||||
kerberos_tgsreq_send(krb_ctx, 0);
|
||||
break;
|
||||
case KRB_TGSREQ_OK:
|
||||
krb_tgsrep_recv(krb_ctx);
|
||||
kerberos_tgsrep_recv(krb_ctx);
|
||||
break;
|
||||
case KRB_TGSREP_OK:
|
||||
return SEC_I_COMPLETE_AND_CONTINUE;
|
||||
@ -539,17 +538,17 @@ PCtxtHandle krbctx_client_init(rdpSettings* settings, SEC_WINNT_AUTH_IDENTITY* i
|
||||
status = kerberos_InitializeSecurityContextA(NULL, &krb_ctx->context, NULL,
|
||||
fContextReq, 0, SECURITY_NATIVE_DREP, NULL, 0, &krb_ctx->context, NULL, &pfContextAttr, &expiration);
|
||||
|
||||
if(status == SEC_E_INVALID_HANDLE)
|
||||
if (status == SEC_E_INVALID_HANDLE)
|
||||
{
|
||||
printf("failed to init kerberos\n");
|
||||
return NULL;
|
||||
}
|
||||
else if(status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
else if (status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
{
|
||||
printf("successfully obtained ticket for TERMSRV\n");
|
||||
return &krb_ctx->context;
|
||||
}
|
||||
else if(status == -1)
|
||||
else if (status == -1)
|
||||
{
|
||||
printf("deadend \n ");
|
||||
return NULL;
|
||||
@ -561,7 +560,7 @@ PCtxtHandle krbctx_client_init(rdpSettings* settings, SEC_WINNT_AUTH_IDENTITY* i
|
||||
}
|
||||
}
|
||||
|
||||
void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
void kerberos_asreq_send(KRB_CONTEXT* context, BYTE errcode)
|
||||
{
|
||||
KrbASREQ* krb_asreq;
|
||||
PAData** pa_data;
|
||||
@ -571,11 +570,11 @@ void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
STREAM* paenc;
|
||||
rdpBlob msg;
|
||||
rdpBlob* encmsg;
|
||||
uint32 curlen, totlen, pai;
|
||||
uint8 *bm;
|
||||
UINT32 curlen, totlen, pai;
|
||||
BYTE *bm;
|
||||
bm = NULL;
|
||||
totlen = pai = 0;
|
||||
krb_asreq = krb_asreq_new(krb_ctx, errcode);
|
||||
krb_asreq = kerberos_asreq_new(context, errcode);
|
||||
pa_data = krb_asreq->padata;
|
||||
enckey = NULL;
|
||||
s = stream_new(2048);
|
||||
@ -586,22 +585,22 @@ void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
stream_seek(paenc, 99);
|
||||
|
||||
/* KDC-REQ-BODY (TAG 4) */
|
||||
totlen += krb_encode_req_body(s, &(krb_asreq->req_body), krb_asreq->type);
|
||||
totlen += krb_encode_contextual_tag(s, 4, totlen);
|
||||
totlen += kerberos_encode_req_body(s, &(krb_asreq->req_body), krb_asreq->type);
|
||||
totlen += kerberos_encode_contextual_tag(s, 4, totlen);
|
||||
|
||||
/* padata = PA-ENC-TIMESTAMP */
|
||||
if(errcode != 0)
|
||||
if (errcode != 0)
|
||||
{
|
||||
freerdp_blob_alloc(&msg, 21);
|
||||
memcpy(msg.data, "\x30\x13\xa0\x11\x18\x0f", 6); // PA-ENC-TS-ENC without optional pausec
|
||||
memcpy(((uint8*) msg.data) + 6, krb_asreq->req_body.from, 15);
|
||||
enckey = string2key(&(krb_ctx->passwd), krb_ctx->enctype);
|
||||
memcpy(((BYTE*) msg.data) + 6, krb_asreq->req_body.from, 15);
|
||||
enckey = string2key(&(context->passwd), context->enctype);
|
||||
encmsg = crypto_kdcmsg_encrypt(&msg, enckey, 1); //RFC4757 section 3 for msgtype (T=1)
|
||||
enc_data.enctype = enckey->enctype;
|
||||
enc_data.kvno = -1;
|
||||
enc_data.encblob.data = encmsg->data;
|
||||
enc_data.encblob.length = encmsg->length;
|
||||
curlen = krb_encode_encrypted_data(paenc, &enc_data);
|
||||
curlen = kerberos_encode_encrypted_data(paenc, &enc_data);
|
||||
freerdp_blob_free(&msg);
|
||||
msg.data = paenc->p;
|
||||
msg.length = curlen;
|
||||
@ -616,7 +615,7 @@ void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
|
||||
freerdp_blob_alloc(&msg, 7);
|
||||
memcpy(msg.data, "\x30\x05\xa0\03\x01\x01", 6); // asn1 data
|
||||
*((uint8*)msg.data + 6) = krb_asreq->pa_pac_request;
|
||||
*((BYTE*)msg.data + 6) = krb_asreq->pa_pac_request;
|
||||
|
||||
/* padata = PA-PAC-REQUEST */
|
||||
(*(pa_data + pai))->type = 128;
|
||||
@ -625,29 +624,29 @@ void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
*(pa_data + ++pai) = NULL;
|
||||
|
||||
/* padata (TAG 3) */
|
||||
curlen = krb_encode_padata(s, pa_data);
|
||||
totlen += curlen + krb_encode_contextual_tag(s, 3, curlen);
|
||||
curlen = kerberos_encode_padata(s, pa_data);
|
||||
totlen += curlen + kerberos_encode_contextual_tag(s, 3, curlen);
|
||||
|
||||
/* MSGTYPE = AS-REQ (TAG 2) */
|
||||
totlen += krb_encode_uint8(s, 2, krb_asreq->type);
|
||||
totlen += kerberos_encode_uint8(s, 2, krb_asreq->type);
|
||||
|
||||
/* KERBEROS PROTOCOL VERSION NO (TAG 1)*/
|
||||
totlen += krb_encode_uint8(s, 1, krb_asreq->pvno);
|
||||
totlen += kerberos_encode_uint8(s, 1, krb_asreq->pvno);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += krb_encode_application_tag(s, krb_asreq->type, totlen);
|
||||
totlen += krb_encode_recordmark(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_application_tag(s, krb_asreq->type, totlen);
|
||||
totlen += kerberos_encode_recordmark(s, totlen);
|
||||
|
||||
/* READY SEND */
|
||||
krb_tcp_send(krb_ctx, s->p, totlen);
|
||||
krb_tcp_send(context, s->p, totlen);
|
||||
|
||||
/* save stuff */
|
||||
krb_ctx->askey = enckey;
|
||||
krb_ctx->nonce = krb_asreq->req_body.nonce;
|
||||
free(krb_ctx->sname);
|
||||
krb_ctx->sname = xstrdup(krb_asreq->req_body.sname);
|
||||
krb_ctx->ctime = get_local_time(krb_asreq->req_body.from);
|
||||
krb_ctx->state = KRB_ASREQ_OK;
|
||||
context->askey = enckey;
|
||||
context->nonce = krb_asreq->req_body.nonce;
|
||||
free(context->sname);
|
||||
context->sname = xstrdup(krb_asreq->req_body.sname);
|
||||
context->ctime = get_local_time(krb_asreq->req_body.from);
|
||||
context->state = KRB_ASREQ_OK;
|
||||
|
||||
/* clean up */
|
||||
freerdp_blob_free(&msg);
|
||||
@ -657,7 +656,7 @@ void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
free(krb_asreq);
|
||||
}
|
||||
|
||||
int krb_asrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
int kerberos_asrep_recv(KRB_CONTEXT* context)
|
||||
{
|
||||
int totlen, tmp, len;
|
||||
int errcode;
|
||||
@ -667,17 +666,18 @@ int krb_asrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
KrbKDCREP* kdc_rep;
|
||||
errcode = -1;
|
||||
s = stream_new(2048);
|
||||
krb_tcp_recv(krb_ctx, s->data, s->size);
|
||||
kerberos_tcp_recv(context, s->data, s->size);
|
||||
|
||||
stream_read_uint32_be(s, totlen);
|
||||
if(totlen >= 2044) // MALFORMED PACKET
|
||||
|
||||
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_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
|
||||
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;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
goto finish;
|
||||
}
|
||||
else
|
||||
@ -685,35 +685,35 @@ int krb_asrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
totlen -= len;
|
||||
krb_err = xnew(KrbERROR);
|
||||
|
||||
if((totlen <= 0) || ((len = krb_decode_krb_error(s, krb_err, totlen)) == 0))
|
||||
if ((totlen <= 0) || ((len = krb_decode_krb_error(s, krb_err, totlen)) == 0))
|
||||
{
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
free(krb_err);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* ERROR CODE */
|
||||
errcode = krb_err->errcode;
|
||||
if(errcode == KRB_AP_ERR_SKEW)
|
||||
if (errcode == KRB_AP_ERR_SKEW)
|
||||
{
|
||||
krb_ctx->state = KRB_ASREP_ERR;
|
||||
context->state = KRB_ASREP_ERR;
|
||||
goto errclean;
|
||||
}
|
||||
else if(errcode == KDC_ERR_PREAUTH_REQ)
|
||||
else if (errcode == KDC_ERR_PREAUTH_REQ)
|
||||
{
|
||||
/* should parse PA-ENC-TYPE-INFO2 */
|
||||
krb_ctx->state = KRB_ASREP_ERR;
|
||||
context->state = KRB_ASREP_ERR;
|
||||
goto errclean;
|
||||
}
|
||||
else if(errcode == KDC_ERR_C_PRINCIPAL_UNKNOWN)
|
||||
else if (errcode == KDC_ERR_C_PRINCIPAL_UNKNOWN)
|
||||
{
|
||||
printf("KDC_ERR_C_PRINCIPAL_UNKNOWN\n");
|
||||
krb_ctx->state = KRB_ASREP_ERR;
|
||||
context->state = KRB_ASREP_ERR;
|
||||
goto errclean;
|
||||
}
|
||||
else
|
||||
{
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
goto errclean;
|
||||
}
|
||||
errclean:
|
||||
@ -727,18 +727,18 @@ int krb_asrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
totlen -= len;
|
||||
|
||||
krb_asrep = xnew(KrbASREP);
|
||||
if(krb_decode_kdc_rep(s, &(krb_asrep->kdc_rep), totlen) == 0)
|
||||
if (krb_decode_kdc_rep(s, &(krb_asrep->kdc_rep), totlen) == 0)
|
||||
{
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
xfree(krb_asrep);
|
||||
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;
|
||||
if (kerberos_verify_kdcrep(context, kdc_rep, KRB_TAG_ASREP) == 0)
|
||||
context->state = KRB_ASREP_OK;
|
||||
else
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
|
||||
/* clean up */
|
||||
kerberos_free_asrep(krb_asrep);
|
||||
@ -750,7 +750,7 @@ int krb_asrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
return errcode;
|
||||
}
|
||||
|
||||
void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
void kerberos_tgsreq_send(KRB_CONTEXT* context, BYTE errcode)
|
||||
{
|
||||
KrbTGSREQ* krb_tgsreq;
|
||||
KrbAPREQ* krb_apreq;
|
||||
@ -759,11 +759,11 @@ void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
STREAM* s;
|
||||
STREAM* sapreq;
|
||||
rdpBlob msg;
|
||||
uint32 curlen, totlen, tmp;
|
||||
uint8 *bm;
|
||||
UINT32 curlen, totlen, tmp;
|
||||
BYTE *bm;
|
||||
bm = NULL;
|
||||
totlen = tmp = 0;
|
||||
krb_tgsreq = krb_tgsreq_new(krb_ctx, errcode);
|
||||
krb_tgsreq = kerberos_tgsreq_new(context, errcode);
|
||||
krb_auth = xnew(Authenticator);
|
||||
pa_data = krb_tgsreq->padata;
|
||||
s = stream_new(4096);
|
||||
@ -774,27 +774,27 @@ void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
stream_seek(sapreq, 2047);
|
||||
|
||||
/* KDC-REQ-BODY (TAG 4) */
|
||||
totlen += krb_encode_req_body(s, &(krb_tgsreq->req_body), krb_tgsreq->type);
|
||||
totlen += kerberos_encode_req_body(s, &(krb_tgsreq->req_body), krb_tgsreq->type);
|
||||
stream_get_mark(s, bm);
|
||||
tmp = totlen;
|
||||
totlen += krb_encode_contextual_tag(s, 4, totlen);
|
||||
totlen += kerberos_encode_contextual_tag(s, 4, totlen);
|
||||
|
||||
msg.data = bm;
|
||||
msg.length = tmp;
|
||||
|
||||
/* Authenticator */
|
||||
krb_auth->avno = KRB_VERSION;
|
||||
krb_auth->cname = krb_ctx->cname;
|
||||
krb_auth->crealm = krb_ctx->realm;
|
||||
krb_auth->cksumtype = get_cksum_type(krb_ctx->enctype);
|
||||
krb_auth->cksum = crypto_kdcmsg_cksum(&msg, krb_ctx->askey, 6); //RFC4757 section 3 for msgtype (T=6)
|
||||
krb_auth->cname = context->cname;
|
||||
krb_auth->crealm = context->realm;
|
||||
krb_auth->cksumtype = get_cksum_type(context->enctype);
|
||||
krb_auth->cksum = crypto_kdcmsg_cksum(&msg, context->askey, 6); //RFC4757 section 3 for msgtype (T=6)
|
||||
krb_auth->ctime = krb_tgsreq->req_body.from;
|
||||
krb_auth->cusec = 0;
|
||||
crypto_nonce((uint8*)&(krb_auth->seqno), 4);
|
||||
crypto_nonce((BYTE*)&(krb_auth->seqno), 4);
|
||||
|
||||
/* PA-TGS-REQ */
|
||||
krb_apreq = krb_apreq_new(krb_ctx, &(krb_ctx->asticket), krb_auth);
|
||||
curlen = krb_encode_apreq(sapreq, krb_apreq);
|
||||
krb_apreq = kerberos_apreq_new(context, &(context->asticket), krb_auth);
|
||||
curlen = kerberos_encode_apreq(sapreq, krb_apreq);
|
||||
xfree(krb_apreq) ;
|
||||
|
||||
msg.data = sapreq->p;
|
||||
@ -803,28 +803,28 @@ void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
(*pa_data)->value = msg;
|
||||
|
||||
/* PA-DATA (TAG 3) */
|
||||
curlen = krb_encode_padata(s, pa_data);
|
||||
totlen += curlen + krb_encode_contextual_tag(s, 3, curlen);
|
||||
curlen = kerberos_encode_padata(s, pa_data);
|
||||
totlen += curlen + kerberos_encode_contextual_tag(s, 3, curlen);
|
||||
|
||||
/* MSGTYPE (TAG 2) */
|
||||
totlen += krb_encode_uint8(s, 2, krb_tgsreq->type);
|
||||
totlen += kerberos_encode_uint8(s, 2, krb_tgsreq->type);
|
||||
|
||||
/* VERSION NO (TAG 1) */
|
||||
totlen += krb_encode_uint8(s, 1, krb_tgsreq->pvno);
|
||||
totlen += kerberos_encode_uint8(s, 1, krb_tgsreq->pvno);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += krb_encode_application_tag(s, krb_tgsreq->type, totlen);
|
||||
totlen += krb_encode_recordmark(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_application_tag(s, krb_tgsreq->type, totlen);
|
||||
totlen += kerberos_encode_recordmark(s, totlen);
|
||||
|
||||
/* READY SEND */
|
||||
krb_tcp_send(krb_ctx, s->p, totlen);
|
||||
krb_tcp_send(context, s->p, totlen);
|
||||
|
||||
/* save stuff */
|
||||
krb_ctx->nonce = krb_tgsreq->req_body.nonce;
|
||||
free(krb_ctx->sname);
|
||||
krb_ctx->sname = xstrdup(krb_tgsreq->req_body.sname);
|
||||
krb_ctx->ctime = get_local_time(krb_tgsreq->req_body.from);
|
||||
krb_ctx->state = KRB_TGSREQ_OK;
|
||||
context->nonce = krb_tgsreq->req_body.nonce;
|
||||
free(context->sname);
|
||||
context->sname = xstrdup(krb_tgsreq->req_body.sname);
|
||||
context->ctime = get_local_time(krb_tgsreq->req_body.from);
|
||||
context->state = KRB_TGSREQ_OK;
|
||||
|
||||
/* clean up */
|
||||
freerdp_blob_free(krb_auth->cksum);
|
||||
@ -836,7 +836,7 @@ void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
stream_free(s);
|
||||
}
|
||||
|
||||
int krb_tgsrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
int kerberos_tgsrep_recv(KRB_CONTEXT* context)
|
||||
{
|
||||
int totlen, tmp, len;
|
||||
int errcode;
|
||||
@ -845,15 +845,16 @@ int krb_tgsrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
KrbKDCREP* kdc_rep;
|
||||
errcode = -1;
|
||||
s = stream_new(2048);
|
||||
krb_tcp_recv(krb_ctx, s->data, s->size);
|
||||
kerberos_tcp_recv(context, s->data, s->size);
|
||||
|
||||
stream_read_uint32_be(s, totlen);
|
||||
if(totlen >= 2044) // MALFORMED PACKET
|
||||
|
||||
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
|
||||
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;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
goto finish;
|
||||
}
|
||||
else /* TGS-REP process */
|
||||
@ -861,19 +862,19 @@ int krb_tgsrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
totlen -= len;
|
||||
|
||||
krb_tgsrep = xnew(KrbTGSREP);
|
||||
krb_ctx->tgskey = xnew(KrbENCKey);
|
||||
context->tgskey = xnew(KrbENCKey);
|
||||
if(krb_decode_kdc_rep(s, &(krb_tgsrep->kdc_rep), totlen) == 0)
|
||||
{
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
xfree(krb_tgsrep);
|
||||
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;
|
||||
if(kerberos_verify_kdcrep(context, kdc_rep, KRB_TAG_TGSREP) == 0)
|
||||
context->state = KRB_TGSREP_OK;
|
||||
else
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
|
||||
/* clean up */
|
||||
kerberos_free_tgsrep(krb_tgsrep);
|
||||
@ -885,63 +886,64 @@ int krb_tgsrep_recv(KRB_CONTEXT* krb_ctx)
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int krb_verify_kdcrep(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep, int msgtype)
|
||||
int kerberos_verify_kdcrep(KRB_CONTEXT* context, KrbKDCREP* kdc_rep, int msgtype)
|
||||
{
|
||||
ENCKDCREPPart* reppart;
|
||||
KrbENCKey* key;
|
||||
rdpBlob* decmsg;
|
||||
uint8 tag;
|
||||
BYTE tag;
|
||||
tag = 0;
|
||||
key = NULL;
|
||||
|
||||
/* Verify everything */
|
||||
if((kdc_rep->pvno != KRB_VERSION) || (kdc_rep->type != msgtype) || strcasecmp(kdc_rep->cname, krb_ctx->cname) || strcasecmp(kdc_rep->realm, krb_ctx->realm))
|
||||
if ((kdc_rep->pvno != KRB_VERSION) || (kdc_rep->type != msgtype) || strcasecmp(kdc_rep->cname, context->cname) || strcasecmp(kdc_rep->realm, context->realm))
|
||||
{
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
return -1;
|
||||
}
|
||||
/* decrypt enc-part */
|
||||
if(krb_ctx->askey->enctype != kdc_rep->enc_part.enctype && msgtype == KRB_TAG_ASREP)
|
||||
{
|
||||
freerdp_blob_free(&(krb_ctx->askey->skey));
|
||||
free(krb_ctx->askey);
|
||||
krb_ctx->askey = string2key(&(krb_ctx->passwd), kdc_rep->enc_part.enctype);
|
||||
}
|
||||
krb_ctx->askey->enctype = kdc_rep->enc_part.enctype;
|
||||
decmsg = crypto_kdcmsg_decrypt(&(kdc_rep->enc_part.encblob), krb_ctx->askey, 8); //RFC4757 section 3 for msgtype (T=8)
|
||||
|
||||
if(msgtype == KRB_TAG_ASREP)
|
||||
/* decrypt enc-part */
|
||||
if (context->askey->enctype != kdc_rep->enc_part.enctype && msgtype == KRB_TAG_ASREP)
|
||||
{
|
||||
key = krb_ctx->askey;
|
||||
freerdp_blob_free(&(context->askey->skey));
|
||||
free(context->askey);
|
||||
context->askey = string2key(&(context->passwd), kdc_rep->enc_part.enctype);
|
||||
}
|
||||
context->askey->enctype = kdc_rep->enc_part.enctype;
|
||||
decmsg = crypto_kdcmsg_decrypt(&(kdc_rep->enc_part.encblob), context->askey, 8); //RFC4757 section 3 for msgtype (T=8)
|
||||
|
||||
if (msgtype == KRB_TAG_ASREP)
|
||||
{
|
||||
key = context->askey;
|
||||
tag = 25;
|
||||
}
|
||||
else if (msgtype == KRB_TAG_TGSREP)
|
||||
{
|
||||
key = krb_ctx->tgskey;
|
||||
key = context->tgskey;
|
||||
tag = 26;
|
||||
}
|
||||
|
||||
/* KDC-REP-PART decode */
|
||||
if(decmsg == NULL || ((reppart = krb_decode_enc_reppart(decmsg, tag)) == NULL))
|
||||
if (decmsg == NULL || ((reppart = krb_decode_enc_reppart(decmsg, tag)) == NULL))
|
||||
{
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
return -1;
|
||||
}
|
||||
freerdp_blob_free(decmsg);
|
||||
free(decmsg);
|
||||
|
||||
/* Verify KDC-REP-PART */
|
||||
if(reppart->nonce != krb_ctx->nonce || strcasecmp(reppart->realm, krb_ctx->realm) || strcasecmp(reppart->sname, krb_ctx->sname))
|
||||
if (reppart->nonce != context->nonce || strcasecmp(reppart->realm, context->realm) || strcasecmp(reppart->sname, context->sname))
|
||||
{
|
||||
kerberos_free_reppart(reppart);
|
||||
free(reppart);
|
||||
krb_ctx->state = KRB_PACKET_ERROR;
|
||||
context->state = KRB_PACKET_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save stuff */
|
||||
krb_ctx->clockskew = reppart->authtime - krb_ctx->ctime; //Used to synchronize clocks
|
||||
krb_save_ticket(krb_ctx, kdc_rep);
|
||||
context->clockskew = reppart->authtime - context->ctime; //Used to synchronize clocks
|
||||
kerberos_save_ticket(context, kdc_rep);
|
||||
freerdp_blob_copy(&(key->skey), &(reppart->key.skey));
|
||||
key->enctype = reppart->key.enctype;
|
||||
kerberos_free_reppart(reppart);
|
||||
@ -949,7 +951,7 @@ int krb_verify_kdcrep(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep, int msgtype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void krb_save_ticket(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep)
|
||||
void kerberos_save_ticket(KRB_CONTEXT* context, KrbKDCREP* kdc_rep)
|
||||
{
|
||||
Ticket* src;
|
||||
Ticket* dst;
|
||||
@ -958,9 +960,9 @@ void krb_save_ticket(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep)
|
||||
src = &(kdc_rep->etgt);
|
||||
|
||||
if (kdc_rep->type == KRB_TAG_ASREP)
|
||||
dst = &(krb_ctx->asticket);
|
||||
dst = &(context->asticket);
|
||||
else if (kdc_rep->type == KRB_TAG_TGSREP)
|
||||
dst = &(krb_ctx->tgsticket);
|
||||
dst = &(context->tgsticket);
|
||||
|
||||
dst->tktvno = src->tktvno;
|
||||
dst->realm = xstrdup(src->realm);
|
||||
@ -971,12 +973,12 @@ void krb_save_ticket(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep)
|
||||
freerdp_blob_copy(&(dst->enc_part.encblob), &(src->enc_part.encblob));
|
||||
}
|
||||
|
||||
void krb_reqbody_init(KRB_CONTEXT* krb_ctx, KDCReqBody* req_body, uint8 reqtype)
|
||||
void kerberos_reqbody_init(KRB_CONTEXT* context, KDCReqBody* req_body, BYTE reqtype)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
req_body->cname = xstrdup(krb_ctx->cname);
|
||||
req_body->realm = xstrdup(krb_ctx->realm);
|
||||
req_body->cname = xstrdup(context->cname);
|
||||
req_body->realm = xstrdup(context->realm);
|
||||
|
||||
if (reqtype == KRB_TAG_ASREQ)
|
||||
{
|
||||
@ -988,26 +990,26 @@ void krb_reqbody_init(KRB_CONTEXT* krb_ctx, KDCReqBody* req_body, uint8 reqtype)
|
||||
else if (reqtype == KRB_TAG_TGSREQ)
|
||||
{
|
||||
req_body->kdc_options = 0x40000000 | 0x00800000 | 0x00010000; /* forwardable , renewable, canonicalize */
|
||||
req_body->sname = xzalloc((strlen(krb_ctx->settings->hostname) + 10) * sizeof(char));
|
||||
req_body->sname = xzalloc((strlen(context->settings->hostname) + 10) * sizeof(char));
|
||||
strcpy(req_body->sname, APP_SERVER);
|
||||
strcat(req_body->sname, krb_ctx->settings->hostname);
|
||||
strcat(req_body->sname, context->settings->hostname);
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
t += krb_ctx->clockskew; /* fix clockskew */
|
||||
t += context->clockskew; /* fix clockskew */
|
||||
|
||||
req_body->from = get_utc_time((time_t)(t));
|
||||
req_body->till = get_utc_time((time_t)(t + 473040000));
|
||||
req_body->rtime = get_utc_time((time_t)(t + 473040000));
|
||||
|
||||
crypto_nonce((uint8*) &(req_body->nonce), 4);
|
||||
crypto_nonce((BYTE*) &(req_body->nonce), 4);
|
||||
}
|
||||
|
||||
KrbASREQ* krb_asreq_new(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
KrbASREQ* kerberos_asreq_new(KRB_CONTEXT* context, BYTE errcode)
|
||||
{
|
||||
KrbASREQ* krb_asreq;
|
||||
PAData** lpa_data;
|
||||
uint8 pacntmax, i;
|
||||
BYTE pacntmax, i;
|
||||
pacntmax = 2;
|
||||
|
||||
krb_asreq = xnew(KrbASREQ);
|
||||
@ -1020,18 +1022,18 @@ KrbASREQ* krb_asreq_new(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
for (i = 0; i < pacntmax; i++)
|
||||
*(lpa_data + i) = (PAData*)xzalloc(sizeof(PAData));
|
||||
|
||||
krb_reqbody_init(krb_ctx, &(krb_asreq->req_body), krb_asreq->type);
|
||||
kerberos_reqbody_init(context, &(krb_asreq->req_body), krb_asreq->type);
|
||||
|
||||
return krb_asreq;
|
||||
}
|
||||
|
||||
KrbAPREQ* krb_apreq_new(KRB_CONTEXT* krb_ctx, Ticket* ticket, Authenticator* krb_auth)
|
||||
KrbAPREQ* kerberos_apreq_new(KRB_CONTEXT* context, Ticket* ticket, Authenticator* krb_auth)
|
||||
{
|
||||
KrbAPREQ* krb_apreq;
|
||||
STREAM* as;
|
||||
rdpBlob msg;
|
||||
rdpBlob* encmsg;
|
||||
uint32 len;
|
||||
UINT32 len;
|
||||
|
||||
as = stream_new(1024);
|
||||
stream_seek(as, 1023);
|
||||
@ -1044,11 +1046,11 @@ KrbAPREQ* krb_apreq_new(KRB_CONTEXT* krb_ctx, Ticket* ticket, Authenticator* krb
|
||||
|
||||
if (krb_auth != NULL)
|
||||
{
|
||||
len = krb_encode_authenticator(as, krb_auth);
|
||||
len = kerberos_encode_authenticator(as, krb_auth);
|
||||
msg.data = as->p;
|
||||
msg.length = len;
|
||||
encmsg = crypto_kdcmsg_encrypt(&msg, krb_ctx->askey, 7); /* RFC4757 section 3 for msgtype (T=7) */
|
||||
krb_apreq->enc_auth.enctype = krb_ctx->askey->enctype;
|
||||
encmsg = crypto_kdcmsg_encrypt(&msg, context->askey, 7); /* RFC4757 section 3 for msgtype (T=7) */
|
||||
krb_apreq->enc_auth.enctype = context->askey->enctype;
|
||||
krb_apreq->enc_auth.kvno = -1;
|
||||
krb_apreq->enc_auth.encblob.data = encmsg->data;
|
||||
krb_apreq->enc_auth.encblob.length = encmsg->length;
|
||||
@ -1060,10 +1062,10 @@ KrbAPREQ* krb_apreq_new(KRB_CONTEXT* krb_ctx, Ticket* ticket, Authenticator* krb
|
||||
return krb_apreq;
|
||||
}
|
||||
|
||||
KrbTGSREQ* krb_tgsreq_new(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
KrbTGSREQ* kerberos_tgsreq_new(KRB_CONTEXT* context, BYTE errcode)
|
||||
{
|
||||
KrbTGSREQ* krb_tgsreq;
|
||||
uint8 pacntmax;
|
||||
BYTE pacntmax;
|
||||
pacntmax = 1;
|
||||
|
||||
krb_tgsreq = xnew(KrbTGSREQ);
|
||||
@ -1075,7 +1077,7 @@ KrbTGSREQ* krb_tgsreq_new(KRB_CONTEXT* krb_ctx, uint8 errcode)
|
||||
*(krb_tgsreq->padata) = xnew(PAData);
|
||||
*(krb_tgsreq->padata + 1) = NULL;
|
||||
|
||||
krb_reqbody_init(krb_ctx, &(krb_tgsreq->req_body), krb_tgsreq->type);
|
||||
kerberos_reqbody_init(context, &(krb_tgsreq->req_body), krb_tgsreq->type);
|
||||
|
||||
return krb_tgsreq;
|
||||
}
|
||||
@ -1096,9 +1098,10 @@ void kerberos_free_padata(PAData** padata)
|
||||
PAData** lpa_data;
|
||||
lpa_data = padata;
|
||||
|
||||
if(lpa_data == NULL)
|
||||
if (lpa_data == NULL)
|
||||
return;
|
||||
while(*lpa_data != NULL)
|
||||
|
||||
while (*lpa_data != NULL)
|
||||
{
|
||||
free(*lpa_data);
|
||||
lpa_data++;
|
||||
@ -1107,7 +1110,7 @@ void kerberos_free_padata(PAData** padata)
|
||||
|
||||
void kerberos_free_kdcrep(KrbKDCREP* kdc_rep)
|
||||
{
|
||||
if(kdc_rep != NULL)
|
||||
if (kdc_rep != NULL)
|
||||
{
|
||||
kerberos_free_padata(kdc_rep->padata);
|
||||
free(kdc_rep->cname);
|
||||
@ -1120,7 +1123,7 @@ void kerberos_free_kdcrep(KrbKDCREP* kdc_rep)
|
||||
|
||||
void kerberos_free_reppart(ENCKDCREPPart* reppart)
|
||||
{
|
||||
if(reppart != NULL)
|
||||
if (reppart != NULL)
|
||||
{
|
||||
freerdp_blob_free(&(reppart->key.skey));
|
||||
free(reppart->sname);
|
||||
@ -1130,7 +1133,7 @@ void kerberos_free_reppart(ENCKDCREPPart* reppart)
|
||||
|
||||
void kerberos_free_req_body(KDCReqBody* req_body)
|
||||
{
|
||||
if(req_body != NULL)
|
||||
if (req_body != NULL)
|
||||
{
|
||||
free(req_body->sname);
|
||||
free(req_body->realm);
|
||||
@ -1143,7 +1146,7 @@ void kerberos_free_req_body(KDCReqBody* req_body)
|
||||
|
||||
void kerberos_free_asreq(KrbASREQ* krb_asreq)
|
||||
{
|
||||
if(krb_asreq != NULL)
|
||||
if (krb_asreq != NULL)
|
||||
{
|
||||
kerberos_free_padata(krb_asreq->padata);
|
||||
kerberos_free_req_body(&(krb_asreq->req_body));
|
||||
@ -1152,7 +1155,7 @@ void kerberos_free_asreq(KrbASREQ* krb_asreq)
|
||||
|
||||
void kerberos_free_asrep(KrbASREP* krb_asrep)
|
||||
{
|
||||
if(krb_asrep != NULL)
|
||||
if (krb_asrep != NULL)
|
||||
{
|
||||
kerberos_free_kdcrep(&(krb_asrep->kdc_rep));
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/settings.h>
|
||||
@ -88,7 +89,7 @@
|
||||
#define AD_IF_RELEVANT 1
|
||||
|
||||
#define GETUINT16( _s, _p) do{ \
|
||||
*(_p) = (uint8)(_s)[0] << 8 | (uint8)(_s)[1]; \
|
||||
*(_p) = (BYTE)(_s)[0] << 8 | (BYTE)(_s)[1]; \
|
||||
(_s) += 2; } while (0)
|
||||
#define _GET_BYTE_LENGTH(_n) (((_n) > 0xFF) ? 3 :(((_n) > 0x7F) ? 2 : 1))
|
||||
|
||||
@ -114,9 +115,9 @@ typedef enum _KRBCTX_STATE KRBCTX_STATE;
|
||||
struct _kdc_srv_entry
|
||||
{
|
||||
struct _kdc_srv_entry* next;
|
||||
uint16 priority;
|
||||
uint16 weight;
|
||||
uint16 port;
|
||||
UINT16 priority;
|
||||
UINT16 weight;
|
||||
UINT16 port;
|
||||
char* kdchost;
|
||||
};
|
||||
typedef struct _kdc_srv_entry KDCENTRY;
|
||||
@ -131,13 +132,13 @@ typedef struct _PA_DATA PAData;
|
||||
struct _AUTH_DATA
|
||||
{
|
||||
int ad_type;
|
||||
uint8* ad_data;
|
||||
BYTE* ad_data;
|
||||
};
|
||||
typedef struct _AUTH_DATA AuthData;
|
||||
|
||||
struct _Krb_ENCData
|
||||
{
|
||||
sint32 enctype;
|
||||
INT32 enctype;
|
||||
int kvno;
|
||||
rdpBlob encblob;
|
||||
};
|
||||
@ -145,7 +146,7 @@ typedef struct _Krb_ENCData KrbENCData;
|
||||
|
||||
struct _Krb_ENCKey
|
||||
{
|
||||
sint32 enctype;
|
||||
INT32 enctype;
|
||||
rdpBlob skey;
|
||||
};
|
||||
typedef struct _Krb_ENCKey KrbENCKey;
|
||||
@ -154,7 +155,7 @@ struct _ENC_KDC_REPPART
|
||||
{
|
||||
KrbENCKey key;
|
||||
int nonce;
|
||||
uint32 flags;
|
||||
UINT32 flags;
|
||||
time_t authtime;
|
||||
time_t endtime;
|
||||
char *realm;
|
||||
@ -178,23 +179,23 @@ struct _Krb_Authenticator
|
||||
char* cname;
|
||||
int cksumtype;
|
||||
rdpBlob* cksum;
|
||||
uint32 cusec;
|
||||
UINT32 cusec;
|
||||
char* ctime;
|
||||
uint32 seqno;
|
||||
UINT32 seqno;
|
||||
AuthData auth_data;
|
||||
};
|
||||
typedef struct _Krb_Authenticator Authenticator;
|
||||
|
||||
struct _KDC_REQ_BODY
|
||||
{
|
||||
uint32 kdc_options;
|
||||
UINT32 kdc_options;
|
||||
char* cname;
|
||||
char* realm;
|
||||
char* sname;
|
||||
char* from;
|
||||
char* till;
|
||||
char* rtime;
|
||||
uint32 nonce;
|
||||
UINT32 nonce;
|
||||
};
|
||||
typedef struct _KDC_REQ_BODY KDCReqBody;
|
||||
|
||||
@ -234,7 +235,7 @@ struct _KRB_APREQ
|
||||
{
|
||||
int pvno;
|
||||
int type;
|
||||
uint32 ap_options;
|
||||
UINT32 ap_options;
|
||||
Ticket* ticket;
|
||||
KrbENCData enc_auth;
|
||||
};
|
||||
@ -246,7 +247,7 @@ struct _KRB_ERROR
|
||||
int type;
|
||||
int errcode;
|
||||
char* stime;
|
||||
uint32 susec;
|
||||
UINT32 susec;
|
||||
char* realm;
|
||||
char* sname;
|
||||
rdpBlob edata;
|
||||
@ -284,20 +285,19 @@ typedef struct _KRB_TGTREP KrbTGTREP;
|
||||
|
||||
struct _KRB_CONTEXT
|
||||
{
|
||||
UNICONV* uniconv;
|
||||
rdpSettings* settings;
|
||||
int ksockfd;
|
||||
uint16 krbport;
|
||||
UINT16 krbport;
|
||||
char* krbhost;
|
||||
char* cname;
|
||||
char* realm;
|
||||
char* sname;
|
||||
char* hostname;
|
||||
rdpBlob passwd;
|
||||
sint32 enctype;
|
||||
INT32 enctype;
|
||||
time_t clockskew;
|
||||
time_t ctime;
|
||||
uint32 nonce;
|
||||
UINT32 nonce;
|
||||
Ticket asticket;
|
||||
KrbENCKey* askey;
|
||||
Ticket tgsticket;
|
||||
@ -318,22 +318,22 @@ char* get_dns_queryname(char *host, char* protocol);
|
||||
int krb_get_realm(rdpSettings* settings);
|
||||
KDCENTRY* krb_locate_kdc(rdpSettings* settings);
|
||||
|
||||
int krb_tcp_connect(KRB_CONTEXT* krb_ctx, KDCENTRY* entry);
|
||||
int krb_tcp_send(KRB_CONTEXT* krb_ctx, uint8* data, uint32 length);
|
||||
int krb_tcp_recv(KRB_CONTEXT* krb_ctx, uint8* data, uint32 length);
|
||||
int kerberos_tcp_connect(KRB_CONTEXT* krb_ctx, KDCENTRY* entry);
|
||||
int kerberos_tcp_send(KRB_CONTEXT* krb_ctx, BYTE* data, UINT32 length);
|
||||
int kerberos_tcp_recv(KRB_CONTEXT* krb_ctx, BYTE* data, UINT32 length);
|
||||
|
||||
void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode);
|
||||
int krb_asrep_recv(KRB_CONTEXT* krb_ctx);
|
||||
void kerberos_asreq_send(KRB_CONTEXT* krb_ctx, BYTE errcode);
|
||||
int kerberos_asrep_recv(KRB_CONTEXT* krb_ctx);
|
||||
|
||||
void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode);
|
||||
int krb_tgsrep_recv(KRB_CONTEXT* krb_ctx);
|
||||
void kerberos_tgsreq_send(KRB_CONTEXT* krb_ctx, BYTE errcode);
|
||||
int kerberos_tgsrep_recv(KRB_CONTEXT* krb_ctx);
|
||||
|
||||
int krb_verify_kdcrep(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep, int msgtype);
|
||||
void krb_save_ticket(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep);
|
||||
int kerberos_verify_kdcrep(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep, int msgtype);
|
||||
void kerberos_save_ticket(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep);
|
||||
|
||||
KrbASREQ* krb_asreq_new(KRB_CONTEXT* krb_ctx, uint8 errcode);
|
||||
KrbTGSREQ* krb_tgsreq_new(KRB_CONTEXT* krb_Rss, uint8 errcode);
|
||||
KrbAPREQ* krb_apreq_new(KRB_CONTEXT* krb_ctx, Ticket* ticket, Authenticator* krb_auth);
|
||||
KrbASREQ* kerberos_asreq_new(KRB_CONTEXT* krb_ctx, BYTE errcode);
|
||||
KrbTGSREQ* kerberos_tgsreq_new(KRB_CONTEXT* krb_Rss, BYTE errcode);
|
||||
KrbAPREQ* kerberos_apreq_new(KRB_CONTEXT* krb_ctx, Ticket* ticket, Authenticator* krb_auth);
|
||||
|
||||
void kerberos_ContextFree(KRB_CONTEXT* krb_ctx);
|
||||
void kerberos_free_ticket(Ticket* ticket);
|
||||
|
@ -20,14 +20,18 @@
|
||||
#include "kerberos.h"
|
||||
#include "kerberos_crypto.h"
|
||||
|
||||
uint8* crypto_md4_hash(rdpBlob* blob)
|
||||
BYTE* crypto_md4_hash(rdpBlob* blob)
|
||||
{
|
||||
BYTE* hash;
|
||||
MD4_CTX md4_ctx;
|
||||
uint8* hash;
|
||||
hash = (uint8*)xzalloc(16);
|
||||
|
||||
hash = (BYTE*) malloc(16);
|
||||
ZeroMemory(hash, 16);
|
||||
|
||||
MD4_Init(&md4_ctx);
|
||||
MD4_Update(&md4_ctx, blob->data, blob->length);
|
||||
MD4_Final(hash, &md4_ctx);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -36,24 +40,27 @@ KrbENCKey* string2key(rdpBlob* string, sint8 enctype)
|
||||
KrbENCKey* key;
|
||||
key = xnew(KrbENCKey);
|
||||
key->enctype = enctype;
|
||||
|
||||
switch(enctype)
|
||||
{
|
||||
case ETYPE_RC4_HMAC:
|
||||
key->skey.data = crypto_md4_hash(string);
|
||||
key->skey.length = 16;
|
||||
break;
|
||||
case ETYPE_RC4_HMAC:
|
||||
key->skey.data = crypto_md4_hash(string);
|
||||
key->skey.length = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
rdpBlob* crypto_kdcmsg_encrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
|
||||
rdpBlob* crypto_kdcmsg_encrypt_rc4(rdpBlob* msg, BYTE* key, UINT32 msgtype)
|
||||
{
|
||||
rdpBlob* encmsg;
|
||||
uint8* K1;
|
||||
uint8* K3;
|
||||
uint32 len;
|
||||
BYTE* K1;
|
||||
BYTE* K3;
|
||||
UINT32 len;
|
||||
krbEdata* edata;
|
||||
CryptoRc4 rc4;
|
||||
|
||||
K1 = xzalloc(16);
|
||||
K3 = xzalloc(16);
|
||||
len = ((msg->length > 16) ? msg->length : 16);
|
||||
@ -61,22 +68,23 @@ rdpBlob* crypto_kdcmsg_encrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
|
||||
edata = xzalloc(len);
|
||||
encmsg = xnew(rdpBlob);
|
||||
freerdp_blob_alloc(encmsg, len);
|
||||
HMAC(EVP_md5(), (void*) key, 16, (uint8*)&msgtype, 4, (void*) K1, NULL);
|
||||
crypto_nonce((uint8*)(edata->Confounder), 8);
|
||||
HMAC(EVP_md5(), (void*) key, 16, (BYTE*)&msgtype, 4, (void*) K1, NULL);
|
||||
crypto_nonce((BYTE*)(edata->Confounder), 8);
|
||||
memcpy(&(edata->data[0]), msg->data, msg->length);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (uint8*)&(edata->Checksum), 16, (void*)K3, NULL);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (BYTE*) edata->Confounder, len - 16, (void*) &(edata->Checksum), NULL);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (BYTE*) &(edata->Checksum), 16, (void*) K3, NULL);
|
||||
memcpy(encmsg->data, &(edata->Checksum), 16);
|
||||
rc4 = crypto_rc4_init(K3, 16);
|
||||
crypto_rc4(rc4, len - 16, (uint8*) edata->Confounder, (uint8*)(((uint8*) encmsg->data) + 16));
|
||||
crypto_rc4(rc4, len - 16, (BYTE*) edata->Confounder, (BYTE*)(((BYTE*) encmsg->data) + 16));
|
||||
crypto_rc4_free(rc4);
|
||||
xfree(K1);
|
||||
xfree(K3);
|
||||
xfree(edata);
|
||||
free(K1);
|
||||
free(K3);
|
||||
free(edata);
|
||||
|
||||
return encmsg;
|
||||
}
|
||||
|
||||
rdpBlob* crypto_kdcmsg_encrypt(rdpBlob* msg, KrbENCKey* key, uint32 msgtype)
|
||||
rdpBlob* crypto_kdcmsg_encrypt(rdpBlob* msg, KrbENCKey* key, UINT32 msgtype)
|
||||
{
|
||||
switch(key->enctype)
|
||||
{
|
||||
@ -85,44 +93,50 @@ rdpBlob* crypto_kdcmsg_encrypt(rdpBlob* msg, KrbENCKey* key, uint32 msgtype)
|
||||
return NULL;
|
||||
return crypto_kdcmsg_encrypt_rc4(msg, key->skey.data, msgtype);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdpBlob* crypto_kdcmsg_decrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
|
||||
rdpBlob* crypto_kdcmsg_decrypt_rc4(rdpBlob* msg, BYTE* key, UINT32 msgtype)
|
||||
{
|
||||
rdpBlob* decmsg;
|
||||
uint8* K1;
|
||||
uint8* K3;
|
||||
uint32 len;
|
||||
BYTE* K1;
|
||||
BYTE* K3;
|
||||
UINT32 len;
|
||||
krbEdata* edata;
|
||||
CryptoRc4 rc4;
|
||||
|
||||
K1 = xzalloc(16);
|
||||
K3 = xzalloc(16);
|
||||
len = msg->length;
|
||||
edata = xzalloc(len);
|
||||
HMAC(EVP_md5(), (void*) key, 16, (uint8*) &msgtype, 4, (void*) K1, NULL);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (uint8*) msg->data , 16, (void*) K3, NULL);
|
||||
HMAC(EVP_md5(), (void*) key, 16, (BYTE*) &msgtype, 4, (void*) K1, NULL);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (BYTE*) msg->data , 16, (void*) K3, NULL);
|
||||
rc4 = crypto_rc4_init(K3, 16);
|
||||
crypto_rc4(rc4, len - 16, (uint8*)(((uint8*) msg->data) + 16), (uint8*) edata->Confounder);
|
||||
crypto_rc4(rc4, len - 16, (BYTE*)(((BYTE*) msg->data) + 16), (BYTE*) edata->Confounder);
|
||||
crypto_rc4_free(rc4);
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL);
|
||||
if(memcmp(msg->data, &edata->Checksum, 16))
|
||||
HMAC(EVP_md5(), (void*) K1, 16, (BYTE*)edata->Confounder, len - 16, (void*) &(edata->Checksum), NULL);
|
||||
|
||||
if (memcmp(msg->data, &edata->Checksum, 16))
|
||||
{
|
||||
xfree(edata) ;
|
||||
xfree(K1) ;
|
||||
xfree(K3) ;
|
||||
free(edata) ;
|
||||
free(K1) ;
|
||||
free(K3) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decmsg = xnew(rdpBlob);
|
||||
freerdp_blob_alloc(decmsg, len);
|
||||
memcpy(decmsg->data, edata, len);
|
||||
xfree(K1);
|
||||
xfree(K3);
|
||||
xfree(edata);
|
||||
|
||||
free(K1);
|
||||
free(K3);
|
||||
free(edata);
|
||||
|
||||
return decmsg;
|
||||
}
|
||||
|
||||
rdpBlob* crypto_kdcmsg_decrypt(rdpBlob* msg, KrbENCKey* key, uint32 msgtype)
|
||||
rdpBlob* crypto_kdcmsg_decrypt(rdpBlob* msg, KrbENCKey* key, UINT32 msgtype)
|
||||
{
|
||||
switch(key->enctype)
|
||||
{
|
||||
@ -134,29 +148,29 @@ rdpBlob* crypto_kdcmsg_decrypt(rdpBlob* msg, KrbENCKey* key, uint32 msgtype)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdpBlob* crypto_kdcmsg_cksum_hmacmd5(rdpBlob* msg, uint8* key, uint32 msgtype)
|
||||
rdpBlob* crypto_kdcmsg_cksum_hmacmd5(rdpBlob* msg, BYTE* key, UINT32 msgtype)
|
||||
{
|
||||
rdpBlob* cksum;
|
||||
uint8* Ksign;
|
||||
uint8* tmpdata;
|
||||
uint8* tmp;
|
||||
BYTE* Ksign;
|
||||
BYTE* tmpdata;
|
||||
BYTE* tmp;
|
||||
CryptoMd5 md5;
|
||||
Ksign = xzalloc(16);
|
||||
tmp = xzalloc(16);
|
||||
cksum = xnew(rdpBlob);
|
||||
freerdp_blob_alloc(cksum, 16);
|
||||
tmpdata = xzalloc(msg->length + 4);
|
||||
HMAC(EVP_md5(), (void*) key, 16, (uint8*)"signaturekey\0", 13, (void*) Ksign, NULL);
|
||||
HMAC(EVP_md5(), (void*) key, 16, (BYTE*)"signaturekey\0", 13, (void*) Ksign, NULL);
|
||||
memcpy(tmpdata, (void*)&msgtype, 4);
|
||||
memcpy(tmpdata + 4, msg->data, msg->length);
|
||||
md5 = crypto_md5_init();
|
||||
crypto_md5_update(md5, tmpdata, msg->length + 4);
|
||||
crypto_md5_final(md5, tmp);
|
||||
HMAC(EVP_md5(), (void*) Ksign, 16, (uint8*)tmp, 16, (void*) cksum->data, NULL);
|
||||
HMAC(EVP_md5(), (void*) Ksign, 16, (BYTE*)tmp, 16, (void*) cksum->data, NULL);
|
||||
return cksum;
|
||||
}
|
||||
|
||||
rdpBlob* crypto_kdcmsg_cksum(rdpBlob* msg, KrbENCKey* key, uint32 msgtype)
|
||||
rdpBlob* crypto_kdcmsg_cksum(rdpBlob* msg, KrbENCKey* key, UINT32 msgtype)
|
||||
{
|
||||
switch(key->enctype)
|
||||
{
|
||||
@ -168,12 +182,13 @@ rdpBlob* crypto_kdcmsg_cksum(rdpBlob* msg, KrbENCKey* key, uint32 msgtype)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_cksum_type(uint32 enctype)
|
||||
int get_cksum_type(UINT32 enctype)
|
||||
{
|
||||
switch(enctype)
|
||||
{
|
||||
case ETYPE_RC4_HMAC:
|
||||
return KRB_CKSUM_HMAC_MD5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "kerberos_encode.h"
|
||||
|
||||
int krb_encode_sequence_tag(STREAM* s, uint32 len)
|
||||
int kerberos_encode_sequence_tag(STREAM* s, uint32 len)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen;
|
||||
@ -31,7 +31,7 @@ int krb_encode_sequence_tag(STREAM* s, uint32 len)
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_contextual_tag(STREAM* s, uint8 tag, uint32 len)
|
||||
int kerberos_encode_contextual_tag(STREAM* s, uint8 tag, uint32 len)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen;
|
||||
@ -43,7 +43,7 @@ int krb_encode_contextual_tag(STREAM* s, uint8 tag, uint32 len)
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_application_tag(STREAM* s, uint8 tag, uint32 len)
|
||||
int kerberos_encode_application_tag(STREAM* s, uint8 tag, uint32 len)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen;
|
||||
@ -55,7 +55,7 @@ int krb_encode_application_tag(STREAM* s, uint8 tag, uint32 len)
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_recordmark(STREAM* s, uint32 len)
|
||||
int kerberos_encode_recordmark(STREAM* s, uint32 len)
|
||||
{
|
||||
uint8* bm;
|
||||
stream_rewind(s, 4);
|
||||
@ -65,7 +65,7 @@ int krb_encode_recordmark(STREAM* s, uint32 len)
|
||||
return 4;
|
||||
}
|
||||
|
||||
int krb_encode_cname(STREAM* s, uint8 tag, char* cname)
|
||||
int kerberos_encode_cname(STREAM* s, uint8 tag, char* cname)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 len;
|
||||
@ -84,7 +84,7 @@ int krb_encode_cname(STREAM* s, uint8 tag, char* cname)
|
||||
return len;
|
||||
}
|
||||
|
||||
int krb_encode_sname(STREAM* s, uint8 tag, char* sname)
|
||||
int kerberos_encode_sname(STREAM* s, uint8 tag, char* sname)
|
||||
{
|
||||
uint8* bm;
|
||||
char* str;
|
||||
@ -115,7 +115,7 @@ int krb_encode_sname(STREAM* s, uint8 tag, char* sname)
|
||||
return len;
|
||||
}
|
||||
|
||||
int krb_encode_uint8(STREAM* s, uint8 tag, uint8 val)
|
||||
int kerberos_encode_uint8(STREAM* s, uint8 tag, uint8 val)
|
||||
{
|
||||
uint8* bm;
|
||||
stream_rewind(s, 5);
|
||||
@ -126,7 +126,7 @@ int krb_encode_uint8(STREAM* s, uint8 tag, uint8 val)
|
||||
return 5;
|
||||
}
|
||||
|
||||
int krb_encode_integer(STREAM* s, uint8 tag, int val)
|
||||
int kerberos_encode_integer(STREAM* s, uint8 tag, int val)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen;
|
||||
@ -139,7 +139,7 @@ int krb_encode_integer(STREAM* s, uint8 tag, int val)
|
||||
return (totlen + 2);
|
||||
}
|
||||
|
||||
int krb_encode_options(STREAM* s, uint8 tag, uint32 options)
|
||||
int kerberos_encode_options(STREAM* s, uint8 tag, uint32 options)
|
||||
{
|
||||
uint8* bm;
|
||||
stream_rewind(s, 9);
|
||||
@ -151,7 +151,7 @@ int krb_encode_options(STREAM* s, uint8 tag, uint32 options)
|
||||
return 9;
|
||||
}
|
||||
|
||||
int krb_encode_string(STREAM* s, uint8 tag, char* str)
|
||||
int kerberos_encode_string(STREAM* s, uint8 tag, char* str)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 len;
|
||||
@ -164,7 +164,7 @@ int krb_encode_string(STREAM* s, uint8 tag, char* str)
|
||||
return (len + 4);
|
||||
}
|
||||
|
||||
int krb_encode_time(STREAM* s, uint8 tag, char* strtime)
|
||||
int kerberos_encode_time(STREAM* s, uint8 tag, char* strtime)
|
||||
{
|
||||
uint8* bm;
|
||||
stream_rewind(s, 19);
|
||||
@ -175,7 +175,7 @@ int krb_encode_time(STREAM* s, uint8 tag, char* strtime)
|
||||
return 19;
|
||||
}
|
||||
|
||||
int krb_encode_octet_string(STREAM* s, uint8* string, uint32 len)
|
||||
int kerberos_encode_octet_string(STREAM* s, uint8* string, uint32 len)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen;
|
||||
@ -187,41 +187,41 @@ int krb_encode_octet_string(STREAM* s, uint8* string, uint32 len)
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_encrypted_data(STREAM* s, KrbENCData* enc_data)
|
||||
int kerberos_encode_encrypted_data(STREAM* s, KrbENCData* enc_data)
|
||||
{
|
||||
uint32 totlen;
|
||||
|
||||
/* Encrypted Data[2] */
|
||||
totlen = krb_encode_octet_string(s, (enc_data->encblob).data, (enc_data->encblob).length);
|
||||
totlen += krb_encode_contextual_tag(s, 2, totlen);
|
||||
totlen = kerberos_encode_octet_string(s, (enc_data->encblob).data, (enc_data->encblob).length);
|
||||
totlen += kerberos_encode_contextual_tag(s, 2, totlen);
|
||||
|
||||
/* Encrypted key version no[1] */
|
||||
if(enc_data->kvno != -1)
|
||||
totlen += krb_encode_uint8(s, 1, enc_data->kvno);
|
||||
totlen += kerberos_encode_uint8(s, 1, enc_data->kvno);
|
||||
|
||||
/* Encrypted Type[0] */
|
||||
totlen += krb_encode_integer(s, 0, enc_data->enctype);
|
||||
totlen += kerberos_encode_integer(s, 0, enc_data->enctype);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_checksum(STREAM* s, rdpBlob* cksum, int cktype)
|
||||
int kerberos_encode_checksum(STREAM* s, rdpBlob* cksum, int cktype)
|
||||
{
|
||||
uint32 totlen;
|
||||
|
||||
/* Checksum Data[1] */
|
||||
totlen = krb_encode_octet_string(s, cksum->data, cksum->length);
|
||||
totlen += krb_encode_contextual_tag(s, 1, totlen);
|
||||
totlen = kerberos_encode_octet_string(s, cksum->data, cksum->length);
|
||||
totlen += kerberos_encode_contextual_tag(s, 1, totlen);
|
||||
|
||||
/* Checksum Type[0] */
|
||||
totlen += krb_encode_integer(s, 0, cktype);
|
||||
totlen += kerberos_encode_integer(s, 0, cktype);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_padata(STREAM* s, PAData** pa_data)
|
||||
int kerberos_encode_padata(STREAM* s, PAData** pa_data)
|
||||
{
|
||||
uint32 totlen;
|
||||
uint32 curlen;
|
||||
@ -233,23 +233,22 @@ int krb_encode_padata(STREAM* s, PAData** pa_data)
|
||||
while (*lpa_data != NULL)
|
||||
{
|
||||
/* padata value */
|
||||
curlen = krb_encode_octet_string(s, ((*lpa_data)->value).data, ((*lpa_data)->value).length);
|
||||
curlen += krb_encode_contextual_tag(s, 2, curlen);
|
||||
curlen = kerberos_encode_octet_string(s, ((*lpa_data)->value).data, ((*lpa_data)->value).length);
|
||||
curlen += kerberos_encode_contextual_tag(s, 2, curlen);
|
||||
|
||||
/* padata type */
|
||||
curlen += krb_encode_integer(s, 1, ((*lpa_data)->type));
|
||||
curlen += krb_encode_sequence_tag(s, curlen);
|
||||
curlen += kerberos_encode_integer(s, 1, ((*lpa_data)->type));
|
||||
curlen += kerberos_encode_sequence_tag(s, curlen);
|
||||
totlen += curlen;
|
||||
lpa_data++;
|
||||
}
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
|
||||
int krb_encode_authenticator(STREAM* s, Authenticator *krb_auth)
|
||||
int kerberos_encode_authenticator(STREAM* s, Authenticator* krb_auth)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen, curlen;
|
||||
@ -264,55 +263,55 @@ int krb_encode_authenticator(STREAM* s, Authenticator *krb_auth)
|
||||
stream_set_mark(s, bm);
|
||||
|
||||
/* ctime[5] */
|
||||
totlen += krb_encode_time(s, 5, krb_auth->ctime);
|
||||
totlen += kerberos_encode_time(s, 5, krb_auth->ctime);
|
||||
|
||||
/* cusec[4] */
|
||||
totlen += krb_encode_integer(s, 4, krb_auth->cusec);
|
||||
totlen += kerberos_encode_integer(s, 4, krb_auth->cusec);
|
||||
|
||||
/* cksum[3] */
|
||||
curlen = krb_encode_checksum(s, krb_auth->cksum, krb_auth->cksumtype);
|
||||
totlen += krb_encode_contextual_tag(s, 3, curlen) + curlen;
|
||||
curlen = kerberos_encode_checksum(s, krb_auth->cksum, krb_auth->cksumtype);
|
||||
totlen += kerberos_encode_contextual_tag(s, 3, curlen) + curlen;
|
||||
|
||||
/* cname[2] */
|
||||
totlen += krb_encode_cname(s, 2, krb_auth->cname);
|
||||
totlen += kerberos_encode_cname(s, 2, krb_auth->cname);
|
||||
|
||||
/* crealm[1] */
|
||||
totlen += krb_encode_string(s, 1, krb_auth->crealm);
|
||||
totlen += kerberos_encode_string(s, 1, krb_auth->crealm);
|
||||
|
||||
/* avno[0] */
|
||||
totlen += krb_encode_uint8(s, 0, krb_auth->avno);
|
||||
totlen += kerberos_encode_uint8(s, 0, krb_auth->avno);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += krb_encode_application_tag(s, 2, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_application_tag(s, 2, totlen);
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_ticket(STREAM* s, uint8 tag, Ticket* ticket)
|
||||
int kerberos_encode_ticket(STREAM* s, uint8 tag, Ticket* ticket)
|
||||
{
|
||||
uint32 totlen;
|
||||
|
||||
/* Encrypted DATA[3] */
|
||||
totlen = krb_encode_encrypted_data(s, &(ticket->enc_part));
|
||||
totlen += krb_encode_contextual_tag(s, 3, totlen);
|
||||
totlen = kerberos_encode_encrypted_data(s, &(ticket->enc_part));
|
||||
totlen += kerberos_encode_contextual_tag(s, 3, totlen);
|
||||
|
||||
/* sname[2] */
|
||||
totlen += krb_encode_sname(s, 2, ticket->sname);
|
||||
totlen += kerberos_encode_sname(s, 2, ticket->sname);
|
||||
|
||||
/* realm[1] */
|
||||
totlen += krb_encode_string(s, 1, ticket->realm);
|
||||
totlen += kerberos_encode_string(s, 1, ticket->realm);
|
||||
|
||||
/* ticket vno[0] */
|
||||
totlen += krb_encode_uint8(s, 0, ticket->tktvno);
|
||||
totlen += kerberos_encode_uint8(s, 0, ticket->tktvno);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += krb_encode_application_tag(s, 1, totlen);
|
||||
totlen += krb_encode_contextual_tag(s, tag, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_application_tag(s, 1, totlen);
|
||||
totlen += kerberos_encode_contextual_tag(s, tag, totlen);
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_req_body(STREAM* s, KDCReqBody* req_body, int msgtype)
|
||||
int kerberos_encode_req_body(STREAM* s, KDCReqBody* req_body, int msgtype)
|
||||
{
|
||||
uint8* bm;
|
||||
uint32 totlen;
|
||||
@ -339,73 +338,73 @@ int krb_encode_req_body(STREAM* s, KDCReqBody* req_body, int msgtype)
|
||||
stream_set_mark(s, bm);
|
||||
|
||||
/* till[5] and rtime (tag 6)*/
|
||||
totlen += krb_encode_time(s, 6, req_body->rtime);
|
||||
totlen += krb_encode_time(s, 5, req_body->till);
|
||||
totlen += kerberos_encode_time(s, 6, req_body->rtime);
|
||||
totlen += kerberos_encode_time(s, 5, req_body->till);
|
||||
|
||||
/* SNAME[3]*/
|
||||
totlen += krb_encode_sname(s, 3, req_body->sname);
|
||||
totlen += kerberos_encode_sname(s, 3, req_body->sname);
|
||||
|
||||
/* REALM[2] */
|
||||
totlen += krb_encode_string(s, 2, req_body->realm);
|
||||
totlen += kerberos_encode_string(s, 2, req_body->realm);
|
||||
|
||||
/* CNAME[1] */
|
||||
totlen += krb_encode_cname(s, 1, req_body->cname);
|
||||
totlen += kerberos_encode_cname(s, 1, req_body->cname);
|
||||
|
||||
/* KDCOptions[0]*/
|
||||
totlen += krb_encode_options(s, 0, req_body->kdc_options);
|
||||
totlen += kerberos_encode_options(s, 0, req_body->kdc_options);
|
||||
|
||||
/* KDC_BODY */
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_apreq(STREAM* s, KrbAPREQ* krb_apreq)
|
||||
int kerberos_encode_apreq(STREAM* s, KrbAPREQ* krb_apreq)
|
||||
{
|
||||
uint32 totlen;
|
||||
|
||||
/* Encrypted Authenticator[4] */
|
||||
totlen = krb_encode_encrypted_data(s, &(krb_apreq->enc_auth));
|
||||
totlen += krb_encode_contextual_tag(s, 4, totlen);
|
||||
totlen = kerberos_encode_encrypted_data(s, &(krb_apreq->enc_auth));
|
||||
totlen += kerberos_encode_contextual_tag(s, 4, totlen);
|
||||
|
||||
/* Ticket[3] */
|
||||
totlen += krb_encode_ticket(s, 3, krb_apreq->ticket);
|
||||
totlen += kerberos_encode_ticket(s, 3, krb_apreq->ticket);
|
||||
|
||||
/* APOPTIONS[2] */
|
||||
totlen += krb_encode_options(s, 2, krb_apreq->ap_options);
|
||||
totlen += kerberos_encode_options(s, 2, krb_apreq->ap_options);
|
||||
|
||||
/* MSGTYPE[1] */
|
||||
totlen += krb_encode_uint8(s , 1, krb_apreq->type);
|
||||
totlen += kerberos_encode_uint8(s , 1, krb_apreq->type);
|
||||
|
||||
/* VERSION NO[0] */
|
||||
totlen += krb_encode_uint8(s, 0, krb_apreq->pvno);
|
||||
totlen += kerberos_encode_uint8(s, 0, krb_apreq->pvno);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += krb_encode_application_tag(s, krb_apreq->type, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_application_tag(s, krb_apreq->type, totlen);
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
int krb_encode_tgtreq(STREAM* s, KrbTGTREQ* krb_tgtreq)
|
||||
int kerberos_encode_tgtreq(STREAM* s, KrbTGTREQ* krb_tgtreq)
|
||||
{
|
||||
uint32 totlen;
|
||||
totlen = 0;
|
||||
|
||||
/* realm[3] optional */
|
||||
if(krb_tgtreq->realm != NULL)
|
||||
totlen += krb_encode_string(s, 3, krb_tgtreq->realm);
|
||||
if (krb_tgtreq->realm != NULL)
|
||||
totlen += kerberos_encode_string(s, 3, krb_tgtreq->realm);
|
||||
|
||||
/* sname[2] optional */
|
||||
if(krb_tgtreq->sname != NULL)
|
||||
totlen += krb_encode_sname(s, 3, krb_tgtreq->sname);
|
||||
if (krb_tgtreq->sname != NULL)
|
||||
totlen += kerberos_encode_sname(s, 3, krb_tgtreq->sname);
|
||||
|
||||
/* msgtype[1] */
|
||||
totlen += krb_encode_uint8(s , 1, krb_tgtreq->type);
|
||||
totlen += kerberos_encode_uint8(s , 1, krb_tgtreq->type);
|
||||
|
||||
/* pvno[0] */
|
||||
totlen += krb_encode_uint8(s, 0, krb_tgtreq->pvno);
|
||||
totlen += kerberos_encode_uint8(s, 0, krb_tgtreq->pvno);
|
||||
|
||||
totlen += krb_encode_sequence_tag(s, totlen);
|
||||
totlen += kerberos_encode_sequence_tag(s, totlen);
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
@ -24,25 +24,25 @@
|
||||
#ifndef WINPR_SSPI_KERBEROS_ENCODE_H
|
||||
#define WINPR_SSPI_KERBEROS_ENCODE_H
|
||||
|
||||
int krb_encode_sequence_tag(STREAM* s, uint32 len);
|
||||
int krb_encode_contextual_tag(STREAM* s, uint8 tag, uint32 len);
|
||||
int krb_encode_application_tag(STREAM* s, uint8 tag, uint32 len);
|
||||
int krb_encode_recordmark(STREAM* s, uint32 len);
|
||||
int krb_encode_cname(STREAM* s, uint8 tag, char* cname);
|
||||
int krb_encode_sname(STREAM* s, uint8 tag, char* sname);
|
||||
int krb_encode_uint8(STREAM* s, uint8 tag, uint8 val);
|
||||
int krb_encode_integer(STREAM* s, uint8 tag, int val);
|
||||
int krb_encode_options(STREAM* s, uint8 tag, uint32 options);
|
||||
int krb_encode_string(STREAM* s, uint8 tag, char* str);
|
||||
int krb_encode_time(STREAM* s, uint8 tag, char* strtime);
|
||||
int krb_encode_octet_string(STREAM* s, uint8* string, uint32 len);
|
||||
int krb_encode_padata(STREAM* s, PAData** pa_data);
|
||||
int krb_encode_encrypted_data(STREAM* s, KrbENCData* enc_data);
|
||||
int krb_encode_checksum(STREAM* s, rdpBlob* cksum, int cktype);
|
||||
int krb_encode_authenticator(STREAM* s, Authenticator *krb_auth);
|
||||
int krb_encode_ticket(STREAM* s, uint8 tag, Ticket* ticket);
|
||||
int krb_encode_req_body(STREAM* s, KDCReqBody* req_body, int msgtype);
|
||||
int krb_encode_apreq(STREAM* s, KrbAPREQ* krb_apreq);
|
||||
int krb_encode_tgtreq(STREAM* s, KrbTGTREQ* krb_tgtreq);
|
||||
int kerberos_encode_sequence_tag(STREAM* s, uint32 len);
|
||||
int kerberos_encode_contextual_tag(STREAM* s, uint8 tag, uint32 len);
|
||||
int kerberos_encode_application_tag(STREAM* s, uint8 tag, uint32 len);
|
||||
int kerberos_encode_recordmark(STREAM* s, uint32 len);
|
||||
int kerberos_encode_cname(STREAM* s, uint8 tag, char* cname);
|
||||
int kerberos_encode_sname(STREAM* s, uint8 tag, char* sname);
|
||||
int kerberos_encode_uint8(STREAM* s, uint8 tag, uint8 val);
|
||||
int kerberos_encode_integer(STREAM* s, uint8 tag, int val);
|
||||
int kerberos_encode_options(STREAM* s, uint8 tag, uint32 options);
|
||||
int kerberos_encode_string(STREAM* s, uint8 tag, char* str);
|
||||
int kerberos_encode_time(STREAM* s, uint8 tag, char* strtime);
|
||||
int kerberos_encode_octet_string(STREAM* s, uint8* string, uint32 len);
|
||||
int kerberos_encode_padata(STREAM* s, PAData** pa_data);
|
||||
int kerberos_encode_encrypted_data(STREAM* s, KrbENCData* enc_data);
|
||||
int kerberos_encode_checksum(STREAM* s, rdpBlob* cksum, int cktype);
|
||||
int kerberos_encode_authenticator(STREAM* s, Authenticator *krb_auth);
|
||||
int kerberos_encode_ticket(STREAM* s, uint8 tag, Ticket* ticket);
|
||||
int kerberos_encode_req_body(STREAM* s, KDCReqBody* req_body, int msgtype);
|
||||
int kerberos_encode_apreq(STREAM* s, KrbAPREQ* krb_apreq);
|
||||
int kerberos_encode_tgtreq(STREAM* s, KrbTGTREQ* krb_tgtreq);
|
||||
|
||||
#endif /* WINPR_SSPI_KERBEROS_ENCODE_H */
|
||||
|
@ -46,59 +46,6 @@ const SecPkgInfoW NEGOTIATE_SecPkgInfoW =
|
||||
L"Microsoft Package Negotiator" /* Comment */
|
||||
};
|
||||
|
||||
void negotiate_SetContextIdentity(NEGOTIATE_CONTEXT* context, SEC_WINNT_AUTH_IDENTITY* identity)
|
||||
{
|
||||
context->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
|
||||
if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
{
|
||||
context->identity.UserLength = strlen((char*) identity->User) * 2;
|
||||
context->identity.User = (UINT16*) malloc(context->identity.UserLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, (char*) identity->User, strlen((char*) identity->User),
|
||||
(LPWSTR) context->identity.User, context->identity.UserLength / 2);
|
||||
|
||||
if (identity->DomainLength > 0)
|
||||
{
|
||||
context->identity.DomainLength = strlen((char*) identity->Domain) * 2;
|
||||
context->identity.Domain = (UINT16*) malloc(context->identity.DomainLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, (char*) identity->Domain, strlen((char*) identity->Domain),
|
||||
(LPWSTR) context->identity.Domain, context->identity.DomainLength / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->identity.Domain = (UINT16*) NULL;
|
||||
context->identity.DomainLength = 0;
|
||||
}
|
||||
|
||||
context->identity.PasswordLength = strlen((char*) identity->Password) * 2;
|
||||
context->identity.Password = (UINT16*) malloc(context->identity.PasswordLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, (char*) identity->Password, strlen((char*) identity->Password),
|
||||
(LPWSTR) context->identity.Password, context->identity.PasswordLength / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->identity.User = (UINT16*) malloc(identity->UserLength);
|
||||
memcpy(context->identity.User, identity->User, identity->UserLength);
|
||||
context->identity.UserLength = identity->UserLength;
|
||||
|
||||
if (identity->DomainLength > 0)
|
||||
{
|
||||
context->identity.Domain = (UINT16*) malloc(identity->DomainLength);
|
||||
memcpy(context->identity.Domain, identity->Domain, identity->DomainLength);
|
||||
context->identity.DomainLength = identity->DomainLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->identity.Domain = (UINT16*) NULL;
|
||||
context->identity.DomainLength = 0;
|
||||
}
|
||||
|
||||
context->identity.Password = (UINT16*) malloc(identity->PasswordLength);
|
||||
memcpy(context->identity.Password, identity->Password, identity->PasswordLength);
|
||||
context->identity.PasswordLength = identity->PasswordLength;
|
||||
}
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
@ -123,7 +70,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCre
|
||||
context = negotiate_ContextNew();
|
||||
|
||||
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
negotiate_SetContextIdentity(context, &credentials->identity);
|
||||
sspi_CopyAuthIdentity(&context->identity, &credentials->identity);
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phNewContext, context);
|
||||
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME);
|
||||
@ -157,7 +104,6 @@ NEGOTIATE_CONTEXT* negotiate_ContextNew()
|
||||
{
|
||||
context->NegotiateFlags = 0;
|
||||
context->state = NEGOTIATE_STATE_INITIAL;
|
||||
context->uniconv = freerdp_uniconv_new();
|
||||
}
|
||||
|
||||
return context;
|
||||
|
@ -41,9 +41,8 @@ typedef enum _NEGOTIATE_STATE NEGOTIATE_STATE;
|
||||
struct _NEGOTIATE_CONTEXT
|
||||
{
|
||||
NEGOTIATE_STATE state;
|
||||
UNICONV* uniconv;
|
||||
uint32 NegotiateFlags;
|
||||
CtxtHandle* auth_ctx;
|
||||
PCtxtHandle auth_ctx;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SecBuffer NegoInitMessage;
|
||||
};
|
||||
|
@ -301,6 +301,33 @@ void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* d
|
||||
}
|
||||
}
|
||||
|
||||
void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity)
|
||||
{
|
||||
if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
{
|
||||
sspi_SetAuthIdentity(identity, (char*) srcIdentity->User,
|
||||
(char*) srcIdentity->Domain, (char*) srcIdentity->Password);
|
||||
|
||||
identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
|
||||
identity->UserLength = srcIdentity->UserLength;
|
||||
identity->User = malloc(identity->UserLength);
|
||||
CopyMemory(identity->User, srcIdentity->User, identity->UserLength);
|
||||
|
||||
identity->DomainLength = srcIdentity->DomainLength;
|
||||
identity->Domain = malloc(identity->DomainLength);
|
||||
CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength);
|
||||
|
||||
identity->PasswordLength = srcIdentity->PasswordLength;
|
||||
identity->Password = malloc(identity->PasswordLength);
|
||||
CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength);
|
||||
}
|
||||
|
||||
void sspi_GlobalInit()
|
||||
{
|
||||
sspi_ContextBufferAllocTableNew();
|
||||
|
@ -43,6 +43,7 @@ void sspi_SecureHandleSetUpperPointer(SecHandle* handle, void* pointer);
|
||||
void sspi_SecureHandleFree(SecHandle* handle);
|
||||
|
||||
void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* domain, char* password);
|
||||
void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity);
|
||||
|
||||
enum SecurityFunctionTableIndex
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user