[Ttssh2-commit] [4928] - SFTP実装のため、バッファ操作関数の整理。

svnno****@sourc***** svnno****@sourc*****
2012年 5月 3日 (木) 23:39:47 JST


Revision: 4928
          http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=4928
Author:   yutakapon
Date:     2012-05-03 23:39:47 +0900 (Thu, 03 May 2012)
Log Message:
-----------
- SFTP実装のため、バッファ操作関数の整理。
- SFTPバージョン交換まで実装確認。

Modified Paths:
--------------
    trunk/ttssh2/ttxssh/buffer.c
    trunk/ttssh2/ttxssh/buffer.h
    trunk/ttssh2/ttxssh/sftp.c
    trunk/ttssh2/ttxssh/sftp.h

-------------- next part --------------
Modified: trunk/ttssh2/ttxssh/buffer.c
===================================================================
--- trunk/ttssh2/ttxssh/buffer.c	2012-05-03 13:18:59 UTC (rev 4927)
+++ trunk/ttssh2/ttxssh/buffer.c	2012-05-03 14:39:47 UTC (rev 4928)
@@ -11,6 +11,13 @@
 #include <openssl/ec.h>
 #include <zlib.h>
 
+// \x83o\x83b\x83t\x83@\x82̃I\x83t\x83Z\x83b\x83g\x82\xF0\x8F\x89\x8A\x{227B0B5}\x81A\x82܂\xBE\x93ǂ\xF1\x82ł\xA2\x82Ȃ\xA2\x8F\xF3\x91Ԃɂ\xB7\x82\xE9\x81B
+// Tera Term(TTSSH)\x83I\x83\x8A\x83W\x83i\x83\x8B\x8A֐\x94\x81B
+void buffer_rewind(buffer_t *buf)
+{
+	buf->offset = 0;
+}
+
 void buffer_clear(buffer_t *buf)
 {
 	buf->offset = 0;
@@ -144,6 +151,59 @@
 	ret = buffer_append(msg, ptr, size);
 }
 
+int buffer_get_ret(buffer_t *msg, void *buf, int len)
+{
+	if (len > msg->len - msg->offset) {
+		// TODO: \x83G\x83\x89\x81[\x8F\x88\x97\x9D
+		OutputDebugPrintf("buffer_get_ret: trying to get more bytes %d than in buffer %d",
+		    len, msg->len - msg->offset);
+		return (-1);
+	}
+	memcpy(buf, msg->buf + msg->offset, len);
+	msg->offset += len;
+	return (0);
+}
+
+int buffer_get_int_ret(int *ret, buffer_t *msg)
+{
+	unsigned char buf[4];
+
+	if (buffer_get_ret(msg, (char *) buf, 4) == -1)
+		return (-1);
+	if (ret != NULL)
+		*ret = get_uint32(buf);
+	return (0);
+}
+
+int buffer_get_int(buffer_t *msg)
+{
+	int ret = -1;
+
+	if (buffer_get_int_ret(&ret, msg) == -1) {
+		// TODO: \x83G\x83\x89\x81[\x8F\x88\x97\x9D
+		OutputDebugPrintf("buffer_get_int: buffer error");
+	}
+	return (ret);
+}
+
+int buffer_get_char_ret(char *ret, buffer_t *msg)
+{
+	if (buffer_get_ret(msg, ret, 1) == -1)
+		return (-1);
+	return (0);
+}
+
+int buffer_get_char(buffer_t *msg)
+{
+	char ch;
+
+	if (buffer_get_char_ret(&ch, msg) == -1) {
+		// TODO: \x83G\x83\x89\x81[\x8F\x88\x97\x9D
+		OutputDebugPrintf("buffer_get_char: buffer error");
+	}
+	return (unsigned char)ch;
+}
+
 // getting string buffer.
 // NOTE: You should free the return pointer if it's unused.
 // (2005.6.26 yutaka)

Modified: trunk/ttssh2/ttxssh/buffer.h
===================================================================
--- trunk/ttssh2/ttxssh/buffer.h	2012-05-03 13:18:59 UTC (rev 4927)
+++ trunk/ttssh2/ttxssh/buffer.h	2012-05-03 14:39:47 UTC (rev 4928)
@@ -6,10 +6,10 @@
 #include <zlib.h>
 
 typedef struct buffer {
-	char *buf;
-	int offset;
-	int maxlen;
-	int len;
+	char *buf;      /* \x83o\x83b\x83t\x83@\x82̐擪\x83|\x83C\x83\x93\x83^\x81Brealloc()\x82ɂ\xE6\x82\xE8\x95ϓ\xAE\x82\xB7\x82\xE9\x81B*/
+	int offset;     /* \x8C\xBB\x8D݂̓ǂݏo\x82\xB5\x88ʒu */
+	int maxlen;     /* \x83o\x83b\x83t\x83@\x82̍ő\xE5\x83T\x83C\x83Y */
+	int len;        /* \x83o\x83b\x83t\x83@\x82Ɋ܂܂\xEA\x82\xE9\x97L\x8C\xF8\x82ȃf\x81[\x83^\x83T\x83C\x83Y */
 } buffer_t;
 
 void buffer_clear(buffer_t *buf);
@@ -36,5 +36,11 @@
 void buffer_consume(buffer_t *buf, int shift_byte);
 int buffer_compress(z_stream *zstream, char *payload, int len, buffer_t *compbuf);
 int buffer_decompress(z_stream *zstream, char *payload, int len, buffer_t *compbuf);
+int buffer_get_ret(buffer_t *msg, void *buf, int len);
+int buffer_get_int_ret(int *ret, buffer_t *msg);
+int buffer_get_int(buffer_t *msg);
+int buffer_get_char_ret(char *ret, buffer_t *msg);
+int buffer_get_char(buffer_t *msg);
+void buffer_rewind(buffer_t *buf);
 
 #endif				/* BUFFER_H */

Modified: trunk/ttssh2/ttxssh/sftp.c
===================================================================
--- trunk/ttssh2/ttxssh/sftp.c	2012-05-03 13:18:59 UTC (rev 4927)
+++ trunk/ttssh2/ttxssh/sftp.c	2012-05-03 14:39:47 UTC (rev 4928)
@@ -51,6 +51,30 @@
 #include <sys/stat.h>
 #include <assert.h>
 
+static void sftp_do_syslog(PTInstVar pvar, int level, char *fmt, ...)
+{
+	char tmp[1024];
+	va_list arg;
+
+	va_start(arg, fmt);
+	_vsnprintf(tmp, sizeof(tmp), fmt, arg);
+	va_end(arg);
+
+	notify_verbose_message(pvar, tmp, level);
+}
+
+static void sftp_syslog(PTInstVar pvar, char *fmt, ...)
+{
+	char tmp[1024];
+	va_list arg;
+
+	va_start(arg, fmt);
+	_vsnprintf(tmp, sizeof(tmp), fmt, arg);
+	va_end(arg);
+
+	notify_verbose_message(pvar, tmp, LOG_LEVEL_VERBOSE);
+}
+
 // SFTP\x90\xEA\x97p\x83o\x83b\x83t\x83@\x82\xF0\x8Am\x95ۂ\xB7\x82\xE9\x81BSCP\x82Ƃ͈قȂ\xE8\x81A\x90擪\x82Ɍ㑱\x82̃f\x81[\x83^\x83T\x83C\x83Y\x82𖄂ߍ\x9E\x82ށB
 static void sftp_buffer_alloc(buffer_t **message)
 {
@@ -89,7 +113,35 @@
 	SSH2_send_channel_data(pvar, c, p, len);
 }
 
+static void sftp_get_msg(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen, buffer_t **message)
+{
+	buffer_t *msg = *message;
+	int msg_len;
+
+	// \x83o\x83b\x83t\x83@\x82\xF0\x8Am\x95ۂ\xB5\x81A\x83f\x81[\x83^\x82\xF0\x82\xB7\x82ׂĕ\xFA\x82荞\x82ށB\x88ȍ~\x82\xCD buffer_t \x8C^\x82\xF0\x92ʂ\xB5\x82đ\x80\x8D삷\x82\xE9\x81B
+	// \x82\xBB\x82\xA4\x82\xB5\x82\xBD\x82ق\xA4\x82\xAA OpenSSH \x82̃R\x81[\x83h\x82Ƃ̐e\x98a\x90\xAB\x82\xAA\x97ǂ\xAD\x82Ȃ邽\x82߁B
+	buffer_clear(msg);
+	buffer_append(msg, data, buflen);
+	buffer_rewind(msg);
+
+	msg_len = buffer_get_int(msg);
+	if (msg_len > SFTP_MAX_MSG_LENGTH) {
+		// TODO:
+		OutputDebugPrintf("Received message too long %u", msg_len);
+		goto error;
+	}
+	if (msg_len + 4 != buflen) {
+		// TODO:
+		OutputDebugPrintf("Buffer length %u is invalid", buflen);
+		goto error;
+	}
+
+error:
+	return;
+}
+
 // SFTP\x92ʐM\x8AJ\x8En\x91O\x82̃l\x83S\x83V\x83G\x81[\x83V\x83\x87\x83\x93
+// based on do_init()#sftp-client.c
 void sftp_do_init(PTInstVar pvar, Channel_t *c)
 {
 	buffer_t *msg;
@@ -101,10 +153,45 @@
 	buffer_put_int(msg, SSH2_FILEXFER_VERSION);
 	sftp_send_msg(pvar, c, msg);
 	sftp_buffer_free(msg);
+
+	sftp_syslog(pvar, "SFTP client version %u", SSH2_FILEXFER_VERSION);
 }
 
+static void sftp_do_init_recv(PTInstVar pvar, buffer_t *msg)
+{
+	unsigned int type;
+
+	type = buffer_get_char(msg);
+	if (type != SSH2_FXP_VERSION) {
+		goto error;
+	}
+	sftp_syslog(pvar, "SFTP server version %u", type);
+
+error:
+	return;
+}
+
+// SFTP\x8E\xF3\x90M\x8F\x88\x97\x9D -\x83\x81\x83C\x83\x93\x83\x8B\x81[\x83`\x83\x93-
 void sftp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen)
 {
+	buffer_t *msg;
+	int state;
+
 	OutputDebugPrintf("len %d\n", buflen);
 
+	/*
+	 * Allocate buffer
+	 */
+	sftp_buffer_alloc(&msg);
+	sftp_get_msg(pvar, c, data, buflen, &msg);
+
+	state = c->sftp.state;
+	if (state == SFTP_INIT) {
+		sftp_do_init_recv(pvar, msg);
+	}
+
+	/*
+	 * Free buffer
+	 */
+	sftp_buffer_free(msg);
 }

Modified: trunk/ttssh2/ttxssh/sftp.h
===================================================================
--- trunk/ttssh2/ttxssh/sftp.h	2012-05-03 13:18:59 UTC (rev 4927)
+++ trunk/ttssh2/ttxssh/sftp.h	2012-05-03 14:39:47 UTC (rev 4928)
@@ -99,6 +99,8 @@
 #define SSH2_FX_OP_UNSUPPORTED		8
 #define SSH2_FX_MAX			8
 
+/* Maximum packet that we are willing to send/accept */
+#define SFTP_MAX_MSG_LENGTH	(256 * 1024)
 
 void sftp_do_init(PTInstVar pvar, Channel_t *c);
 void sftp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen);



Ttssh2-commit メーリングリストの案内