Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3101 - (hide annotations) (download) (as text)
Wed Jan 30 12:19:27 2008 UTC (16 years, 2 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 8965 byte(s)
不正なProtocol Version Exchangeをスキップする処理を追加した(RFC4253対応)

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

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