source: other-projects/trunk/gs3-release-maker/tasks/sshtaskdef/src/mindbright/ssh/SSHFtpTunnel.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 6.0 KB
Line 
1/******************************************************************************
2 *
3 * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden.
4 * www.mindbright.se, [email protected]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *****************************************************************************
17 * $Author: mats $
18 * $Date: 2000/03/30 13:36:59 $
19 * $Name: rel1-2-1 $
20 *****************************************************************************/
21package mindbright.ssh;
22
23import java.net.*;
24import java.io.*;
25
26public class SSHFtpTunnel extends SSHTunnel {
27
28 public final static String TUNNEL_NAME = "#FTP";
29 public final static int MAX_REMOTE_LISTEN = 10;
30
31 boolean havePORT;
32
33 boolean waitingPASVResponse;
34 String localAddrPASVStr;
35 InetAddress localAddr;
36
37 byte[][] newPortMsg;
38
39 static int timeWaitKludgeToggler;
40 static Object timeWaitKludgeCrit = new Object();
41
42 public SSHFtpTunnel(Socket ioSocket, int channelId, int remoteChannelId,
43 SSHChannelController controller)
44 throws IOException {
45 super(ioSocket, channelId, remoteChannelId, controller);
46
47 int a1, a2, a3, a4;
48
49 havePORT = controller.sshAsClient().havePORTFtp;
50
51 if(havePORT) {
52 int firstPort = controller.sshAsClient().firstFTPPort;
53 byte[] serverAddr = controller.sshAsClient().getServerRealAddr().getAddress();
54 a1 = serverAddr[0] & 0xff;
55 a2 = serverAddr[1] & 0xff;
56 a3 = serverAddr[2] & 0xff;
57 a4 = serverAddr[3] & 0xff;
58 String msg;
59 newPortMsg = new byte[MAX_REMOTE_LISTEN][1];
60 for(int i = 0; i < MAX_REMOTE_LISTEN; i++) {
61 int p1 = ((firstPort + i) >>> 8) & 0xff;
62 int p2 = (firstPort + i) & 0xff;
63 msg = "PORT " + a1 + "," + a2 + "," + a3 + "," + a4 + "," + p1 + "," + p2 + "\n";
64 newPortMsg[i] = msg.getBytes();
65 }
66 }
67
68 localAddr = controller.sshAsClient().getLocalAddr();
69
70 byte[] localAddrArr = controller.sshAsClient().getLocalAddr().getAddress();
71
72 if(localAddrArr[0] == 0) {
73 localAddrArr = InetAddress.getLocalHost().getAddress();
74 }
75
76 a1 = localAddrArr[0] & 0xff;
77 a2 = localAddrArr[1] & 0xff;
78 a3 = localAddrArr[2] & 0xff;
79 a4 = localAddrArr[3] & 0xff;
80 localAddrPASVStr = a1 + "," + a2 + "," + a3 + "," + a4;
81 }
82
83 boolean parseHostAndPort(String msg, int[] d) {
84 boolean ok = true;
85 int cl = 0;
86 int cn = 0;
87 try {
88 for(int i = 0; i < 6; i++) {
89 String num;
90 if(i == 5) {
91 cn = msg.indexOf(')', cl);
92 if(cn == -1)
93 cn = msg.indexOf('\r', cl);
94 else if(cn == -1)
95 cn = msg.indexOf('\n', cl);
96 } else
97 cn = msg.indexOf(',', cl);
98 num = msg.substring(cl, cn);
99 cl = cn + 1;
100 d[i] = Integer.parseInt(num);
101 }
102 } catch (Exception e) {
103 ok = false;
104 }
105 return ok;
106 }
107
108 public void receive(SSHPdu pdu) {
109 String msg = new String(pdu.rawData(), pdu.rawOffset(), pdu.rawSize());
110
111 if(msg.startsWith("PASV") || msg.startsWith("pasv")) {
112 waitingPASVResponse = true;
113 } else if(msg.startsWith("PORT ") || msg.startsWith("port ")) {
114 if(!havePORT) {
115 controller.alert("Ftp-client is using PORT commands, either \n" +
116 "enable 'passive mode' in the ftp-client or \n" +
117 "enable 'ftp PORT' in 'SSH Settings' and reconnect.");
118 } else {
119 msg = msg.substring(5);
120 int[] d = new int[6];
121
122 if(parseHostAndPort(msg, d)) {
123 byte[] dst = pdu.rawData();
124 byte[] newmsg;
125 String mapName;
126
127 synchronized(timeWaitKludgeCrit) {
128 newmsg = newPortMsg[timeWaitKludgeToggler];
129 mapName = TUNNEL_NAME + timeWaitKludgeToggler;
130 timeWaitKludgeToggler = (timeWaitKludgeToggler + 1) % MAX_REMOTE_LISTEN;
131 }
132
133 int len = newmsg.length;
134 int off = pdu.rawOffset() - 4;
135 dst[off++] = (byte)((len >>> 24) & 0xff);
136 dst[off++] = (byte)((len >>> 16) & 0xff);
137 dst[off++] = (byte)((len >>> 8) & 0xff);
138 dst[off++] = (byte)(len & 0xff);
139 System.arraycopy(newmsg, 0, dst, off, len);
140 pdu.rawAdjustSize(off + len);
141
142 String toHost = d[0] + "." + d[1] + "." + d[2] + "." + d[3];
143 int toPort = (d[4] << 8) | d[5];
144 controller.addHostMapTemporary(mapName, toHost, toPort);
145 } else {
146 controller.alert("Bug in SSHFtpTunnel (PORT), please report: " + msg);
147 }
148 }
149 }
150
151 super.receive(pdu);
152 }
153
154 public void transmit(SSHPdu pdu) {
155 SSHListenChannel listenChan = null;
156 String msg = new String(pdu.rawData(), pdu.rawOffset(), pdu.rawSize());
157
158 if(waitingPASVResponse && msg.startsWith("227 ")) {
159 byte[] newmsg;
160 waitingPASVResponse = false;
161 msg = msg.substring(27);
162 int[] d = new int[6];
163 if(parseHostAndPort(msg, d)) {
164 String toHost = d[0] + "." + d[1] + "." + d[2] + "." + d[3];
165 int toPort = (d[4] << 8) | d[5];
166 int localPort;
167 try {
168 listenChan = controller.newListenChannel(localAddr.getHostAddress(), 0,
169 toHost, toPort, "general");
170 } catch(IOException e) {
171 controller.alert("Error in FtpTunnel: " + e.toString());
172 }
173 listenChan.setTemporaryListener(true); // Go away after next accept...
174 localPort = listenChan.getListenPort();
175 int p1 = (localPort >>> 8) & 0xff;
176 int p2 = localPort & 0xff;
177 msg = "227 Entering Passive Mode (" + localAddrPASVStr + "," + p1 + "," + p2 + ")\n";
178 newmsg = msg.getBytes();
179 pdu.rawSetData(newmsg);
180 } else {
181 controller.alert("Bug in SSHFtpTunnel (PASV), please report: " + msg);
182 }
183 }
184
185 super.transmit(pdu);
186 }
187
188 public String getDescription() {
189 if(ioSocket != null)
190 return ioSocket.getInetAddress().getHostAddress() + ":" + ioSocket.getPort() + " <-ftp-> " +
191 getLocalHost() + ":" + ioSocket.getLocalPort() + " <-ssh-> " + remoteDesc;
192 else
193 return "< N/A >";
194 }
195
196}
Note: See TracBrowser for help on using the repository browser.