libwinpr-sspi: cleanup of data types

This commit is contained in:
Marc-André Moreau 2012-05-24 22:20:51 -04:00
parent 9fd0d13a1c
commit 45009824be
11 changed files with 371 additions and 376 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;
};

View File

@ -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();

View File

@ -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
{