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

Quick Search    Search Deep

Source code: mindbright/ssh/SSHPduOutputStream.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:20 $
19   * $Name:  $
20   *****************************************************************************/
21  package mindbright.ssh;
22  
23  import java.io.*;
24  import java.math.BigInteger;
25  
26  import mindbright.security.*;
27  import mindbright.util.*;
28  
29  public final class SSHPduOutputStream extends SSHDataOutputStream implements SSHPdu {
30  
31    static final class PduByteArrayOutputStream extends ByteArrayOutputStream {
32      PduByteArrayOutputStream() {
33    super();
34      }
35  
36      PduByteArrayOutputStream(int size) {
37        super(size);
38      }
39  
40      PduByteArrayOutputStream(byte[] buf) {
41        this.buf = buf;
42      }
43  
44      public byte[] getBuf() {
45        return buf;
46      }
47  
48      public int getCount() {
49        return count;
50      }
51  
52      public void setBuf(byte[] buf) {
53        this.buf = buf;
54      }
55  
56      public void setCount(int count) {
57        this.count = count;
58      }
59    }
60  
61    public static final int SSH_DEFAULT_PKT_LEN = 8192;
62    public static int mtu = SSH_DEFAULT_PKT_LEN;
63  
64    public static synchronized void setMTU(int newMtu) {
65      mtu = newMtu;
66    }
67  
68    byte[]  readFromRawData;
69    int     readFromOff;
70    int     readFromSize;
71  
72    public int    type;
73    public Cipher cipher;
74  
75    SSHPduOutputStream(Cipher cipher) {
76      super(null);
77      this.cipher = cipher;
78    }
79  
80    SSHPduOutputStream(int type, Cipher cipher) throws IOException {
81      super(new PduByteArrayOutputStream(mtu));
82      this.type   = type;
83      this.cipher = cipher;
84      if(cipher != null) {
85        PduByteArrayOutputStream bytes = (PduByteArrayOutputStream)out;
86        SecureRandom rand = SSH.secureRandom();
87        rand.nextPadBytes(bytes.getBuf(), 8);
88        bytes.setCount(8);
89      } else {
90        for(int i = 0; i < 8; i++)
91    write(0);
92      }
93      write(type);
94    }
95  
96    public SSHPdu createPdu() throws IOException {
97      SSHPdu pdu;
98      pdu = new SSHPduOutputStream(this.type, this.cipher);
99      return pdu;
100   }
101 
102   public void readFrom(InputStream in) throws IOException {
103     if(type != SSH.MSG_CHANNEL_DATA &&
104        type != SSH.CMSG_STDIN_DATA)
105       throw new IOException("Trying to read raw data into non-data PDU");
106 
107     PduByteArrayOutputStream bytes = (PduByteArrayOutputStream) out;
108 
109     readFromRawData = bytes.getBuf();
110     readFromOff     = bytes.size() + 4; // Leave space for size
111 
112     readFromSize = in.read(readFromRawData, readFromOff, mtu - readFromOff);
113     if(readFromSize == -1)
114       throw new IOException("EOF");
115 
116     writeInt(readFromSize);
117     bytes.setCount(readFromOff + readFromSize);
118   }
119 
120   public void writeTo(OutputStream sshOut) throws IOException {
121     PduByteArrayOutputStream bytes = (PduByteArrayOutputStream) out;
122     byte[]                   padData;
123     int                      iSz;
124     int                      pad;
125     int                      crc32;
126     int                      padSz;
127     int                      off = 0;
128 
129     iSz   = bytes.size();
130     pad   = (iSz + 4) % 8;
131     crc32 = (int)CRC32.getValue(bytes.getBuf(), pad, iSz - pad);
132     padSz = iSz + 4 - pad;
133     writeInt(crc32);
134 
135     padData = bytes.getBuf();
136 
137     if(cipher != null) {
138       cipher.encrypt(padData, pad, padData, pad, padSz);
139     }
140 
141     int sz = padSz - (8 - pad);
142     sshOut.write((sz >>> 24) & 0xff);
143     sshOut.write((sz >>> 16) & 0xff);
144     sshOut.write((sz >>>  8) & 0xff);
145     sshOut.write((sz >>>  0) & 0xff);
146 
147     sshOut.write(padData, pad, padSz);
148 
149     sshOut.flush();
150   }
151 
152   public byte[] rawData() {
153     return readFromRawData;
154   }
155   public void rawSetData(byte[] raw) {
156   }
157   public int rawOffset() {
158     return readFromOff;
159   }
160   public int rawSize() {
161     // !!! return readFromSize;
162     //
163     byte[] bytes = readFromRawData;
164     int    off   = readFromOff - 4;
165     int ch1 = ((bytes[off++] + 256) & 0xff);
166     int ch2 = ((bytes[off++] + 256) & 0xff);
167     int ch3 = ((bytes[off++] + 256) & 0xff);
168     int ch4 = ((bytes[off]   + 256) & 0xff);
169     return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
170   }
171   public void rawAdjustSize(int size) {
172     PduByteArrayOutputStream bytes = (PduByteArrayOutputStream) out;
173     bytes.setCount(size);
174   }
175 
176 }
177