Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3003 - (hide annotations) (download) (as text)
Mon Aug 20 14:21:57 2007 UTC (16 years, 6 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/pkt.c
File MIME type: text/x-csrc
File size: 8763 byte(s)
インデントを変更した。

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     #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 maya 3003 pvar->pkt_state.buf + pvar->pkt_state.datastart,
62     pvar->pkt_state.datalen);
63 yutakakn 2728 pvar->pkt_state.datastart = 0;
64     }
65    
66     buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
67 maya 3003 up_to_amount);
68 yutakakn 2728
69     _ASSERT(pvar->pkt_state.buf != NULL);
70    
71     amount_read = (pvar->Precv) (pvar->socket,
72 maya 3003 pvar->pkt_state.buf +
73     pvar->pkt_state.datalen,
74     up_to_amount - pvar->pkt_state.datalen,
75     0);
76 yutakakn 2728
77     if (amount_read > 0) {
78     /* Update seen_newline if necessary */
79     if (!pvar->pkt_state.seen_server_ID
80 maya 3003 && !pvar->pkt_state.seen_newline) {
81 yutakakn 2728 int i;
82    
83     for (i = 0; i < amount_read; i++) {
84     if (pvar->pkt_state.buf[pvar->pkt_state.datalen + i] ==
85 maya 3003 '\n') {
86 yutakakn 2728 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 maya 3003 pvar->pkt_state.buf + pvar->pkt_state.datastart,
110     pvar->pkt_state.datalen);
111 yutakakn 2728 pvar->pkt_state.datastart = 0;
112     }
113    
114     buf_ensure_size(&pvar->pkt_state.buf, &pvar->pkt_state.buflen,
115 maya 3003 up_to_amount);
116 yutakakn 2728
117     for (i = 0 ; i < (int)up_to_amount ; i++) {
118     amount_read = (pvar->Precv) (pvar->socket,
119 maya 3003 &buf[i], 1, 0);
120 yutakakn 2728 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 maya 3003 (pvar->pkt_state.seen_newline
160     || pvar->pkt_state.datalen >= 255)) {
161 yutakakn 2728 /* 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 maya 3003 pvar->pkt_state.buf[i] != '\n'
168     && i < pvar->pkt_state.datalen; i++) {
169 yutakakn 2728 }
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 maya 3003 && pvar->pkt_state.datalen >=
192     (unsigned int) SSH_get_min_packet_size(pvar)) {
193 yutakakn 2728 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 yutakapon 2922 //DEBUG_PRINT_TO_FILE(0, data, pvar->pkt_state.datalen);
204 yutakakn 2728 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 maya 2994 UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar,
241     "Oversized packet received from server; connection will close.");
242 maya 2937 notify_fatal_error(pvar, pvar->ts->UIMsg);
243 yutakakn 2728 } 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 maya 3003 pvar->socket, MAKELPARAM(FD_READ, 0));
293 yutakakn 2728 }
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