Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mindbright/ssh/SSHTunnel.java


1   /******************************************************************************
2    *
3    * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden.
4    *                 www.mindbright.se, info@mindbright.se
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: nallen $
18   * $Date: 2001/11/12 16:31:23 $
19   * $Name:  $
20   *****************************************************************************/
21  package mindbright.ssh;
22  
23  import java.net.*;
24  import java.io.*;
25  
26  public class SSHTunnel implements SSHChannelListener {
27  
28    int channelId;
29    int remoteChannelId;
30  
31    boolean   sentInputEOF;
32    boolean   sentOutputClosed;
33    boolean   receivedInputEOF;
34    boolean   receivedOutputClosed;
35  
36    protected SSHChannelController controller;
37  
38    protected Socket       ioSocket;
39    protected SSHTxChannel txChan;
40    protected SSHRxChannel rxChan;
41  
42    protected SSHPduQueue  txQueue;
43  
44    protected String remoteDesc;
45  
46    public SSHTunnel(Socket ioSocket, int channelId, int remoteChannelId,
47         SSHChannelController controller)
48      throws IOException {
49  
50      this.ioSocket             = ioSocket;
51      this.channelId            = channelId;
52      this.remoteChannelId      = remoteChannelId;
53      this.controller           = controller;
54      this.sentInputEOF         = false;
55      this.sentOutputClosed     = false;
56      this.receivedInputEOF     = false;
57      this.receivedOutputClosed = false;
58  
59      if(ioSocket != null) {
60        try {
61    rxChan = new SSHRxChannel(new BufferedInputStream(ioSocket.getInputStream(), 8192), channelId);
62    txChan = new SSHTxChannel(new BufferedOutputStream(ioSocket.getOutputStream()), channelId);
63        } catch (Exception e) {
64    throw new IOException("Could not create tunnel: " + e.toString());
65        }
66        txQueue = txChan.getQueue();
67        rxChan.setSSHPduFactory(new SSHPduOutputStream(SSH.MSG_CHANNEL_DATA, controller.sndCipher));
68        txChan.setSSHChannelListener(this);
69        rxChan.setSSHChannelListener(this);
70      }
71    }
72  
73    public int getLocalPort() {
74      if(ioSocket != null)
75        return ioSocket.getLocalPort();
76      return 0;
77    }
78  
79    public String getLocalHost() {
80      if(ioSocket != null)
81        return ioSocket.getLocalAddress().getHostAddress();
82      return "N/A";
83    }
84  
85    public boolean isOpen() {
86      if(this.remoteChannelId == SSH.UNKNOWN_CHAN_NUM)
87        return false;
88      return true;
89    }
90  
91    public boolean setRemoteChannelId(int remoteChannelId) {
92      if(isOpen())
93        return false;
94      this.remoteChannelId = remoteChannelId;
95      return true;
96    }
97  
98    public void start() {
99      txChan.start();
100     rxChan.start();
101   }
102 
103   public void openFailure() {
104     if(ioSocket != null) {
105       try {
106   ioSocket.close();
107       } catch (IOException e) {
108   // !!!
109       }
110     }
111   }
112 
113   public SSHPdu prepare(SSHPdu pdu) throws IOException {
114     ((SSHPduOutputStream)pdu).writeInt(remoteChannelId);
115     return pdu;
116   }
117 
118   public void receive(SSHPdu pdu) {
119     controller.transmit(pdu);
120   }
121 
122   public void transmit(SSHPdu pdu) {
123     txQueue.putLast(pdu);
124   }
125 
126   public void close(SSHChannel chan) {
127     if(chan == null || chan instanceof SSHTxChannel) {
128       sendOutputClosed();
129       try {
130   ioSocket.close();
131       } catch (IOException e) {
132   controller.alert("Error closing socket for: " + channelId + " : " + e.toString());
133       }
134     } else {
135       sendInputEOF();
136     }
137     checkTermination();
138   }
139 
140   public synchronized void terminateNow() {
141     close(null);
142   }
143 
144   public synchronized void checkTermination() {
145     if(sentInputEOF && sentOutputClosed &&
146        receivedInputEOF && receivedOutputClosed) {
147       controller.delTunnel(channelId);
148       if(txChan != null && txChan.isAlive())
149   txChan.stop();
150       if(rxChan != null && rxChan.isAlive())
151   rxChan.stop();
152     }
153   }
154 
155   public void sendOutputClosed() {
156     if(sentOutputClosed)
157       return;
158     try {
159       SSHPduOutputStream pdu = new SSHPduOutputStream(SSH.MSG_CHANNEL_OUTPUT_CLOSED,
160                   controller.sndCipher);
161       pdu.writeInt(remoteChannelId);
162       controller.transmit(pdu);
163       sentOutputClosed = true;
164     } catch (Exception e) {
165       controller.alert("Error sending output-closed: " + e.toString());
166     }
167   }
168 
169   public void sendInputEOF() {
170     if(sentInputEOF)
171       return;
172     try {
173       SSHPduOutputStream pdu = new SSHPduOutputStream(SSH.MSG_CHANNEL_INPUT_EOF,
174                   controller.sndCipher);
175       pdu.writeInt(remoteChannelId);
176       controller.transmit(pdu);
177       sentInputEOF = true;
178     } catch (Exception e) {
179       controller.alert("Error sending input-EOF: " + e.toString());
180     }
181   }
182 
183   public void receiveOutputClosed() {
184     if(rxChan != null)
185       rxChan.stop();
186     receivedOutputClosed = true;
187     sendInputEOF();
188     checkTermination();
189   }
190 
191   public void receiveInputEOF() {
192     if(txChan != null)
193       txChan.setClosePending();
194     receivedInputEOF = true;
195     checkTermination();
196   }
197 
198   public void setRemoteDesc(String desc) {
199     remoteDesc = desc;
200   }
201 
202   public String getDescription() {
203     if(ioSocket != null)
204       return ioSocket.getInetAddress().getHostAddress() + ":" + ioSocket.getPort() + " <--> " +
205   getLocalHost() + ":" + ioSocket.getLocalPort() + " <-ssh-> " + remoteDesc;
206     else
207       return "< N/A >";
208   }
209 
210 }