001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch;
031:
032: import java.net.*;
033:
034: class ChannelX11 extends Channel {
035:
036: static private final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
037: static private final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
038:
039: static private final int TIMEOUT = 10 * 1000;
040:
041: private static String host = "127.0.0.1";
042: private static int port = 6000;
043:
044: private boolean init = true;
045:
046: static byte[] cookie = null;
047: private static byte[] cookie_hex = null;
048:
049: private static java.util.Hashtable faked_cookie_pool = new java.util.Hashtable();
050: private static java.util.Hashtable faked_cookie_hex_pool = new java.util.Hashtable();
051:
052: private static byte[] table = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
053: 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 };
054:
055: private Socket socket = null;
056:
057: static int revtable(byte foo) {
058: for (int i = 0; i < table.length; i++) {
059: if (table[i] == foo)
060: return i;
061: }
062: return 0;
063: }
064:
065: static void setCookie(String foo) {
066: cookie_hex = foo.getBytes();
067: cookie = new byte[16];
068: for (int i = 0; i < 16; i++) {
069: cookie[i] = (byte) (((revtable(cookie_hex[i * 2]) << 4) & 0xf0) | ((revtable(cookie_hex[i * 2 + 1])) & 0xf));
070: }
071: }
072:
073: static void setHost(String foo) {
074: host = foo;
075: }
076:
077: static void setPort(int foo) {
078: port = foo;
079: }
080:
081: static byte[] getFakedCookie(Session session) {
082: synchronized (faked_cookie_hex_pool) {
083: byte[] foo = (byte[]) faked_cookie_hex_pool.get(session);
084: if (foo == null) {
085: Random random = Session.random;
086: foo = new byte[16];
087: synchronized (random) {
088: random.fill(foo, 0, 16);
089: }
090: /*
091: System.err.print("faked_cookie: ");
092: for(int i=0; i<foo.length; i++){
093: System.err.print(Integer.toHexString(foo[i]&0xff)+":");
094: }
095: System.err.println("");
096: */
097: faked_cookie_pool.put(session, foo);
098: byte[] bar = new byte[32];
099: for (int i = 0; i < 16; i++) {
100: bar[2 * i] = table[(foo[i] >>> 4) & 0xf];
101: bar[2 * i + 1] = table[(foo[i]) & 0xf];
102: }
103: faked_cookie_hex_pool.put(session, bar);
104: foo = bar;
105: }
106: return foo;
107: }
108: }
109:
110: ChannelX11() {
111: super ();
112:
113: setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
114: setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
115: setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
116:
117: type = "x11".getBytes();
118:
119: connected = true;
120: /*
121: try{
122: socket=Util.createSocket(host, port, TIMEOUT);
123: socket.setTcpNoDelay(true);
124: io=new IO();
125: io.setInputStream(socket.getInputStream());
126: io.setOutputStream(socket.getOutputStream());
127: }
128: catch(Exception e){
129: //System.err.println(e);
130: }
131: */
132: }
133:
134: public void run() {
135:
136: try {
137: socket = Util.createSocket(host, port, TIMEOUT);
138: socket.setTcpNoDelay(true);
139: io = new IO();
140: io.setInputStream(socket.getInputStream());
141: io.setOutputStream(socket.getOutputStream());
142: sendOpenConfirmation();
143: } catch (Exception e) {
144: sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
145: close = true;
146: disconnect();
147: return;
148: }
149:
150: thread = Thread.currentThread();
151: Buffer buf = new Buffer(rmpsize);
152: Packet packet = new Packet(buf);
153: int i = 0;
154: try {
155: while (thread != null && io != null && io.in != null) {
156: i = io.in.read(buf.buffer, 14,
157: buf.buffer.length - 14 - 32 - 20 // padding and mac
158: );
159: if (i <= 0) {
160: eof();
161: break;
162: }
163: if (close)
164: break;
165: packet.reset();
166: buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA);
167: buf.putInt(recipient);
168: buf.putInt(i);
169: buf.skip(i);
170: session.write(packet, this , i);
171: }
172: } catch (Exception e) {
173: //System.err.println(e);
174: }
175: disconnect();
176: }
177:
178: private byte[] cache = new byte[0];
179:
180: private byte[] addCache(byte[] foo, int s, int l) {
181: byte[] bar = new byte[cache.length + l];
182: System.arraycopy(foo, s, bar, cache.length, l);
183: if (cache.length > 0)
184: System.arraycopy(cache, 0, bar, 0, cache.length);
185: cache = bar;
186: return cache;
187: }
188:
189: void write(byte[] foo, int s, int l) throws java.io.IOException {
190: //if(eof_local)return;
191:
192: if (init) {
193:
194: foo = addCache(foo, s, l);
195: s = 0;
196: l = foo.length;
197:
198: if (l < 9)
199: return;
200:
201: int plen = (foo[s + 6] & 0xff) * 256 + (foo[s + 7] & 0xff);
202: int dlen = (foo[s + 8] & 0xff) * 256 + (foo[s + 9] & 0xff);
203:
204: if ((foo[s] & 0xff) == 0x42) {
205: } else if ((foo[s] & 0xff) == 0x6c) {
206: plen = ((plen >>> 8) & 0xff) | ((plen << 8) & 0xff00);
207: dlen = ((dlen >>> 8) & 0xff) | ((dlen << 8) & 0xff00);
208: } else {
209: // ??
210: }
211:
212: if (l < 12 + plen + ((-plen) & 3) + dlen)
213: return;
214:
215: byte[] bar = new byte[dlen];
216: System.arraycopy(foo, s + 12 + plen + ((-plen) & 3), bar,
217: 0, dlen);
218: byte[] faked_cookie = null;
219:
220: synchronized (faked_cookie_pool) {
221: faked_cookie = (byte[]) faked_cookie_pool.get(session);
222: }
223:
224: /*
225: System.err.print("faked_cookie: ");
226: for(int i=0; i<faked_cookie.length; i++){
227: System.err.print(Integer.toHexString(faked_cookie[i]&0xff)+":");
228: }
229: System.err.println("");
230: System.err.print("bar: ");
231: for(int i=0; i<bar.length; i++){
232: System.err.print(Integer.toHexString(bar[i]&0xff)+":");
233: }
234: System.err.println("");
235: */
236:
237: if (equals(bar, faked_cookie)) {
238: if (cookie != null)
239: System.arraycopy(cookie, 0, foo, s + 12 + plen
240: + ((-plen) & 3), dlen);
241: } else {
242: //System.err.println("wrong cookie");
243: thread = null;
244: eof();
245: io.close();
246: disconnect();
247: }
248: init = false;
249: io.put(foo, s, l);
250: cache = null;
251: return;
252: }
253: io.put(foo, s, l);
254: }
255:
256: private static boolean equals(byte[] foo, byte[] bar) {
257: if (foo.length != bar.length)
258: return false;
259: for (int i = 0; i < foo.length; i++) {
260: if (foo[i] != bar[i])
261: return false;
262: }
263: return true;
264: }
265: }
|