Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2992 - (hide annotations) (download) (as text)
Wed Aug 8 16:04:09 2007 UTC (16 years, 10 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/pkt.c
File MIME type: text/x-csrc
File size: 9307 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     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],
120     1,
121     0);
122     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     (pvar->pkt_state.seen_newline
162     || pvar->pkt_state.datalen >= 255)) {
163     /* 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     pvar->pkt_state.buf[i] != '\n'
170     && i < pvar->pkt_state.datalen; i++) {
171     }
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     }
188    
189     pvar->pkt_state.datastart += i;
190     pvar->pkt_state.datalen -= i;
191    
192     } else if (pvar->pkt_state.seen_server_ID
193     && pvar->pkt_state.datalen >=
194     (unsigned int) SSH_get_min_packet_size(pvar)) {
195     char FAR *data =
196     pvar->pkt_state.buf + pvar->pkt_state.datastart;
197     uint32 padding;
198     uint32 pktsize;
199     uint32 total_packet_size;
200    
201     //debug_print(10, data, pvar->pkt_state.datalen);
202    
203     // SSH2�����������p�P�b�g�������������������B
204     if (!pvar->pkt_state.predecrypted_packet) {
205 yutakapon 2922 //DEBUG_PRINT_TO_FILE(0, data, pvar->pkt_state.datalen);
206 yutakakn 2728 SSH_predecrpyt_packet(pvar, data);
207    
208     if (SSHv1(pvar)) {
209     pvar->pkt_state.predecrypted_packet = TRUE;
210     } else { // for SSH2(yutaka)
211     // do nothing
212     pvar->pkt_state.predecrypted_packet = TRUE;
213     }
214     }
215    
216     if (SSHv1(pvar)) {
217     uint32 realpktsize = get_uint32_MSBfirst(data);
218    
219     padding = 8 - (realpktsize % 8);
220     pktsize = realpktsize + padding;
221     } else {
222     // SSH2���p�P�b�g�������� packet-size(4)+padding(1)+type(1) �������B
223     pktsize = get_uint32_MSBfirst(data);
224     padding = (unsigned char) data[4];
225     }
226    
227     // �p�P�b�g(TCP�y�C���[�h)���S�����T�C�Y���ASSH�y�C���[�h�{4�i�{MAC�j�������B
228     // +4���ASSH�y�C���[�h���T�C�Y���i�[�������������iint�^�j�B
229     total_packet_size = pktsize + 4 + SSH_get_clear_MAC_size(pvar);
230    
231     if (total_packet_size <= pvar->pkt_state.datalen) {
232     /* the data must be 4 byte aligned. */
233     SSH_handle_packet(pvar, data, pktsize, padding);
234     pvar->pkt_state.predecrypted_packet = FALSE;
235    
236     pvar->pkt_state.datastart += total_packet_size;
237     pvar->pkt_state.datalen -= total_packet_size;
238    
239     } else if (total_packet_size > 4 * 1024 * 1024) {
240     // 4MB���������������p�P�b�g�����������A�����I�������B
241     // ���������f�[�^�������������s�����A���F�����������������B
242 maya 2980 #ifndef NO_I18N
243 maya 2992 strncpy_s(pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg), "Oversized packet received from server; connection will close.", _TRUNCATE);
244 maya 2942 UTIL_get_lang_msg("MSG_PKT_OVERSIZED_ERROR", pvar);
245 maya 2937 notify_fatal_error(pvar, pvar->ts->UIMsg);
246     #else
247 yutakakn 2728 notify_fatal_error(pvar,
248     "Oversized packet received from server; connection will close.");
249 maya 2937 #endif
250 yutakakn 2728 } 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     }
309 yutakakn 2761
310     /*
311     * $Log: not supported by cvs2svn $
312 maya 2992 * Revision 1.6 2007/06/06 14:10:12 maya
313     * �v���v���Z�b�T�������\�������������������������AINET6 �� I18N �� #define ���t�]�������B
314     *
315 maya 2980 * Revision 1.5 2006/12/05 09:20:36 maya
316     * �\�����b�Z�[�W��������������
317     *
318 maya 2942 * Revision 1.4 2006/11/23 02:19:30 maya
319     * �\�����b�Z�[�W�������t�@�C�����������������R�[�h���������J�n�����B
320     *
321 maya 2937 * Revision 1.3 2006/10/29 17:15:47 yutakapon
322     * DEBUG_PRINT_TO_FILE�}�N���������B
323     *
324 yutakapon 2922 * Revision 1.2 2004/12/19 15:39:58 yutakakn
325     * CVS LogID������
326     *
327 yutakakn 2761 */

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