Develop and Download Open Source Software

Browse Subversion Repository

Contents of /ttssh2/trunk/ttxssh/pkt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3003 - (show annotations) (download) (as text)
Mon Aug 20 14:21:57 2007 UTC (16 years, 7 months ago) by maya
File MIME type: text/x-csrc
File size: 8763 byte(s)
インデントを変更した。

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other materials
13 provided with the distribution.
14
15 The name of Robert O'Callahan may not be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 This code is copyright (C) 1998-1999 Robert O'Callahan.
31 See LICENSE.TXT for the license.
32 */
33
34 #include "ttxssh.h"
35 #include "util.h"
36
37 //#define READAMOUNT 60000
38 // 60000 -> 65536 ���g���BSSH2����window�������s�������ASSH2��window size��
39 // �������������K�v�������B(2004.10.17 yutaka)
40 #define READAMOUNT 65536
41
42 void PKT_init(PTInstVar pvar)
43 {
44 buf_create(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
45 pvar->pkt_state.datastart = 0;
46 pvar->pkt_state.datalen = 0;
47 pvar->pkt_state.seen_server_ID = FALSE;
48 pvar->pkt_state.seen_newline = FALSE;
49 pvar->pkt_state.predecrypted_packet = FALSE;
50 }
51
52 /* Read some data, leave no more than up_to_amount bytes in the buffer,
53 return the number of bytes read or -1 on error or blocking. */
54 static int recv_data(PTInstVar pvar, unsigned long up_to_amount)
55 {
56 int amount_read;
57
58 /* Shuffle data to the start of the buffer */
59 if (pvar->pkt_state.datastart != 0) {
60 memmove(pvar->pkt_state.buf,
61 pvar->pkt_state.buf + pvar->pkt_state.datastart,
62 pvar->pkt_state.datalen);
63 pvar->pkt_state.datastart = 0;
64 }
65
66 buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
67 up_to_amount);
68
69 _ASSERT(pvar->pkt_state.buf != NULL);
70
71 amount_read = (pvar->Precv) (pvar->socket,
72 pvar->pkt_state.buf +
73 pvar->pkt_state.datalen,
74 up_to_amount - pvar->pkt_state.datalen,
75 0);
76
77 if (amount_read > 0) {
78 /* Update seen_newline if necessary */
79 if (!pvar->pkt_state.seen_server_ID
80 && !pvar->pkt_state.seen_newline) {
81 int i;
82
83 for (i = 0; i < amount_read; i++) {
84 if (pvar->pkt_state.buf[pvar->pkt_state.datalen + i] ==
85 '\n') {
86 pvar->pkt_state.seen_newline = 1;
87 }
88 }
89 }
90
91 pvar->pkt_state.datalen += amount_read;
92 }
93
94 return amount_read;
95 }
96
97
98 // ���s�R�[�h���o��������������
99 static int recv_line_data(PTInstVar pvar)
100 {
101 int amount_read;
102 char buf[256];
103 size_t up_to_amount = sizeof(buf);
104 int i;
105
106 /* Shuffle data to the start of the buffer */
107 if (pvar->pkt_state.datastart != 0) {
108 memmove(pvar->pkt_state.buf,
109 pvar->pkt_state.buf + pvar->pkt_state.datastart,
110 pvar->pkt_state.datalen);
111 pvar->pkt_state.datastart = 0;
112 }
113
114 buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
115 up_to_amount);
116
117 for (i = 0 ; i < (int)up_to_amount ; i++) {
118 amount_read = (pvar->Precv) (pvar->socket,
119 &buf[i], 1, 0);
120 if (amount_read != 1) {
121 return 0; // error
122 }
123
124 pvar->pkt_state.datalen += amount_read;
125
126 if (buf[i] == '\n') { // 0x0a
127 buf[i+1] = 0;
128 break;
129 }
130 }
131 amount_read = i + 1; // ���������T�C�Y�iLF�������j
132 memcpy(pvar->pkt_state.buf, buf, amount_read);
133
134 pvar->pkt_state.seen_newline = 1;
135
136 return amount_read;
137 }
138
139
140 /* This function does two things:
141 -- reads data from the sshd and feeds the SSH protocol packets to ssh.c
142 -- copies any available decrypted session data into the application buffer
143 */
144 int PKT_recv(PTInstVar pvar, char FAR * buf, int buflen)
145 {
146 int amount_in_buf = 0;
147 BOOL connection_closed = FALSE;
148
149 while (SSH_is_any_payload(pvar) ? buflen > 0 : !connection_closed) {
150 if (SSH_is_any_payload(pvar)) {
151 /* ssh.c has some session data for us to give to Teraterm. */
152 int grabbed = SSH_extract_payload(pvar, buf, buflen);
153
154 amount_in_buf += grabbed;
155 buf += grabbed;
156 buflen -= grabbed;
157
158 } else if (!pvar->pkt_state.seen_server_ID &&
159 (pvar->pkt_state.seen_newline
160 || pvar->pkt_state.datalen >= 255)) {
161 /* We're looking for the initial ID string and either we've seen the
162 terminating newline, or we've exceeded the limit at which we should see
163 a newline. */
164 unsigned int i;
165
166 for (i = 0;
167 pvar->pkt_state.buf[i] != '\n'
168 && i < pvar->pkt_state.datalen; i++) {
169 }
170 if (pvar->pkt_state.buf[i] == '\n') {
171 i++;
172 }
173
174 // SSH�T�[�o���o�[�W�����`�F�b�N���s��
175 if (SSH_handle_server_ID(pvar, pvar->pkt_state.buf, i)) {
176 pvar->pkt_state.seen_server_ID = 1;
177
178 if (SSHv1(pvar)) {
179
180 } else { // for SSH2(yutaka)
181 // send Key Exchange Init
182 SSH2_send_kexinit(pvar);
183 }
184
185 }
186
187 pvar->pkt_state.datastart += i;
188 pvar->pkt_state.datalen -= i;
189
190 } else if (pvar->pkt_state.seen_server_ID
191 && pvar->pkt_state.datalen >=
192 (unsigned int) SSH_get_min_packet_size(pvar)) {
193 char FAR *data =
194 pvar->pkt_state.buf + pvar->pkt_state.datastart;
195 uint32 padding;
196 uint32 pktsize;
197 uint32 total_packet_size;
198
199 //debug_print(10, data, pvar->pkt_state.datalen);
200
201 // SSH2�����������p�P�b�g�������������������B
202 if (!pvar->pkt_state.predecrypted_packet) {
203 //DEBUG_PRINT_TO_FILE(0, data, pvar->pkt_state.datalen);
204 SSH_predecrpyt_packet(pvar, data);
205
206 if (SSHv1(pvar)) {
207 pvar->pkt_state.predecrypted_packet = TRUE;
208 } else { // for SSH2(yutaka)
209 // do nothing
210 pvar->pkt_state.predecrypted_packet = TRUE;
211 }
212 }
213
214 if (SSHv1(pvar)) {
215 uint32 realpktsize = get_uint32_MSBfirst(data);
216
217 padding = 8 - (realpktsize % 8);
218 pktsize = realpktsize + padding;
219 } else {
220 // SSH2���p�P�b�g�������� packet-size(4)+padding(1)+type(1) �������B
221 pktsize = get_uint32_MSBfirst(data);
222 padding = (unsigned char) data[4];
223 }
224
225 // �p�P�b�g(TCP�y�C���[�h)���S�����T�C�Y���ASSH�y�C���[�h�{4�i�{MAC�j�������B
226 // +4���ASSH�y�C���[�h���T�C�Y���i�[�������������iint�^�j�B
227 total_packet_size = pktsize + 4 + SSH_get_clear_MAC_size(pvar);
228
229 if (total_packet_size <= pvar->pkt_state.datalen) {
230 /* the data must be 4 byte aligned. */
231 SSH_handle_packet(pvar, data, pktsize, padding);
232 pvar->pkt_state.predecrypted_packet = FALSE;
233
234 pvar->pkt_state.datastart += total_packet_size;
235 pvar->pkt_state.datalen -= total_packet_size;
236
237 } else if (total_packet_size > 4 * 1024 * 1024) {
238 // 4MB���������������p�P�b�g�����������A�����I�������B
239 // ���������f�[�^�������������s�����A���F�����������������B
240 UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar,
241 "Oversized packet received from server; connection will close.");
242 notify_fatal_error(pvar, pvar->ts->UIMsg);
243 } else {
244 int amount_read =
245 recv_data(pvar, max(total_packet_size, READAMOUNT));
246
247 if (amount_read == SOCKET_ERROR) {
248 if (amount_in_buf == 0) {
249 return SOCKET_ERROR;
250 } else {
251 return amount_in_buf;
252 }
253 } else {
254 if (amount_read == 0) {
255 connection_closed = TRUE;
256 }
257 }
258 }
259
260
261 } else {
262 // �p�P�b�g�����M�i����60KB�j
263 int amount_read;
264
265 if (pvar->pkt_state.seen_server_ID == 0) {
266 //amount_read = recv_line_data(pvar);
267 amount_read = recv_data(pvar, READAMOUNT);
268
269 } else {
270 amount_read = recv_data(pvar, READAMOUNT);
271
272 }
273
274 if (amount_read == SOCKET_ERROR) {
275 if (amount_in_buf == 0) {
276 return SOCKET_ERROR;
277 } else {
278 return amount_in_buf;
279 }
280 } else if (amount_read == 0) {
281 connection_closed = TRUE;
282 }
283 }
284
285 if (pvar->fatal_error) {
286 return amount_in_buf;
287 }
288 }
289
290 if (SSH_is_any_payload(pvar)) {
291 PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
292 pvar->socket, MAKELPARAM(FD_READ, 0));
293 }
294
295 return amount_in_buf;
296 }
297
298 void PKT_end(PTInstVar pvar)
299 {
300 buf_destroy(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
301 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26