1
1

re-indented the source code with this script:

indent \
--braces-on-if-line \
--braces-after-struct-decl-line \
--space-after-cast \
--line-length 79 \
--comment-line-length 79 \
--cuddle-else \
--no-tabs \
--tab-size 8 \
--indent-level 4 \
--no-space-after-for \
--space-after-if \
--space-after-while \
--no-space-after-function-call-names \
*.[ch]
Этот коммит содержится в:
Daniel Stenberg 2007-08-06 20:48:04 +00:00
родитель 4c3dd3ea9f
Коммит 210459db4b
20 изменённых файлов: 6378 добавлений и 4497 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -47,27 +47,28 @@
/* {{{ libssh2_comp_method_none_comp /* {{{ libssh2_comp_method_none_comp
* Minimalist compression: Absolutely none * Minimalist compression: Absolutely none
*/ */
static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session, static int
int compress, libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
unsigned char **dest, int compress,
unsigned long *dest_len, unsigned char **dest,
unsigned long payload_limit, unsigned long *dest_len,
int *free_dest, unsigned long payload_limit,
const unsigned char *src, int *free_dest,
unsigned long src_len, const unsigned char *src,
void **abstract) unsigned long src_len, void **abstract)
{ {
(void)session; (void) session;
(void)compress; (void) compress;
(void)payload_limit; (void) payload_limit;
(void)abstract; (void) abstract;
*dest = (unsigned char *)src; *dest = (unsigned char *) src;
*dest_len = src_len; *dest_len = src_len;
*free_dest = 0; *free_dest = 0;
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = { static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
@ -87,39 +88,46 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
* Deal... * Deal...
*/ */
static voidpf libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) static voidpf
libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
{ {
LIBSSH2_SESSION *session = (LIBSSH2_SESSION*)opaque; LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
return (voidpf)LIBSSH2_ALLOC(session, items * size); return (voidpf) LIBSSH2_ALLOC(session, items * size);
} }
static void libssh2_comp_method_zlib_free(voidpf opaque, voidpf address) static void
libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
{ {
LIBSSH2_SESSION *session = (LIBSSH2_SESSION*)opaque; LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
LIBSSH2_FREE(session, address); LIBSSH2_FREE(session, address);
} }
/* }}} */ /* }}} */
/* {{{ libssh2_comp_method_zlib_init /* {{{ libssh2_comp_method_zlib_init
* All your bandwidth are belong to us (so save some) * All your bandwidth are belong to us (so save some)
*/ */
static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress, void **abstract) static int
libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
void **abstract)
{ {
z_stream *strm; z_stream *strm;
int status; int status;
strm = LIBSSH2_ALLOC(session, sizeof(z_stream)); strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
if (!strm) { if (!strm) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for zlib compression/decompression", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for zlib compression/decompression",
0);
return -1; return -1;
} }
memset(strm, 0, sizeof(z_stream)); memset(strm, 0, sizeof(z_stream));
strm->opaque = (voidpf)session; strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func)libssh2_comp_method_zlib_alloc; strm->zalloc = (alloc_func) libssh2_comp_method_zlib_alloc;
strm->zfree = (free_func)libssh2_comp_method_zlib_free; strm->zfree = (free_func) libssh2_comp_method_zlib_free;
if (compress) { if (compress) {
/* deflate */ /* deflate */
status = deflateInit(strm, Z_DEFAULT_COMPRESSION); status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
@ -136,20 +144,21 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress,
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_comp_method_zlib_comp /* {{{ libssh2_comp_method_zlib_comp
* zlib, a compression standard for all occasions * zlib, a compression standard for all occasions
*/ */
static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, static int
int compress, libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
unsigned char **dest, int compress,
unsigned long *dest_len, unsigned char **dest,
unsigned long payload_limit, unsigned long *dest_len,
int *free_dest, unsigned long payload_limit,
const unsigned char *src, int *free_dest,
unsigned long src_len, const unsigned char *src,
void **abstract) unsigned long src_len, void **abstract)
{ {
z_stream *strm = *abstract; z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of /* A short-term alloc of a full data chunk is better than a series of
@ -163,17 +172,19 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
out_maxlen = 25; out_maxlen = 25;
} }
if (out_maxlen > (int)payload_limit) { if (out_maxlen > (int) payload_limit) {
out_maxlen = payload_limit; out_maxlen = payload_limit;
} }
strm->next_in = (unsigned char *)src; strm->next_in = (unsigned char *) src;
strm->avail_in = src_len; strm->avail_in = src_len;
strm->next_out = (unsigned char *)LIBSSH2_ALLOC(session, out_maxlen); strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
out = (char *)strm->next_out; out = (char *) strm->next_out;
strm->avail_out = out_maxlen; strm->avail_out = out_maxlen;
if (!strm->next_out) { if (!strm->next_out) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate compression/decompression buffer", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate compression/decompression buffer",
0);
return -1; return -1;
} }
while (strm->avail_in) { while (strm->avail_in) {
@ -185,7 +196,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
status = inflate(strm, Z_PARTIAL_FLUSH); status = inflate(strm, Z_PARTIAL_FLUSH);
} }
if (status != Z_OK) { if (status != Z_OK) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure", 0);
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
@ -193,80 +205,92 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
unsigned long out_ofs = out_maxlen - strm->avail_out; unsigned long out_ofs = out_maxlen - strm->avail_out;
char *newout; char *newout;
out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); out_maxlen +=
compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
if ((out_maxlen > (int)payload_limit) && if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
!compress && limiter++) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase", 0); "Excessive growth in decompression phase", 0);
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
newout = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) { if (!newout) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand compress/decompression buffer",
0);
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
out = newout; out = newout;
strm->next_out = (unsigned char *)out + out_ofs; strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); strm->avail_out +=
} else while (!strm->avail_out) { compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
/* Done with input, might be a byte or two in internal buffer during compress } else
* Or potentially many bytes if it's a decompress while (!strm->avail_out) {
*/ /* Done with input, might be a byte or two in internal buffer during compress
int grow_size = compress ? 8 : 1024; * Or potentially many bytes if it's a decompress
char *newout; */
int grow_size = compress ? 8 : 1024;
char *newout;
if (out_maxlen >= (int)payload_limit) { if (out_maxlen >= (int) payload_limit) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0); libssh2_error(session, LIBSSH2_ERROR_ZLIB,
LIBSSH2_FREE(session, out); "Excessive growth in decompression phase",
return -1; 0);
} LIBSSH2_FREE(session, out);
return -1;
}
if (grow_size > (int)(payload_limit - out_maxlen)) { if (grow_size > (int) (payload_limit - out_maxlen)) {
grow_size = payload_limit - out_maxlen; grow_size = payload_limit - out_maxlen;
} }
out_maxlen += grow_size; out_maxlen += grow_size;
strm->avail_out = grow_size; strm->avail_out = grow_size;
newout = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) { if (!newout) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
LIBSSH2_FREE(session, out); "Unable to expand final compress/decompress buffer",
return -1; 0);
} LIBSSH2_FREE(session, out);
out = newout; return -1;
strm->next_out = (unsigned char *)out + out_maxlen - }
grow_size; out = newout;
strm->next_out = (unsigned char *) out + out_maxlen -
grow_size;
if (compress) { if (compress) {
status = deflate(strm, Z_PARTIAL_FLUSH); status = deflate(strm, Z_PARTIAL_FLUSH);
} else { } else {
status = inflate(strm, Z_PARTIAL_FLUSH); status = inflate(strm, Z_PARTIAL_FLUSH);
}
if (status != Z_OK) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure", 0);
LIBSSH2_FREE(session, out);
return -1;
}
} }
if (status != Z_OK) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0);
LIBSSH2_FREE(session, out);
return -1;
}
}
} }
*dest = (unsigned char *)out; *dest = (unsigned char *) out;
*dest_len = out_maxlen - strm->avail_out; *dest_len = out_maxlen - strm->avail_out;
*free_dest = 1; *free_dest = 1;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_comp_method_zlib_dtor /* {{{ libssh2_comp_method_zlib_dtor
* All done, no more compression for you * All done, no more compression for you
*/ */
static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress, void **abstract) static int
libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
void **abstract)
{ {
z_stream *strm = *abstract; z_stream *strm = *abstract;
@ -286,6 +310,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = { static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
@ -308,7 +333,8 @@ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
NULL NULL
}; };
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) { const LIBSSH2_COMP_METHOD **
libssh2_comp_methods(void)
{
return _libssh2_comp_methods; return _libssh2_comp_methods;
} }

Просмотреть файл

@ -41,47 +41,51 @@
/* {{{ libssh2_crypt_none_crypt /* {{{ libssh2_crypt_none_crypt
* Minimalist cipher: VERY secure *wink* * Minimalist cipher: VERY secure *wink*
*/ */
static int libssh2_crypt_none_crypt(LIBSSH2_SESSION *session, unsigned char *buf, void **abstract) static int
libssh2_crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
void **abstract)
{ {
/* Do nothing to the data! */ /* Do nothing to the data! */
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
"none", "none",
8, /* blocksize (SSH2 defines minimum blocksize as 8) */ 8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */ 0, /* iv_len */
0, /* secret_len */ 0, /* secret_len */
0, /* flags */ 0, /* flags */
NULL, NULL,
libssh2_crypt_none_crypt, libssh2_crypt_none_crypt,
NULL NULL
}; };
#endif /* LIBSSH2_CRYPT_NONE */ #endif /* LIBSSH2_CRYPT_NONE */
struct crypt_ctx { struct crypt_ctx
{
int encrypt; int encrypt;
_libssh2_cipher_type(algo); _libssh2_cipher_type(algo);
_libssh2_cipher_ctx h; _libssh2_cipher_ctx h;
}; };
static int _libssh2_init (LIBSSH2_SESSION *session, static int
const LIBSSH2_CRYPT_METHOD *method, _libssh2_init(LIBSSH2_SESSION * session,
unsigned char *iv, int *free_iv, const LIBSSH2_CRYPT_METHOD * method,
unsigned char *secret, int *free_secret, unsigned char *iv, int *free_iv,
int encrypt, void **abstract) unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{ {
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx)); sizeof(struct crypt_ctx));
if (!ctx) { if (!ctx) {
return -1; return -1;
} }
ctx->encrypt = encrypt; ctx->encrypt = encrypt;
ctx->algo = method->algo; ctx->algo = method->algo;
if (_libssh2_cipher_init (&ctx->h, ctx->algo, iv, secret, encrypt)) if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
{ LIBSSH2_FREE(session, ctx);
LIBSSH2_FREE (session, ctx);
return -1; return -1;
} }
*abstract = ctx; *abstract = ctx;
@ -90,17 +94,19 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
return 0; return 0;
} }
static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract) static int
_libssh2_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
void **abstract)
{ {
struct crypt_ctx *cctx = *(struct crypt_ctx **)abstract; struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
(void)session; (void) session;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
cctx->encrypt, block);
} }
static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract) static int
_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
struct crypt_ctx **cctx = (struct crypt_ctx **)abstract; struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if (cctx && *cctx) { if (cctx && *cctx) {
_libssh2_cipher_dtor(&(*cctx)->h); _libssh2_cipher_dtor(&(*cctx)->h);
LIBSSH2_FREE(session, *cctx); LIBSSH2_FREE(session, *cctx);
@ -112,10 +118,10 @@ static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract)
#if LIBSSH2_AES #if LIBSSH2_AES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc", "aes128-cbc",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */ 16, /* secret length -- 16*8 == 128bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -124,10 +130,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
"aes192-cbc", "aes192-cbc",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */ 24, /* secret length -- 24*8 == 192bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -136,10 +142,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
"aes256-cbc", "aes256-cbc",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -147,12 +153,13 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
}; };
/* rijndael-cbc@lysator.liu.se == aes256-cbc */ /* rijndael-cbc@lysator.liu.se == aes256-cbc */
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
"rijndael-cbc@lysator.liu.se", "rijndael-cbc@lysator.liu.se",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -163,10 +170,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_
#if LIBSSH2_BLOWFISH #if LIBSSH2_BLOWFISH
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
"blowfish-cbc", "blowfish-cbc",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -177,10 +184,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
#if LIBSSH2_RC4 #if LIBSSH2_RC4
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
"arcfour", "arcfour",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -191,10 +198,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
#if LIBSSH2_CAST #if LIBSSH2_CAST
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
"cast128-cbc", "cast128-cbc",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -205,10 +212,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
#if LIBSSH2_3DES #if LIBSSH2_3DES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
"3des-cbc", "3des-cbc",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
24, /* secret length */ 24, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@ -219,7 +226,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
#if LIBSSH2_AES #if LIBSSH2_AES
&libssh2_crypt_method_aes256_cbc, &libssh2_crypt_method_aes256_cbc,
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
&libssh2_crypt_method_aes192_cbc, &libssh2_crypt_method_aes192_cbc,
&libssh2_crypt_method_aes128_cbc, &libssh2_crypt_method_aes128_cbc,
#endif /* LIBSSH2_AES */ #endif /* LIBSSH2_AES */
@ -242,6 +249,8 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
}; };
/* Expose to kex.c */ /* Expose to kex.c */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) { const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)
{
return _libssh2_crypt_methods; return _libssh2_crypt_methods;
} }

Просмотреть файл

@ -47,22 +47,23 @@
* ssh-rsa * * ssh-rsa *
*********** */ *********** */
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **abstract); static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
void **abstract);
/* {{{ libssh2_hostkey_method_ssh_rsa_init /* {{{ libssh2_hostkey_method_ssh_rsa_init
* Initialize the server hostkey working area with e/n pair * Initialize the server hostkey working area with e/n pair
*/ */
static int static int
libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data, const unsigned char *hostkey_data,
unsigned long hostkey_data_len, unsigned long hostkey_data_len,
void **abstract) void **abstract)
{ {
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
const unsigned char *s, *e, *n; const unsigned char *s, *e, *n;
unsigned long len, e_len, n_len; unsigned long len, e_len, n_len;
(void)hostkey_data_len; (void) hostkey_data_len;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
@ -73,7 +74,7 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
len = libssh2_ntohu32(s); len = libssh2_ntohu32(s);
s += 4; s += 4;
if (len != 7 || strncmp((char *)s, "ssh-rsa", 7) != 0) { if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) {
return -1; return -1;
} }
s += 7; s += 7;
@ -81,25 +82,32 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
e_len = libssh2_ntohu32(s); e_len = libssh2_ntohu32(s);
s += 4; s += 4;
e = s; s += e_len; e = s;
n_len = libssh2_ntohu32(s); s += 4; s += e_len;
n = s; s += n_len; n_len = libssh2_ntohu32(s);
s += 4;
n = s;
s += n_len;
if (_libssh2_rsa_new (&rsactx, e, e_len, n, n_len, NULL, 0, if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
return -1; return -1;
*abstract = rsactx; *abstract = rsactx;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_initPEM /* {{{ libssh2_hostkey_method_ssh_rsa_initPEM
* Load a Private Key from a PEM file * Load a Private Key from a PEM file
*/ */
static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, static int
const char *privkeyfile, unsigned const char *passphrase, void **abstract) libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{ {
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
FILE *fp; FILE *fp;
@ -115,7 +123,7 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
return -1; return -1;
} }
ret = _libssh2_rsa_new_private (&rsactx, session, fp, passphrase); ret = _libssh2_rsa_new_private(&rsactx, session, fp, passphrase);
fclose(fp); fclose(fp);
if (ret) { if (ret) {
return -1; return -1;
@ -125,34 +133,42 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_sign /* {{{ libssh2_hostkey_method_ssh_rsa_sign
* Verify signature created by remote * Verify signature created by remote
*/ */
static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session, static int
const unsigned char *sig, libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
unsigned long sig_len, const unsigned char *sig,
const unsigned char *m, unsigned long sig_len,
unsigned long m_len, const unsigned char *m,
void **abstract) unsigned long m_len, void **abstract)
{ {
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void)session; (void) session;
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
sig += 15; sig_len -= 15; sig += 15;
return _libssh2_rsa_sha1_verify (rsactx, sig, sig_len, m, m_len); sig_len -= 15;
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_signv /* {{{ libssh2_hostkey_method_ssh_rsa_signv
* Construct a signature from an array of vectors * Construct a signature from an array of vectors
*/ */
static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, static int
unsigned long veccount, const struct iovec datavec[], void **abstract) libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
const struct iovec datavec[],
void **abstract)
{ {
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
int ret; int ret;
unsigned int i; unsigned int i;
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
@ -165,23 +181,24 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign
libssh2_sha1_final(ctx, hash); libssh2_sha1_final(ctx, hash);
ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
signature, signature_len); signature, signature_len);
if (ret) { if (ret) {
return -1; return -1;
} }
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_dtor /* {{{ libssh2_hostkey_method_ssh_rsa_dtor
* Shutdown the hostkey * Shutdown the hostkey
*/ */
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, static int
void **abstract) libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void)session; (void) session;
_libssh2_rsa_free(rsactx); _libssh2_rsa_free(rsactx);
@ -189,6 +206,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
@ -198,7 +216,7 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
libssh2_hostkey_method_ssh_rsa_initPEM, libssh2_hostkey_method_ssh_rsa_initPEM,
libssh2_hostkey_method_ssh_rsa_sig_verify, libssh2_hostkey_method_ssh_rsa_sig_verify,
libssh2_hostkey_method_ssh_rsa_signv, libssh2_hostkey_method_ssh_rsa_signv,
NULL, /* encrypt */ NULL, /* encrypt */
libssh2_hostkey_method_ssh_rsa_dtor, libssh2_hostkey_method_ssh_rsa_dtor,
}; };
#endif /* LIBSSH2_RSA */ #endif /* LIBSSH2_RSA */
@ -208,21 +226,22 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
* ssh-dss * * ssh-dss *
*********** */ *********** */
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void **abstract); static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
void **abstract);
/* {{{ libssh2_hostkey_method_ssh_dss_init /* {{{ libssh2_hostkey_method_ssh_dss_init
* Initialize the server hostkey working area with p/q/g/y set * Initialize the server hostkey working area with p/q/g/y set
*/ */
static int static int
libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data, const unsigned char *hostkey_data,
unsigned long hostkey_data_len, unsigned long hostkey_data_len,
void **abstract) void **abstract)
{ {
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
const unsigned char *p, *q, *g, *y, *s; const unsigned char *p, *q, *g, *y, *s;
unsigned long p_len, q_len, g_len, y_len, len; unsigned long p_len, q_len, g_len, y_len, len;
(void)hostkey_data_len; (void) hostkey_data_len;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_dss_dtor(session, abstract); libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
@ -230,36 +249,47 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
} }
s = hostkey_data; s = hostkey_data;
len = libssh2_ntohu32(s); s += 4; len = libssh2_ntohu32(s);
if (len != 7 || strncmp((char *)s, "ssh-dss", 7) != 0) { s += 4;
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
return -1; return -1;
} s += 7; }
s += 7;
p_len = libssh2_ntohu32(s); s += 4; p_len = libssh2_ntohu32(s);
p = s; s += p_len; s += 4;
q_len = libssh2_ntohu32(s); s += 4; p = s;
q = s; s += q_len; s += p_len;
g_len = libssh2_ntohu32(s); s += 4; q_len = libssh2_ntohu32(s);
g = s; s += g_len; s += 4;
y_len = libssh2_ntohu32(s); s += 4; q = s;
y = s; s += y_len; s += q_len;
g_len = libssh2_ntohu32(s);
s += 4;
g = s;
s += g_len;
y_len = libssh2_ntohu32(s);
s += 4;
y = s;
s += y_len;
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
y, y_len, NULL, 0);
*abstract = dsactx; *abstract = dsactx;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_initPEM /* {{{ libssh2_hostkey_method_ssh_dss_initPEM
* Load a Private Key from a PEM file * Load a Private Key from a PEM file
*/ */
static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, static int
const char *privkeyfile, libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
unsigned const char *passphrase, const char *privkeyfile,
void **abstract) unsigned const char *passphrase,
void **abstract)
{ {
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
FILE *fp; FILE *fp;
@ -275,7 +305,7 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
return -1; return -1;
} }
ret = _libssh2_dsa_new_private (&dsactx, session, fp, passphrase); ret = _libssh2_dsa_new_private(&dsactx, session, fp, passphrase);
fclose(fp); fclose(fp);
if (ret) { if (ret) {
return -1; return -1;
@ -285,33 +315,46 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_sign /* {{{ libssh2_hostkey_method_ssh_dss_sign
* Verify signature created by remote * Verify signature created by remote
*/ */
static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, static int
const unsigned char *m, unsigned long m_len, void **abstract) libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
{ {
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
/* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */
sig += 15; sig_len -= 15; sig += 15;
sig_len -= 15;
if (sig_len != 40) { if (sig_len != 40) {
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length", 0); libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid DSS signature length", 0);
return -1; return -1;
} }
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_signv /* {{{ libssh2_hostkey_method_ssh_dss_signv
* Construct a signature from an array of vectors * Construct a signature from an array of vectors
*/ */
static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, static int
unsigned long veccount, const struct iovec datavec[], void **abstract) libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
const struct iovec datavec[],
void **abstract)
{ {
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx; libssh2_sha1_ctx ctx;
unsigned int i; unsigned int i;
@ -330,25 +373,24 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
} }
libssh2_sha1_final(ctx, hash); libssh2_sha1_final(ctx, hash);
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
*signature))
{
LIBSSH2_FREE(session, *signature); LIBSSH2_FREE(session, *signature);
return -1; return -1;
} }
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_dtor /* {{{ libssh2_hostkey_method_ssh_dss_dtor
* Shutdown the hostkey method * Shutdown the hostkey method
*/ */
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, static int
void **abstract) libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
(void)session; (void) session;
_libssh2_dsa_free(dsactx); _libssh2_dsa_free(dsactx);
@ -356,6 +398,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = { static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
@ -365,7 +408,7 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
libssh2_hostkey_method_ssh_dss_initPEM, libssh2_hostkey_method_ssh_dss_initPEM,
libssh2_hostkey_method_ssh_dss_sig_verify, libssh2_hostkey_method_ssh_dss_sig_verify,
libssh2_hostkey_method_ssh_dss_signv, libssh2_hostkey_method_ssh_dss_signv,
NULL, /* encrypt */ NULL, /* encrypt */
libssh2_hostkey_method_ssh_dss_dtor, libssh2_hostkey_method_ssh_dss_dtor,
}; };
#endif /* LIBSSH2_DSA */ #endif /* LIBSSH2_DSA */
@ -380,7 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
NULL NULL
}; };
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) const LIBSSH2_HOSTKEY_METHOD **
libssh2_hostkey_methods(void)
{ {
return _libssh2_hostkey_methods; return _libssh2_hostkey_methods;
} }
@ -391,21 +435,21 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
* Length of buffer is determined by hash type * Length of buffer is determined by hash type
* i.e. MD5 == 16, SHA1 == 20 * i.e. MD5 == 16, SHA1 == 20
*/ */
LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type) LIBSSH2_API const char *
libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
{ {
switch (hash_type) { switch (hash_type) {
#if LIBSSH2_MD5 #if LIBSSH2_MD5
case LIBSSH2_HOSTKEY_HASH_MD5: case LIBSSH2_HOSTKEY_HASH_MD5:
return (char *)session->server_hostkey_md5; return (char *) session->server_hostkey_md5;
break; break;
#endif /* LIBSSH2_MD5 */ #endif /* LIBSSH2_MD5 */
case LIBSSH2_HOSTKEY_HASH_SHA1: case LIBSSH2_HOSTKEY_HASH_SHA1:
return (char *)session->server_hostkey_sha1; return (char *) session->server_hostkey_sha1;
break; break;
default: default:
return NULL; return NULL;
} }
} }
/* }}} */ /* }}} */

1152
src/kex.c

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -38,29 +38,29 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <string.h> #include <string.h>
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int
const unsigned char *edata, _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
unsigned long elen, const unsigned char *edata,
const unsigned char *ndata, unsigned long elen,
unsigned long nlen, const unsigned char *ndata,
const unsigned char *ddata, unsigned long nlen,
unsigned long dlen, const unsigned char *ddata,
const unsigned char *pdata, unsigned long dlen,
unsigned long plen, const unsigned char *pdata,
const unsigned char *qdata, unsigned long plen,
unsigned long qlen, const unsigned char *qdata,
const unsigned char *e1data, unsigned long qlen,
unsigned long e1len, const unsigned char *e1data,
const unsigned char *e2data, unsigned long e1len,
unsigned long e2len, const unsigned char *e2data,
const unsigned char *coeffdata, unsigned long e2len,
unsigned long coefflen) const unsigned char *coeffdata, unsigned long coefflen)
{ {
int rc; int rc;
(void)e1data; (void) e1data;
(void)e1len; (void) e1len;
(void)e2data; (void) e2data;
(void)e2len; (void) e2len;
if (ddata) { if (ddata) {
rc = gcry_sexp_build rc = gcry_sexp_build
@ -69,11 +69,10 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
nlen, ndata, elen, edata, dlen, ddata, plen, pdata, nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata); qlen, qdata, coefflen, coeffdata);
} else { } else {
rc = gcry_sexp_build (rsa, NULL, "(public-key(rsa(n%b)(e%b)))", rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata); nlen, ndata, elen, edata);
} }
if (rc) if (rc) {
{
*rsa = NULL; *rsa = NULL;
return -1; return -1;
} }
@ -81,11 +80,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
return 0; return 0;
} }
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, int
const unsigned char *sig, _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
unsigned long sig_len, const unsigned char *sig,
const unsigned char *m, unsigned long sig_len,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash; gcry_sexp_t s_sig, s_hash;
@ -93,38 +92,37 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
libssh2_sha1(m, m_len, hash); libssh2_sha1(m, m_len, hash);
rc = gcry_sexp_build (&s_hash, NULL, rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))", "(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash); SHA_DIGEST_LENGTH, hash);
if (rc != 0) { if (rc != 0) {
return -1; return -1;
} }
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))", rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
sig_len, sig);
if (rc != 0) { if (rc != 0) {
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return -1; return -1;
} }
rc = gcry_pk_verify (s_sig, s_hash, rsa); rc = gcry_pk_verify(s_sig, s_hash, rsa);
gcry_sexp_release (s_sig); gcry_sexp_release(s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1; return (rc == 0) ? 0 : -1;
} }
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, int
const unsigned char *p, _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
unsigned long p_len, const unsigned char *p,
const unsigned char *q, unsigned long p_len,
unsigned long q_len, const unsigned char *q,
const unsigned char *g, unsigned long q_len,
unsigned long g_len, const unsigned char *g,
const unsigned char *y, unsigned long g_len,
unsigned long y_len, const unsigned char *y,
const unsigned char *x, unsigned long y_len,
unsigned long x_len) const unsigned char *x, unsigned long x_len)
{ {
int rc; int rc;
@ -134,9 +132,9 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
} else { } else {
rc = gcry_sexp_build (dsactx, NULL, rc = gcry_sexp_build(dsactx, NULL,
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
p_len, p, q_len, q, g_len, g, y_len, y); p_len, p, q_len, q, g_len, g, y_len, y);
} }
if (rc) { if (rc) {
@ -147,10 +145,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
return 0; return 0;
} }
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, int
LIBSSH2_SESSION *session, _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
char *data, *save_data; char *data, *save_data;
unsigned int datalen; unsigned int datalen;
@ -158,95 +156,94 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
char *n, *e, *d, *p, *q, *e1, *e2, *coeff; char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
(void)passphrase; (void) passphrase;
ret = _libssh2_pem_parse (session, ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----", "-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----",
fp, &data, &datalen); fp, &data, &datalen);
if (ret) { if (ret) {
return -1; return -1;
} }
save_data = data; save_data = data;
if (_libssh2_pem_decode_sequence (&data, &datalen)) { if (_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
/* First read Version field (should be 0). */ /* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if (ret != 0 || (nlen != 1 && *n != '\0')) { if (ret != 0 || (nlen != 1 && *n != '\0')) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &e, &elen); ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &d, &dlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &e1, &e1len); ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &e2, &e2len); ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &coeff, &coefflen); ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
if (_libssh2_rsa_new (rsa, e, elen, n, nlen, d, dlen, p, plen, if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len, q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
coeff, coefflen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = 0; ret = 0;
fail: fail:
LIBSSH2_FREE (session, save_data); LIBSSH2_FREE(session, save_data);
return ret; return ret;
} }
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, int
LIBSSH2_SESSION *session, _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
char *data, *save_data; char *data, *save_data;
unsigned int datalen; unsigned int datalen;
@ -254,55 +251,55 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
char *p, *q, *g, *y, *x; char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen; unsigned int plen, qlen, glen, ylen, xlen;
(void)passphrase; (void) passphrase;
ret = _libssh2_pem_parse (session, ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----", "-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----", "-----END DSA PRIVATE KEY-----",
fp, &data, &datalen); fp, &data, &datalen);
if (ret) { if (ret) {
return -1; return -1;
} }
save_data = data; save_data = data;
if (_libssh2_pem_decode_sequence (&data, &datalen)) { if (_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
/* First read Version field (should be 0). */ /* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0 || (plen != 1 && *p != '\0')) { if (ret != 0 || (plen != 1 && *p != '\0')) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &g, &glen); ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &y, &ylen); ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &x, &xlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
@ -313,25 +310,24 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
goto fail; goto fail;
} }
if (_libssh2_dsa_new (dsa, p, plen, q, qlen, if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
g, glen, y, ylen, x, xlen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = 0; ret = 0;
fail: fail:
LIBSSH2_FREE (session, save_data); LIBSSH2_FREE(session, save_data);
return ret; return ret;
} }
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, int
libssh2_dsa_ctx *rsactx, _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *hash, libssh2_dsa_ctx * rsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char **signature, unsigned long hash_len,
unsigned long *signature_len) unsigned char **signature, unsigned long *signature_len)
{ {
gcry_sexp_t sig_sexp; gcry_sexp_t sig_sexp;
gcry_sexp_t data; gcry_sexp_t data;
@ -343,15 +339,15 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
return -1; return -1;
} }
if (gcry_sexp_build (&data, NULL, if (gcry_sexp_build(&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))", "(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) { hash_len, hash)) {
return -1; return -1;
} }
rc = gcry_pk_sign (&sig_sexp, data, rsactx); rc = gcry_pk_sign(&sig_sexp, data, rsactx);
gcry_sexp_release (data); gcry_sexp_release(data);
if (rc != 0) { if (rc != 0) {
return -1; return -1;
@ -373,18 +369,18 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
} }
*signature = LIBSSH2_ALLOC(session, size); *signature = LIBSSH2_ALLOC(session, size);
memcpy (*signature, tmp, size); memcpy(*signature, tmp, size);
*signature_len = size; *signature_len = size;
return rc; return rc;
} }
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, int
const unsigned char *hash, _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char *sig) unsigned long hash_len, unsigned char *sig)
{ {
unsigned char zhash[SHA_DIGEST_LENGTH+1]; unsigned char zhash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t sig_sexp; gcry_sexp_t sig_sexp;
gcry_sexp_t data; gcry_sexp_t data;
int ret; int ret;
@ -395,17 +391,16 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
return -1; return -1;
} }
memcpy (zhash + 1, hash, hash_len); memcpy(zhash + 1, hash, hash_len);
zhash[0] = 0; zhash[0] = 0;
if (gcry_sexp_build (&data, NULL, "(data (value %b))", if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
hash_len + 1, zhash)) {
return -1; return -1;
} }
ret = gcry_pk_sign (&sig_sexp, data, dsactx); ret = gcry_pk_sign(&sig_sexp, data, dsactx);
gcry_sexp_release (data); gcry_sexp_release(data);
if (ret != 0) { if (ret != 0) {
return -1; return -1;
@ -435,13 +430,13 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
goto out; goto out;
} }
memcpy (sig, tmp, 20); memcpy(sig, tmp, 20);
gcry_sexp_release (data); gcry_sexp_release(data);
/* Extract S. */ /* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s",0); data = gcry_sexp_find_token(sig_sexp, "s", 0);
if (!data) { if (!data) {
ret = -1; ret = -1;
goto out; goto out;
@ -463,80 +458,79 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
goto out; goto out;
} }
memcpy (sig + 20, tmp, 20); memcpy(sig + 20, tmp, 20);
ret = 0; ret = 0;
out: out:
if (sig_sexp) { if (sig_sexp) {
gcry_sexp_release (sig_sexp); gcry_sexp_release(sig_sexp);
} }
if (data) { if (data) {
gcry_sexp_release (data); gcry_sexp_release(data);
} }
return ret; return ret;
} }
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, int
const unsigned char *sig, _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *sig,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH+1]; unsigned char hash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t s_sig, s_hash; gcry_sexp_t s_sig, s_hash;
int rc = -1; int rc = -1;
libssh2_sha1(m, m_len, hash+1); libssh2_sha1(m, m_len, hash + 1);
hash[0] = 0; hash[0] = 0;
if (gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))", if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
SHA_DIGEST_LENGTH+1, hash)) { SHA_DIGEST_LENGTH + 1, hash)) {
return -1; return -1;
} }
if (gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) { 20, sig, 20, sig + 20)) {
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return -1; return -1;
} }
rc = gcry_pk_verify (s_sig, s_hash, dsactx); rc = gcry_pk_verify(s_sig, s_hash, dsactx);
gcry_sexp_release (s_sig); gcry_sexp_release(s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1; return (rc == 0) ? 0 : -1;
} }
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int
_libssh2_cipher_type(algo), _libssh2_cipher_init(_libssh2_cipher_ctx * h,
unsigned char *iv, _libssh2_cipher_type(algo),
unsigned char *secret, unsigned char *iv, unsigned char *secret, int encrypt)
int encrypt)
{ {
int mode = 0, ret; int mode = 0, ret;
int keylen = gcry_cipher_get_algo_keylen (algo); int keylen = gcry_cipher_get_algo_keylen(algo);
(void)encrypt; (void) encrypt;
if (algo != GCRY_CIPHER_ARCFOUR) { if (algo != GCRY_CIPHER_ARCFOUR) {
mode = GCRY_CIPHER_MODE_CBC; mode = GCRY_CIPHER_MODE_CBC;
} }
ret = gcry_cipher_open (h, algo, mode, 0); ret = gcry_cipher_open(h, algo, mode, 0);
if (ret) { if (ret) {
return -1; return -1;
} }
ret = gcry_cipher_setkey (*h, secret, keylen); ret = gcry_cipher_setkey(*h, secret, keylen);
if (ret) { if (ret) {
gcry_cipher_close (*h); gcry_cipher_close(*h);
return -1; return -1;
} }
if (algo != GCRY_CIPHER_ARCFOUR) { if (algo != GCRY_CIPHER_ARCFOUR) {
int blklen = gcry_cipher_get_algo_blklen (algo); int blklen = gcry_cipher_get_algo_blklen(algo);
ret = gcry_cipher_setiv (*h, iv, blklen); ret = gcry_cipher_setiv(*h, iv, blklen);
if (ret) { if (ret) {
gcry_cipher_close (*h); gcry_cipher_close(*h);
return -1; return -1;
} }
} }
@ -544,12 +538,12 @@ int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
return 0; return 0;
} }
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int
_libssh2_cipher_type(algo), _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
int encrypt, _libssh2_cipher_type(algo),
unsigned char *block) int encrypt, unsigned char *block)
{ {
size_t blklen = gcry_cipher_get_algo_blklen (algo); size_t blklen = gcry_cipher_get_algo_blklen(algo);
int ret; int ret;
if (blklen == 1) { if (blklen == 1) {
/* Hack for arcfour. */ /* Hack for arcfour. */
@ -557,11 +551,9 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
} }
if (encrypt) { if (encrypt) {
ret = gcry_cipher_encrypt (*ctx, block, blklen, ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
block, blklen);
} else { } else {
ret = gcry_cipher_decrypt (*ctx, block, blklen, ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
block, blklen);
} }
return ret; return ret;
} }

Просмотреть файл

@ -93,66 +93,59 @@
#define libssh2_rsa_ctx struct gcry_sexp #define libssh2_rsa_ctx struct gcry_sexp
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata, const unsigned char *edata,
unsigned long elen, unsigned long elen,
const unsigned char *ndata, const unsigned char *ndata,
unsigned long nlen, unsigned long nlen,
const unsigned char *ddata, const unsigned char *ddata,
unsigned long dlen, unsigned long dlen,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *e1data, const unsigned char *e1data,
unsigned long e1len, unsigned long e1len,
const unsigned char *e2data, const unsigned char *e2data,
unsigned long e2len, unsigned long e2len,
const unsigned char *coeffdata, const unsigned char *coeffdata, unsigned long coefflen);
unsigned long coefflen); int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, unsigned long sig_len,
const unsigned char *sig, const unsigned char *m, unsigned long m_len);
unsigned long sig_len, int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *m, libssh2_rsa_ctx * rsactx,
unsigned long m_len); const unsigned char *hash,
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, unsigned long hash_len,
libssh2_rsa_ctx *rsactx, unsigned char **signature,
const unsigned char *hash, unsigned long *signature_len);
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len);
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx) #define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)
#define libssh2_dsa_ctx struct gcry_sexp #define libssh2_dsa_ctx struct gcry_sexp
int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *gdata, const unsigned char *gdata,
unsigned long glen, unsigned long glen,
const unsigned char *ydata, const unsigned char *ydata,
unsigned long ylen, unsigned long ylen,
const unsigned char *x, const unsigned char *x, unsigned long x_len);
unsigned long x_len); int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsa, const unsigned char *m, unsigned long m_len);
const unsigned char *sig, int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *hash,
unsigned long m_len); unsigned long hash_len, unsigned char *sig);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig);
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) #define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
@ -167,16 +160,14 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5 #define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5
#define _libssh2_cipher_3des GCRY_CIPHER_3DES #define _libssh2_cipher_3des GCRY_CIPHER_3DES
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *iv,
unsigned char *secret, unsigned char *secret, int encrypt);
int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
int encrypt, int encrypt, unsigned char *block);
unsigned char *block);
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) #define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -41,12 +41,15 @@
/* {{{ libssh2_mac_none_MAC /* {{{ libssh2_mac_none_MAC
* Minimalist MAC: No MAC * Minimalist MAC: No MAC
*/ */
static int libssh2_mac_none_MAC(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned long seqno, const unsigned char *packet,
unsigned long packet_len, const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{ {
return 0; return 0;
} }
/* }}} */ /* }}} */
@ -63,20 +66,24 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
/* {{{ libssh2_mac_method_common_init /* {{{ libssh2_mac_method_common_init
* Initialize simple mac methods * Initialize simple mac methods
*/ */
static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract) static int
libssh2_mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{ {
*abstract = key; *abstract = key;
*free_key = 0; *free_key = 0;
(void)session; (void) session;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_mac_method_common_dtor /* {{{ libssh2_mac_method_common_dtor
* Cleanup simple mac methods * Cleanup simple mac methods
*/ */
static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstract) static int
libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
if (*abstract) { if (*abstract) {
LIBSSH2_FREE(session, *abstract); LIBSSH2_FREE(session, *abstract);
@ -85,18 +92,23 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_mac_method_hmac_sha1_hash /* {{{ libssh2_mac_method_hmac_sha1_hash
* Calculate hash using full sha1 value * Calculate hash using full sha1 value
*/ */
static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void) session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
@ -111,6 +123,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
@ -125,17 +138,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
/* {{{ libssh2_mac_method_hmac_sha1_96_hash /* {{{ libssh2_mac_method_hmac_sha1_96_hash
* Calculate hash using first 96 bits of sha1 value * Calculate hash using first 96 bits of sha1 value
*/ */
static int libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{ {
unsigned char temp[SHA_DIGEST_LENGTH]; unsigned char temp[SHA_DIGEST_LENGTH];
libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
memcpy(buf, (char *)temp, 96 / 8); addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
@ -150,13 +169,17 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
/* {{{ libssh2_mac_method_hmac_md5_hash /* {{{ libssh2_mac_method_hmac_md5_hash
* Calculate hash using full md5 value * Calculate hash using full md5 value
*/ */
static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void) session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
@ -171,6 +194,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
@ -185,17 +209,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
/* {{{ libssh2_mac_method_hmac_md5_96_hash /* {{{ libssh2_mac_method_hmac_md5_96_hash
* Calculate hash using first 96 bits of md5 value * Calculate hash using first 96 bits of md5 value
*/ */
static int libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{ {
unsigned char temp[MD5_DIGEST_LENGTH]; unsigned char temp[MD5_DIGEST_LENGTH];
libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
memcpy(buf, (char *)temp, 96 / 8); addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
@ -211,13 +241,18 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
/* {{{ libssh2_mac_method_hmac_ripemd160_hash /* {{{ libssh2_mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value * Calculate hash using ripemd160 value
*/ */
static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len,
void **abstract)
{ {
libssh2_hmac_ctx ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void) session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
@ -232,6 +267,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
@ -268,7 +304,8 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
NULL NULL
}; };
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) { const LIBSSH2_MAC_METHOD **
libssh2_mac_methods(void)
{
return _libssh2_mac_methods; return _libssh2_mac_methods;
} }

Просмотреть файл

@ -42,17 +42,20 @@
/* {{{ libssh2_ntohu32 /* {{{ libssh2_ntohu32
*/ */
unsigned long libssh2_ntohu32(const unsigned char *buf) unsigned long
libssh2_ntohu32(const unsigned char *buf)
{ {
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
} }
/* }}} */ /* }}} */
/* {{{ libssh2_ntohu64 /* {{{ libssh2_ntohu64
* Note: Some 32-bit platforms have issues with bitops on long longs * Note: Some 32-bit platforms have issues with bitops on long longs
* Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses * Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses
*/ */
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf) libssh2_uint64_t
libssh2_ntohu64(const unsigned char *buf)
{ {
unsigned long msl, lsl; unsigned long msl, lsl;
@ -61,22 +64,26 @@ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
return ((msl * 65536) * 65536) + lsl; return ((msl * 65536) * 65536) + lsl;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_htonu32 /* {{{ libssh2_htonu32
*/ */
void libssh2_htonu32(unsigned char *buf, unsigned long value) void
libssh2_htonu32(unsigned char *buf, unsigned long value)
{ {
buf[0] = (value >> 24) & 0xFF; buf[0] = (value >> 24) & 0xFF;
buf[1] = (value >> 16) & 0xFF; buf[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF; buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF; buf[3] = value & 0xFF;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_htonu64 /* {{{ libssh2_htonu64
*/ */
void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) void
libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
{ {
unsigned long msl = (value / 65536) / 65536; unsigned long msl = (value / 65536) / 65536;
@ -90,6 +97,7 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
buf[6] = (value >> 8) & 0xFF; buf[6] = (value >> 8) & 0xFF;
buf[7] = value & 0xFF; buf[7] = value & 0xFF;
} }
/* }}} */ /* }}} */
/* Base64 Conversion */ /* Base64 Conversion */
@ -97,11 +105,11 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
/* {{{ */ /* {{{ */
static const char libssh2_base64_table[] = static const char libssh2_base64_table[] =
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
}; };
static const char libssh2_base64_pad = '='; static const char libssh2_base64_pad = '=';
@ -110,7 +118,7 @@ static const short libssh2_base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
@ -123,42 +131,46 @@ static const short libssh2_base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
}; };
/* }}} */ /* }}} */
/* {{{ libssh2_base64_decode /* {{{ libssh2_base64_decode
* Decode a base64 chunk and store it into a newly alloc'd buffer * Decode a base64 chunk and store it into a newly alloc'd buffer
*/ */
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen, LIBSSH2_API int
const char *src, unsigned int src_len) libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{ {
unsigned char *s, *d; unsigned char *s, *d;
short v; short v;
int i = 0, len = 0; int i = 0, len = 0;
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
d = (unsigned char *)*data; d = (unsigned char *) *data;
if (!d) { if (!d) {
return -1; return -1;
} }
for(s = (unsigned char *)src; ((char*)s) < (src + src_len); s++) { for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
if ((v = libssh2_base64_reverse_table[*s]) < 0) continue; if ((v = libssh2_base64_reverse_table[*s]) < 0)
continue;
switch (i % 4) { switch (i % 4) {
case 0: case 0:
d[len] = v << 2; d[len] = v << 2;
break; break;
case 1: case 1:
d[len++] |= v >> 4; d[len++] |= v >> 4;
d[len] = v << 4; d[len] = v << 4;
break; break;
case 2: case 2:
d[len++] |= v >> 2; d[len++] |= v >> 2;
d[len] = v << 6; d[len] = v << 6;
break; break;
case 3: case 3:
d[len++] |= v; d[len++] |= v;
break; break;
} }
i++; i++;
} }
@ -171,22 +183,24 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
*datalen = len; *datalen = len;
return 0; return 0;
} }
/* }}} */ /* }}} */
#ifdef LIBSSH2DEBUG #ifdef LIBSSH2DEBUG
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask) LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{ {
session->showmask = bitmask; session->showmask = bitmask;
return 0; return 0;
} }
void _libssh2_debug(LIBSSH2_SESSION *session, int context, void
const char *format, ...) _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{ {
char buffer[1536]; char buffer[1536];
int len; int len;
va_list vargs; va_list vargs;
static const char * const contexts[9] = { static const char *const contexts[9] = {
"Unknown", "Unknown",
"Transport", "Transport",
"Key Exchange", "Key Exchange",
@ -201,7 +215,7 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
if (context < 1 || context > 8) { if (context < 1 || context > 8) {
context = 0; context = 0;
} }
if (!(session->showmask & (1<<context))) { if (!(session->showmask & (1 << context))) {
/* no such output asked for */ /* no such output asked for */
return; return;
} }
@ -217,10 +231,11 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
} }
#else #else
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask) LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{ {
(void)session; (void) session;
(void)bitmask; (void) bitmask;
return 0; return 0;
} }
#endif #endif

Просмотреть файл

@ -43,23 +43,23 @@
#define EVP_MAX_BLOCK_LENGTH 32 #define EVP_MAX_BLOCK_LENGTH 32
#endif #endif
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int
const unsigned char *edata, _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
unsigned long elen, const unsigned char *edata,
const unsigned char *ndata, unsigned long elen,
unsigned long nlen, const unsigned char *ndata,
const unsigned char *ddata, unsigned long nlen,
unsigned long dlen, const unsigned char *ddata,
const unsigned char *pdata, unsigned long dlen,
unsigned long plen, const unsigned char *pdata,
const unsigned char *qdata, unsigned long plen,
unsigned long qlen, const unsigned char *qdata,
const unsigned char *e1data, unsigned long qlen,
unsigned long e1len, const unsigned char *e1data,
const unsigned char *e2data, unsigned long e1len,
unsigned long e2len, const unsigned char *e2data,
const unsigned char *coeffdata, unsigned long e2len,
unsigned long coefflen) const unsigned char *coeffdata, unsigned long coefflen)
{ {
*rsa = RSA_new(); *rsa = RSA_new();
@ -91,32 +91,32 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
return 0; return 0;
} }
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx, int
const unsigned char *sig, _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
unsigned long sig_len, const unsigned char *sig,
const unsigned char *m, unsigned long sig_len,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
int ret; int ret;
SHA1(m, m_len, hash); SHA1(m, m_len, hash);
ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
(unsigned char *)sig, sig_len, rsactx); (unsigned char *) sig, sig_len, rsactx);
return (ret == 1) ? 0 : -1; return (ret == 1) ? 0 : -1;
} }
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, int
const unsigned char *p, _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
unsigned long p_len, const unsigned char *p,
const unsigned char *q, unsigned long p_len,
unsigned long q_len, const unsigned char *q,
const unsigned char *g, unsigned long q_len,
unsigned long g_len, const unsigned char *g,
const unsigned char *y, unsigned long g_len,
unsigned long y_len, const unsigned char *y,
const unsigned char *x, unsigned long y_len,
unsigned long x_len) const unsigned char *x, unsigned long x_len)
{ {
*dsactx = DSA_new(); *dsactx = DSA_new();
@ -140,10 +140,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
return 0; return 0;
} }
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, int
const unsigned char *sig, _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *sig,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
DSA_SIG dsasig; DSA_SIG dsasig;
@ -162,27 +162,26 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
return (ret == 1) ? 0 : -1; return (ret == 1) ? 0 : -1;
} }
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int
_libssh2_cipher_type(algo), _libssh2_cipher_init(_libssh2_cipher_ctx * h,
unsigned char *iv, _libssh2_cipher_type(algo),
unsigned char *secret, unsigned char *iv, unsigned char *secret, int encrypt)
int encrypt)
{ {
EVP_CIPHER_CTX_init(h); EVP_CIPHER_CTX_init(h);
EVP_CipherInit(h, algo(), secret, iv, encrypt); EVP_CipherInit(h, algo(), secret, iv, encrypt);
return 0; return 0;
} }
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int
_libssh2_cipher_type(algo), _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
int encrypt, _libssh2_cipher_type(algo),
unsigned char *block) int encrypt, unsigned char *block)
{ {
int blocksize = ctx->cipher->block_size; int blocksize = ctx->cipher->block_size;
unsigned char buf[EVP_MAX_BLOCK_LENGTH]; unsigned char buf[EVP_MAX_BLOCK_LENGTH];
int ret; int ret;
(void)algo; (void) algo;
(void)encrypt; (void) encrypt;
if (blocksize == 1) { if (blocksize == 1) {
/* Hack for arcfour. */ /* Hack for arcfour. */
@ -199,11 +198,10 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
* calling program * calling program
*/ */
static int static int
passphrase_cb(char *buf, int size, passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
int rwflag, char *passphrase)
{ {
int passphrase_len = strlen(passphrase); int passphrase_len = strlen(passphrase);
(void)rwflag; (void) rwflag;
if (passphrase_len > (size - 1)) { if (passphrase_len > (size - 1)) {
passphrase_len = size - 1; passphrase_len = size - 1;
@ -214,12 +212,12 @@ passphrase_cb(char *buf, int size,
return passphrase_len; return passphrase_len;
} }
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, int
LIBSSH2_SESSION *session, _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
(void)session; (void) session;
if (!EVP_get_cipherbyname("des")) { if (!EVP_get_cipherbyname("des")) {
/* If this cipher isn't loaded it's a pretty good indication that none are. /* If this cipher isn't loaded it's a pretty good indication that none are.
* I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
@ -227,20 +225,20 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
*/ */
OpenSSL_add_all_ciphers(); OpenSSL_add_all_ciphers();
} }
*rsa = PEM_read_RSAPrivateKey(fp, NULL, (void*)passphrase_cb, *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void *) passphrase_cb,
(void*)passphrase); (void *) passphrase);
if (!*rsa) { if (!*rsa) {
return -1; return -1;
} }
return 0; return 0;
} }
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, int
LIBSSH2_SESSION *session, _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
(void)session; (void) session;
if (!EVP_get_cipherbyname("des")) { if (!EVP_get_cipherbyname("des")) {
/* If this cipher isn't loaded it's a pretty good indication that none are. /* If this cipher isn't loaded it's a pretty good indication that none are.
* I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
@ -248,20 +246,20 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
*/ */
OpenSSL_add_all_ciphers(); OpenSSL_add_all_ciphers();
} }
*dsa = PEM_read_DSAPrivateKey(fp, NULL, (void*)passphrase_cb, *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void *) passphrase_cb,
(void*)passphrase); (void *) passphrase);
if (!*dsa) { if (!*dsa) {
return -1; return -1;
} }
return 0; return 0;
} }
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, int
libssh2_rsa_ctx *rsactx, _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *hash, libssh2_rsa_ctx * rsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char **signature, unsigned long hash_len,
unsigned long *signature_len) unsigned char **signature, unsigned long *signature_len)
{ {
int ret; int ret;
unsigned char *sig; unsigned char *sig;
@ -287,14 +285,14 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
return 0; return 0;
} }
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, int
const unsigned char *hash, _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char *signature) unsigned long hash_len, unsigned char *signature)
{ {
DSA_SIG *sig; DSA_SIG *sig;
int r_len, s_len, rs_pad; int r_len, s_len, rs_pad;
(void)hash_len; (void) hash_len;
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
if (!sig) { if (!sig) {

Просмотреть файл

@ -131,66 +131,59 @@
#define libssh2_rsa_ctx RSA #define libssh2_rsa_ctx RSA
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata, const unsigned char *edata,
unsigned long elen, unsigned long elen,
const unsigned char *ndata, const unsigned char *ndata,
unsigned long nlen, unsigned long nlen,
const unsigned char *ddata, const unsigned char *ddata,
unsigned long dlen, unsigned long dlen,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *e1data, const unsigned char *e1data,
unsigned long e1len, unsigned long e1len,
const unsigned char *e2data, const unsigned char *e2data,
unsigned long e2len, unsigned long e2len,
const unsigned char *coeffdata, const unsigned char *coeffdata, unsigned long coefflen);
unsigned long coefflen); int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, unsigned long sig_len,
const unsigned char *sig, const unsigned char *m, unsigned long m_len);
unsigned long sig_len, int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *m, libssh2_rsa_ctx * rsactx,
unsigned long m_len); const unsigned char *hash,
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, unsigned long hash_len,
libssh2_rsa_ctx *rsactx, unsigned char **signature,
const unsigned char *hash, unsigned long *signature_len);
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len);
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx) #define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
#define libssh2_dsa_ctx DSA #define libssh2_dsa_ctx DSA
int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *gdata, const unsigned char *gdata,
unsigned long glen, unsigned long glen,
const unsigned char *ydata, const unsigned char *ydata,
unsigned long ylen, unsigned long ylen,
const unsigned char *x, const unsigned char *x, unsigned long x_len);
unsigned long x_len); int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, const unsigned char *m, unsigned long m_len);
const unsigned char *sig, int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *hash,
unsigned long m_len); unsigned long hash_len, unsigned char *sig);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig);
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx) #define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
@ -205,16 +198,14 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
#define _libssh2_cipher_cast5 EVP_cast5_cbc #define _libssh2_cipher_cast5 EVP_cast5_cbc
#define _libssh2_cipher_3des EVP_des_ede3_cbc #define _libssh2_cipher_3des EVP_des_ede3_cbc
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *iv,
unsigned char *secret, unsigned char *secret, int encrypt);
int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
int encrypt, int encrypt, unsigned char *block);
unsigned char *block);
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

114
src/pem.c
Просмотреть файл

@ -37,18 +37,16 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
static int readline (char *line, int line_size, FILE *fp) static int
readline(char *line, int line_size, FILE * fp)
{ {
if (!fgets(line, line_size, fp)) if (!fgets(line, line_size, fp)) {
{
return -1; return -1;
} }
if (*line && line[strlen(line) - 1] == '\n') if (*line && line[strlen(line) - 1] == '\n') {
{
line[strlen(line) - 1] = '\0'; line[strlen(line) - 1] = '\0';
} }
if (*line && line[strlen(line) - 1] == '\r') if (*line && line[strlen(line) - 1] == '\r') {
{
line[strlen(line) - 1] = '\0'; line[strlen(line) - 1] = '\0';
} }
return 0; return 0;
@ -56,132 +54,114 @@ static int readline (char *line, int line_size, FILE *fp)
#define LINE_SIZE 128 #define LINE_SIZE 128
int _libssh2_pem_parse (LIBSSH2_SESSION *session, int
const char *headerbegin, _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerend, const char *headerbegin,
FILE *fp, const char *headerend,
char **data, unsigned int *datalen) FILE * fp, char **data, unsigned int *datalen)
{ {
char line[LINE_SIZE]; char line[LINE_SIZE];
char *b64data = NULL; char *b64data = NULL;
unsigned int b64datalen = 0; unsigned int b64datalen = 0;
int ret; int ret;
do do {
{ if (readline(line, LINE_SIZE, fp)) {
if (readline(line, LINE_SIZE, fp))
{
return -1; return -1;
} }
} }
while (strcmp (line, headerbegin) != 0); while (strcmp(line, headerbegin) != 0);
*line = '\0'; *line = '\0';
do do {
{ if (*line) {
if (*line)
{
char *tmp; char *tmp;
size_t linelen; size_t linelen;
linelen = strlen (line); linelen = strlen(line);
tmp = LIBSSH2_REALLOC (session, b64data, tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
b64datalen + linelen); if (!tmp) {
if (!tmp)
{
ret = -1; ret = -1;
goto out; goto out;
} }
memcpy (tmp + b64datalen, line, linelen); memcpy(tmp + b64datalen, line, linelen);
b64data = tmp; b64data = tmp;
b64datalen += linelen; b64datalen += linelen;
} }
if (readline(line, LINE_SIZE, fp)) if (readline(line, LINE_SIZE, fp)) {
{
ret = -1; ret = -1;
goto out; goto out;
} }
} while (strcmp (line, headerend) != 0); } while (strcmp(line, headerend) != 0);
if (libssh2_base64_decode(session, data, datalen, if (libssh2_base64_decode(session, data, datalen, b64data, b64datalen)) {
b64data, b64datalen))
{
ret = -1; ret = -1;
goto out; goto out;
} }
ret = 0; ret = 0;
out: out:
if (b64data) { if (b64data) {
LIBSSH2_FREE (session, b64data); LIBSSH2_FREE(session, b64data);
} }
return ret; return ret;
} }
static int read_asn1_length (const unsigned char *data, static int
unsigned int datalen, read_asn1_length(const unsigned char *data,
unsigned int *len) unsigned int datalen, unsigned int *len)
{ {
unsigned int lenlen; unsigned int lenlen;
int nextpos; int nextpos;
if (datalen < 1) if (datalen < 1) {
{
return -1; return -1;
} }
*len = data[0]; *len = data[0];
if (*len >= 0x80) if (*len >= 0x80) {
{
lenlen = *len & 0x7F; lenlen = *len & 0x7F;
*len = data[1]; *len = data[1];
if (1 + lenlen > datalen) if (1 + lenlen > datalen) {
{
return -1; return -1;
} }
if (lenlen > 1) if (lenlen > 1) {
{
*len <<= 8; *len <<= 8;
*len |= data[2]; *len |= data[2];
} }
} } else {
else
{
lenlen = 0; lenlen = 0;
} }
nextpos = 1 + lenlen; nextpos = 1 + lenlen;
if (lenlen > 2 || 1 + lenlen + *len > datalen) if (lenlen > 2 || 1 + lenlen + *len > datalen) {
{
return -1; return -1;
} }
return nextpos; return nextpos;
} }
int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen) int
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
{ {
unsigned int len; unsigned int len;
int lenlen; int lenlen;
if (*datalen < 1) if (*datalen < 1) {
{
return -1; return -1;
} }
if ((*data)[0] != '\x30') if ((*data)[0] != '\x30') {
{
return -1; return -1;
} }
(*data)++; (*data)++;
(*datalen)--; (*datalen)--;
lenlen = read_asn1_length (*data, *datalen, &len); lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len != *datalen) if (lenlen < 0 || lenlen + len != *datalen) {
{
return -1; return -1;
} }
@ -191,28 +171,26 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
return 0; return 0;
} }
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen, int
unsigned char **i, unsigned int *ilen) _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen)
{ {
unsigned int len; unsigned int len;
int lenlen; int lenlen;
if (*datalen < 1) if (*datalen < 1) {
{
return -1; return -1;
} }
if ((*data)[0] != '\x02') if ((*data)[0] != '\x02') {
{
return -1; return -1;
} }
(*data)++; (*data)++;
(*datalen)--; (*datalen)--;
lenlen = read_asn1_length (*data, *datalen, &len); lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len > *datalen) if (lenlen < 0 || lenlen + len > *datalen) {
{
return -1; return -1;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

537
src/scp.c
Просмотреть файл

@ -46,7 +46,8 @@
* otherwise the blocking error code would erase the true * otherwise the blocking error code would erase the true
* cause of the error. * cause of the error.
*/ */
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb) LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
{ {
int path_len = strlen(path); int path_len = strlen(path);
int rc; int rc;
@ -56,63 +57,78 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_size = 0; session->scpRecv_size = 0;
session->scpRecv_mtime = 0; session->scpRecv_mtime = 0;
session->scpRecv_atime = 0; session->scpRecv_atime = 0;
session->scpRecv_command_len = path_len + sizeof("scp -f "); session->scpRecv_command_len = path_len + sizeof("scp -f ");
if (sb) { if (sb) {
session->scpRecv_command_len++; session->scpRecv_command_len++;
} }
session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len); session->scpRecv_command =
LIBSSH2_ALLOC(session, session->scpRecv_command_len);
if (!session->scpRecv_command) { if (!session->scpRecv_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for SCP session", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for SCP session",
0);
return NULL; return NULL;
} }
if (sb) { if (sb) {
memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1); memcpy(session->scpRecv_command, "scp -pf ",
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len); sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
path_len);
} else { } else {
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1); memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, path_len); memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
path_len);
} }
session->scpRecv_command[session->scpRecv_command_len - 1] = '\0'; session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive"); _libssh2_debug(session, LIBSSH2_DBG_SCP,
"Opening channel for SCP receive");
session->scpRecv_state = libssh2_NB_state_created; session->scpRecv_state = libssh2_NB_state_created;
} }
if (session->scpRecv_state == libssh2_NB_state_created) { if (session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */ /* Allocate a channel */
do { do {
session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, session->scpRecv_channel =
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, libssh2_channel_open_ex(session, "session",
NULL, 0); sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->scpRecv_channel) { if (!session->scpRecv_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { if (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) {
LIBSSH2_FREE(session, session->scpRecv_command); LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL; session->scpRecv_command = NULL;
session->scpRecv_state = libssh2_NB_state_idle; session->scpRecv_state = libssh2_NB_state_idle;
return NULL; return NULL;
} } else if (libssh2_session_last_errno(session) ==
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL; return NULL;
} }
} }
} while (!session->scpRecv_channel); } while (!session->scpRecv_channel);
session->scpRecv_state = libssh2_NB_state_sent; session->scpRecv_state = libssh2_NB_state_sent;
} }
if (session->scpRecv_state == libssh2_NB_state_sent) { if (session->scpRecv_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */ /* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *)session->scpRecv_command, session->scpRecv_command_len); rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpRecv_command,
session->scpRecv_command_len);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
return NULL; return NULL;
} } else if (rc) {
else if (rc) {
LIBSSH2_FREE(session, session->scpRecv_command); LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL; session->scpRecv_command = NULL;
goto scp_recv_error; goto scp_recv_error;
@ -123,40 +139,47 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
/* SCP ACK */ /* SCP ACK */
session->scpRecv_response[0] = '\0'; session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent1; session->scpRecv_state = libssh2_NB_state_sent1;
} }
if (session->scpRecv_state == libssh2_NB_state_sent1) { if (session->scpRecv_state == libssh2_NB_state_sent1) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1); rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
(char *) session->scpRecv_response, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup", 0);
return NULL; return NULL;
} } else if (rc != 1) {
else if (rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
/* Parse SCP response */ /* Parse SCP response */
session->scpRecv_response_len = 0; session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent2; session->scpRecv_state = libssh2_NB_state_sent2;
} }
if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) { if ((session->scpRecv_state == libssh2_NB_state_sent2)
while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { || (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb
&& (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p; unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) { if (session->scpRecv_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
(char *)session->scpRecv_response + session->scpRecv_response_len, 1); (char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response", 0);
return NULL; return NULL;
} } else if (rc <= 0) {
else if (rc <= 0) {
/* Timeout, give up */ /* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response", 0);
goto scp_recv_error; goto scp_recv_error;
} }
session->scpRecv_response_len++; session->scpRecv_response_len++;
@ -166,17 +189,25 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
* Set this as the default error for here, if * Set this as the default error for here, if
* we are successful it will be replaced * we are successful it will be replaced
*/ */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response, missing Time data",
session->scpRecv_err_len = libssh2_channel_packet_data_len(session->scpRecv_channel, 0); 0);
session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1);
session->scpRecv_err_len =
libssh2_channel_packet_data_len(session->
scpRecv_channel, 0);
session->scpRecv_err_msg =
LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1);
if (!session->scpRecv_err_msg) { if (!session->scpRecv_err_msg) {
goto scp_recv_error; goto scp_recv_error;
} }
memset(session->scpRecv_err_msg, 0, session->scpRecv_err_len+1); memset(session->scpRecv_err_msg, 0,
session->scpRecv_err_len + 1);
/* Read the remote error message */ /* Read the remote error message */
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, session->scpRecv_err_msg, session->scpRecv_err_len); rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
session->scpRecv_err_msg,
session->scpRecv_err_len);
if (rc <= 0) { if (rc <= 0) {
/* /*
* Since we have alread started reading this packet, it is * Since we have alread started reading this packet, it is
@ -184,29 +215,49 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
*/ */
LIBSSH2_FREE(session, session->scpRecv_err_msg); LIBSSH2_FREE(session, session->scpRecv_err_msg);
session->scpRecv_err_msg = NULL; session->scpRecv_err_msg = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string",
0);
goto scp_recv_error; goto scp_recv_error;
} }
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpRecv_err_msg, 1);
session->scpRecv_err_msg = NULL; session->scpRecv_err_msg = NULL;
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len > 1) && if ((session->scpRecv_response_len > 1) &&
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') || ((session->
(session->scpRecv_response[session->scpRecv_response_len-1] > '9')) && scpRecv_response[session->scpRecv_response_len - 1] <
(session->scpRecv_response[session->scpRecv_response_len-1] != ' ') && '0')
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') && || (session->
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { scpRecv_response[session->scpRecv_response_len - 1] >
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); '9'))
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
' ')
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\r')
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response", 0);
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { if ((session->scpRecv_response_len < 9)
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { || (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */ /* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server",
0);
goto scp_recv_error; goto scp_recv_error;
} }
/* Way too short to be an SCP response, or not done yet, short circuit */ /* Way too short to be an SCP response, or not done yet, short circuit */
@ -214,125 +265,168 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
/* We're guaranteed not to go under response_len == 0 by the logic above */ /* We're guaranteed not to go under response_len == 0 by the logic above */
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) session->scpRecv_response_len--; while ((session->
session->scpRecv_response[session->scpRecv_response_len] = '\0'; scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
|| (session->
scpRecv_response[session->scpRecv_response_len -
1] == '\n'))
session->scpRecv_response_len--;
session->scpRecv_response[session->scpRecv_response_len] =
'\0';
if (session->scpRecv_response_len < 8) { if (session->scpRecv_response_len < 8) {
/* EOL came too soon */ /* EOL came too soon */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short",
0);
goto scp_recv_error; goto scp_recv_error;
} }
s = session->scpRecv_response + 1; s = session->scpRecv_response + 1;
p = (unsigned char *)strchr((char *)s, ' '); p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) { if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime",
0);
goto scp_recv_error; goto scp_recv_error;
} }
*(p++) = '\0'; *(p++) = '\0';
/* Make sure we don't get fooled by leftover values */ /* Make sure we don't get fooled by leftover values */
errno = 0; errno = 0;
session->scpRecv_mtime = strtol((char *)s, NULL, 10); session->scpRecv_mtime = strtol((char *) s, NULL, 10);
if (errno) { if (errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mtime",
0);
goto scp_recv_error; goto scp_recv_error;
} }
s = (unsigned char *)strchr((char *)p, ' '); s = (unsigned char *) strchr((char *) p, ' ');
if (!s || ((s - p) <= 0)) { if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime.usec",
0);
goto scp_recv_error; goto scp_recv_error;
} }
/* Ignore mtime.usec */ /* Ignore mtime.usec */
s++; s++;
p = (unsigned char *)strchr((char *)s, ' '); p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) { if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed",
0);
goto scp_recv_error; goto scp_recv_error;
} }
*(p++) = '\0'; *(p++) = '\0';
/* Make sure we don't get fooled by leftover values */ /* Make sure we don't get fooled by leftover values */
errno = 0; errno = 0;
session->scpRecv_atime = strtol((char *)s, NULL, 10); session->scpRecv_atime = strtol((char *) s, NULL, 10);
if (errno) { if (errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid atime",
0);
goto scp_recv_error; goto scp_recv_error;
} }
/* SCP ACK */ /* SCP ACK */
session->scpRecv_response[0] = '\0'; session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent3; session->scpRecv_state = libssh2_NB_state_sent3;
} }
if (session->scpRecv_state == libssh2_NB_state_sent3) { if (session->scpRecv_state == libssh2_NB_state_sent3) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1); rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK", 0);
return NULL; return NULL;
} } else if (rc != 1) {
else if (rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime); _libssh2_debug(session, LIBSSH2_DBG_SCP,
"mtime = %ld, atime = %ld",
session->scpRecv_mtime, session->scpRecv_atime);
/* We *should* check that atime.usec is valid, but why let that stop use? */ /* We *should* check that atime.usec is valid, but why let that stop use? */
break; break;
} }
} }
session->scpRecv_state = libssh2_NB_state_sent4; session->scpRecv_state = libssh2_NB_state_sent4;
} }
if (session->scpRecv_state == libssh2_NB_state_sent4) { if (session->scpRecv_state == libssh2_NB_state_sent4) {
session->scpRecv_response_len = 0; session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent5; session->scpRecv_state = libssh2_NB_state_sent5;
} }
if ((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) { if ((session->scpRecv_state == libssh2_NB_state_sent5)
|| (session->scpRecv_state == libssh2_NB_state_sent6)) {
while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
char *s, *p, *e = NULL; char *s, *p, *e = NULL;
if (session->scpRecv_state == libssh2_NB_state_sent5) { if (session->scpRecv_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
(char *)session->scpRecv_response + session->scpRecv_response_len, 1); (char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response", 0);
return NULL; return NULL;
} } else if (rc <= 0) {
else if (rc <= 0) {
/* Timeout, give up */ /* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response", 0);
goto scp_recv_error; goto scp_recv_error;
} }
session->scpRecv_response_len++; session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'C') { if (session->scpRecv_response[0] != 'C') {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server", 0);
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len > 1) && if ((session->scpRecv_response_len > 1) &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') && (session->
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n') && scpRecv_response[session->scpRecv_response_len - 1] !=
((session->scpRecv_response[session->scpRecv_response_len-1] < 32) || '\r')
(session->scpRecv_response[session->scpRecv_response_len-1] > 126))) { && (session->
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')
&&
((session->
scpRecv_response[session->scpRecv_response_len - 1] < 32)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] >
126))) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response", 0);
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { if ((session->scpRecv_response_len < 7)
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { || (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */ /* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server",
0);
goto scp_recv_error; goto scp_recv_error;
} }
/* Way too short to be an SCP response, or not done yet, short circuit */ /* Way too short to be an SCP response, or not done yet, short circuit */
@ -340,24 +434,33 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
/* We're guaranteed not to go under response_len == 0 by the logic above */ /* We're guaranteed not to go under response_len == 0 by the logic above */
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || while ((session->
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) { scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
|| (session->
scpRecv_response[session->scpRecv_response_len -
1] == '\n')) {
session->scpRecv_response_len--; session->scpRecv_response_len--;
} }
session->scpRecv_response[session->scpRecv_response_len] = '\0'; session->scpRecv_response[session->scpRecv_response_len] =
'\0';
if (session->scpRecv_response_len < 6) { if (session->scpRecv_response_len < 6) {
/* EOL came too soon */ /* EOL came too soon */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short",
0);
goto scp_recv_error; goto scp_recv_error;
} }
s = (char *)session->scpRecv_response + 1; s = (char *) session->scpRecv_response + 1;
p = strchr(s, ' '); p = strchr(s, ' ');
if (!p || ((p - s) <= 0)) { if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mode",
0);
goto scp_recv_error; goto scp_recv_error;
} }
@ -366,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0; errno = 0;
session->scpRecv_mode = strtol(s, &e, 8); session->scpRecv_mode = strtol(s, &e, 8);
if ((e && *e) || errno) { if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mode",
0);
goto scp_recv_error; goto scp_recv_error;
} }
s = strchr(p, ' '); s = strchr(p, ' ');
if (!s || ((s - p) <= 0)) { if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed",
0); 0);
goto scp_recv_error; goto scp_recv_error;
} }
@ -383,32 +489,38 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0; errno = 0;
session->scpRecv_size = strtol(p, &e, 10); session->scpRecv_size = strtol(p, &e, 10);
if ((e && *e) || errno) { if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size",
0);
goto scp_recv_error; goto scp_recv_error;
} }
/* SCP ACK */ /* SCP ACK */
session->scpRecv_response[0] = '\0'; session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent6; session->scpRecv_state = libssh2_NB_state_sent6;
} }
if (session->scpRecv_state == libssh2_NB_state_sent6) { if (session->scpRecv_state == libssh2_NB_state_sent6) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1); rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK", 0);
return NULL; return NULL;
} } else if (rc != 1) {
else if (rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size); _libssh2_debug(session, LIBSSH2_DBG_SCP,
"mode = 0%lo size = %ld", session->scpRecv_mode,
session->scpRecv_size);
/* We *should* check that basename is valid, but why let that stop us? */ /* We *should* check that basename is valid, but why let that stop us? */
break; break;
} }
} }
session->scpRecv_state = libssh2_NB_state_sent7; session->scpRecv_state = libssh2_NB_state_sent7;
} }
@ -423,13 +535,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_state = libssh2_NB_state_idle; session->scpRecv_state = libssh2_NB_state_idle;
return session->scpRecv_channel; return session->scpRecv_channel;
scp_recv_error: scp_recv_error:
while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN); while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN);
session->scpRecv_channel = NULL; session->scpRecv_channel = NULL;
session->scpRecv_state = libssh2_NB_state_idle; session->scpRecv_state = libssh2_NB_state_idle;
return NULL; return NULL;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_scp_send_ex /* {{{ libssh2_scp_send_ex
@ -440,7 +553,8 @@ scp_recv_error:
* cause of the error. * cause of the error.
*/ */
LIBSSH2_API LIBSSH2_CHANNEL * LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime) libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
size_t size, long mtime, long atime)
{ {
int path_len = strlen(path); int path_len = strlen(path);
unsigned const char *base; unsigned const char *base;
@ -448,124 +562,147 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
if (session->scpSend_state == libssh2_NB_state_idle) { if (session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len = path_len + sizeof("scp -t "); session->scpSend_command_len = path_len + sizeof("scp -t ");
if (mtime || atime) { if (mtime || atime) {
session->scpSend_command_len++; session->scpSend_command_len++;
} }
session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len); session->scpSend_command =
LIBSSH2_ALLOC(session, session->scpSend_command_len);
if (!session->scpSend_command) { if (!session->scpSend_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for scp session",
0);
return NULL; return NULL;
} }
if (mtime || atime) { if (mtime || atime) {
memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1); memcpy(session->scpSend_command, "scp -pt ",
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len); sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
path_len);
} else { } else {
memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1); memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1);
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, path_len); memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path,
path_len);
} }
session->scpSend_command[session->scpSend_command_len - 1] = '\0'; session->scpSend_command[session->scpSend_command_len - 1] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send"); _libssh2_debug(session, LIBSSH2_DBG_SCP,
"Opening channel for SCP send");
/* Allocate a channel */ /* Allocate a channel */
session->scpSend_state = libssh2_NB_state_created; session->scpSend_state = libssh2_NB_state_created;
} }
if (session->scpSend_state == libssh2_NB_state_created) { if (session->scpSend_state == libssh2_NB_state_created) {
session->scpSend_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, session->scpSend_channel =
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) { if (!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it through */ /* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL; session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_idle; session->scpSend_state = libssh2_NB_state_idle;
return NULL; return NULL;
} } else if (libssh2_session_last_errno(session) ==
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL; return NULL;
} }
} }
session->scpSend_state = libssh2_NB_state_sent; session->scpSend_state = libssh2_NB_state_sent;
} }
if (session->scpSend_state == libssh2_NB_state_sent) { if (session->scpSend_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */ /* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1, rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
(char *)session->scpSend_command, session->scpSend_command_len); sizeof("exec") - 1,
(char *) session->scpSend_command,
session->scpSend_command_len);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
return NULL; return NULL;
} } else if (rc) {
else if (rc) {
/* previous call set libssh2_session_last_error(), pass it through */ /* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL; session->scpSend_command = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string", 0);
goto scp_send_error; goto scp_send_error;
} }
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL; session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_sent1; session->scpSend_state = libssh2_NB_state_sent1;
} }
if (session->scpSend_state == libssh2_NB_state_sent1) { if (session->scpSend_state == libssh2_NB_state_sent1) {
/* Wait for ACK */ /* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote", 0);
return NULL; return NULL;
} } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); "Invalid ACK response from remote", 0);
goto scp_send_error; goto scp_send_error;
} }
if (mtime || atime) { if (mtime || atime) {
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, session->scpSend_response_len =
"T%ld 0 %ld 0\n", mtime, atime); snprintf((char *) session->scpSend_response,
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response); LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
atime);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
session->scpSend_response);
} }
session->scpSend_state = libssh2_NB_state_sent2; session->scpSend_state = libssh2_NB_state_sent2;
} }
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
if (mtime || atime) { if (mtime || atime) {
if (session->scpSend_state == libssh2_NB_state_sent2) { if (session->scpSend_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len); session->scpSend_response_len);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file", 0);
return NULL; return NULL;
} } else if (rc != session->scpSend_response_len) {
else if (rc != session->scpSend_response_len) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); "Unable to send time data for SCP file", 0);
goto scp_send_error; goto scp_send_error;
} }
session->scpSend_state = libssh2_NB_state_sent3; session->scpSend_state = libssh2_NB_state_sent3;
} }
if (session->scpSend_state == libssh2_NB_state_sent3) { if (session->scpSend_state == libssh2_NB_state_sent3) {
/* Wait for ACK */ /* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
return NULL; return NULL;
} } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); "Invalid ACK response from remote", 0);
goto scp_send_error; goto scp_send_error;
} }
session->scpSend_state = libssh2_NB_state_sent4; session->scpSend_state = libssh2_NB_state_sent4;
} }
} else { } else {
@ -576,62 +713,73 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
if (session->scpSend_state == libssh2_NB_state_sent4) { if (session->scpSend_state == libssh2_NB_state_sent4) {
/* Send mode, size, and basename */ /* Send mode, size, and basename */
base = (unsigned char *)strrchr(path, '/'); base = (unsigned char *) strrchr(path, '/');
if (base) { if (base) {
base++; base++;
} else { } else {
base = (unsigned char *)path; base = (unsigned char *) path;
} }
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, session->scpSend_response_len =
"C0%o %lu %s\n", mode, (unsigned long)size, base); snprintf((char *) session->scpSend_response,
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response); LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
(unsigned long) size, base);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
session->scpSend_response);
session->scpSend_state = libssh2_NB_state_sent5; session->scpSend_state = libssh2_NB_state_sent5;
} }
if (session->scpSend_state == libssh2_NB_state_sent5) { if (session->scpSend_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len); session->scpSend_response_len);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file", 0);
return NULL; return NULL;
} } else if (rc != session->scpSend_response_len) {
else if (rc != session->scpSend_response_len) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); "Unable to send core file data for SCP file", 0);
goto scp_send_error; goto scp_send_error;
} }
session->scpSend_state = libssh2_NB_state_sent6; session->scpSend_state = libssh2_NB_state_sent6;
} }
if (session->scpSend_state == libssh2_NB_state_sent6) { if (session->scpSend_state == libssh2_NB_state_sent6) {
/* Wait for ACK */ /* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
return NULL; return NULL;
} } else if (rc <= 0) {
else if (rc <= 0) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); "Invalid ACK response from remote", 0);
goto scp_send_error; goto scp_send_error;
} } else if (session->scpSend_response[0] != 0) {
else if (session->scpSend_response[0] != 0) {
/* /*
* Set this as the default error for here, if * Set this as the default error for here, if
* we are successful it will be replaced * we are successful it will be replaced
*/ */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1); session->scpSend_err_len =
libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg =
LIBSSH2_ALLOC(session, session->scpSend_err_len + 1);
if (!session->scpSend_err_msg) { if (!session->scpSend_err_msg) {
goto scp_send_error; goto scp_send_error;
} }
memset(session->scpSend_err_msg, 0, session->scpSend_err_len+1); memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
/* Read the remote error message */ /* Read the remote error message */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len); rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
session->scpSend_err_msg,
session->scpSend_err_len);
if (rc <= 0) { if (rc <= 0) {
/* /*
* Since we have alread started reading this packet, it is * Since we have alread started reading this packet, it is
@ -641,22 +789,23 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
session->scpSend_err_msg = NULL; session->scpSend_err_msg = NULL;
goto scp_send_error; goto scp_send_error;
} }
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpSend_err_msg, 1); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpSend_err_msg, 1);
session->scpSend_err_msg = NULL; session->scpSend_err_msg = NULL;
goto scp_send_error; goto scp_send_error;
} }
} }
session->scpSend_state = libssh2_NB_state_idle; session->scpSend_state = libssh2_NB_state_idle;
return session->scpSend_channel; return session->scpSend_channel;
scp_send_error: scp_send_error:
while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN); while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN);
session->scpSend_channel = NULL; session->scpSend_channel = NULL;
session->scpSend_state = libssh2_NB_state_idle; session->scpSend_state = libssh2_NB_state_idle;
return NULL; return NULL;
} }
/* }}} */
/* }}} */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1567
src/sftp.c

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -43,47 +43,47 @@
#include <assert.h> #include <assert.h>
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ #define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */ #define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
#ifdef LIBSSH2DEBUG #ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.' #define UNPRINTABLE_CHAR '.'
static void debugdump(LIBSSH2_SESSION *session, static void
const char *desc, unsigned char *ptr, debugdump(LIBSSH2_SESSION * session,
unsigned long size) const char *desc, unsigned char *ptr, unsigned long size)
{ {
size_t i; size_t i;
size_t c; size_t c;
FILE *stream = stdout; FILE *stream = stdout;
unsigned int width=0x10; unsigned int width = 0x10;
if (!(session->showmask & (1<< LIBSSH2_DBG_TRANS))) { if (!(session->showmask & (1 << LIBSSH2_DBG_TRANS))) {
/* not asked for, bail out */ /* not asked for, bail out */
return; return;
}
fprintf(stream, "=> %s (%d bytes)\n", desc, (int)size);
for(i=0; i<size; i+= width) {
fprintf(stream, "%04lx: ", i);
/* hex not disabled, show it */
for(c = 0; c < width; c++) {
if (i+c < size)
fprintf(stream, "%02x ", ptr[i+c]);
else
fputs(" ", stream);
} }
for(c = 0; (c < width) && (i+c < size); c++) { fprintf(stream, "=> %s (%d bytes)\n", desc, (int) size);
fprintf(stream, "%c",
(ptr[i+c]>=0x20) && for(i = 0; i < size; i += width) {
(ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR);
fprintf(stream, "%04lx: ", (long)i);
/* hex not disabled, show it */
for(c = 0; c < width; c++) {
if (i + c < size)
fprintf(stream, "%02x ", ptr[i + c]);
else
fputs(" ", stream);
}
for(c = 0; (c < width) && (i + c < size); c++) {
fprintf(stream, "%c",
(ptr[i + c] >= 0x20) &&
(ptr[i + c] < 0x80) ? ptr[i + c] : UNPRINTABLE_CHAR);
}
fputc('\n', stream); /* newline */
} }
fputc('\n', stream); /* newline */ fflush(stream);
}
fflush(stream);
} }
#else #else
#define debugdump(a,x,y,z) #define debugdump(a,x,y,z)
@ -95,35 +95,36 @@ static void debugdump(LIBSSH2_SESSION *session,
* returns PACKET_NONE on success and PACKET_FAIL on failure * returns PACKET_NONE on success and PACKET_FAIL on failure
*/ */
static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source, static libssh2pack_t
unsigned char *dest, int len) decrypt(LIBSSH2_SESSION * session, unsigned char *source,
unsigned char *dest, int len)
{ {
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int blocksize = session->remote.crypt->blocksize; int blocksize = session->remote.crypt->blocksize;
/* if we get called with a len that isn't an even number of blocksizes /* if we get called with a len that isn't an even number of blocksizes
we risk losing those extra bytes */ we risk losing those extra bytes */
assert((len % blocksize) == 0); assert((len % blocksize) == 0);
while(len >= blocksize) { while (len >= blocksize) {
if (session->remote.crypt->crypt(session, source, if (session->remote.crypt->crypt(session, source,
&session->remote.crypt_abstract)) { &session->remote.crypt_abstract)) {
libssh2_error(session, LIBSSH2_ERROR_DECRYPT, libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
(char *)"Error decrypting packet", 0); (char *) "Error decrypting packet", 0);
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL; return PACKET_FAIL;
} }
/* if the crypt() function would write to a given address it /* if the crypt() function would write to a given address it
wouldn't have to memcpy() and we could avoid this memcpy() wouldn't have to memcpy() and we could avoid this memcpy()
too */ too */
memcpy(dest, source, blocksize); memcpy(dest, source, blocksize);
len -= blocksize; /* less bytes left */ len -= blocksize; /* less bytes left */
dest += blocksize; /* advance write pointer */ dest += blocksize; /* advance write pointer */
source += blocksize; /* advance read pointer */ source += blocksize; /* advance read pointer */
} }
return PACKET_NONE; /* all is fine */ return PACKET_NONE; /* all is fine */
} }
/* /*
@ -131,26 +132,26 @@ static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
* collected. * collected.
*/ */
static libssh2pack_t static libssh2pack_t
fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
{ {
unsigned char macbuf[MAX_MACSIZE]; unsigned char macbuf[MAX_MACSIZE];
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int rc; int rc;
if (session->fullpacket_state == libssh2_NB_state_idle) { if (session->fullpacket_state == libssh2_NB_state_idle) {
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
session->fullpacket_payload_len = p->packet_length-1; session->fullpacket_payload_len = p->packet_length - 1;
if (encrypted) { if (encrypted) {
/* Calculate MAC hash */ /* Calculate MAC hash */
session->remote.mac->hash(session, session->remote.mac->hash(session, macbuf, /* store hash here */
macbuf, /* store hash here */
session->remote.seqno, session->remote.seqno,
p->init, 5, p->init, 5,
p->payload, session->fullpacket_payload_len, p->payload,
session->fullpacket_payload_len,
&session->remote.mac_abstract); &session->remote.mac_abstract);
/* Compare the calculated hash with the MAC we just read from /* Compare the calculated hash with the MAC we just read from
* the network. The read one is at the very end of the payload * the network. The read one is at the very end of the payload
* buffer. Note that 'payload_len' here is the packet_length * buffer. Note that 'payload_len' here is the packet_length
@ -161,55 +162,53 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
session->fullpacket_macstate = LIBSSH2_MAC_INVALID; session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
} }
} }
session->remote.seqno++; session->remote.seqno++;
/* ignore the padding */ /* ignore the padding */
session->fullpacket_payload_len -= p->padding_length; session->fullpacket_payload_len -= p->padding_length;
/* Check for and deal with decompression */ /* Check for and deal with decompression */
if (session->remote.comp && if (session->remote.comp && strcmp(session->remote.comp->name, "none")) {
strcmp(session->remote.comp->name, "none")) {
unsigned char *data; unsigned char *data;
unsigned long data_len; unsigned long data_len;
int free_payload = 1; int free_payload = 1;
if (session->remote.comp->comp(session, 0, if (session->remote.comp->comp(session, 0,
&data, &data_len, &data, &data_len,
LIBSSH2_PACKET_MAXDECOMP, LIBSSH2_PACKET_MAXDECOMP,
&free_payload, &free_payload,
p->payload, session->fullpacket_payload_len, p->payload,
session->fullpacket_payload_len,
&session->remote.comp_abstract)) { &session->remote.comp_abstract)) {
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL; return PACKET_FAIL;
} }
if (free_payload) { if (free_payload) {
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
p->payload = data; p->payload = data;
session->fullpacket_payload_len = data_len; session->fullpacket_payload_len = data_len;
} } else {
else {
if (data == p->payload) { if (data == p->payload) {
/* It's not to be freed, because the /* It's not to be freed, because the
* compression layer reused payload, So let's * compression layer reused payload, So let's
* do the same! * do the same!
*/ */
session->fullpacket_payload_len = data_len; session->fullpacket_payload_len = data_len;
} } else {
else {
/* No comp_method actually lets this happen, /* No comp_method actually lets this happen,
* but let's prepare for the future */ * but let's prepare for the future */
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
/* We need a freeable struct otherwise the /* We need a freeable struct otherwise the
* brigade won't know what to do with it */ * brigade won't know what to do with it */
p->payload = LIBSSH2_ALLOC(session, data_len); p->payload = LIBSSH2_ALLOC(session, data_len);
if (!p->payload) { if (!p->payload) {
libssh2_error(session, libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for copy of uncompressed data",
(char *)"Unable to allocate memory for copy of uncompressed data", 0); 0);
return PACKET_ENOMEM; return PACKET_ENOMEM;
} }
memcpy(p->payload, data, data_len); memcpy(p->payload, data, data_len);
@ -217,27 +216,28 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
} }
} }
} }
session->fullpacket_packet_type = p->payload[0]; session->fullpacket_packet_type = p->payload[0];
debugdump(session, "libssh2_packet_read() plain", debugdump(session, "libssh2_packet_read() plain",
p->payload, session->fullpacket_payload_len); p->payload, session->fullpacket_payload_len);
session->fullpacket_state = libssh2_NB_state_created; session->fullpacket_state = libssh2_NB_state_created;
} }
if (session->fullpacket_state == libssh2_NB_state_created) { if (session->fullpacket_state == libssh2_NB_state_created) {
rc = libssh2_packet_add(session, p->payload, session->fullpacket_payload_len, session->fullpacket_macstate); rc = libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len,
session->fullpacket_macstate);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN; return PACKET_EAGAIN;
} } else if (rc < 0) {
else if (rc < 0) {
return PACKET_FAIL; return PACKET_FAIL;
} }
} }
session->fullpacket_state = libssh2_NB_state_idle; session->fullpacket_state = libssh2_NB_state_idle;
return session->fullpacket_packet_type; return session->fullpacket_packet_type;
} }
@ -256,7 +256,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
* This function reads the binary stream as specified in chapter 6 of RFC4253 * This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol" * "The Secure Shell (SSH) Transport Layer Protocol"
*/ */
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) libssh2pack_t
libssh2_packet_read(LIBSSH2_SESSION * session)
{ {
libssh2pack_t rc; libssh2pack_t rc;
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
@ -268,7 +269,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
int blocksize; int blocksize;
int minimum; int minimum;
int encrypted = 1; int encrypted = 1;
/* /*
* =============================== NOTE =============================== * =============================== NOTE ===============================
* I know this is very ugly and not a really good use of "goto", but * I know this is very ugly and not a really good use of "goto", but
@ -279,39 +280,39 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
encrypted = session->readPack_encrypted; encrypted = session->readPack_encrypted;
goto libssh2_packet_read_point1; goto libssh2_packet_read_point1;
} }
do { do {
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
return PACKET_NONE; return PACKET_NONE;
} }
if (session->state & LIBSSH2_STATE_NEWKEYS) { if (session->state & LIBSSH2_STATE_NEWKEYS) {
blocksize = session->remote.crypt->blocksize; blocksize = session->remote.crypt->blocksize;
} else { } else {
encrypted = 0; /* not encrypted */ encrypted = 0; /* not encrypted */
blocksize = 5; /* not strictly true, but we can use 5 here to blocksize = 5; /* not strictly true, but we can use 5 here to
make the checks below work fine still */ make the checks below work fine still */
} }
minimum = p->total_num ? p->total_num - p->data_num : blocksize; minimum = p->total_num ? p->total_num - p->data_num : blocksize;
/* read/use a whole big chunk into a temporary area stored in /* read/use a whole big chunk into a temporary area stored in
the LIBSSH2_SESSION struct. We will decrypt data from that the LIBSSH2_SESSION struct. We will decrypt data from that
buffer into the packet buffer so this temp one doesn't have buffer into the packet buffer so this temp one doesn't have
to be able to keep a whole SSH packet, just be large enough to be able to keep a whole SSH packet, just be large enough
so that we can read big chunks from the network layer. */ so that we can read big chunks from the network layer. */
/* how much data there is remaining in the buffer to deal with /* how much data there is remaining in the buffer to deal with
before we should read more from the network */ before we should read more from the network */
remainbuf = p->writeidx - p->readidx; remainbuf = p->writeidx - p->readidx;
/* if remainbuf turns negative we have a bad internal error */ /* if remainbuf turns negative we have a bad internal error */
assert(remainbuf >= 0); assert(remainbuf >= 0);
if (remainbuf < minimum) { if (remainbuf < minimum) {
/* If we have less than a minimum left, it is too /* If we have less than a minimum left, it is too
little data to deal with, read more */ little data to deal with, read more */
ssize_t nread; ssize_t nread;
/* move any remainder to the start of the buffer so /* move any remainder to the start of the buffer so
that we can do a full refill */ that we can do a full refill */
if (remainbuf) { if (remainbuf) {
@ -322,10 +323,12 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* nothing to move, just zero the indexes */ /* nothing to move, just zero the indexes */
p->readidx = p->writeidx = 0; p->readidx = p->writeidx = 0;
} }
/* now read a big chunk from the network into the temp buffer */ /* now read a big chunk from the network into the temp buffer */
nread = recv(session->socket_fd, &p->buf[remainbuf], PACKETBUFSIZE-remainbuf, nread =
LIBSSH2_SOCKET_RECV_FLAGS(session)); recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) { if (nread <= 0) {
/* check if this is due to EAGAIN and return /* check if this is due to EAGAIN and return
the special return code if so, error out the special return code if so, error out
@ -339,30 +342,30 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
&p->buf[remainbuf], nread); &p->buf[remainbuf], nread);
/* advance write pointer */ /* advance write pointer */
p->writeidx += nread; p->writeidx += nread;
/* update remainbuf counter */ /* update remainbuf counter */
remainbuf = p->writeidx - p->readidx; remainbuf = p->writeidx - p->readidx;
} }
/* how much data to deal with from the buffer */ /* how much data to deal with from the buffer */
numbytes = remainbuf; numbytes = remainbuf;
if (numbytes < blocksize) { if (numbytes < blocksize) {
/* we can't act on anything less than blocksize */ /* we can't act on anything less than blocksize */
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
if (!p->total_num) { if (!p->total_num) {
/* No payload package area allocated yet. To know the /* No payload package area allocated yet. To know the
size of this payload, we need to decrypt the first size of this payload, we need to decrypt the first
blocksize data. */ blocksize data. */
if (encrypted) { if (encrypted) {
rc = decrypt(session, &p->buf[p->readidx], block, blocksize); rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
if (rc != PACKET_NONE) { if (rc != PACKET_NONE) {
return rc; return rc;
} }
/* save the first 5 bytes of the decrypted package, to be /* save the first 5 bytes of the decrypted package, to be
used in the hash calculation later down. */ used in the hash calculation later down. */
memcpy(p->init, &p->buf[p->readidx], 5); memcpy(p->init, &p->buf[p->readidx], 5);
} else { } else {
@ -370,20 +373,22 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
the working block buffer */ the working block buffer */
memcpy(block, &p->buf[p->readidx], blocksize); memcpy(block, &p->buf[p->readidx], blocksize);
} }
/* advance the read pointer */ /* advance the read pointer */
p->readidx += blocksize; p->readidx += blocksize;
/* we now have the initial blocksize bytes decrypted, /* we now have the initial blocksize bytes decrypted,
* and we can extract packet and padding length from it * and we can extract packet and padding length from it
*/ */
p->packet_length = libssh2_ntohu32(block); p->packet_length = libssh2_ntohu32(block);
p->padding_length = block[4]; p->padding_length = block[4];
/* total_num is the number of bytes following the initial /* total_num is the number of bytes following the initial
(5 bytes) packet length and padding length fields */ (5 bytes) packet length and padding length fields */
p->total_num = p->packet_length -1 + (encrypted ? session->remote.mac->mac_len : 0); p->total_num =
p->packet_length - 1 +
(encrypted ? session->remote.mac->mac_len : 0);
/* RFC4253 section 6.1 Maximum Packet Length says: /* RFC4253 section 6.1 Maximum Packet Length says:
* *
* "All implementations MUST be able to process * "All implementations MUST be able to process
@ -395,7 +400,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
if (p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) { if (p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
return PACKET_TOOBIG; return PACKET_TOOBIG;
} }
/* Get a packet handle put data into. We get one to /* Get a packet handle put data into. We get one to
hold all data, including padding and MAC. */ hold all data, including padding and MAC. */
p->payload = LIBSSH2_ALLOC(session, p->total_num); p->payload = LIBSSH2_ALLOC(session, p->total_num);
@ -404,40 +409,40 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
} }
/* init write pointer to start of payload buffer */ /* init write pointer to start of payload buffer */
p->wptr = p->payload; p->wptr = p->payload;
if (blocksize > 5) { if (blocksize > 5) {
/* copy the data from index 5 to the end of /* copy the data from index 5 to the end of
the blocksize from the temporary buffer to the blocksize from the temporary buffer to
the start of the decrypted buffer */ the start of the decrypted buffer */
memcpy(p->wptr, &block[5], blocksize-5); memcpy(p->wptr, &block[5], blocksize - 5);
p->wptr += blocksize-5; /* advance write pointer */ p->wptr += blocksize - 5; /* advance write pointer */
} }
/* init the data_num field to the number of bytes of /* init the data_num field to the number of bytes of
the package read so far */ the package read so far */
p->data_num = p->wptr - p->payload; p->data_num = p->wptr - p->payload;
/* we already dealt with a blocksize worth of data */ /* we already dealt with a blocksize worth of data */
numbytes -= blocksize; numbytes -= blocksize;
} }
/* how much there is left to add to the current payload /* how much there is left to add to the current payload
package */ package */
remainpack = p->total_num - p->data_num; remainpack = p->total_num - p->data_num;
if (numbytes > remainpack) { if (numbytes > remainpack) {
/* if we have more data in the buffer than what is going into this /* if we have more data in the buffer than what is going into this
particular packet, we limit this round to this packet only */ particular packet, we limit this round to this packet only */
numbytes = remainpack; numbytes = remainpack;
} }
if (encrypted) { if (encrypted) {
/* At the end of the incoming stream, there is a MAC, /* At the end of the incoming stream, there is a MAC,
and we don't want to decrypt that since we need it and we don't want to decrypt that since we need it
"raw". We MUST however decrypt the padding data "raw". We MUST however decrypt the padding data
since it is used for the hash later on. */ since it is used for the hash later on. */
int skip = session->remote.mac->mac_len; int skip = session->remote.mac->mac_len;
/* if what we have plus numbytes is bigger than the /* if what we have plus numbytes is bigger than the
total minus the skip margin, we should lower the total minus the skip margin, we should lower the
amount to decrypt even more */ amount to decrypt even more */
@ -449,10 +454,10 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
frac = numdecrypt % blocksize; frac = numdecrypt % blocksize;
if (frac) { if (frac) {
/* not an aligned amount of blocks, /* not an aligned amount of blocks,
align it */ align it */
numdecrypt -= frac; numdecrypt -= frac;
/* and make it no unencrypted data /* and make it no unencrypted data
after it */ after it */
numbytes = 0; numbytes = 0;
} }
} }
@ -460,7 +465,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* unencrypted data should not be decrypted at all */ /* unencrypted data should not be decrypted at all */
numdecrypt = 0; numdecrypt = 0;
} }
/* if there are bytes to decrypt, do that */ /* if there are bytes to decrypt, do that */
if (numdecrypt > 0) { if (numdecrypt > 0) {
/* now decrypt the lot */ /* now decrypt the lot */
@ -468,23 +473,23 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
if (rc != PACKET_NONE) { if (rc != PACKET_NONE) {
return rc; return rc;
} }
/* advance the read pointer */ /* advance the read pointer */
p->readidx += numdecrypt; p->readidx += numdecrypt;
/* advance write pointer */ /* advance write pointer */
p->wptr += numdecrypt; p->wptr += numdecrypt;
/* increse data_num */ /* increse data_num */
p->data_num += numdecrypt; p->data_num += numdecrypt;
/* bytes left to take care of without decryption */ /* bytes left to take care of without decryption */
numbytes -= numdecrypt; numbytes -= numdecrypt;
} }
/* if there are bytes to copy that aren't decrypted, simply /* if there are bytes to copy that aren't decrypted, simply
copy them as-is to the target buffer */ copy them as-is to the target buffer */
if (numbytes > 0) { if (numbytes > 0) {
memcpy(p->wptr, &p->buf[p->readidx], numbytes); memcpy(p->wptr, &p->buf[p->readidx], numbytes);
/* advance the read pointer */ /* advance the read pointer */
p->readidx += numbytes; p->readidx += numbytes;
/* advance write pointer */ /* advance write pointer */
@ -492,68 +497,71 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* increse data_num */ /* increse data_num */
p->data_num += numbytes; p->data_num += numbytes;
} }
/* now check how much data there's left to read to finish the /* now check how much data there's left to read to finish the
current packet */ current packet */
remainpack = p->total_num - p->data_num; remainpack = p->total_num - p->data_num;
if (!remainpack) { if (!remainpack) {
/* we have a full packet */ /* we have a full packet */
libssh2_packet_read_point1: libssh2_packet_read_point1:
rc = fullpacket(session, encrypted); rc = fullpacket(session, encrypted);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
session->readPack_encrypted = encrypted; session->readPack_encrypted = encrypted;
session->readPack_state = libssh2_NB_state_jump1; session->readPack_state = libssh2_NB_state_jump1;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
p->total_num = 0; /* no packet buffer available */ p->total_num = 0; /* no packet buffer available */
return rc; return rc;
} }
} while (1); /* loop */ } while (1); /* loop */
return PACKET_FAIL; /* we never reach this point */ return PACKET_FAIL; /* we never reach this point */
} }
/* }}} */ /* }}} */
#ifndef OLDSEND #ifndef OLDSEND
static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len, ssize_t *ret) static libssh2pack_t
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len, ssize_t * ret)
{ {
ssize_t rc; ssize_t rc;
ssize_t length; ssize_t length;
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
if (!p->outbuf) { if (!p->outbuf) {
*ret = 0; *ret = 0;
return PACKET_NONE; return PACKET_NONE;
} }
/* send as much as possible of the existing packet */ /* send as much as possible of the existing packet */
if ((data != p->odata) || (data_len != p->olen)) { if ((data != p->odata) || (data_len != p->olen)) {
/* When we are about to complete the sending of a packet, it is vital /* When we are about to complete the sending of a packet, it is vital
that the caller doesn't try to send a new/different packet since that the caller doesn't try to send a new/different packet since
we don't add this one up until the previous one has been sent. To we don't add this one up until the previous one has been sent. To
make the caller really notice his/hers flaw, we return error for make the caller really notice his/hers flaw, we return error for
this case */ this case */
return PACKET_BADUSE; return PACKET_BADUSE;
} }
*ret = 1; /* set to make our parent return */ *ret = 1; /* set to make our parent return */
/* number of bytes left to send */ /* number of bytes left to send */
length = p->ototal_num - p->osent; length = p->ototal_num - p->osent;
rc = send(session->socket_fd, &p->outbuf[p->osent], length, LIBSSH2_SOCKET_SEND_FLAGS(session)); rc = send(session->socket_fd, &p->outbuf[p->osent], length,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (rc == length) { if (rc == length) {
/* the remainder of the package was sent */ /* the remainder of the package was sent */
LIBSSH2_FREE(session, p->outbuf); LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL; p->outbuf = NULL;
p->ototal_num = 0; p->ototal_num = 0;
} } else if (rc < 0) {
else if (rc < 0) {
/* nothing was sent */ /* nothing was sent */
if (errno != EAGAIN) { if (errno != EAGAIN) {
/* send failure! */ /* send failure! */
@ -561,10 +569,11 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
} }
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length); debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
p->osent += length; /* we sent away this much data */ length);
p->osent += length; /* we sent away this much data */
return PACKET_NONE; return PACKET_NONE;
} }
@ -577,16 +586,20 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
* sent, and this function should then be called with the same argument set * sent, and this function should then be called with the same argument set
* (same data pointer and same data_len) until zero or failure is returned. * (same data pointer and same data_len) until zero or failure is returned.
*/ */
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len) int
libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len)
{ {
int blocksize = (session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->blocksize : 8; int blocksize =
(session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
blocksize : 8;
int padding_length; int padding_length;
int packet_length; int packet_length;
int total_length; int total_length;
int free_data=0; int free_data = 0;
#ifdef RANDOM_PADDING #ifdef RANDOM_PADDING
int rand_max; int rand_max;
int seed = data[0]; /* FIXME: make this random */ int seed = data[0]; /* FIXME: make this random */
#endif #endif
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int encrypted; int encrypted;
@ -595,41 +608,42 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
libssh2pack_t rc; libssh2pack_t rc;
unsigned char *orgdata = data; unsigned char *orgdata = data;
unsigned long orgdata_len = data_len; unsigned long orgdata_len = data_len;
debugdump(session, "libssh2_packet_write plain", data, data_len); debugdump(session, "libssh2_packet_write plain", data, data_len);
/* FIRST, check if we have a pending write to complete */ /* FIRST, check if we have a pending write to complete */
rc = send_existing(session, data, data_len, &ret); rc = send_existing(session, data, data_len, &ret);
if (rc || ret) { if (rc || ret) {
return rc; return rc;
} }
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0; encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
/* check if we should compress */ /* check if we should compress */
if (encrypted && strcmp(session->local.comp->name, "none")) { if (encrypted && strcmp(session->local.comp->name, "none")) {
if (session->local.comp->comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP, if (session->local.comp->
&free_data, data, data_len, &session->local.comp_abstract)) { comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
return PACKET_COMPRESS; /* compression failure */ &free_data, data, data_len, &session->local.comp_abstract)) {
return PACKET_COMPRESS; /* compression failure */
} }
} }
/* RFC4253 says: Note that the length of the concatenation of /* RFC4253 says: Note that the length of the concatenation of
'packet_length', 'padding_length', 'payload', and 'random padding' 'packet_length', 'padding_length', 'payload', and 'random padding'
MUST be a multiple of the cipher block size or 8, whichever is MUST be a multiple of the cipher block size or 8, whichever is
larger. */ larger. */
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
packet_length = data_len + 1 + 4; /* 1 is for padding_length field packet_length = data_len + 1 + 4; /* 1 is for padding_length field
4 for the packet_length field */ 4 for the packet_length field */
/* at this point we have it all except the padding */ /* at this point we have it all except the padding */
/* first figure out our minimum padding amount to make it an even /* first figure out our minimum padding amount to make it an even
block size */ block size */
padding_length = blocksize - (packet_length % blocksize); padding_length = blocksize - (packet_length % blocksize);
/* if the padding becomes too small we add another blocksize worth /* if the padding becomes too small we add another blocksize worth
of it (taken from the original libssh2 where it didn't have any of it (taken from the original libssh2 where it didn't have any
real explanation) */ real explanation) */
@ -639,19 +653,20 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
#ifdef RANDOM_PADDING #ifdef RANDOM_PADDING
/* FIXME: we can add padding here, but that also makes the packets /* FIXME: we can add padding here, but that also makes the packets
bigger etc */ bigger etc */
/* now we can add 'blocksize' to the padding_length N number of times /* now we can add 'blocksize' to the padding_length N number of times
(to "help thwart traffic analysis") but it must be less than 255 in (to "help thwart traffic analysis") but it must be less than 255 in
total */ total */
rand_max = (255 - padding_length)/blocksize + 1; rand_max = (255 - padding_length) / blocksize + 1;
padding_length += blocksize * (seed % rand_max); padding_length += blocksize * (seed % rand_max);
#endif #endif
packet_length += padding_length; packet_length += padding_length;
/* append the MAC length to the total_length size */ /* append the MAC length to the total_length size */
total_length = packet_length + (encrypted?session->local.mac->mac_len:0); total_length =
packet_length + (encrypted ? session->local.mac->mac_len : 0);
/* allocate memory to store the outgoing packet in, in case we can't /* allocate memory to store the outgoing packet in, in case we can't
send the whole one and thus need to keep it after this function send the whole one and thus need to keep it after this function
returns. */ returns. */
@ -659,7 +674,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
if (!p->outbuf) { if (!p->outbuf) {
return PACKET_ENOMEM; return PACKET_ENOMEM;
} }
/* store packet_length, which is the size of the whole packet except /* store packet_length, which is the size of the whole packet except
the MAC and the packet_length field itself */ the MAC and the packet_length field itself */
libssh2_htonu32(p->outbuf, packet_length - 4); libssh2_htonu32(p->outbuf, packet_length - 4);
@ -672,51 +687,54 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
if (free_data) { if (free_data) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
if (encrypted) { if (encrypted) {
/* Calculate MAC hash. Put the output at index packet_length, /* Calculate MAC hash. Put the output at index packet_length,
since that size includes the whole packet. The MAC is since that size includes the whole packet. The MAC is
calculated on the entire unencrypted packet, including all calculated on the entire unencrypted packet, including all
fields except the MAC field itself. */ fields except the MAC field itself. */
session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length, session->local.mac->hash(session, p->outbuf + packet_length,
NULL, 0, &session->local.mac_abstract); session->local.seqno, p->outbuf,
packet_length, NULL, 0,
&session->local.mac_abstract);
/* Encrypt the whole packet data, one block size at a time. /* Encrypt the whole packet data, one block size at a time.
The MAC field is not encrypted. */ The MAC field is not encrypted. */
for(i=0; i < packet_length; i += session->local.crypt->blocksize) { for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
unsigned char *ptr = &p->outbuf[i]; unsigned char *ptr = &p->outbuf[i];
if (session->local.crypt->crypt(session, ptr, &session->local.crypt_abstract)) if (session->local.crypt->
return PACKET_FAIL; /* encryption failure */ crypt(session, ptr, &session->local.crypt_abstract))
return PACKET_FAIL; /* encryption failure */
} }
} }
session->local.seqno++; session->local.seqno++;
ret = send(session->socket_fd, p->outbuf, total_length, ret = send(session->socket_fd, p->outbuf, total_length,
LIBSSH2_SOCKET_SEND_FLAGS(session)); LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret != -1) { if (ret != -1) {
debugdump(session, "libssh2_packet_write send()", p->outbuf, ret); debugdump(session, "libssh2_packet_write send()", p->outbuf, ret);
} }
if (ret != total_length) { if (ret != total_length) {
if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) { if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
/* the whole packet could not be sent, save the rest */ /* the whole packet could not be sent, save the rest */
p->odata = orgdata; p->odata = orgdata;
p->olen = orgdata_len; p->olen = orgdata_len;
p->osent = (ret == -1)?0:ret; p->osent = (ret == -1) ? 0 : ret;
p->ototal_num = total_length; p->ototal_num = total_length;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
return PACKET_FAIL; return PACKET_FAIL;
} }
/* the whole thing got sent away */ /* the whole thing got sent away */
p->odata = NULL; p->odata = NULL;
p->olen = 0; p->olen = 0;
LIBSSH2_FREE(session, p->outbuf); LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL; p->outbuf = NULL;
return PACKET_NONE; /* all is good */ return PACKET_NONE; /* all is good */
} }
/* }}} */ /* }}} */

Разница между файлами не показана из-за своего большого размера Загрузить разницу