?? secure.c
字號(hào):
} } s_mark_end(s);}/* Parse a public key structure */static RD_BOOLsec_parse_public_key(STREAM s, uint8 * modulus, uint8 * exponent){ uint32 magic, modulus_len; in_uint32_le(s, magic); if (magic != SEC_RSA_MAGIC) { error("RSA magic 0x%x\n", magic); return False; } in_uint32_le(s, modulus_len); modulus_len -= SEC_PADDING_SIZE; if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE)) { error("Bad server public key size (%u bits)\n", modulus_len * 8); return False; } in_uint8s(s, 8); /* modulus_bits, unknown */ in_uint8a(s, exponent, SEC_EXPONENT_SIZE); in_uint8a(s, modulus, modulus_len); in_uint8s(s, SEC_PADDING_SIZE); g_server_public_key_len = modulus_len; return s_check(s);}/* Parse a public signature structure */static RD_BOOLsec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent){ uint8 signature[SEC_MAX_MODULUS_SIZE]; uint32 sig_len; if (len != 72) { return True; } memset(signature, 0, sizeof(signature)); sig_len = len - 8; in_uint8a(s, signature, sig_len); return ssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, g_server_public_key_len, signature, sig_len);}/* Parse a crypto information structure */static RD_BOOLsec_parse_crypt_info(STREAM s, uint32 * rc4_key_size, uint8 ** server_random, uint8 * modulus, uint8 * exponent){ uint32 crypt_level, random_len, rsa_info_len; uint32 cacert_len, cert_len, flags; SSL_CERT *cacert, *server_cert; SSL_RKEY *server_public_key; uint16 tag, length; uint8 *next_tag, *end; in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */ in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */ if (crypt_level == 0) /* no encryption */ return False; in_uint32_le(s, random_len); in_uint32_le(s, rsa_info_len); if (random_len != SEC_RANDOM_SIZE) { error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE); return False; } in_uint8p(s, *server_random, random_len); /* RSA info */ end = s->p + rsa_info_len; if (end > s->end) return False; in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */ if (flags & 1) { DEBUG_RDP5(("We're going for the RDP4-style encryption\n")); in_uint8s(s, 8); /* unknown */ while (s->p < end) { in_uint16_le(s, tag); in_uint16_le(s, length); next_tag = s->p + length; switch (tag) { case SEC_TAG_PUBKEY: if (!sec_parse_public_key(s, modulus, exponent)) return False; DEBUG_RDP5(("Got Public key, RDP4-style\n")); break; case SEC_TAG_KEYSIG: if (!sec_parse_public_sig(s, length, modulus, exponent)) return False; break; default: unimpl("crypt tag 0x%x\n", tag); } s->p = next_tag; } } else { uint32 certcount; DEBUG_RDP5(("We're going for the RDP5-style encryption\n")); in_uint32_le(s, certcount); /* Number of certificates */ if (certcount < 2) { error("Server didn't send enough X509 certificates\n"); return False; } for (; certcount > 2; certcount--) { /* ignore all the certificates between the root and the signing CA */ uint32 ignorelen; SSL_CERT *ignorecert; DEBUG_RDP5(("Ignored certs left: %d\n", certcount)); in_uint32_le(s, ignorelen); DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen)); ignorecert = ssl_cert_read(s->p, ignorelen); in_uint8s(s, ignorelen); if (ignorecert == NULL) { /* XXX: error out? */ DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n")); }#ifdef WITH_DEBUG_RDP5 DEBUG_RDP5(("cert #%d (ignored):\n", certcount)); ssl_cert_print_fp(stdout, ignorecert);#endif } /* Do da funky X.509 stuffy "How did I find out about this? I looked up and saw a bright light and when I came to I had a scar on my forehead and knew about X.500" - Peter Gutman in a early version of http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt */ in_uint32_le(s, cacert_len); DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len)); cacert = ssl_cert_read(s->p, cacert_len); in_uint8s(s, cacert_len); if (NULL == cacert) { error("Couldn't load CA Certificate from server\n"); return False; } in_uint32_le(s, cert_len); DEBUG_RDP5(("Certificate length is %d\n", cert_len)); server_cert = ssl_cert_read(s->p, cert_len); in_uint8s(s, cert_len); if (NULL == server_cert) { ssl_cert_free(cacert); error("Couldn't load Certificate from server\n"); return False; } if (!ssl_certs_ok(server_cert, cacert)) { ssl_cert_free(server_cert); ssl_cert_free(cacert); error("Security error CA Certificate invalid\n"); return False; } ssl_cert_free(cacert); in_uint8s(s, 16); /* Padding */ server_public_key = ssl_cert_to_rkey(server_cert, &g_server_public_key_len); if (NULL == server_public_key) { DEBUG_RDP5(("Didn't parse X509 correctly\n")); ssl_cert_free(server_cert); return False; } ssl_cert_free(server_cert); if ((g_server_public_key_len < SEC_MODULUS_SIZE) || (g_server_public_key_len > SEC_MAX_MODULUS_SIZE)) { error("Bad server public key size (%u bits)\n", g_server_public_key_len * 8); ssl_rkey_free(server_public_key); return False; } if (ssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE, modulus, SEC_MAX_MODULUS_SIZE) != 0) { error("Problem extracting RSA exponent, modulus"); ssl_rkey_free(server_public_key); return False; } ssl_rkey_free(server_public_key); return True; /* There's some garbage here we don't care about */ } return s_check_end(s);}/* Process crypto information blob */static voidsec_process_crypt_info(STREAM s){ uint8 *server_random = NULL; uint8 client_random[SEC_RANDOM_SIZE]; uint8 modulus[SEC_MAX_MODULUS_SIZE]; uint8 exponent[SEC_EXPONENT_SIZE]; uint32 rc4_key_size; memset(modulus, 0, sizeof(modulus)); memset(exponent, 0, sizeof(exponent)); if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent)) { DEBUG(("Failed to parse crypt info\n")); return; } DEBUG(("Generating client random\n")); generate_random(client_random); sec_rsa_encrypt(g_sec_crypted_random, client_random, SEC_RANDOM_SIZE, g_server_public_key_len, modulus, exponent); sec_generate_keys(client_random, server_random, rc4_key_size);}/* Process SRV_INFO, find RDP version supported by server */static voidsec_process_srv_info(STREAM s){ in_uint16_le(s, g_server_rdp_version); DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version)); if (1 == g_server_rdp_version) { g_use_rdp5 = 0; g_server_depth = 8; }}/* Process connect response data blob */voidsec_process_mcs_data(STREAM s){ uint16 tag, length; uint8 *next_tag; uint8 len; in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */ in_uint8(s, len); if (len & 0x80) in_uint8(s, len); while (s->p < s->end) { in_uint16_le(s, tag); in_uint16_le(s, length); if (length <= 4) return; next_tag = s->p + length - 4; switch (tag) { case SEC_TAG_SRV_INFO: sec_process_srv_info(s); break; case SEC_TAG_SRV_CRYPT: sec_process_crypt_info(s); break; case SEC_TAG_SRV_CHANNELS: /* FIXME: We should parse this information and use it to map RDP5 channels to MCS channels */ break; default: unimpl("response tag 0x%x\n", tag); } s->p = next_tag; }}/* Receive secure transport packet */STREAMsec_recv(uint8 * rdpver){ uint32 sec_flags; uint16 channel; STREAM s; while ((s = mcs_recv(&channel, rdpver)) != NULL) { if (rdpver != NULL) { if (*rdpver != 3) { if (*rdpver & 0x80) { in_uint8s(s, 8); /* signature */ sec_decrypt(s->p, s->end - s->p); } return s; } } if (g_encryption || !g_licence_issued) { in_uint32_le(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { in_uint8s(s, 8); /* signature */ sec_decrypt(s->p, s->end - s->p); } if (sec_flags & SEC_LICENCE_NEG) { licence_process(s); continue; } if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */ { uint8 swapbyte; in_uint8s(s, 8); /* signature */ sec_decrypt(s->p, s->end - s->p); /* Check for a redirect packet, starts with 00 04 */ if (s->p[0] == 0 && s->p[1] == 4) { /* for some reason the PDU and the length seem to be swapped. This isn't good, but we're going to do a byte for byte swap. So the first foure value appear as: 00 04 XX YY, where XX YY is the little endian length. We're going to use 04 00 as the PDU type, so after our swap this will look like: XX YY 04 00 */ swapbyte = s->p[0]; s->p[0] = s->p[2]; s->p[2] = swapbyte; swapbyte = s->p[1]; s->p[1] = s->p[3]; s->p[3] = swapbyte; swapbyte = s->p[2]; s->p[2] = s->p[3]; s->p[3] = swapbyte; }#ifdef WITH_DEBUG /* warning! this debug statement will show passwords in the clear! */ hexdump(s->p, s->end - s->p);#endif } } if (channel != MCS_GLOBAL_CHANNEL) { channel_process(s, channel); *rdpver = 0xff; return s; } return s; } return NULL;}/* Establish a secure connection */RD_BOOLsec_connect(char *server, char *username){ struct stream mcs_data; /* We exchange some RDP data during the MCS-Connect */ mcs_data.size = 512; mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size); sec_out_mcs_data(&mcs_data); if (!mcs_connect(server, &mcs_data, username)) return False; /* sec_process_mcs_data(&mcs_data); */ if (g_encryption) sec_establish_key(); xfree(mcs_data.data); return True;}/* Establish a secure connection */RD_BOOLsec_reconnect(char *server){ struct stream mcs_data; /* We exchange some RDP data during the MCS-Connect */ mcs_data.size = 512; mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size); sec_out_mcs_data(&mcs_data); if (!mcs_reconnect(server, &mcs_data)) return False; /* sec_process_mcs_data(&mcs_data); */ if (g_encryption) sec_establish_key(); xfree(mcs_data.data); return True;}/* Disconnect a connection */voidsec_disconnect(void){ mcs_disconnect();}/* reset the state of the sec layer */voidsec_reset_state(void){ g_server_rdp_version = 0; g_sec_encrypt_use_count = 0; g_sec_decrypt_use_count = 0; mcs_reset_state();}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -