Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3227 - (show annotations) (download) (as text)
Tue Mar 24 15:10:33 2009 UTC (15 years, 2 months ago) by maya
File MIME type: text/x-csrc
File size: 9291 byte(s)
CVS から SVN へ移行: 改行コードを LF から CR+LF へ変換
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 #include "pkt.h"
37
38 //#define READAMOUNT 60000
39 // 60000 -> 65536 ���g���BSSH2����window�������s�������ASSH2��window size��
40 // �������������K�v�������B(2004.10.17 yutaka)
41 //#define READAMOUNT 65536
42 // 65536 -> 131072 ���g���B(2007.10.29 maya)
43 #define READAMOUNT CHAN_SES_WINDOW_DEFAULT
44
45 void PKT_init(PTInstVar pvar)
46 {
47 buf_create(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
48 pvar->pkt_state.datastart = 0;
49 pvar->pkt_state.datalen = 0;
50 pvar->pkt_state.seen_server_ID = FALSE;
51 pvar->pkt_state.seen_newline = FALSE;
52 pvar->pkt_state.predecrypted_packet = FALSE;
53 }
54
55 /* Read some data, leave no more than up_to_amount bytes in the buffer,
56 return the number of bytes read or -1 on error or blocking. */
57 static int recv_data(PTInstVar pvar, unsigned long up_to_amount)
58 {
59 int amount_read;
60
61 /* Shuffle data to the start of the buffer */
62 if (pvar->pkt_state.datastart != 0) {
63 memmove(pvar->pkt_state.buf,
64 pvar->pkt_state.buf + pvar->pkt_state.datastart,
65 pvar->pkt_state.datalen);
66 pvar->pkt_state.datastart = 0;
67 }
68
69 buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
70 up_to_amount);
71
72 _ASSERT(pvar->pkt_state.buf != NULL);
73
74 amount_read = (pvar->Precv) (pvar->socket,
75 pvar->pkt_state.buf +
76 pvar->pkt_state.datalen,
77 up_to_amount - pvar->pkt_state.datalen,
78 0);
79
80 if (amount_read > 0) {
81 /* Update seen_newline if necessary */
82 if (!pvar->pkt_state.seen_server_ID
83 && !pvar->pkt_state.seen_newline) {
84 int i;
85
86 for (i = 0; i < amount_read; i++) {
87 if (pvar->pkt_state.buf[pvar->pkt_state.datalen + i] ==
88 '\n') {
89 pvar->pkt_state.seen_newline = 1;
90 }
91 }
92 }
93
94 pvar->pkt_state.datalen += amount_read;
95 }
96
97 return amount_read;
98 }
99
100
101 // ���s�R�[�h���o��������������
102 static int recv_line_data(PTInstVar pvar)
103 {
104 int amount_read;
105 char buf[256];
106 size_t up_to_amount = sizeof(buf);
107 int i;
108
109 /* Shuffle data to the start of the buffer */
110 if (pvar->pkt_state.datastart != 0) {
111 memmove(pvar->pkt_state.buf,
112 pvar->pkt_state.buf + pvar->pkt_state.datastart,
113 pvar->pkt_state.datalen);
114 pvar->pkt_state.datastart = 0;
115 }
116
117 buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
118 up_to_amount);
119
120 for (i = 0 ; i < (int)up_to_amount ; i++) {
121 amount_read = (pvar->Precv) (pvar->socket,
122 &buf[i], 1, 0);
123 if (amount_read != 1) {
124 return 0; // error
125 }
126
127 pvar->pkt_state.datalen += amount_read;
128
129 if (buf[i] == '\n') { // 0x0a
130 buf[i+1] = 0;
131 break;
132 }
133 }
134 amount_read = i + 1; // ���������T�C�Y�iLF�������j
135 memcpy(pvar->pkt_state.buf, buf, amount_read);
136
137 pvar->pkt_state.seen_newline = 1;
138
139 return amount_read;
140 }
141
142
143 /* This function does two things:
144 -- reads data from the sshd and feeds the SSH protocol packets to ssh.c
145 -- copies any available decrypted session data into the application buffer
146 */
147 int PKT_recv(PTInstVar pvar, char FAR * buf, int buflen)
148 {
149 int amount_in_buf = 0;
150 BOOL connection_closed = FALSE;
151
152 while (SSH_is_any_payload(pvar) ? buflen > 0 : !connection_closed) {
153 if (SSH_is_any_payload(pvar)) {
154 /* ssh.c has some session data for us to give to Tera Term. */
155 int grabbed = SSH_extract_payload(pvar, buf, buflen);
156
157 amount_in_buf += grabbed;
158 buf += grabbed;
159 buflen -= grabbed;
160
161 } else if (!pvar->pkt_state.seen_server_ID &&
162 (pvar->pkt_state.seen_newline
163 || pvar->pkt_state.datalen >= 255)) {
164 /* We're looking for the initial ID string and either we've seen the
165 terminating newline, or we've exceeded the limit at which we should see
166 a newline. */
167 unsigned int i;
168
169 for (i = 0;
170 pvar->pkt_state.buf[i] != '\n'
171 && i < pvar->pkt_state.datalen; i++) {
172 }
173 if (pvar->pkt_state.buf[i] == '\n') {
174 i++;
175 }
176
177 // SSH�T�[�o���o�[�W�����`�F�b�N���s��
178 if (SSH_handle_server_ID(pvar, pvar->pkt_state.buf, i)) {
179 pvar->pkt_state.seen_server_ID = 1;
180
181 if (SSHv1(pvar)) {
182
183 } else { // for SSH2(yutaka)
184 // send Key Exchange Init
185 SSH2_send_kexinit(pvar);
186 }
187
188 } else {
189 // reset flag to re-read server ID (2008.1.24 yutaka)
190 pvar->pkt_state.seen_newline = 0;
191
192 }
193
194 pvar->pkt_state.datastart += i;
195 pvar->pkt_state.datalen -= i;
196
197 } else if (pvar->pkt_state.seen_server_ID
198 && pvar->pkt_state.datalen >=
199 (unsigned int) SSH_get_min_packet_size(pvar)) {
200 char FAR *data =
201 pvar->pkt_state.buf + pvar->pkt_state.datastart;
202 uint32 padding;
203 uint32 pktsize;
204 uint32 total_packet_size;
205
206 //debug_print(10, data, pvar->pkt_state.datalen);
207
208 // SSH2�����������p�P�b�g�������������������B
209 if (!pvar->pkt_state.predecrypted_packet) {
210 //DEBUG_PRINT_TO_FILE(0, data, pvar->pkt_state.datalen);
211 SSH_predecrpyt_packet(pvar, data);
212
213 if (SSHv1(pvar)) {
214 pvar->pkt_state.predecrypted_packet = TRUE;
215 } else { // for SSH2(yutaka)
216 // do nothing
217 pvar->pkt_state.predecrypted_packet = TRUE;
218 }
219 }
220
221 if (SSHv1(pvar)) {
222 uint32 realpktsize = get_uint32_MSBfirst(data);
223
224 padding = 8 - (realpktsize % 8);
225 pktsize = realpktsize + padding;
226 } else {
227 // SSH2���p�P�b�g�������� packet-size(4)+padding(1)+type(1) �������B
228 pktsize = get_uint32_MSBfirst(data);
229 padding = (unsigned char) data[4];
230 }
231
232 // �p�P�b�g(TCP�y�C���[�h)���S�����T�C�Y���ASSH�y�C���[�h�{4�i�{MAC�j�������B
233 // +4���ASSH�y�C���[�h���T�C�Y���i�[�������������iint�^�j�B
234 total_packet_size = pktsize + 4 + SSH_get_clear_MAC_size(pvar);
235
236 if (total_packet_size <= pvar->pkt_state.datalen) {
237 /* the data must be 4 byte aligned. */
238 SSH_handle_packet(pvar, data, pktsize, padding);
239 pvar->pkt_state.predecrypted_packet = FALSE;
240
241 pvar->pkt_state.datastart += total_packet_size;
242 pvar->pkt_state.datalen -= total_packet_size;
243
244 } else if (total_packet_size > PACKET_MAX_SIZE) {
245 // 4MB���������������p�P�b�g�����������A�����I�������B
246 // ���������f�[�^�������������s�����A���F�����������������B
247 UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar,
248 "Oversized packet received from server; connection will close.");
249 notify_fatal_error(pvar, pvar->ts->UIMsg);
250 } else {
251 int amount_read =
252 recv_data(pvar, max(total_packet_size, READAMOUNT));
253
254 if (amount_read == SOCKET_ERROR) {
255 if (amount_in_buf == 0) {
256 return SOCKET_ERROR;
257 } else {
258 return amount_in_buf;
259 }
260 } else {
261 if (amount_read == 0) {
262 connection_closed = TRUE;
263 }
264 }
265 }
266
267
268 } else {
269 // �p�P�b�g�����M�i����60KB�j
270 int amount_read;
271
272 if (pvar->pkt_state.seen_server_ID == 0) {
273 //amount_read = recv_line_data(pvar);
274 amount_read = recv_data(pvar, READAMOUNT);
275
276 } else {
277 amount_read = recv_data(pvar, READAMOUNT);
278
279 }
280
281 if (amount_read == SOCKET_ERROR) {
282 if (amount_in_buf == 0) {
283 return SOCKET_ERROR;
284 } else {
285 return amount_in_buf;
286 }
287 } else if (amount_read == 0) {
288 connection_closed = TRUE;
289 }
290 }
291
292 if (pvar->fatal_error) {
293 return amount_in_buf;
294 }
295 }
296
297 if (SSH_is_any_payload(pvar)) {
298 PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
299 pvar->socket, MAKELPARAM(FD_READ, 0));
300 }
301
302 return amount_in_buf;
303 }
304
305 void PKT_end(PTInstVar pvar)
306 {
307 buf_destroy(&pvar->pkt_state.buf, &pvar->pkt_state.buflen);
308 }

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