void settings_free(rdpSettings* settings) { if (settings != NULL) { freerdp_uniconv_free(settings->uniconv); xfree(settings->hostname); xfree(settings->username); xfree(settings->password); xfree(settings->domain); xfree(settings->shell); xfree(settings->directory); xfree(settings->ip_address); xfree(settings->client_dir); xfree(settings->cert_file); xfree(settings->privatekey_file); freerdp_blob_free(settings->server_random); freerdp_blob_free(settings->server_certificate); xfree(settings->server_random); xfree(settings->server_certificate); xfree(settings->rdp_key_file); certificate_free(settings->server_cert); xfree(settings->client_auto_reconnect_cookie); xfree(settings->server_auto_reconnect_cookie); xfree(settings->client_time_zone); xfree(settings->bitmapCacheV2CellInfo); xfree(settings->glyphCache); xfree(settings->fragCache); key_free(settings->server_key); xfree(settings->config_path); xfree(settings->current_path); xfree(settings->development_path); xfree(settings); } }
int credssp_authenticate(rdpCredssp* credssp) { NTLMSSP* ntlmssp = credssp->ntlmssp; STREAM* s = stream_new(0); uint8* negoTokenBuffer = (uint8*) xmalloc(2048); if (credssp_ntlmssp_init(credssp) == 0) return 0; if (credssp_get_public_key(credssp) == 0) return 0; /* NTLMSSP NEGOTIATE MESSAGE */ s->p = s->data = negoTokenBuffer; ntlmssp_send(ntlmssp, s); credssp->negoToken.data = s->data; credssp->negoToken.length = s->p - s->data; credssp_send(credssp, &credssp->negoToken, NULL, NULL); /* NTLMSSP CHALLENGE MESSAGE */ if (credssp_recv(credssp, &credssp->negoToken, NULL, NULL) < 0) return -1; s->p = s->data = credssp->negoToken.data; ntlmssp_recv(ntlmssp, s); freerdp_blob_free(&credssp->negoToken); /* NTLMSSP AUTHENTICATE MESSAGE */ s->p = s->data = negoTokenBuffer; ntlmssp_send(ntlmssp, s); /* The last NTLMSSP message is sent with the encrypted public key */ credssp->negoToken.data = s->data; credssp->negoToken.length = s->p - s->data; credssp_encrypt_public_key(credssp, &credssp->pubKeyAuth); credssp_send(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth); /* Encrypted Public Key +1 */ if (credssp_recv(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth) < 0) return -1; if (credssp_verify_public_key(credssp, &credssp->pubKeyAuth) == 0) { /* Failed to verify server public key echo */ return 0; /* DO NOT SEND CREDENTIALS! */ } freerdp_blob_free(&credssp->negoToken); freerdp_blob_free(&credssp->pubKeyAuth); /* Send encrypted credentials */ credssp_encode_ts_credentials(credssp); credssp_encrypt_ts_credentials(credssp, &credssp->authInfo); credssp_send(credssp, NULL, &credssp->authInfo, NULL); xfree(s); return 1; }
void redirection_free(rdpRedirection* redirection) { if (redirection != NULL) { //these four have already been freed in settings_free() and freerdp_string_free() checks for NULL redirection->username.ascii = NULL; redirection->domain.ascii = NULL; redirection->targetNetAddress.ascii = NULL; redirection->targetNetBiosName.ascii = NULL; freerdp_string_free(&redirection->tsvUrl); freerdp_string_free(&redirection->username); freerdp_string_free(&redirection->domain); freerdp_blob_free(&redirection->password_cookie); freerdp_string_free(&redirection->targetFQDN); freerdp_string_free(&redirection->targetNetBiosName); freerdp_string_free(&redirection->targetNetAddress); freerdp_blob_free(&redirection->loadBalanceInfo); if (redirection->targetNetAddresses != NULL) { int i; for (i = 0; i < (int) redirection->targetNetAddressesCount; i++) freerdp_string_free(&redirection->targetNetAddresses[i]); xfree(redirection->targetNetAddresses); } xfree(redirection); } }
void kerberos_ContextFree(KRB_CONTEXT* krb_ctx) { if (krb_ctx != NULL) { xfree(krb_ctx->krbhost); xfree(krb_ctx->cname); xfree(krb_ctx->realm); freerdp_blob_free(&(krb_ctx->passwd)); if(krb_ctx->askey != NULL) { freerdp_blob_free(&(krb_ctx->askey->skey)); xfree(krb_ctx->askey); } if(krb_ctx->tgskey != NULL) { freerdp_blob_free(&(krb_ctx->tgskey->skey)); xfree(krb_ctx->tgskey); } krb_free_ticket(&(krb_ctx->asticket)); krb_free_ticket(&(krb_ctx->tgsticket)); krb_ctx->state = KRB_STATE_FINAL; } }
void key_free(rdpKey* key) { if (key != NULL) { freerdp_blob_free(&key->modulus); freerdp_blob_free(&key->private_exponent); xfree(key); } }
void credssp_free(rdpCredssp* credssp) { if (credssp != NULL) { freerdp_blob_free(&credssp->public_key); freerdp_blob_free(&credssp->ts_credentials); ntlmssp_free(credssp->ntlmssp); xfree(credssp); } }
int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d) { uint8 *p1, *p2; uint8 *signature; rdpBlob public_key; rdpBlob encrypted_public_key; signature = d->data; encrypted_public_key.data = (void*) (signature + 16); encrypted_public_key.length = d->length - 16; ntlmssp_decrypt_message(credssp->ntlmssp, &encrypted_public_key, &public_key, signature); p1 = (uint8*) credssp->public_key.data; p2 = (uint8*) public_key.data; p2[0]--; if (memcmp(p1, p2, public_key.length) != 0) { printf("Could not verify server's public key echo\n"); return 0; } p2[0]++; freerdp_blob_free(&public_key); return 1; }
void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d) { uint8 *p; uint8 signature[16]; rdpBlob encrypted_public_key; NTLMSSP *ntlmssp = credssp->ntlmssp; freerdp_blob_alloc(d, credssp->public_key.length + 16); ntlmssp_encrypt_message(ntlmssp, &credssp->public_key, &encrypted_public_key, signature); #ifdef WITH_DEBUG_NLA printf("Public Key (length = %d)\n", credssp->public_key.length); freerdp_hexdump(credssp->public_key.data, credssp->public_key.length); printf("\n"); printf("Encrypted Public Key (length = %d)\n", encrypted_public_key.length); freerdp_hexdump(encrypted_public_key.data, encrypted_public_key.length); printf("\n"); printf("Signature\n"); freerdp_hexdump(signature, 16); printf("\n"); #endif p = (uint8*) d->data; memcpy(p, signature, 16); /* Message Signature */ memcpy(&p[16], encrypted_public_key.data, encrypted_public_key.length); /* Encrypted Public Key */ freerdp_blob_free(&encrypted_public_key); }
void credssp_encrypt_ts_credentials(rdpCredssp* credssp, rdpBlob* d) { uint8 *p; uint8 signature[16]; rdpBlob encrypted_ts_credentials; NTLMSSP *ntlmssp = credssp->ntlmssp; freerdp_blob_alloc(d, credssp->ts_credentials.length + 16); ntlmssp_encrypt_message(ntlmssp, &credssp->ts_credentials, &encrypted_ts_credentials, signature); #ifdef WITH_DEBUG_NLA printf("TSCredentials (length = %d)\n", credssp->ts_credentials.length); freerdp_hexdump(credssp->ts_credentials.data, credssp->ts_credentials.length); printf("\n"); printf("Encrypted TSCredentials (length = %d)\n", encrypted_ts_credentials.length); freerdp_hexdump(encrypted_ts_credentials.data, encrypted_ts_credentials.length); printf("\n"); printf("Signature\n"); freerdp_hexdump(signature, 16); printf("\n"); #endif p = (uint8*) d->data; memcpy(p, signature, 16); /* Message Signature */ memcpy(&p[16], encrypted_ts_credentials.data, encrypted_ts_credentials.length); /* Encrypted TSCredentials */ freerdp_blob_free(&encrypted_ts_credentials); }
void redirection_free(rdpRedirection* redirection) { if (redirection != NULL) { freerdp_string_free(&redirection->tsvUrl); freerdp_string_free(&redirection->username); freerdp_string_free(&redirection->domain); freerdp_string_free(&redirection->password); freerdp_string_free(&redirection->targetFQDN); freerdp_string_free(&redirection->targetNetBiosName); freerdp_string_free(&redirection->targetNetAddress); freerdp_blob_free(&redirection->loadBalanceInfo); if (redirection->targetNetAddresses != NULL) { int i; for (i = 0; i < redirection->targetNetAddressesCount; i++) freerdp_string_free(&redirection->targetNetAddresses[i]); xfree(redirection->targetNetAddresses); } xfree(redirection); } }
void krb_free_krb_error(KrbERROR* krb_err) { if(krb_err != NULL) { xfree(krb_err->stime); freerdp_blob_free(&(krb_err->edata)); } }
void krb_free_reppart(ENCKDCREPPart* reppart) { if(reppart != NULL) { freerdp_blob_free(&(reppart->key.skey)); xfree(reppart->sname); xfree(reppart->realm); } }
void krb_free_ticket(Ticket* ticket) { if (ticket != NULL) { xfree(ticket->realm); xfree(ticket->sname); freerdp_blob_free(&(ticket->enc_part.encblob)); ticket->enc_part.encblob.data = NULL; } }
void krb_free_kdcrep(KrbKDCREP* kdc_rep) { if(kdc_rep != NULL) { krb_free_padata(kdc_rep->padata); xfree(kdc_rep->cname); xfree(kdc_rep->realm); krb_free_ticket(&(kdc_rep->etgt)); freerdp_blob_free(&(kdc_rep->enc_part.encblob)); kdc_rep->enc_part.encblob.data = NULL; } }
void certificate_free(rdpCertificate* certificate) { if (certificate != NULL) { certificate_free_x509_certificate_chain(certificate->x509_cert_chain); if (certificate->cert_info.modulus.data != NULL) freerdp_blob_free(&(certificate->cert_info.modulus)); xfree(certificate); } }
void tls_free(rdpTls* tls) { if (tls != NULL) { if (tls->ssl) SSL_free(tls->ssl); if (tls->ctx) SSL_CTX_free(tls->ctx); freerdp_blob_free(&tls->public_key); certificate_store_free(tls->certificate_store); xfree(tls); } }
boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s) { int i; uint32 certLength; uint32 numCertBlobs; DEBUG_CERTIFICATE("Server X.509 Certificate Chain"); stream_read_uint32(s, numCertBlobs); /* numCertBlobs */ certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs); for (i = 0; i < (int) numCertBlobs; i++) { stream_read_uint32(s, certLength); DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength); certificate->x509_cert_chain->array[i].data = (uint8*) xmalloc(certLength); stream_read(s, certificate->x509_cert_chain->array[i].data, certLength); certificate->x509_cert_chain->array[i].length = certLength; if (numCertBlobs - i == 2) { rdpCertInfo cert_info; DEBUG_CERTIFICATE("License Server Certificate"); certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &cert_info); DEBUG_LICENSE("modulus length:%d", cert_info.modulus.length); freerdp_blob_free(&cert_info.modulus); } else if (numCertBlobs - i == 1) { DEBUG_CERTIFICATE("Terminal Server Certificate"); certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->cert_info); DEBUG_CERTIFICATE("modulus length:%d", certificate->cert_info.modulus.length); } } return true; }
boolean rdp_client_redirect(rdpRdp* rdp) { rdpSettings* settings = rdp->settings; rdpRedirection* redirection = rdp->redirection; rdp_client_disconnect(rdp); /* FIXME: this is a subset of rdp_free */ crypto_rc4_free(rdp->rc4_decrypt_key); crypto_rc4_free(rdp->rc4_encrypt_key); crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); crypto_hmac_free(rdp->fips_hmac); mcs_free(rdp->mcs); nego_free(rdp->nego); license_free(rdp->license); transport_free(rdp->transport); /* FIXME: this is a subset of settings_free */ freerdp_blob_free(settings->server_random); freerdp_blob_free(settings->server_certificate); xfree(settings->ip_address); rdp->transport = transport_new(settings); rdp->license = license_new(rdp); rdp->nego = nego_new(rdp->transport); rdp->mcs = mcs_new(rdp->transport); rdp->transport->layer = TRANSPORT_LAYER_TCP; settings->redirected_session_id = redirection->sessionID; if (redirection->flags & LB_LOAD_BALANCE_INFO) { nego_set_routing_token(rdp->nego, &redirection->loadBalanceInfo); } else { if (redirection->flags & LB_TARGET_NET_ADDRESS) { xfree(settings->hostname); settings->hostname = xstrdup(redirection->targetNetAddress.ascii); } else if (redirection->flags & LB_TARGET_FQDN) { xfree(settings->hostname); settings->hostname = xstrdup(redirection->targetFQDN.ascii); } else if (redirection->flags & LB_TARGET_NETBIOS_NAME) { xfree(settings->hostname); settings->hostname = xstrdup(redirection->targetNetBiosName.ascii); } } if (redirection->flags & LB_USERNAME) { xfree(settings->username); settings->username = xstrdup(redirection->username.ascii); } if (redirection->flags & LB_DOMAIN) { xfree(settings->domain); settings->domain = xstrdup(redirection->domain.ascii); } if (redirection->flags & LB_PASSWORD) { settings->password_cookie = &redirection->password_cookie; } return rdp_client_connect(rdp); }
int krb_verify_kdcrep(KRB_CONTEXT* krb_ctx, KrbKDCREP* kdc_rep, int msgtype) { ENCKDCREPPart* reppart; KrbENCKey* key; rdpBlob* decmsg; uint8 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)) { krb_ctx->state = KRB_PACKET_ERROR; return -1; } /* decrypt enc-part */ decmsg = xnew(rdpBlob); if(krb_ctx->askey->enctype != kdc_rep->enc_part.enctype && msgtype == KRB_TAG_ASREP) { freerdp_blob_free(&(krb_ctx->askey->skey)); xfree(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) { key = krb_ctx->askey; tag = 25; } else if (msgtype == KRB_TAG_TGSREP) { key = krb_ctx->tgskey; tag = 26; } /* KDC-REP-PART decode */ if(decmsg == NULL || ((reppart = krb_decode_enc_reppart(decmsg, tag)) == NULL)) { krb_ctx->state = KRB_PACKET_ERROR; return -1; } freerdp_blob_free(decmsg); xfree(decmsg); /* Verify KDC-REP-PART */ if(reppart->nonce != krb_ctx->nonce || strcasecmp(reppart->realm, krb_ctx->realm) || strcasecmp(reppart->sname, krb_ctx->sname)) { krb_free_reppart(reppart); xfree(reppart); krb_ctx->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); freerdp_blob_copy(&(key->skey), &(reppart->key.skey)); key->enctype = reppart->key.enctype; krb_free_reppart(reppart); xfree(reppart); return 0; }
void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode) { KrbTGSREQ* krb_tgsreq; KrbAPREQ* krb_apreq; PAData** pa_data; Authenticator* krb_auth; STREAM* s; STREAM* sapreq; rdpBlob msg; uint32 curlen, totlen, tmp; uint8 *bm; bm = NULL; totlen = tmp = 0; krb_tgsreq = krb_tgsreq_new(krb_ctx, errcode); krb_auth = xnew(Authenticator); pa_data = krb_tgsreq->padata; s = stream_new(4096); sapreq = stream_new(2048); //Begin write asn1 data reversely into stream stream_seek(s, 4095); stream_seek(sapreq, 2047); /* KDC-REQ-BODY (TAG 4) */ totlen += krb_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); 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->ctime = krb_tgsreq->req_body.from; krb_auth->cusec = 0; crypto_nonce((uint8*)&(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); msg.data = sapreq->p; msg.length = curlen; (*pa_data)->type = 1; (*pa_data)->value = msg; /* PA-DATA (TAG 3) */ curlen = krb_encode_padata(s, pa_data); totlen += curlen + krb_encode_contextual_tag(s, 3, curlen); /* MSGTYPE (TAG 2) */ totlen += krb_encode_uint8(s, 2, krb_tgsreq->type); /* VERSION NO (TAG 1) */ totlen += krb_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); /* READY SEND */ krb_tcp_send(krb_ctx, s->p, totlen); /* save stuff */ krb_ctx->nonce = krb_tgsreq->req_body.nonce; xfree(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; /* clean up */ freerdp_blob_free(krb_auth->cksum); xfree(krb_auth->cksum); xfree(krb_auth); krb_free_tgsreq(krb_tgsreq); xfree(krb_tgsreq); stream_free(sapreq); stream_free(s); }
void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode) { KrbASREQ* krb_asreq; PAData** pa_data; KrbENCData enc_data; KrbENCKey* enckey; STREAM* s; STREAM* paenc; rdpBlob msg; rdpBlob* encmsg; uint32 curlen, totlen, pai; uint8 *bm; bm = NULL; totlen = pai = 0; krb_asreq = krb_asreq_new(krb_ctx, errcode); pa_data = krb_asreq->padata; enckey = NULL; s = stream_new(2048); paenc = stream_new(100); //Begin write asn1 data reversely into stream stream_seek(s, 1024); 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); /* padata = PA-ENC-TIMESTAMP */ 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); 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); freerdp_blob_free(&msg); msg.data = paenc->p; msg.length = curlen; /* padata = PA-ENC-TIMESTAMP */ (*(pa_data + pai))->type = 2; (*(pa_data + pai))->value = msg; pai++; freerdp_blob_free(encmsg); xfree(encmsg); } 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; /* padata = PA-PAC-REQUEST */ (*(pa_data + pai))->type = 128; (*(pa_data + pai))->value = msg; *(pa_data + ++pai) = NULL; /* padata (TAG 3) */ curlen = krb_encode_padata(s, pa_data); totlen += curlen + krb_encode_contextual_tag(s, 3, curlen); /* MSGTYPE = AS-REQ (TAG 2) */ totlen += krb_encode_uint8(s, 2, krb_asreq->type); /* KERBEROS PROTOCOL VERSION NO (TAG 1)*/ totlen += krb_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); /* READY SEND */ krb_tcp_send(krb_ctx, s->p, totlen); /* save stuff */ krb_ctx->askey = enckey; krb_ctx->nonce = krb_asreq->req_body.nonce; xfree(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; /* clean up */ freerdp_blob_free(&msg); stream_free(s); stream_free(paenc); krb_free_asreq(krb_asreq); xfree(krb_asreq); }