/* Establish a connection up to the ISO layer */ RD_BOOL iso_connect(char *server, char *username, RD_BOOL reconnect) { uint8 code = 0; if (!tcp_connect(server)) return False; if (reconnect) { iso_send_msg(ISO_PDU_CR); } else { iso_send_connection_request(username); } if (iso_recv_msg(&code, NULL) == NULL) return False; if (code != ISO_PDU_CC) { error("expected CC, got 0x%x\n", code); tcp_disconnect(); return False; } return True; }
/* Establish a reconnection up to the ISO layer */ BOOL iso_reconnect(char *server) { uint8 code = 0; if (!tcp_connect(server)) return False; iso_send_msg(ISO_PDU_CR); if (iso_recv_msg(&code, NULL) == NULL) return False; if (code != ISO_PDU_CC) { error("expected CC, got 0x%x\n", code); tcp_disconnect(); return False; } return True; }
/* Disconnect from the ISO layer */ void iso_disconnect(void) { iso_send_msg(ISO_PDU_DR); tcp_disconnect(); }
/* Establish a connection up to the ISO layer */ RD_BOOL iso_connect(char *server, char *username, RD_BOOL reconnect, uint32 * selected_protocol) { STREAM s; uint8 code; g_negotiate_rdp_protocol = True; retry: *selected_protocol = PROTOCOL_RDP; code = 0; if (!tcp_connect(server)) return False; if (reconnect) { iso_send_msg(ISO_PDU_CR); } else { iso_send_connection_request(username); } s = iso_recv_msg(&code, NULL); if (s == NULL) return False; if (code != ISO_PDU_CC) { error("expected CC, got 0x%x\n", code); tcp_disconnect(); return False; } if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8)) { /* handle RDP_NEG_REQ response */ const char *reason = NULL; uint8 type = 0, flags = 0; uint16 length = 0; uint32 data = 0; in_uint8(s, type); in_uint8(s, flags); in_uint16(s, length); in_uint32(s, data); if (type == RDP_NEG_FAILURE) { switch (data) { case SSL_REQUIRED_BY_SERVER: reason = "SSL required by server"; break; case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER: reason = "SSL with user authentication required by server"; break; case SSL_NOT_ALLOWED_BY_SERVER: reason = "SSL not allowed by server"; break; case SSL_CERT_NOT_ON_SERVER: reason = "SSL certificated not on server"; break; case INCONSISTENT_FLAGS: reason = "inconsistent flags"; break; case HYBRID_REQUIRED_BY_SERVER: reason = "hybrid authentication (CredSSP) required by server"; break; default: reason = "unknown reason"; } tcp_disconnect(); warning("RDP protocol negotiation failed with reason: %s (error 0x%x),\n", reason, data); warning("retrying without negotiation using plain RDP protocol.\n"); g_negotiate_rdp_protocol = False; goto retry; } if (type != RDP_NEG_RSP) { tcp_disconnect(); error("expected RDP_NEG_RSP, got type = 0x%x\n", type); warning("retrying without negotiation using plain RDP protocol.\n"); g_negotiate_rdp_protocol = False; goto retry; } /* handle negotiation response */ if (data == PROTOCOL_SSL) { DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL\n")); if (!tcp_tls_connect()) { tcp_disconnect(); DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL FAILED\n")); return False; } /* do not use encryption when using TLS */ g_encryption = False; } else if (data != PROTOCOL_RDP) { tcp_disconnect(); error("unexpected protocol in neqotiation response, got data = 0x%x.\n", data); return False; } *selected_protocol = data; } return True; }
/* Disconnect from the ISO layer */ BOOL iso_disconnect(RDPCLIENT * This) { iso_send_msg(This, ISO_PDU_DR); return tcp_disconnect(This); }