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);