Compare commits

..

2 Commits

Author SHA1 Message Date
Daniel Stenberg
bcc4fd6e82 0.17 re-indent 2007-08-06 20:50:22 +00:00
Daniel Stenberg
210459db4b 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]
2007-08-06 20:48:04 +00:00
21 changed files with 6398 additions and 4497 deletions

20
NEWS
View File

@@ -1,3 +1,23 @@
Version 0.17
------------
Changes since previous version include:
o Re-indented the source code with this GNU indent setup:
--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
Version 0.16 Version 0.16
------------ ------------
Changes since previous version include: Changes since previous version include:

File diff suppressed because it is too large Load Diff

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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;
} }
} }
/* }}} */ /* }}} */

930
src/kex.c

File diff suppressed because it is too large Load Diff

View File

@@ -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;
} }

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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) {

View File

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

File diff suppressed because it is too large Load Diff

114
src/pem.c
View File

@@ -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;
} }

File diff suppressed because it is too large Load Diff

459
src/scp.c
View File

@@ -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;
@@ -63,21 +64,28 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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;
} }
@@ -85,18 +93,23 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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;
} }
} }
@@ -107,12 +120,15 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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;
@@ -128,12 +144,13 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
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;
} }
@@ -143,20 +160,26 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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",
0);
session->scpRecv_err_len = libssh2_channel_packet_data_len(session->scpRecv_channel, 0); session->scpRecv_err_len =
session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1); 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,54 +265,73 @@ 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;
} }
@@ -272,16 +342,20 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
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;
@@ -297,42 +371,62 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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,7 +489,9 @@ 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;
} }
@@ -394,15 +502,19 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
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;
@@ -424,12 +536,13 @@ 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;
@@ -453,40 +567,50 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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;
} }
} }
@@ -496,17 +620,20 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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);
@@ -517,21 +644,26 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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;
@@ -540,14 +672,16 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
/* 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;
} }
@@ -556,13 +690,16 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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;
} }
@@ -576,29 +713,34 @@ 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;
} }
@@ -607,31 +749,37 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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_len =
session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1); 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
@@ -642,7 +790,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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;
} }
@@ -652,11 +801,11 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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;
} }
/* }}} */
/* }}} */

File diff suppressed because it is too large Load Diff

1111
src/sftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -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,21 +95,22 @@ 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;
} }
@@ -119,11 +120,11 @@ static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
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,7 +132,7 @@ 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;
@@ -139,16 +140,16 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
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
@@ -168,8 +169,7 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
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;
@@ -178,7 +178,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 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;
@@ -188,16 +189,14 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
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 */
@@ -207,9 +206,9 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
* 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);
@@ -227,11 +226,12 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
} }
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;
} }
} }
@@ -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;
@@ -288,9 +289,9 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
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;
@@ -324,8 +325,10 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
} }
/* 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
@@ -382,7 +385,9 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* 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:
* *
@@ -409,8 +414,8 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* 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
@@ -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;
} }
} }
@@ -499,7 +504,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
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;
@@ -507,19 +512,22 @@ libssh2_packet_read_point1:
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;
@@ -540,20 +548,20 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
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! */
@@ -562,8 +570,9 @@ 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;
@@ -604,13 +617,14 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
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 */
} }
} }
@@ -621,8 +635,8 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
/* 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 */
@@ -643,14 +657,15 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
/* 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
@@ -678,15 +693,18 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
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 */
} }
} }
@@ -699,11 +717,11 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
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;
} }
@@ -716,7 +734,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
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 */
} }
/* }}} */ /* }}} */

File diff suppressed because it is too large Load Diff