source: other-projects/trunk/gs3-release-maker/tasks/sshtaskdef/src/mindbright/ssh/SSHPduInputStream.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: 5.4 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: 1999/07/19 17:13:50 $
19 * $Name: rel1-2-1 $
20 *****************************************************************************/
21package mindbright.ssh;
22
23import java.io.*;
24import java.math.BigInteger;
25
26import mindbright.security.*;
27import mindbright.util.*;
28
29public final class SSHPduInputStream extends SSHDataInputStream implements SSHPdu {
30
31 static final class PduByteArrayInputStream extends ByteArrayInputStream {
32 PduByteArrayInputStream(byte[] data) {
33 super(data);
34 }
35 public int getPos() {
36 return pos;
37 }
38 public void setPos(int pos) {
39 this.pos = pos;
40 }
41 public byte[] getBuf() {
42 return buf;
43 }
44 public void setBuf(byte[] buf) {
45 this.buf = buf;
46 }
47 }
48
49 public int type;
50 public int length;
51
52 byte[] bytes;
53 Cipher cipher;
54
55 SSHPduInputStream(int type, Cipher cipher) {
56 super(null);
57 this.type = type; // This is the expected type (checked in readFrom())
58 this.cipher = cipher;
59 }
60
61 boolean validChecksum() throws IOException {
62 int padLen = ((length + 8) & ~7);
63 int stored, calculated;
64
65 skip(padLen - 4);
66 stored = readInt();
67 reset();
68
69 calculated = (int)CRC32.getValue(bytes, 0, padLen - 4);
70
71 if(calculated != stored)
72 return false;
73
74 return true;
75 }
76
77 public SSHPdu createPdu() {
78 return new SSHPduInputStream(this.type, this.cipher);
79 }
80
81 public void readFrom(InputStream in) throws IOException {
82 SSHDataInputStream dIn = new SSHDataInputStream(in);
83 int len = dIn.readInt();
84 int padLen = ((len + 8) & ~7);
85 int type;
86 byte[] data;
87
88 if(padLen > 256000)
89 throw new IOException("Corrupt incoming packet, too large");
90
91 data = new byte[padLen];
92
93 dIn.readFully(data);
94 if(cipher != null)
95 cipher.decrypt(data, 0, data, 0, padLen);
96
97 this.in = new PduByteArrayInputStream(data);
98 this.bytes = data;
99 this.length = len;
100
101 if(!this.validChecksum())
102 throw new IOException("Invalid checksum in packet");
103
104 this.skip(8 - (len % 8));
105 type = (int)this.readByte();
106
107 if(type == SSH.MSG_DEBUG) {
108 SSH.logDebug("MSG_DEBUG: " + this.readString());
109 this.readFrom(in);
110 } else if(type == SSH.MSG_IGNORE) {
111 SSH.logIgnore(this);
112 this.readFrom(in);
113 } else {
114 if((this.type != SSH.MSG_ANY) && (this.type != type)) {
115 if(type == SSH.MSG_DISCONNECT)
116 throw new IOException("Server disconnected: " + this.readString());
117 else
118 throw new IOException("Invalid type: " + type + " (expected: " +
119 this.type + ")");
120 }
121 this.type = type;
122 }
123
124 }
125
126 public void writeTo(OutputStream sshOut) throws IOException {
127 int off, n;
128
129 if(type != SSH.MSG_CHANNEL_DATA &&
130 type != SSH.SMSG_STDOUT_DATA &&
131 type != SSH.SMSG_STDERR_DATA)
132 throw new IOException("Trying to write raw data from non-data PDU");
133
134 // Here we assume that the content left is readable through readString
135 // which is the case if this is SSH-data
136 //
137 int len = readInt();
138
139 PduByteArrayInputStream is = (PduByteArrayInputStream)in;
140
141 sshOut.write(bytes, is.getPos(), len);
142
143 sshOut.flush();
144 }
145
146 public byte[] rawData() {
147 return bytes;
148 }
149 public void rawSetData(byte[] raw) {
150 PduByteArrayInputStream is = (PduByteArrayInputStream)in;
151 bytes = new byte[raw.length + 4];
152 is.setPos(0);
153 int len = raw.length;
154 int off = 0;
155 bytes[off++] = (byte)((len >>> 24) & 0xff);
156 bytes[off++] = (byte)((len >>> 16) & 0xff);
157 bytes[off++] = (byte)((len >>> 8) & 0xff);
158 bytes[off++] = (byte)(len & 0xff);
159 System.arraycopy(raw, 0, bytes, off, raw.length);
160 is.setBuf(bytes);
161 }
162 public int rawOffset() {
163 PduByteArrayInputStream is = (PduByteArrayInputStream)in;
164 return is.getPos() + 4; // The first four bytes is the length of the data
165 }
166 public int rawSize() {
167 PduByteArrayInputStream is = (PduByteArrayInputStream)in;
168 int off = is.getPos();
169 int ch1 = ((bytes[off++] + 256) & 0xff);
170 int ch2 = ((bytes[off++] + 256) & 0xff);
171 int ch3 = ((bytes[off++] + 256) & 0xff);
172 int ch4 = ((bytes[off] + 256) & 0xff);
173 return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
174 }
175 // !!! Only allowed to shrink for now !!!
176 public void rawAdjustSize(int size) {
177 PduByteArrayInputStream is = (PduByteArrayInputStream)in;
178 int oldSz = rawSize();
179 if(size >= oldSz)
180 return;
181 int pos = is.getPos() + (oldSz - size);
182 is.setPos(pos);
183 bytes[pos++] = (byte)((size >>> 24) & 0xff);
184 bytes[pos++] = (byte)((size >>> 16) & 0xff);
185 bytes[pos++] = (byte)((size >>> 8) & 0xff);
186 bytes[pos++] = (byte) (size & 0xff);
187 }
188
189}
Note: See TracBrowser for help on using the repository browser.