svnno****@sourc*****
svnno****@sourc*****
2012年 5月 4日 (金) 01:17:09 JST
Revision: 4929 http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=4929 Author: yutakapon Date: 2012-05-04 01:17:09 +0900 (Fri, 04 May 2012) Log Message: ----------- SFTP: 最初のネゴシエーションまで完了。 Modified Paths: -------------- trunk/ttssh2/ttxssh/buffer.c trunk/ttssh2/ttxssh/buffer.h trunk/ttssh2/ttxssh/sftp.c trunk/ttssh2/ttxssh/sftp.h trunk/ttssh2/ttxssh/ssh.h -------------- next part -------------- Modified: trunk/ttssh2/ttxssh/buffer.c =================================================================== --- trunk/ttssh2/ttxssh/buffer.c 2012-05-03 14:39:47 UTC (rev 4928) +++ trunk/ttssh2/ttxssh/buffer.c 2012-05-03 16:17:09 UTC (rev 4929) @@ -151,28 +151,28 @@ 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_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_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) @@ -186,11 +186,11 @@ 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_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) @@ -236,6 +236,21 @@ return(ptr); } +// buffer_get_string() \x82\xCC buffer_t \x94ŁB\x96{\x97\x88\x82͂\xB1\x82\xBF\x82炪 OpenSSH \x83X\x83^\x83C\x83\x8B\x81B +// NOTE: You should free the return pointer if it's unused. +void *buffer_get_string_msg(buffer_t *msg, int *buflen_ptr) +{ + char *data, *olddata; + void *ret; + int off; + + data = olddata = buffer_tail_ptr(msg); + ret = buffer_get_string(&data, buflen_ptr); + off = data - olddata; + msg->offset += off; + return (ret); +} + void buffer_put_string(buffer_t *msg, char *ptr, int size) { char buf[4]; @@ -281,6 +296,12 @@ return (msg->len); } +// \x82܂\xBE\x93ǂݍ\x9E\x82\xF1\x82ł\xA2\x82Ȃ\xA2\x8Ec\x82\xE8\x82̃T\x83C\x83Y\x82\xF0\x95Ԃ\xB7\x81B\x96{\x97\x88\x82͂\xB1\x82\xBF\x82炪 OpenSSH \x83X\x83^\x83C\x83\x8B\x81B +int buffer_remain_len(buffer_t *msg) +{ + return (msg->len - msg->offset); +} + // buffer_append() \x82\xE2 buffer_append_space() \x82Ń\x81\x83b\x83Z\x81[\x83W\x83o\x83b\x83t\x83@\x82ɒlj\xC1\x82\xF0\x8Ds\x82\xA4\x82ƁA // \x93\xE0\x95\x94\x82\xC5 realloc() \x82ɂ\xE6\x82\xE8\x83o\x83b\x83t\x83@\x83|\x83C\x83\x93\x83^\x82\xAA\x95ς\xED\x82\xC1\x82Ă\xB5\x82܂\xA4\x82\xB1\x82Ƃ\xAA\x82\xA0\x82\xE9\x81B // \x83\x81\x83b\x83Z\x81[\x83W\x83o\x83b\x83t\x83@\x82̃|\x83C\x83\x93\x83^\x82\xF0\x8E擾\x82\xB7\x82\xE9\x8Dۂ́A\x83o\x83b\x83t\x83@\x92lj\xC1\x82\xAA\x8A\xAE\x97\xB9\x82\xB5\x82\xBD\x8C\xE3\x82\xC9 Modified: trunk/ttssh2/ttxssh/buffer.h =================================================================== --- trunk/ttssh2/ttxssh/buffer.h 2012-05-03 14:39:47 UTC (rev 4928) +++ trunk/ttssh2/ttxssh/buffer.h 2012-05-03 16:17:09 UTC (rev 4929) @@ -36,11 +36,13 @@ 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_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_ret(char *ret, buffer_t *msg); int buffer_get_char(buffer_t *msg); void buffer_rewind(buffer_t *buf); +void *buffer_get_string_msg(buffer_t *msg, int *buflen_ptr); +int buffer_remain_len(buffer_t *msg); #endif /* BUFFER_H */ Modified: trunk/ttssh2/ttxssh/sftp.c =================================================================== --- trunk/ttssh2/ttxssh/sftp.c 2012-05-03 14:39:47 UTC (rev 4928) +++ trunk/ttssh2/ttxssh/sftp.c 2012-05-03 16:17:09 UTC (rev 4929) @@ -76,6 +76,13 @@ } // 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 +// +// buffer_t +// +---------+------------------------------------+ +// | msg_len | data | +// +---------+------------------------------------+ +// 4byte <------------- msg_len -------------> +// static void sftp_buffer_alloc(buffer_t **message) { buffer_t *msg; @@ -113,6 +120,7 @@ SSH2_send_channel_data(pvar, c, p, len); } +// \x83T\x81[\x83o\x82\xA9\x82\xE7\x8E\xF3\x90M\x82\xB5\x82\xBDSFTP\x83p\x83P\x83b\x83g\x82\xF0\x83o\x83b\x83t\x83@\x82Ɋi\x94[\x82\xB7\x82\xE9\x81B static void sftp_get_msg(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen, buffer_t **message) { buffer_t *msg = *message; @@ -127,12 +135,12 @@ msg_len = buffer_get_int(msg); if (msg_len > SFTP_MAX_MSG_LENGTH) { // TODO: - OutputDebugPrintf("Received message too long %u", msg_len); + sftp_syslog(pvar, "Received message too long %u", msg_len); goto error; } if (msg_len + 4 != buflen) { // TODO: - OutputDebugPrintf("Buffer length %u is invalid", buflen); + sftp_syslog(pvar, "Buffer length %u is invalid", buflen); goto error; } @@ -146,8 +154,15 @@ { buffer_t *msg; + // SFTP\x8AǗ\x9D\x8D\\x91\xA2\x91̂̏\x89\x8A\xFA\x89\xBB + memset(&c->sftp, 0, sizeof(c->sftp)); c->sftp.state = SFTP_INIT; + c->sftp.transfer_buflen = DEFAULT_COPY_BUFLEN; + c->sftp.num_requests = DEFAULT_NUM_REQUESTS; + c->sftp.exts = 0; + c->sftp.limit_kbps = 0; + // \x83l\x83S\x83V\x83G\x81[\x83V\x83\x87\x83\x93\x82̊J\x8En sftp_buffer_alloc(&msg); buffer_put_char(msg, SSH2_FXP_INIT); buffer_put_int(msg, SSH2_FILEXFER_VERSION); @@ -157,7 +172,7 @@ sftp_syslog(pvar, "SFTP client version %u", SSH2_FILEXFER_VERSION); } -static void sftp_do_init_recv(PTInstVar pvar, buffer_t *msg) +static void sftp_do_init_recv(PTInstVar pvar, Channel_t *c, buffer_t *msg) { unsigned int type; @@ -165,8 +180,50 @@ if (type != SSH2_FXP_VERSION) { goto error; } - sftp_syslog(pvar, "SFTP server version %u", type); + c->sftp.version = buffer_get_int(msg); + sftp_syslog(pvar, "SFTP server version %u, remote version %u", type, c->sftp.version); + while (buffer_remain_len(msg) > 0) { + char *name = buffer_get_string_msg(msg, NULL); + char *value = buffer_get_string_msg(msg, NULL); + int known = 0; + + if (strcmp(name, "posix****@opens*****") == 0 && + strcmp(value, "1") == 0) { + c->sftp.exts |= SFTP_EXT_POSIX_RENAME; + known = 1; + } else if (strcmp(name, "statv****@opens*****") == 0 && + strcmp(value, "2") == 0) { + c->sftp.exts |= SFTP_EXT_STATVFS; + known = 1; + } else if (strcmp(name, "fstat****@opens*****") == 0 && + strcmp(value, "2") == 0) { + c->sftp.exts |= SFTP_EXT_FSTATVFS; + known = 1; + } else if (strcmp(name, "hardl****@opens*****") == 0 && + strcmp(value, "1") == 0) { + c->sftp.exts |= SFTP_EXT_HARDLINK; + known = 1; + } + if (known) { + sftp_syslog(pvar, "Server supports extension \"%s\" revision %s", + name, value); + } else { + sftp_syslog(pvar, "Unrecognised server extension \"%s\"", name); + } + + free(name); + free(value); + } + + if (c->sftp.version == 0) { + c->sftp.transfer_buflen = min(c->sftp.transfer_buflen, 20480); + } + c->sftp.limit_kbps = 0; + if (c->sftp.limit_kbps > 0) { + // TODO: + } + error: return; } @@ -177,8 +234,6 @@ buffer_t *msg; int state; - OutputDebugPrintf("len %d\n", buflen); - /* * Allocate buffer */ @@ -187,7 +242,8 @@ state = c->sftp.state; if (state == SFTP_INIT) { - sftp_do_init_recv(pvar, msg); + sftp_do_init_recv(pvar, c, msg); + sftp_syslog(pvar, "Connected to SFTP server."); } /* Modified: trunk/ttssh2/ttxssh/sftp.h =================================================================== --- trunk/ttssh2/ttxssh/sftp.h 2012-05-03 14:39:47 UTC (rev 4928) +++ trunk/ttssh2/ttxssh/sftp.h 2012-05-03 16:17:09 UTC (rev 4929) @@ -99,9 +99,12 @@ #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) +/* Maximum packet that we are willing to send/accept */ +#define SFTP_MAX_MSG_LENGTH (256 * 1024) +#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */ +#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */ + void sftp_do_init(PTInstVar pvar, Channel_t *c); void sftp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen); Modified: trunk/ttssh2/ttxssh/ssh.h =================================================================== --- trunk/ttssh2/ttxssh/ssh.h 2012-05-03 14:39:47 UTC (rev 4928) +++ trunk/ttssh2/ttxssh/ssh.h 2012-05-03 16:17:09 UTC (rev 4929) @@ -664,6 +664,17 @@ typedef struct sftp { enum sftp_state state; + unsigned int transfer_buflen; + unsigned int num_requests; + unsigned int version; + unsigned int msg_id; +#define SFTP_EXT_POSIX_RENAME 0x00000001 +#define SFTP_EXT_STATVFS 0x00000002 +#define SFTP_EXT_FSTATVFS 0x00000004 +#define SFTP_EXT_HARDLINK 0x00000008 + unsigned int exts; + unsigned long long limit_kbps; + //struct bwlimit bwlimit_in, bwlimit_out; } sftp_t; typedef struct channel {