PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/rdp_pure/jx/rdp/MCS.java

https://gitlab.com/manadream/jx
Java | 380 lines | 281 code | 71 blank | 28 comment | 50 complexity | a28ec7db31ec7357168a174caa007e27 MD5 | raw file
  1. package jx.rdp;
  2. import java.io.*;
  3. import java.net.*;
  4. import jx.net.IPAddress;
  5. import jx.zero.*;
  6. import jx.zero.Debug;
  7. public class MCS {
  8. private boolean debug = true;
  9. private HexDump dump = null;
  10. private ISO IsoLayer=null;
  11. private int McsUserID;
  12. /* this for the MCS Layer */
  13. private static final int CONNECT_INITIAL = 0x7f65;
  14. private static final int CONNECT_RESPONSE= 0x7f66;
  15. private static final int BER_TAG_BOOLEAN = 1;
  16. private static final int BER_TAG_INTEGER = 2;
  17. private static final int BER_TAG_OCTET_STRING = 4;
  18. private static final int BER_TAG_RESULT = 10;
  19. private static final int TAG_DOMAIN_PARAMS = 0x30;
  20. private static final int MCS_GLOBAL_CHANNEL =1003;
  21. private static final int EDRQ = 1; /* Erect Domain Request */
  22. private static final int DPUM = 8; /* Disconnect Provider Ultimatum */
  23. private static final int AURQ = 10; /* Attach User Request */
  24. private static final int AUCF = 11; /* Attach User Confirm */
  25. private static final int CJRQ = 14; /* Channel Join Request */
  26. private static final int CJCF = 15; /* Channel Join Confirm */
  27. private static final int SDRQ = 25; /* Send Data Request */
  28. private static final int SDIN = 26; /* Send Data Indication */
  29. public MCS() {
  30. IsoLayer = new ISO();
  31. dump = new HexDump();
  32. }
  33. public void connect(IPAddress host, int port, Packet data) throws IOException, RdesktopException, SocketException {
  34. IsoLayer.connect(host, port);
  35. if(debug)Debug.out.println("Sending Connect Initial ...");
  36. this.sendConnectInitial(data);
  37. if(debug)Debug.out.println("Connect Initial sent");
  38. if(debug)Debug.out.println("Receiving Connect Response ...");
  39. this.receiveConnectResponse(data);
  40. if(debug)Debug.out.println("Connect response received: O.K.");
  41. if(debug)Debug.out.println("Sending Erect Domain Request ...");
  42. send_edrq();
  43. if(debug)Debug.out.println("Erect Domain Request sent");
  44. if(debug)Debug.out.println("Sending AURQ ...");
  45. send_aurq();
  46. if(debug)Debug.out.println("AURQ sent");
  47. if(debug)Debug.out.println("Receiving AUCF ...");
  48. this.McsUserID=receive_aucf();
  49. if(debug)Debug.out.println("AUCF received: O.K.");
  50. if(debug)Debug.out.println("Sending CJRQ ...");
  51. send_cjrq(this.McsUserID+1001);
  52. if(debug)Debug.out.println("CJRQ sent");
  53. if(debug)Debug.out.println("Receiving CJCF ...");
  54. receive_cjcf();
  55. if(debug)Debug.out.println("CJCF received: O.K.");
  56. if(debug)Debug.out.println("Sending CJRQ ...");
  57. send_cjrq(this.MCS_GLOBAL_CHANNEL);
  58. if(debug)Debug.out.println("CJRQ sent");
  59. if(debug)Debug.out.println("Receiving CJCF ...");
  60. receive_cjcf();
  61. if(debug)Debug.out.println("CJCF received: O.K.");
  62. }
  63. /*
  64. public void connect(String host, int port, Packet data) throws UnknownHostException, IOException, RdesktopException, SocketException {
  65. this.connect(InetAddress.getByName(host), port, data);
  66. }
  67. public void connect(InetAddress host, Packet data) throws IOException, RdesktopException, SocketException {
  68. this.connect(host, Constants.PORT, data);
  69. }
  70. public void connect(String host, Packet data) throws UnknownHostException, IOException, RdesktopException, SocketException {
  71. this.connect(InetAddress.getByName(host), Constants.PORT, data);
  72. }*/
  73. public void disconnect() {
  74. IsoLayer.disconnect();
  75. //in=null;
  76. //out=null;
  77. }
  78. public Packet init(int length) throws RdesktopException {
  79. Packet data = IsoLayer.init(length+8);
  80. data.setHeader(Packet.MCS_HEADER);
  81. data.incrementPosition(8);
  82. data.setStart(data.getPosition());
  83. return data;
  84. }
  85. public void send(Packet buffer) throws RdesktopException, IOException {
  86. int length=0;
  87. buffer.setPosition(buffer.getHeader(Packet.MCS_HEADER));
  88. length=buffer.getEnd()-buffer.getHeader(Packet.MCS_HEADER)-8;
  89. length|=0x8000;
  90. buffer.set8((this.SDRQ << 2));
  91. buffer.setBigEndian16(this.McsUserID);
  92. buffer.setBigEndian16(this.MCS_GLOBAL_CHANNEL);
  93. buffer.set8(0x70); //Flags
  94. buffer.setBigEndian16(length);
  95. IsoLayer.send(buffer);
  96. }
  97. public Packet receive() throws IOException, RdesktopException {
  98. int opcode=0, appid=0, length=0;
  99. Packet buffer=IsoLayer.receive();
  100. Packet data =null;
  101. buffer.setHeader(Packet.MCS_HEADER);
  102. opcode = buffer.get8();
  103. appid = opcode>>2;
  104. if (appid != this.SDIN) {
  105. if (appid != this.DPUM) {
  106. throw new RdesktopException("Expected data got" + opcode);
  107. }
  108. throw new EOFException("Ende der Uebertragung!");
  109. }
  110. buffer.incrementPosition(5); // Skip UserID, ChannelID, Flags
  111. length=buffer.get8();
  112. if((length&0x80)!=0) {
  113. buffer.incrementPosition(1);
  114. }
  115. buffer.setStart(buffer.getPosition());
  116. return buffer;
  117. }
  118. /**
  119. * send an Integer encoded according to the ISO ASN.1 Basic Encoding Rules
  120. */
  121. public void sendBerInteger(Packet buffer, int value) {
  122. sendBerHeader(buffer, this.BER_TAG_INTEGER, 2);
  123. buffer.setBigEndian16(value);
  124. }
  125. /**
  126. * send a Header encoded accordibg to the ISO ASN.1 Basic Encoding rules
  127. */
  128. public void sendBerHeader(Packet buffer, int tagval, int length) {
  129. if (tagval > 0xff) {
  130. buffer.setBigEndian16(tagval);
  131. } else {
  132. buffer.set8(tagval);
  133. }
  134. if (length >= 0x80) {
  135. buffer.set8(0x82);
  136. buffer.setBigEndian16(length);
  137. } else {
  138. buffer.set8(length);
  139. }
  140. }
  141. /**
  142. * send a DOMAIN_PARAMS structure encoded according to the ISO ASN.1
  143. * Basic Encoding rules
  144. */
  145. public void sendDomainParams(Packet buffer, int max_channels, int max_users, int max_tokens, int max_pdusize) {
  146. sendBerHeader(buffer, this.TAG_DOMAIN_PARAMS, 32);
  147. sendBerInteger(buffer, max_channels);
  148. sendBerInteger(buffer, max_users);
  149. sendBerInteger(buffer, max_tokens);
  150. sendBerInteger(buffer, 1);
  151. sendBerInteger(buffer, 0);
  152. sendBerInteger(buffer, 1);
  153. sendBerInteger(buffer, max_pdusize);
  154. sendBerInteger(buffer, 2);
  155. }
  156. /**
  157. * send a MCS_CONNECT_INITIAL message (encoded as ASN.1 Ber)
  158. */
  159. public void sendConnectInitial(Packet data) throws IOException, RdesktopException {
  160. int length = 7 + (3 *34) + 4 + data.getEnd();
  161. Packet buffer = IsoLayer.init(length+5);
  162. sendBerHeader(buffer, this.CONNECT_INITIAL, length);
  163. sendBerHeader(buffer, this.BER_TAG_OCTET_STRING, 0); //calling domain
  164. sendBerHeader(buffer, this.BER_TAG_OCTET_STRING, 0); // called domain
  165. sendBerHeader(buffer, this.BER_TAG_BOOLEAN, 1);
  166. buffer.set8(255); //upward flag
  167. sendDomainParams(buffer, 2, 2, 0, 0xffff); //target parameters
  168. sendDomainParams(buffer, 1, 1, 1, 0x420); // minimun parameters
  169. sendDomainParams(buffer, 0xffff, 0xfc17, 0xffff, 0xffff); //maximum parameters
  170. sendBerHeader(buffer, this.BER_TAG_OCTET_STRING, data.getEnd());
  171. data.copyToPacket(buffer, 0, buffer.getPosition(), data.getEnd());
  172. buffer.incrementPosition(data.getEnd());
  173. buffer.markEnd();
  174. IsoLayer.send(buffer);
  175. }
  176. public void receiveConnectResponse(Packet data) throws IOException, RdesktopException {
  177. int result=0;
  178. int length=0;
  179. Packet buffer = IsoLayer.receive();
  180. length=berParseHeader(buffer, this.CONNECT_RESPONSE);
  181. length=berParseHeader(buffer, this.BER_TAG_RESULT);
  182. result=buffer.get8();
  183. if (result != 0) {
  184. throw new RdesktopException("MCS Connect failed! result was " + result);
  185. }
  186. length=berParseHeader(buffer, this.BER_TAG_INTEGER);
  187. length=buffer.get8(); //connect id
  188. parseDomainParams(buffer);
  189. length=berParseHeader(buffer, this.BER_TAG_OCTET_STRING);
  190. if (length > data.size()) {
  191. Debug.out.println("MCS Datalength exceeds size!"+length);
  192. length=data.size();
  193. }
  194. data.copyFromPacket(buffer, buffer.getPosition(), 0, length);
  195. data.setPosition(0);
  196. data.markEnd(length);
  197. buffer.incrementPosition(length);
  198. if (buffer.getPosition() != buffer.getEnd()) {
  199. throw new RdesktopException();
  200. }
  201. }
  202. public void send_edrq() throws IOException, RdesktopException {
  203. Packet buffer = IsoLayer.init(5);
  204. buffer.set8(this.EDRQ << 2);
  205. buffer.setBigEndian16(1); //height
  206. buffer.setBigEndian16(1); //interval
  207. buffer.markEnd();
  208. IsoLayer.send(buffer);
  209. }
  210. public void send_cjrq(int channelid) throws IOException, RdesktopException {
  211. Packet buffer = IsoLayer.init(5);
  212. buffer.set8(this.CJRQ << 2);
  213. buffer.setBigEndian16(this.McsUserID); //height
  214. buffer.setBigEndian16(channelid); //interval
  215. buffer.markEnd();
  216. IsoLayer.send(buffer);
  217. }
  218. public void send_aucf() throws IOException, RdesktopException {
  219. Packet buffer = IsoLayer.init(2);
  220. buffer.set8(this.AUCF << 2);
  221. buffer.set8(0);
  222. buffer.markEnd();
  223. IsoLayer.send(buffer);
  224. }
  225. public void send_aurq() throws IOException, RdesktopException {
  226. Packet buffer = IsoLayer.init(1);
  227. buffer.set8(this.AURQ <<2);
  228. buffer.markEnd();
  229. IsoLayer.send(buffer);
  230. }
  231. public void receive_cjcf() throws IOException, RdesktopException {
  232. int opcode=0, result=0;
  233. Packet buffer = IsoLayer.receive();
  234. opcode=buffer.get8();
  235. if ((opcode >>2) != this.CJCF) {
  236. throw new RdesktopException("Expected CJCF got" + opcode);
  237. }
  238. result=buffer.get8();
  239. if (result!=0) {
  240. throw new RdesktopException("Expected CJRQ got" + result);
  241. }
  242. buffer.incrementPosition(4); //skip userid, req_channelid
  243. if ((opcode&2)!=0) {
  244. buffer.incrementPosition(2); // skip join_channelid
  245. }
  246. if (buffer.getPosition() != buffer.getEnd()){
  247. throw new RdesktopException();
  248. }
  249. }
  250. public int receive_aucf() throws IOException, RdesktopException {
  251. int opcode=0, result=0, UserID=0;
  252. Packet buffer = IsoLayer.receive();
  253. opcode=buffer.get8();
  254. if ((opcode >>2) != this.AUCF) {
  255. throw new RdesktopException("Expected AUCF got" + opcode);
  256. }
  257. result=buffer.get8();
  258. if (result!=0) {
  259. throw new RdesktopException("Expected AURQ got" + result);
  260. }
  261. if ((opcode&2)!=0) {
  262. UserID=buffer.getBigEndian16();
  263. }
  264. if (buffer.getPosition() != buffer.getEnd()){
  265. throw new RdesktopException();
  266. }
  267. return UserID;
  268. }
  269. public int berParseHeader(Packet data, int tagval) throws RdesktopException {
  270. int tag=0;
  271. int length=0;
  272. int len;
  273. if (tagval > 0x000000ff) {
  274. tag = data.getBigEndian16();
  275. } else {
  276. tag = data.get8();
  277. }
  278. if (tag !=tagval) {
  279. throw new RdesktopException("Unexpected tag got " + tag + " expected " +tagval);
  280. }
  281. len=data.get8();
  282. if ((len&0x00000080)!=0) {
  283. len &= ~0x00000080; // subtract 128
  284. length = 0;
  285. while(len--!=0){
  286. length=(length << 8)+data.get8();
  287. }
  288. } else {
  289. length=len;
  290. }
  291. return length;
  292. }
  293. public void parseDomainParams(Packet data) throws RdesktopException {
  294. int length;
  295. length = this.berParseHeader(data, this.TAG_DOMAIN_PARAMS);
  296. data.incrementPosition(length);
  297. if (data.getPosition() > data.getEnd()) {
  298. throw new RdesktopException();
  299. }
  300. }
  301. public Packet getMemory(int size) {
  302. return IsoLayer.getMemory(size);
  303. }
  304. public int getUserID() {
  305. return this.McsUserID;
  306. }
  307. }