1
1

re-indented the source code with this script:

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

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

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

@ -47,15 +47,15 @@
/* {{{ libssh2_comp_method_none_comp
* Minimalist compression: Absolutely none
*/
static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
static int
libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len,
void **abstract)
unsigned long src_len, void **abstract)
{
(void) session;
(void) compress;
@ -68,6 +68,7 @@ static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
@ -87,32 +88,39 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
* 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;
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_FREE(session, address);
}
/* }}} */
/* {{{ libssh2_comp_method_zlib_init
* 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;
int status;
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
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;
}
memset(strm, 0, sizeof(z_stream));
@ -136,20 +144,21 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress,
return 0;
}
/* }}} */
/* {{{ libssh2_comp_method_zlib_comp
* zlib, a compression standard for all occasions
*/
static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
static int
libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len,
void **abstract)
unsigned long src_len, void **abstract)
{
z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of
@ -173,7 +182,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
out = (char *) strm->next_out;
strm->avail_out = out_maxlen;
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;
}
while (strm->avail_in) {
@ -185,7 +196,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
status = inflate(strm, Z_PARTIAL_FLUSH);
}
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);
return -1;
}
@ -193,10 +205,10 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
unsigned long out_ofs = out_maxlen - strm->avail_out;
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) &&
!compress && limiter++) {
if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase", 0);
LIBSSH2_FREE(session, out);
@ -205,14 +217,18 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
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);
return -1;
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
} else while (!strm->avail_out) {
strm->avail_out +=
compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
} else
while (!strm->avail_out) {
/* Done with input, might be a byte or two in internal buffer during compress
* Or potentially many bytes if it's a decompress
*/
@ -220,7 +236,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
char *newout;
if (out_maxlen >= (int) payload_limit) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0);
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase",
0);
LIBSSH2_FREE(session, out);
return -1;
}
@ -234,7 +252,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand final compress/decompress buffer",
0);
LIBSSH2_FREE(session, out);
return -1;
}
@ -248,7 +268,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
status = inflate(strm, Z_PARTIAL_FLUSH);
}
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);
return -1;
}
@ -261,12 +282,15 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
/* {{{ libssh2_comp_method_zlib_dtor
* 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;
@ -286,6 +310,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
return 0;
}
/* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
@ -308,7 +333,8 @@ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
NULL
};
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) {
const LIBSSH2_COMP_METHOD **
libssh2_comp_methods(void)
{
return _libssh2_comp_methods;
}

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

@ -41,11 +41,14 @@
/* {{{ libssh2_crypt_none_crypt
* 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! */
return 0;
}
/* }}} */
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
@ -60,13 +63,15 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
};
#endif /* LIBSSH2_CRYPT_NONE */
struct crypt_ctx {
struct crypt_ctx
{
int encrypt;
_libssh2_cipher_type(algo);
_libssh2_cipher_ctx h;
};
static int _libssh2_init (LIBSSH2_SESSION *session,
static int
_libssh2_init(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
@ -79,8 +84,7 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
}
ctx->encrypt = encrypt;
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);
return -1;
}
@ -90,15 +94,17 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
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;
(void) session;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo,
cctx->encrypt, block);
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, 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;
if (cctx && *cctx) {
@ -147,7 +153,8 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_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",
16, /* blocksize */
16, /* initial value length */
@ -242,6 +249,8 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
};
/* Expose to kex.c */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) {
const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)
{
return _libssh2_crypt_methods;
}

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

@ -47,7 +47,8 @@
* 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
* Initialize the server hostkey working area with e/n pair
@ -81,9 +82,12 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
e_len = libssh2_ntohu32(s);
s += 4;
e = s; s += e_len;
n_len = libssh2_ntohu32(s); s += 4;
n = s; s += n_len;
e = s;
s += e_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,
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
@ -93,13 +97,17 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_initPEM
* Load a Private Key from a PEM file
*/
static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
const char *privkeyfile, unsigned const char *passphrase, void **abstract)
static int
libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
FILE *fp;
@ -125,32 +133,40 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_sign
* Verify signature created by remote
*/
static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session,
static int
libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len,
void **abstract)
unsigned long m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
sig += 15; sig_len -= 15;
sig += 15;
sig_len -= 15;
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_signv
* 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,
unsigned long veccount, const struct iovec datavec[], void **abstract)
static int
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);
int ret;
@ -172,13 +188,14 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_dtor
* Shutdown the hostkey
*/
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_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
@ -189,6 +206,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
@ -208,7 +226,8 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
* 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
* Initialize the server hostkey working area with p/q/g/y set
@ -230,33 +249,44 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
}
s = hostkey_data;
len = libssh2_ntohu32(s); s += 4;
len = libssh2_ntohu32(s);
s += 4;
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
return -1;
} s += 7;
}
s += 7;
p_len = libssh2_ntohu32(s); s += 4;
p = s; s += p_len;
q_len = libssh2_ntohu32(s); s += 4;
q = s; 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;
p_len = libssh2_ntohu32(s);
s += 4;
p = s;
s += p_len;
q_len = libssh2_ntohu32(s);
s += 4;
q = s;
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,
y, y_len, NULL, 0);
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
*abstract = dsactx;
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_initPEM
* Load a Private Key from a PEM file
*/
static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
static int
libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
@ -285,31 +315,44 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_sign
* 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,
const unsigned char *m, unsigned long m_len, void **abstract)
static int
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);
/* 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) {
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 _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_signv
* 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,
unsigned long veccount, const struct iovec datavec[], void **abstract)
static int
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);
unsigned char hash[SHA_DIGEST_LENGTH];
@ -330,22 +373,21 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
}
libssh2_sha1_final(ctx, hash);
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH,
*signature))
{
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
LIBSSH2_FREE(session, *signature);
return -1;
}
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_dtor
* Shutdown the hostkey method
*/
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_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
(void) session;
@ -356,6 +398,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
return 0;
}
/* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
@ -380,7 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
NULL
};
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
const LIBSSH2_HOSTKEY_METHOD **
libssh2_hostkey_methods(void)
{
return _libssh2_hostkey_methods;
}
@ -391,7 +435,8 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
* Length of buffer is determined by hash type
* 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) {
#if LIBSSH2_MD5
@ -406,6 +451,5 @@ LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_
return NULL;
}
}
/* }}} */

738
src/kex.c

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

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

@ -38,7 +38,8 @@
#include "libssh2_priv.h"
#include <string.h>
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
@ -53,8 +54,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen)
const unsigned char *coeffdata, unsigned long coefflen)
{
int rc;
(void) e1data;
@ -72,8 +72,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata);
}
if (rc)
{
if (rc) {
*rsa = NULL;
return -1;
}
@ -81,11 +80,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
return 0;
}
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
int
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len)
const unsigned char *m, unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash;
@ -100,8 +99,7 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
return -1;
}
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))",
sig_len, sig);
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
if (rc != 0) {
gcry_sexp_release(s_hash);
return -1;
@ -114,7 +112,8 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
return (rc == 0) ? 0 : -1;
}
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
int
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
const unsigned char *p,
unsigned long p_len,
const unsigned char *q,
@ -123,8 +122,7 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
unsigned long g_len,
const unsigned char *y,
unsigned long y_len,
const unsigned char *x,
unsigned long x_len)
const unsigned char *x, unsigned long x_len)
{
int rc;
@ -147,10 +145,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
return 0;
}
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
int
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase)
FILE * fp, unsigned const char *passphrase)
{
char *data, *save_data;
unsigned int datalen;
@ -230,8 +228,7 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
}
if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len,
coeff, coefflen)) {
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
ret = -1;
goto fail;
}
@ -243,10 +240,10 @@ fail:
return ret;
}
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
int
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase)
FILE * fp, unsigned const char *passphrase)
{
char *data, *save_data;
unsigned int datalen;
@ -313,8 +310,7 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
goto fail;
}
if (_libssh2_dsa_new (dsa, p, plen, q, qlen,
g, glen, y, ylen, x, xlen)) {
if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
ret = -1;
goto fail;
}
@ -326,12 +322,12 @@ fail:
return ret;
}
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_dsa_ctx * rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len)
unsigned char **signature, unsigned long *signature_len)
{
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
@ -379,10 +375,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
return rc;
}
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
int
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig)
unsigned long hash_len, unsigned char *sig)
{
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t sig_sexp;
@ -398,8 +394,7 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
memcpy(zhash + 1, hash, hash_len);
zhash[0] = 0;
if (gcry_sexp_build (&data, NULL, "(data (value %b))",
hash_len + 1, zhash)) {
if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
return -1;
}
@ -476,10 +471,10 @@ out:
return ret;
}
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
int
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len)
const unsigned char *m, unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t s_sig, s_hash;
@ -506,11 +501,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
return (rc == 0) ? 0 : -1;
}
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt)
unsigned char *iv, unsigned char *secret, int encrypt)
{
int mode = 0, ret;
int keylen = gcry_cipher_get_algo_keylen(algo);
@ -544,10 +538,10 @@ int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
return 0;
}
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block)
int encrypt, unsigned char *block)
{
size_t blklen = gcry_cipher_get_algo_blklen(algo);
int ret;
@ -557,11 +551,9 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
}
if (encrypt) {
ret = gcry_cipher_encrypt (*ctx, block, blklen,
block, blklen);
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
} else {
ret = gcry_cipher_decrypt (*ctx, block, blklen,
block, blklen);
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
}
return ret;
}

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

@ -108,17 +108,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen);
const unsigned char *coeffdata, unsigned long coefflen);
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase);
FILE * fp, unsigned const char *passphrase);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len);
const unsigned char *m, unsigned long m_len);
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
@ -139,20 +136,16 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *x,
unsigned long x_len);
const unsigned char *x, unsigned long x_len);
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase);
FILE * fp, unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len);
const unsigned char *m, unsigned long m_len);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig);
unsigned long hash_len, unsigned char *sig);
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
@ -170,13 +163,11 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt);
unsigned char *secret, int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block);
int encrypt, unsigned char *block);
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))

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

@ -127,7 +127,8 @@ typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
typedef int libssh2pack_t;
typedef enum {
typedef enum
{
libssh2_NB_state_idle = 0,
libssh2_NB_state_allocated,
libssh2_NB_state_created,
@ -144,16 +145,19 @@ typedef enum {
libssh2_NB_state_jump3
} libssh2_nonblocking_states;
typedef struct packet_require_state_t {
typedef struct packet_require_state_t
{
libssh2_nonblocking_states state;
time_t start;
} packet_require_state_t;
typedef struct packet_requirev_state_t {
typedef struct packet_requirev_state_t
{
time_t start;
} packet_requirev_state_t;
typedef struct kmdhgGPsha1kex_state_t {
typedef struct kmdhgGPsha1kex_state_t
{
libssh2_nonblocking_states state;
unsigned char *e_packet;
unsigned char *s_packet;
@ -180,7 +184,8 @@ typedef struct kmdhgGPsha1kex_state_t {
libssh2_nonblocking_states burn_state;
} kmdhgGPsha1kex_state_t;
typedef struct key_exchange_state_low_t {
typedef struct key_exchange_state_low_t
{
libssh2_nonblocking_states state;
packet_require_state_t req_state;
kmdhgGPsha1kex_state_t exchange_state;
@ -192,7 +197,8 @@ typedef struct key_exchange_state_low_t {
unsigned long data_len;
} key_exchange_state_low_t;
typedef struct key_exchange_state_t {
typedef struct key_exchange_state_t
{
libssh2_nonblocking_states state;
packet_require_state_t req_state;
key_exchange_state_low_t key_state_low;
@ -204,7 +210,8 @@ typedef struct key_exchange_state_t {
#define FwdNotReq "Forward not requested"
typedef struct packet_queue_listener_state_t {
typedef struct packet_queue_listener_state_t
{
libssh2_nonblocking_states state;
unsigned char packet[17 + (sizeof(FwdNotReq) - 1)];
unsigned char *host;
@ -220,7 +227,8 @@ typedef struct packet_queue_listener_state_t {
#define X11FwdUnAvil "X11 Forward Unavailable"
typedef struct packet_x11_open_state_t {
typedef struct packet_x11_open_state_t
{
libssh2_nonblocking_states state;
unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)];
unsigned char *shost;
@ -231,7 +239,8 @@ typedef struct packet_x11_open_state_t {
uint32_t shost_len;
} packet_x11_open_state_t;
struct _LIBSSH2_PACKET {
struct _LIBSSH2_PACKET
{
unsigned char type;
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
@ -250,11 +259,13 @@ struct _LIBSSH2_PACKET {
LIBSSH2_PACKET *next, *prev;
};
struct _LIBSSH2_PACKET_BRIGADE {
struct _LIBSSH2_PACKET_BRIGADE
{
LIBSSH2_PACKET *head, *tail;
};
typedef struct _libssh2_channel_data {
typedef struct _libssh2_channel_data
{
/* Identifier */
unsigned long id;
@ -265,7 +276,8 @@ typedef struct _libssh2_channel_data {
char close, eof, extended_data_ignore_mode;
} libssh2_channel_data;
struct _LIBSSH2_CHANNEL {
struct _LIBSSH2_CHANNEL
{
unsigned char *channel_type;
unsigned channel_type_len;
@ -355,11 +367,13 @@ struct _LIBSSH2_CHANNEL {
libssh2_nonblocking_states extData2_state;
};
struct _LIBSSH2_CHANNEL_BRIGADE {
struct _LIBSSH2_CHANNEL_BRIGADE
{
LIBSSH2_CHANNEL *head, *tail;
};
struct _LIBSSH2_LISTENER {
struct _LIBSSH2_LISTENER
{
LIBSSH2_SESSION *session;
char *host;
@ -377,7 +391,8 @@ struct _LIBSSH2_LISTENER {
size_t chanFwdCncl_data_len;
};
typedef struct _libssh2_endpoint_data {
typedef struct _libssh2_endpoint_data
{
unsigned char *banner;
unsigned char *kexinit;
@ -402,7 +417,8 @@ typedef struct _libssh2_endpoint_data {
#define PACKETBUFSIZE 4096
struct transportpacket {
struct transportpacket
{
/* ------------- for incoming data --------------- */
unsigned char buf[PACKETBUFSIZE];
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
@ -437,7 +453,8 @@ struct transportpacket {
unsigned long osent; /* number of bytes already sent */
};
struct _LIBSSH2_PUBLICKEY {
struct _LIBSSH2_PUBLICKEY
{
LIBSSH2_CHANNEL *channel;
unsigned long version;
@ -464,7 +481,8 @@ struct _LIBSSH2_PUBLICKEY {
unsigned long listFetch_data_len;
};
struct _LIBSSH2_SFTP_HANDLE {
struct _LIBSSH2_SFTP_HANDLE
{
LIBSSH2_SFTP *sftp;
LIBSSH2_SFTP_HANDLE *prev, *next;
@ -473,11 +491,14 @@ struct _LIBSSH2_SFTP_HANDLE {
char handle_type;
union _libssh2_sftp_handle_data {
struct _libssh2_sftp_handle_file_data {
union _libssh2_sftp_handle_data
{
struct _libssh2_sftp_handle_file_data
{
libssh2_uint64_t offset;
} file;
struct _libssh2_sftp_handle_dir_data {
struct _libssh2_sftp_handle_dir_data
{
unsigned long names_left;
void *names_packet;
char *next_name;
@ -490,7 +511,8 @@ struct _LIBSSH2_SFTP_HANDLE {
unsigned char *close_packet;
};
struct _LIBSSH2_SFTP {
struct _LIBSSH2_SFTP
{
LIBSSH2_CHANNEL *channel;
unsigned long request_id, version;
@ -570,7 +592,8 @@ struct _LIBSSH2_SFTP {
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
struct _LIBSSH2_SESSION {
struct _LIBSSH2_SESSION
{
/* Memory management callbacks */
void *abstract;
LIBSSH2_ALLOC_FUNC((*alloc));
@ -823,28 +846,40 @@ struct _LIBSSH2_SESSION {
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */
struct _LIBSSH2_KEX_METHOD {
struct _LIBSSH2_KEX_METHOD
{
const char *name;
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
int (*exchange_keys)(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state);
int (*exchange_keys) (LIBSSH2_SESSION * session,
key_exchange_state_low_t * key_state);
long flags;
};
struct _LIBSSH2_HOSTKEY_METHOD {
struct _LIBSSH2_HOSTKEY_METHOD
{
const char *name;
unsigned long hash_len;
int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract);
int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract);
int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract);
int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract);
int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data,
unsigned long hostkey_data_len, void **abstract);
int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
unsigned const char *passphrase, void **abstract);
int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
unsigned long sig_len, const unsigned char *m,
unsigned long m_len, void **abstract);
int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature,
unsigned long *signature_len, unsigned long veccount,
const struct iovec datavec[], void **abstract);
int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst,
unsigned long *dst_len, const unsigned char *src,
unsigned long src_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
};
struct _LIBSSH2_CRYPT_METHOD {
struct _LIBSSH2_CRYPT_METHOD
{
const char *name;
int blocksize;
@ -855,23 +890,31 @@ struct _LIBSSH2_CRYPT_METHOD {
long flags;
int (*init)(LIBSSH2_SESSION *session, const LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract);
int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract);
int (*init) (LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv,
int *free_iv, unsigned char *secret, int *free_secret,
int encrypt, void **abstract);
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
_libssh2_cipher_type(algo);
};
struct _LIBSSH2_COMP_METHOD {
struct _LIBSSH2_COMP_METHOD
{
const char *name;
int (*init) (LIBSSH2_SESSION * session, int compress, void **abstract);
int (*comp)(LIBSSH2_SESSION *session, int compress, unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest,
const unsigned char *src, unsigned long src_len, void **abstract);
int (*comp) (LIBSSH2_SESSION * session, int compress, unsigned char **dest,
unsigned long *dest_len, unsigned long payload_limit,
int *free_dest, const unsigned char *src,
unsigned long src_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract);
};
struct _LIBSSH2_MAC_METHOD {
struct _LIBSSH2_MAC_METHOD
{
const char *name;
/* The length of a given MAC packet */
@ -881,8 +924,12 @@ struct _LIBSSH2_MAC_METHOD {
int key_len;
/* Message Authentication Code Hashing algo */
int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract);
int (*hash)(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, const unsigned char *packet, unsigned long packet_len, const unsigned char *addtl, unsigned long addtl_len, void **abstract);
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
void **abstract);
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
unsigned long seqno, const unsigned char *packet,
unsigned long packet_len, const unsigned char *addtl,
unsigned long addtl_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
};
@ -895,7 +942,8 @@ struct _LIBSSH2_MAC_METHOD {
#define LIBSSH2_DBG_ERROR 7
#define LIBSSH2_DBG_PUBLICKEY 8
#ifdef LIBSSH2DEBUG
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...);
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
...);
#else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
/* C99 style */
@ -905,8 +953,10 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
#define _libssh2_debug(x,y,z,...) do {} while (0)
#else
/* no gcc and not C99, do static and hopefully inline */
static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context,
const char *format, ...) {}
static inline void
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{
}
#endif
#endif
@ -1037,16 +1087,38 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type,
const unsigned char *match_buf,
unsigned long match_len, int poll_socket);
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, packet_require_state_t *state);
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, packet_requirev_state_t *state);
int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state);
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len);
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate);
int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, key_exchange_state_t *state);
int libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len, int poll_socket);
int libssh2_packet_require_ex(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
unsigned long *data_len, unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t * state);
int libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state);
int libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
int libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate);
int libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * state);
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id);
unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL *channel, int stream_id);
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION * session,
unsigned long channel_id);
unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
/* this is the lib-internal set blocking function */
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
@ -1064,8 +1136,7 @@ const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
int _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
FILE *fp,
char **data, unsigned int *datalen);
FILE * fp, char **data, unsigned int *datalen);
int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen);

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

@ -41,12 +41,15 @@
/* {{{ libssh2_mac_none_MAC
* Minimalist MAC: No MAC
*/
static int libssh2_mac_none_MAC(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
static int
libssh2_mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
unsigned long seqno, const unsigned char *packet,
unsigned long packet_len, const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{
return 0;
}
/* }}} */
@ -63,7 +66,9 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
/* {{{ libssh2_mac_method_common_init
* 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;
*free_key = 0;
@ -71,12 +76,14 @@ static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned cha
return 0;
}
/* }}} */
/* {{{ libssh2_mac_method_common_dtor
* 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) {
LIBSSH2_FREE(session, *abstract);
@ -85,14 +92,19 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr
return 0;
}
/* }}} */
/* {{{ libssh2_mac_method_hmac_sha1_hash
* Calculate hash using full sha1 value
*/
static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
static int
libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
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;
unsigned char seqno_buf[4];
@ -111,6 +123,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
return 0;
}
/* }}} */
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
* 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,
const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
static int
libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
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];
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,
addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
@ -150,9 +169,13 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
/* {{{ libssh2_mac_method_hmac_md5_hash
* Calculate hash using full md5 value
*/
static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
static int
libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, 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;
unsigned char seqno_buf[4];
@ -171,6 +194,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
return 0;
}
/* }}} */
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
* 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,
const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
static int
libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
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];
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,
addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
@ -211,9 +241,14 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
/* {{{ libssh2_mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value
*/
static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
static int
libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
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;
unsigned char seqno_buf[4];
@ -232,6 +267,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
@ -268,7 +304,8 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
NULL
};
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) {
const LIBSSH2_MAC_METHOD **
libssh2_mac_methods(void)
{
return _libssh2_mac_methods;
}

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

@ -42,17 +42,20 @@
/* {{{ 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];
}
/* }}} */
/* {{{ libssh2_ntohu64
* 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
*/
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
libssh2_uint64_t
libssh2_ntohu64(const unsigned char *buf)
{
unsigned long msl, lsl;
@ -61,22 +64,26 @@ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
return ((msl * 65536) * 65536) + lsl;
}
/* }}} */
/* {{{ 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[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF;
}
/* }}} */
/* {{{ 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;
@ -90,6 +97,7 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
buf[6] = (value >> 8) & 0xFF;
buf[7] = value & 0xFF;
}
/* }}} */
/* Base64 Conversion */
@ -123,14 +131,17 @@ 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
};
/* }}} */
/* {{{ libssh2_base64_decode
* 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,
const char *src, unsigned int src_len)
LIBSSH2_API int
libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{
unsigned char *s, *d;
short v;
@ -143,7 +154,8 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
}
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) {
case 0:
d[len] = v << 2;
@ -171,17 +183,19 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
*datalen = len;
return 0;
}
/* }}} */
#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;
return 0;
}
void _libssh2_debug(LIBSSH2_SESSION *session, int context,
const char *format, ...)
void
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{
char buffer[1536];
int len;
@ -217,7 +231,8 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
}
#else
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{
(void) session;
(void) bitmask;

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

@ -43,7 +43,8 @@
#define EVP_MAX_BLOCK_LENGTH 32
#endif
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
@ -58,8 +59,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen)
const unsigned char *coeffdata, unsigned long coefflen)
{
*rsa = RSA_new();
@ -91,11 +91,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
return 0;
}
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
int
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len)
const unsigned char *m, unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
int ret;
@ -106,7 +106,8 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
return (ret == 1) ? 0 : -1;
}
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
int
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
const unsigned char *p,
unsigned long p_len,
const unsigned char *q,
@ -115,8 +116,7 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
unsigned long g_len,
const unsigned char *y,
unsigned long y_len,
const unsigned char *x,
unsigned long x_len)
const unsigned char *x, unsigned long x_len)
{
*dsactx = DSA_new();
@ -140,10 +140,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
return 0;
}
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
int
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len)
const unsigned char *m, unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
DSA_SIG dsasig;
@ -162,21 +162,20 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
return (ret == 1) ? 0 : -1;
}
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt)
unsigned char *iv, unsigned char *secret, int encrypt)
{
EVP_CIPHER_CTX_init(h);
EVP_CipherInit(h, algo(), secret, iv, encrypt);
return 0;
}
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block)
int encrypt, unsigned char *block)
{
int blocksize = ctx->cipher->block_size;
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
@ -199,8 +198,7 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
* calling program
*/
static int
passphrase_cb(char *buf, int size,
int rwflag, char *passphrase)
passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
{
int passphrase_len = strlen(passphrase);
(void) rwflag;
@ -214,10 +212,10 @@ passphrase_cb(char *buf, int size,
return passphrase_len;
}
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
int
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase)
FILE * fp, unsigned const char *passphrase)
{
(void) session;
if (!EVP_get_cipherbyname("des")) {
@ -235,10 +233,10 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
return 0;
}
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
int
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase)
FILE * fp, unsigned const char *passphrase)
{
(void) session;
if (!EVP_get_cipherbyname("des")) {
@ -256,12 +254,12 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
return 0;
}
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len)
unsigned char **signature, unsigned long *signature_len)
{
int ret;
unsigned char *sig;
@ -287,10 +285,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
return 0;
}
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
int
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *signature)
unsigned long hash_len, unsigned char *signature)
{
DSA_SIG *sig;
int r_len, s_len, rs_pad;

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

@ -146,17 +146,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen);
const unsigned char *coeffdata, unsigned long coefflen);
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase);
FILE * fp, unsigned const char *passphrase);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len);
const unsigned char *m, unsigned long m_len);
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
@ -177,20 +174,16 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *x,
unsigned long x_len);
const unsigned char *x, unsigned long x_len);
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE *fp,
unsigned const char *passphrase);
FILE * fp, unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len);
const unsigned char *m, unsigned long m_len);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig);
unsigned long hash_len, unsigned char *sig);
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
@ -208,13 +201,11 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt);
unsigned char *secret, int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block);
int encrypt, unsigned char *block);
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)

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

@ -80,18 +80,27 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
(void) datalen;
if (listen_state->state == libssh2_NB_state_idle) {
listen_state->sender_channel = libssh2_ntohu32(s); s += 4;
listen_state->sender_channel = libssh2_ntohu32(s);
s += 4;
listen_state->initial_window_size = libssh2_ntohu32(s); s += 4;
listen_state->packet_size = libssh2_ntohu32(s); s += 4;
listen_state->initial_window_size = libssh2_ntohu32(s);
s += 4;
listen_state->packet_size = libssh2_ntohu32(s);
s += 4;
listen_state->host_len = libssh2_ntohu32(s); s += 4;
listen_state->host = s; s += listen_state->host_len;
listen_state->port = libssh2_ntohu32(s); s += 4;
listen_state->host_len = libssh2_ntohu32(s);
s += 4;
listen_state->host = s;
s += listen_state->host_len;
listen_state->port = libssh2_ntohu32(s);
s += 4;
listen_state->shost_len = libssh2_ntohu32(s); s += 4;
listen_state->shost = s; s += listen_state->shost_len;
listen_state->sport = libssh2_ntohu32(s); s += 4;
listen_state->shost_len = libssh2_ntohu32(s);
s += 4;
listen_state->shost = s;
s += listen_state->shost_len;
listen_state->sport = libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Remote received connection from %s:%ld to %s:%ld",
@ -105,7 +114,9 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
while (listen) {
if ((listen->port == (int) listen_state->port) &&
(strlen(listen->host) == listen_state->host_len) &&
(memcmp(listen->host, listen_state->host, listen_state->host_len) == 0)) {
(memcmp
(listen->host, listen_state->host,
listen_state->host_len) == 0)) {
/* This is our listener */
LIBSSH2_CHANNEL *channel, *last_queued = listen->queue;
@ -135,7 +146,9 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
channel->session = session;
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
channel->channel_type = LIBSSH2_ALLOC(session,
channel->channel_type_len + 1);
channel->
channel_type_len +
1);
if (!channel->channel_type) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new connection",
@ -149,13 +162,18 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
channel->channel_type_len + 1);
channel->remote.id = listen_state->sender_channel;
channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
channel->remote.window_size_initial =
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.window_size =
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.packet_size =
LIBSSH2_CHANNEL_PACKET_DEFAULT;
channel->local.id = libssh2_channel_nextid(session);
channel->local.window_size_initial = listen_state->initial_window_size;
channel->local.window_size = listen_state->initial_window_size;
channel->local.window_size_initial =
listen_state->initial_window_size;
channel->local.window_size =
listen_state->initial_window_size;
channel->local.packet_size = listen_state->packet_size;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
@ -185,8 +203,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
17);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc) {
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open confirmation",
0);
@ -239,8 +256,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
rc = libssh2_packet_write(session, listen_state->packet, packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc) {
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send open failure", 0);
listen_state->state = libssh2_NB_state_idle;
@ -250,6 +266,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
return 0;
}
}
/* }}} */
/* {{{ libssh2_packet_x11_open
@ -271,12 +288,18 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
(void) datalen;
if (x11open_state->state == libssh2_NB_state_idle) {
x11open_state->sender_channel = libssh2_ntohu32(s); s += 4;
x11open_state->initial_window_size = libssh2_ntohu32(s); s += 4;
x11open_state->packet_size = libssh2_ntohu32(s); s += 4;
x11open_state->shost_len = libssh2_ntohu32(s); s += 4;
x11open_state->shost = s; s += x11open_state->shost_len;
x11open_state->sport = libssh2_ntohu32(s); s += 4;
x11open_state->sender_channel = libssh2_ntohu32(s);
s += 4;
x11open_state->initial_window_size = libssh2_ntohu32(s);
s += 4;
x11open_state->packet_size = libssh2_ntohu32(s);
s += 4;
x11open_state->shost_len = libssh2_ntohu32(s);
s += 4;
x11open_state->shost = s;
s += x11open_state->shost_len;
x11open_state->sport = libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"X11 Connection Received from %s:%ld on channel %lu",
@ -301,7 +324,8 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
channel->session = session;
channel->channel_type_len = sizeof("x11") - 1;
channel->channel_type = LIBSSH2_ALLOC(session,
channel->channel_type_len + 1);
channel->channel_type_len +
1);
if (!channel->channel_type) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new connection",
@ -310,15 +334,18 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
goto x11_exit;
}
memcpy(channel->channel_type, "x11", channel->channel_type_len + 1);
memcpy(channel->channel_type, "x11",
channel->channel_type_len + 1);
channel->remote.id = x11open_state->sender_channel;
channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.window_size_initial =
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
channel->local.id = libssh2_channel_nextid(session);
channel->local.window_size_initial = x11open_state->initial_window_size;
channel->local.window_size_initial =
x11open_state->initial_window_size;
channel->local.window_size = x11open_state->initial_window_size;
channel->local.packet_size = x11open_state->packet_size;
@ -331,10 +358,14 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
channel->remote.packet_size);
p = x11open_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
libssh2_htonu32(p, channel->remote.id); p += 4;
libssh2_htonu32(p, channel->local.id); p += 4;
libssh2_htonu32(p, channel->remote.window_size_initial); p += 4;
libssh2_htonu32(p, channel->remote.packet_size); p += 4;
libssh2_htonu32(p, channel->remote.id);
p += 4;
libssh2_htonu32(p, channel->local.id);
p += 4;
libssh2_htonu32(p, channel->remote.window_size_initial);
p += 4;
libssh2_htonu32(p, channel->remote.packet_size);
p += 4;
x11open_state->state = libssh2_NB_state_created;
}
@ -343,8 +374,7 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
rc = libssh2_packet_write(session, x11open_state->packet, 17);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc) {
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open confirmation", 0);
x11open_state->state = libssh2_NB_state_idle;
@ -366,7 +396,8 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
* Pass control to the callback, they may turn right around and
* free the channel, or actually use it
*/
LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, x11open_state->sport);
LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost,
x11open_state->sport);
x11open_state->state = libssh2_NB_state_idle;
return 0;
@ -378,9 +409,12 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
x11_exit:
p = x11open_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
libssh2_htonu32(p, x11open_state->sender_channel); p += 4;
libssh2_htonu32(p, failure_code); p += 4;
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1); p += 4;
libssh2_htonu32(p, x11open_state->sender_channel);
p += 4;
libssh2_htonu32(p, failure_code);
p += 4;
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
p += 4;
memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
p += sizeof(X11FwdUnAvil) - 1;
libssh2_htonu32(p, 0);
@ -388,8 +422,7 @@ x11_exit:
rc = libssh2_packet_write(session, x11open_state->packet, packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc) {
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send open failure", 0);
x11open_state->state = libssh2_NB_state_idle;
@ -398,12 +431,14 @@ x11_exit:
x11open_state->state = libssh2_NB_state_idle;
return 0;
}
/* }}} */
/* {{{ libssh2_packet_new
* Create a new packet and attach it to the brigade
*/
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
int
libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate)
{
int rc;
@ -469,11 +504,9 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
*/
if (session->packAdd_state == libssh2_NB_state_jump1) {
goto libssh2_packet_add_jump_point1;
}
else if (session->packAdd_state == libssh2_NB_state_jump2) {
} else if (session->packAdd_state == libssh2_NB_state_jump2) {
goto libssh2_packet_add_jump_point2;
}
else if (session->packAdd_state == libssh2_NB_state_jump3) {
} else if (session->packAdd_state == libssh2_NB_state_jump3) {
goto libssh2_packet_add_jump_point3;
}
@ -586,7 +619,8 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
session->packAdd_data_head += 9;
{
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32(data + 1));
libssh2_ntohu32
(data + 1));
if (!session->packAdd_channel) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
@ -606,14 +640,17 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"%d bytes received for channel %lu/%lu stream #%lu",
(int)(datalen - session->packAdd_data_head),
(int) (datalen -
session->packAdd_data_head),
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id,
stream_id);
}
#endif
if ((session->packAdd_channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) &&
(data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
if ((session->packAdd_channel->remote.
extended_data_ignore_mode ==
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE)
&& (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
/* Pretend we didn't receive this */
LIBSSH2_FREE(session, data);
@ -623,8 +660,10 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
/* Adjust the window based on the block we just freed */
libssh2_packet_add_jump_point1:
session->packAdd_state = libssh2_NB_state_jump1;
rc = libssh2_channel_receive_window_adjust(session->packAdd_channel,
datalen - 13, 0);
rc = libssh2_channel_receive_window_adjust(session->
packAdd_channel,
datalen - 13,
0);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
@ -636,7 +675,8 @@ libssh2_packet_add_jump_point1:
* REMEMBER! remote means remote as source of data,
* NOT remote window!
*/
if (session->packAdd_channel->remote.packet_size < (datalen - session->packAdd_data_head)) {
if (session->packAdd_channel->remote.packet_size <
(datalen - session->packAdd_data_head)) {
/*
* Spec says we MAY ignore bytes sent beyond
* packet_size
@ -645,7 +685,9 @@ libssh2_packet_add_jump_point1:
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"Packet contains more data than we offered to receive, truncating",
0);
datalen = session->packAdd_channel->remote.packet_size + session->packAdd_data_head;
datalen =
session->packAdd_channel->remote.packet_size +
session->packAdd_data_head;
}
if (session->packAdd_channel->remote.window_size <= 0) {
/*
@ -663,15 +705,19 @@ libssh2_packet_add_jump_point1:
/* Reset EOF status */
session->packAdd_channel->remote.eof = 0;
if ((datalen - session->packAdd_data_head) > session->packAdd_channel->remote.window_size) {
if ((datalen - session->packAdd_data_head) >
session->packAdd_channel->remote.window_size) {
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"Remote sent more data than current window allows, truncating",
0);
datalen = session->packAdd_channel->remote.window_size + session->packAdd_data_head;
datalen =
session->packAdd_channel->remote.window_size +
session->packAdd_data_head;
} else {
/* Now that we've received it, shrink our window */
session->packAdd_channel->remote.window_size -= datalen - session->packAdd_data_head;
session->packAdd_channel->remote.window_size -=
datalen - session->packAdd_data_head;
}
}
break;
@ -679,7 +725,8 @@ libssh2_packet_add_jump_point1:
case SSH_MSG_CHANNEL_EOF:
{
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32(data + 1));
libssh2_ntohu32
(data + 1));
if (!session->packAdd_channel) {
/* We may have freed already, just quietly ignore this... */
@ -704,13 +751,17 @@ libssh2_packet_add_jump_point1:
case SSH_MSG_CHANNEL_REQUEST:
{
if (libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
&& !memcmp("exit-status", data + 9, sizeof("exit-status") - 1)) {
&& !memcmp("exit-status", data + 9,
sizeof("exit-status") - 1)) {
/* we've got "exit-status" packet. Set the session value */
session->packAdd_channel = libssh2_channel_locate(session, libssh2_ntohu32(data+1));
session->packAdd_channel =
libssh2_channel_locate(session,
libssh2_ntohu32(data + 1));
if (session->packAdd_channel) {
session->packAdd_channel->exit_status = libssh2_ntohu32(data + 9 + sizeof("exit-status"));
session->packAdd_channel->exit_status =
libssh2_ntohu32(data + 9 + sizeof("exit-status"));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Exit status %lu received for channel %lu/%lu",
session->packAdd_channel->exit_status,
@ -728,7 +779,8 @@ libssh2_packet_add_jump_point1:
case SSH_MSG_CHANNEL_CLOSE:
{
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32(data + 1));
libssh2_ntohu32
(data + 1));
if (!session->packAdd_channel) {
/* We may have freed already, just quietly ignore this... */
@ -753,13 +805,17 @@ libssh2_packet_add_jump_point1:
case SSH_MSG_CHANNEL_OPEN:
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
((sizeof("forwarded-tcpip")-1) == libssh2_ntohu32(data + 1)) &&
(memcmp(data + 5, "forwarded-tcpip", sizeof("forwarded-tcpip") - 1) == 0)) {
((sizeof("forwarded-tcpip") - 1) == libssh2_ntohu32(data + 1))
&&
(memcmp
(data + 5, "forwarded-tcpip",
sizeof("forwarded-tcpip") - 1) == 0)) {
libssh2_packet_add_jump_point2:
session->packAdd_state = libssh2_NB_state_jump2;
rc = libssh2_packet_queue_listener(session, data, datalen,
&session->packAdd_Qlstn_state);
&session->
packAdd_Qlstn_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
@ -790,7 +846,8 @@ libssh2_packet_add_jump_point3:
{
unsigned long bytestoadd = libssh2_ntohu32(data + 5);
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32(data + 1));
libssh2_ntohu32
(data + 1));
if (session->packAdd_channel && bytestoadd) {
session->packAdd_channel->local.window_size += bytestoadd;
@ -813,7 +870,8 @@ libssh2_packet_add_jump_point3:
}
if (session->packAdd_state == libssh2_NB_state_sent) {
session->packAdd_packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
session->packAdd_packet =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
if (!session->packAdd_packet) {
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for LIBSSH2_PACKET");
@ -869,14 +927,18 @@ libssh2_packet_add_jump_point3:
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
/* }}} */
/* {{{ libssh2_packet_ask
* Scan the brigade for a matching packet type, optionally poll the socket for
* a packet first
*/
int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len,
unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket)
int
libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len, int poll_socket)
{
LIBSSH2_PACKET *packet = session->packets.head;
@ -896,8 +958,16 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
"Looking for packet of type: %d", (int) packet_type);
while (packet) {
if (packet->data[0] == packet_type && (packet->data_len >= (match_ofs + match_len)) &&
(!match_buf || (memcmp(packet->data + match_ofs, match_buf, match_len) == 0))) {
if (packet->data[0] == packet_type
&& (packet->data_len >= (match_ofs + match_len)) && (!match_buf
||
(memcmp
(packet->
data +
match_ofs,
match_buf,
match_len)
== 0))) {
*data = packet->data;
*data_len = packet->data_len;
@ -921,13 +991,15 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
}
return -1;
}
/* }}} */
/* {{{ libssh2_packet_askv
* Scan for any of a list of packet types in the brigade, optionally poll the
* socket for a packet first
*/
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
int
libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
@ -952,6 +1024,7 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
return -1;
}
/* }}} */
/* {{{ waitsocket
@ -962,7 +1035,8 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
*
* FIXME: convert to use poll on systems that have it.
*/
int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds)
int
libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds)
{
struct timeval timeout;
int rc;
@ -987,42 +1061,48 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds)
* Returns negative on error
* Returns 0 when it has taken care of the requested packet.
*/
int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data,
unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len, packet_require_state_t *state)
int
libssh2_packet_require_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t * state)
{
if (state->start == 0) {
if (libssh2_packet_ask_ex(session, packet_type, data, data_len, match_ofs, match_buf, match_len, 0) == 0) {
if (libssh2_packet_ask_ex
(session, packet_type, data, data_len, match_ofs, match_buf,
match_len, 0) == 0) {
/* A packet was available in the packet brigade */
return 0;
}
state->start = time(NULL);
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "May block until packet of type %d becomes available", (int)packet_type);
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"May block until packet of type %d becomes available",
(int) packet_type);
}
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
libssh2pack_t ret = libssh2_packet_read(session);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if ((ret == 0) && (!session->socket_block)) {
} else if ((ret == 0) && (!session->socket_block)) {
/* If we are in non-blocking and there is no data, return that */
return PACKET_EAGAIN;
}
else if (ret < 0) {
} else if (ret < 0) {
state->start = 0;
/* an error which is not just because of blocking */
return ret;
}
else if (ret == packet_type) {
} else if (ret == packet_type) {
/* Be lazy, let packet_ask pull it out of the brigade */
ret = libssh2_packet_ask_ex(session, packet_type, data, data_len, match_ofs, match_buf, match_len, 0);
ret =
libssh2_packet_ask_ex(session, packet_type, data, data_len,
match_ofs, match_buf, match_len, 0);
state->start = 0;
return ret;
}
else if (ret == 0) {
} else if (ret == 0) {
/* nothing available, wait until data arrives or we time out */
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
@ -1036,6 +1116,7 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ
/* Only reached if the socket died */
return -1;
}
/* }}} */
/* {{{ libssh2_packet_burn
@ -1043,7 +1124,9 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ
* discards it
* Used during KEX exchange to discard badly guessed KEX_INIT packets
*/
int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state)
int
libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state)
{
unsigned char *data;
unsigned long data_len;
@ -1056,32 +1139,34 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
all_packets[i - 1] = i;
}
if (libssh2_packet_askv_ex(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
if (libssh2_packet_askv_ex
(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
i = data[0];
/* A packet was available in the packet brigade, burn it */
LIBSSH2_FREE(session, data);
return i;
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Blocking until packet becomes available to burn");
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"Blocking until packet becomes available to burn");
*state = libssh2_NB_state_created;
}
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (ret < 0) {
} else if (ret < 0) {
*state = libssh2_NB_state_idle;
return ret;
}
else if (ret == 0) {
} else if (ret == 0) {
/* FIXME: this might busyloop */
continue;
}
/* Be lazy, let packet_ask pull it out of the brigade */
if (0 == libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0, 0)) {
if (0 ==
libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
0)) {
/* Smoke 'em if you got 'em */
LIBSSH2_FREE(session, data);
*state = libssh2_NB_state_idle;
@ -1092,6 +1177,7 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
/* Only reached if the socket died */
return -1;
}
/* }}} */
/*
@ -1103,11 +1189,18 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
* packet_types is a null terminated list of packet_type numbers
*/
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data,
unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len, packet_requirev_state_t *state)
int
libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state)
{
if (libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0) == 0) {
if (libssh2_packet_askv_ex
(session, packet_types, data, data_len, match_ofs, match_buf,
match_len, 0) == 0) {
/* One of the packets listed was available in the packet
brigade */
state->start = 0;
@ -1130,15 +1223,16 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa
if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
state->start = 0;
return PACKET_TIMEOUT;
}
else if (ret == PACKET_EAGAIN) {
} else if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
}
if (strchr((char *) packet_types, ret)) {
/* Be lazy, let packet_ask pull it out of the brigade */
return libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0);
return libssh2_packet_askv_ex(session, packet_types, data,
data_len, match_ofs, match_buf,
match_len, 0);
}
}
@ -1146,4 +1240,5 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa
state->start = 0;
return -1;
}
/* }}} */

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

@ -37,18 +37,16 @@
#include "libssh2_priv.h"
static int readline (char *line, int line_size, FILE *fp)
{
if (!fgets(line, line_size, fp))
static int
readline(char *line, int line_size, FILE * fp)
{
if (!fgets(line, line_size, fp)) {
return -1;
}
if (*line && line[strlen(line) - 1] == '\n')
{
if (*line && line[strlen(line) - 1] == '\n') {
line[strlen(line) - 1] = '\0';
}
if (*line && line[strlen(line) - 1] == '\r')
{
if (*line && line[strlen(line) - 1] == '\r') {
line[strlen(line) - 1] = '\0';
}
return 0;
@ -56,21 +54,19 @@ static int readline (char *line, int line_size, FILE *fp)
#define LINE_SIZE 128
int _libssh2_pem_parse (LIBSSH2_SESSION *session,
int
_libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
FILE *fp,
char **data, unsigned int *datalen)
FILE * fp, char **data, unsigned int *datalen)
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
int ret;
do
{
if (readline(line, LINE_SIZE, fp))
{
do {
if (readline(line, LINE_SIZE, fp)) {
return -1;
}
}
@ -78,18 +74,14 @@ int _libssh2_pem_parse (LIBSSH2_SESSION *session,
*line = '\0';
do
{
if (*line)
{
do {
if (*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC (session, b64data,
b64datalen + linelen);
if (!tmp)
{
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if (!tmp) {
ret = -1;
goto out;
}
@ -98,16 +90,13 @@ int _libssh2_pem_parse (LIBSSH2_SESSION *session,
b64datalen += linelen;
}
if (readline(line, LINE_SIZE, fp))
{
if (readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while (strcmp(line, headerend) != 0);
if (libssh2_base64_decode(session, data, datalen,
b64data, b64datalen))
{
if (libssh2_base64_decode(session, data, datalen, b64data, b64datalen)) {
ret = -1;
goto out;
}
@ -120,59 +109,51 @@ out:
return ret;
}
static int read_asn1_length (const unsigned char *data,
unsigned int datalen,
unsigned int *len)
static int
read_asn1_length(const unsigned char *data,
unsigned int datalen, unsigned int *len)
{
unsigned int lenlen;
int nextpos;
if (datalen < 1)
{
if (datalen < 1) {
return -1;
}
*len = data[0];
if (*len >= 0x80)
{
if (*len >= 0x80) {
lenlen = *len & 0x7F;
*len = data[1];
if (1 + lenlen > datalen)
{
if (1 + lenlen > datalen) {
return -1;
}
if (lenlen > 1)
{
if (lenlen > 1) {
*len <<= 8;
*len |= data[2];
}
}
else
{
} else {
lenlen = 0;
}
nextpos = 1 + lenlen;
if (lenlen > 2 || 1 + lenlen + *len > datalen)
{
if (lenlen > 2 || 1 + lenlen + *len > datalen) {
return -1;
}
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;
int lenlen;
if (*datalen < 1)
{
if (*datalen < 1) {
return -1;
}
if ((*data)[0] != '\x30')
{
if ((*data)[0] != '\x30') {
return -1;
}
@ -180,8 +161,7 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
(*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len != *datalen)
{
if (lenlen < 0 || lenlen + len != *datalen) {
return -1;
}
@ -191,19 +171,18 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
return 0;
}
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
int
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen)
{
unsigned int len;
int lenlen;
if (*datalen < 1)
{
if (*datalen < 1) {
return -1;
}
if ((*data)[0] != '\x02')
{
if ((*data)[0] != '\x02') {
return -1;
}
@ -211,8 +190,7 @@ int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
(*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len > *datalen)
{
if (lenlen < 0 || lenlen + len > *datalen) {
return -1;
}

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

@ -45,16 +45,20 @@
#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1
#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2
typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST {
typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST
{
int code;
const char *name;
int name_len;
} LIBSSH2_PUBLICKEY_CODE_LIST;
static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
{ LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1 },
{ LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1 },
{ LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1 },
{LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}
,
{LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}
,
{LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1}
,
{0, NULL, 0}
};
@ -72,15 +76,32 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8
static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
{ LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1 },
{ LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", sizeof("access denied") - 1 },
{ LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", sizeof("storage exceeded") - 1 },
{ LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", sizeof("version not supported") - 1 },
{ LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", sizeof("key not found") - 1 },
{ LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", sizeof("key not supported") - 1 },
{ LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", sizeof("key already present") - 1 },
{ LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", sizeof("general failure") - 1 },
{ LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", sizeof("request not supported") - 1 },
{LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1}
,
{LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied",
sizeof("access denied") - 1}
,
{LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded",
sizeof("storage exceeded") - 1}
,
{LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported",
sizeof("version not supported") - 1}
,
{LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found",
sizeof("key not found") - 1}
,
{LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported",
sizeof("key not supported") - 1}
,
{LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present",
sizeof("key already present") - 1}
,
{LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure",
sizeof("general failure") - 1}
,
{LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported",
sizeof("request not supported") - 1}
,
{0, NULL, 0}
};
@ -91,7 +112,8 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \""
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
static void
libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, int status,
libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
LIBSSH2_SESSION * session, int status,
const unsigned char *message, int message_len)
{
const char *status_text;
@ -112,32 +134,41 @@ libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *s
status_text_len = libssh2_publickey_status_codes[status].name_len;
}
m_len = (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1) + status_text_len +
m_len =
(sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1) + status_text_len +
(sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1) + message_len +
(sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1);
m = LIBSSH2_ALLOC(session, m_len + 1);
if (!m) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for status message", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for status message", 0);
return;
}
s = m;
memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_START, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1);
memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_START,
sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1);
s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1;
memcpy(s, status_text, status_text_len); s += status_text_len;
memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_MID, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1);
memcpy(s, status_text, status_text_len);
s += status_text_len;
memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_MID,
sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1);
s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1;
memcpy(s, message, message_len); s += message_len;
memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_END, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1);
memcpy(s, message, message_len);
s += message_len;
memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_END,
sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1);
s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END);
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, m, 1);
}
/* }}} */
/* {{{ libssh2_publickey_packet_receive
* Read a packet from the subsystem
*/
static int
libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, unsigned long *data_len)
libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
unsigned char **data, unsigned long *data_len)
{
LIBSSH2_CHANNEL *channel = pkey->channel;
LIBSSH2_SESSION *session = channel->session;
@ -148,16 +179,18 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data,
rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc != 4) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0);
} else if (rc != 4) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid response from publickey subsystem", 0);
return -1;
}
pkey->receive_packet_len = libssh2_ntohu32(buffer);
pkey->receive_packet = LIBSSH2_ALLOC(session, pkey->receive_packet_len);
pkey->receive_packet =
LIBSSH2_ALLOC(session, pkey->receive_packet_len);
if (!pkey->receive_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate publickey response buffer", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate publickey response buffer", 0);
return -1;
}
@ -165,12 +198,14 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data,
}
if (pkey->receive_state == libssh2_NB_state_sent) {
rc = libssh2_channel_read_ex(channel, 0, (char *)pkey->receive_packet, pkey->receive_packet_len);
rc = libssh2_channel_read_ex(channel, 0, (char *) pkey->receive_packet,
pkey->receive_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc != pkey->receive_packet_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0);
} else if (rc != pkey->receive_packet_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for publickey subsystem response packet",
0);
LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL;
pkey->receive_state = libssh2_NB_state_idle;
@ -185,23 +220,28 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data,
return 0;
}
/* }}} */
/* {{{ libssh2_publickey_response_id
* Translate a string response name to a numeric code
* Data will be incremented by 4 + response_len on success only
*/
static int libssh2_publickey_response_id(unsigned char **pdata, int data_len)
static int
libssh2_publickey_response_id(unsigned char **pdata, int data_len)
{
unsigned long response_len;
unsigned char *data = *pdata;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes = libssh2_publickey_response_codes;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes =
libssh2_publickey_response_codes;
if (data_len < 4) {
/* Malformed response */
return -1;
}
response_len = libssh2_ntohu32(data); data += 4; data_len -= 4;
response_len = libssh2_ntohu32(data);
data += 4;
data_len -= 4;
if (data_len < response_len) {
/* Malformed response */
return -1;
@ -218,12 +258,14 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len)
return -1;
}
/* }}} */
/* {{{ libssh2_publickey_response_success
* Generic helper routine to wait for success response and nothing else
*/
static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
static int
libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
{
LIBSSH2_SESSION *session = pkey->channel->session;
unsigned char *data, *s;
@ -235,15 +277,17 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
rc = libssh2_publickey_packet_receive(pkey, &data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from publickey subsystem",
0);
return -1;
}
s = data;
if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0);
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code", 0);
LIBSSH2_FREE(session, data);
return -1;
}
@ -255,14 +299,20 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
status = libssh2_ntohu32(s); s += 4;
descr_len = libssh2_ntohu32(s); s += 4;
descr = s; s += descr_len;
lang_len = libssh2_ntohu32(s); s += 4;
lang = s; s += lang_len;
status = libssh2_ntohu32(s);
s += 4;
descr_len = libssh2_ntohu32(s);
s += 4;
descr = s;
s += descr_len;
lang_len = libssh2_ntohu32(s);
s += 4;
lang = s;
s += lang_len;
if (s > data + data_len) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0);
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet", 0);
LIBSSH2_FREE(session, data);
return -1;
}
@ -272,13 +322,16 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
return 0;
}
libssh2_publickey_status_error(pkey, session, status, descr, descr_len);
libssh2_publickey_status_error(pkey, session, status, descr,
descr_len);
LIBSSH2_FREE(session, data);
return -1;
}
default:
/* Unknown/Unexpected */
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0);
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring",
0);
LIBSSH2_FREE(session, data);
data = NULL;
}
@ -286,6 +339,7 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
/* never reached, but include `return` to silence compiler warnings */
return -1;
}
/* }}} */
@ -296,7 +350,8 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
/* {{{ libssh2_publickey_init
* Startup the publickey subsystem
*/
LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
LIBSSH2_API LIBSSH2_PUBLICKEY *
libssh2_publickey_init(LIBSSH2_SESSION * session)
{
/* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */
unsigned char buffer[19];
@ -309,23 +364,32 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_pkey = NULL;
session->pkeyInit_channel = NULL;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem");
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Initializing publickey subsystem");
session->pkeyInit_state = libssh2_NB_state_allocated;
}
if (session->pkeyInit_state == libssh2_NB_state_allocated) {
do {
session->pkeyInit_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT,
NULL, 0);
if (!session->pkeyInit_channel && (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN)) {
session->pkeyInit_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->pkeyInit_channel
&& (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN)) {
/* The error state is already set, so leave it */
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block to startup channel", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block to startup channel", 0);
return NULL;
}
else if (!session->pkeyInit_channel && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel", 0);
} else if (!session->pkeyInit_channel
&& (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN)) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to startup channel", 0);
goto err_exit;
}
} while (!session->pkeyInit_channel);
@ -334,14 +398,17 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
}
if (session->pkeyInit_state == libssh2_NB_state_sent) {
rc = libssh2_channel_process_startup(session->pkeyInit_channel, "subsystem", sizeof("subsystem") - 1,
rc = libssh2_channel_process_startup(session->pkeyInit_channel,
"subsystem",
sizeof("subsystem") - 1,
"publickey", strlen("publickey"));
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting publickkey subsystem", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickkey subsystem", 0);
return NULL;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem", 0);
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to request publickey subsystem", 0);
goto err_exit;
}
@ -349,15 +416,19 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
}
if (session->pkeyInit_state == libssh2_NB_state_sent1) {
rc = libssh2_channel_handle_extended_data2(session->pkeyInit_channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
rc = libssh2_channel_handle_extended_data2(session->pkeyInit_channel,
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting publickkey subsystem", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickkey subsystem", 0);
return NULL;
}
session->pkeyInit_pkey = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
session->pkeyInit_pkey =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
if (!session->pkeyInit_pkey) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new publickey structure", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new publickey structure", 0);
goto err_exit;
}
memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
@ -365,25 +436,32 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_pkey->version = 0;
s = buffer;
libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); s += 4;
libssh2_htonu32(s, sizeof("version") - 1); s += 4;
memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1;
libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4;
libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4);
s += 4;
libssh2_htonu32(s, sizeof("version") - 1);
s += 4;
memcpy(s, "version", sizeof("version") - 1);
s += sizeof("version") - 1;
libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support",
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Sending publickey version packet advertising version %d support",
(int) LIBSSH2_PUBLICKEY_VERSION);
session->pkeyInit_state = libssh2_NB_state_sent2;
}
if (session->pkeyInit_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_write_ex(session->pkeyInit_channel, 0, (char*)buffer, (s - buffer));
rc = libssh2_channel_write_ex(session->pkeyInit_channel, 0,
(char *) buffer, (s - buffer));
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending publickkey version packet", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickkey version packet", 0);
return NULL;
}
else if ((s - buffer) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0);
} else if ((s - buffer) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey version packet", 0);
goto err_exit;
}
@ -392,19 +470,28 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
if (session->pkeyInit_state == libssh2_NB_state_sent3) {
while (1) {
rc = libssh2_publickey_packet_receive(session->pkeyInit_pkey, &session->pkeyInit_data, &session->pkeyInit_data_len);
rc = libssh2_publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data,
&session->pkeyInit_data_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from publickey subsystem", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from publickey subsystem",
0);
return NULL;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from publickey subsystem",
0);
goto err_exit;
}
s = session->pkeyInit_data;
if ((response = libssh2_publickey_response_id(&s, session->pkeyInit_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0);
if ((response =
libssh2_publickey_response_id(&s,
session->pkeyInit_data_len)) <
0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code", 0);
goto err_exit;
}
@ -415,30 +502,44 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
status = libssh2_ntohu32(s); s += 4;
descr_len = libssh2_ntohu32(s); s += 4;
descr = s; s += descr_len;
lang_len = libssh2_ntohu32(s); s += 4;
lang = s; s += lang_len;
status = libssh2_ntohu32(s);
s += 4;
descr_len = libssh2_ntohu32(s);
s += 4;
descr = s;
s += descr_len;
lang_len = libssh2_ntohu32(s);
s += 4;
lang = s;
s += lang_len;
if (s > session->pkeyInit_data + session->pkeyInit_data_len) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0);
if (s >
session->pkeyInit_data + session->pkeyInit_data_len) {
libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet",
0);
goto err_exit;
}
libssh2_publickey_status_error(NULL, session, status, descr, descr_len);
libssh2_publickey_status_error(NULL, session, status,
descr, descr_len);
goto err_exit;
}
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
/* What we want */
session->pkeyInit_pkey->version = libssh2_ntohu32(s);
if (session->pkeyInit_pkey->version > LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu",
if (session->pkeyInit_pkey->version >
LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Truncating remote publickey version from %lu",
session->pkeyInit_pkey->version);
session->pkeyInit_pkey->version = LIBSSH2_PUBLICKEY_VERSION;
session->pkeyInit_pkey->version =
LIBSSH2_PUBLICKEY_VERSION;
}
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu",
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Enabling publickey subsystem version %lu",
session->pkeyInit_pkey->version);
LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL;
@ -448,7 +549,8 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
default:
/* Unknown/Unexpected */
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring", 0);
"Unexpected publickey subsystem response, ignoring",
0);
LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL;
}
@ -461,7 +563,8 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
if (session->pkeyInit_channel) {
rc = libssh2_channel_close(session->pkeyInit_channel);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block closing channel", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block closing channel", 0);
return NULL;
}
}
@ -476,14 +579,17 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_idle;
return NULL;
}
/* }}} */
/* {{{ libssh2_publickey_add_ex
* Add a new public key entry
*/
LIBSSH2_API int
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
const unsigned char *blob, unsigned long blob_len, char overwrite, unsigned long num_attrs,
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
unsigned long name_len, const unsigned char *blob,
unsigned long blob_len, char overwrite,
unsigned long num_attrs,
const libssh2_publickey_attribute attrs[])
{
LIBSSH2_CHANNEL *channel = pkey->channel;
@ -497,13 +603,15 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, uns
if (pkey->add_state == libssh2_NB_state_idle) {
pkey->add_packet = NULL;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey", name);
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey",
name);
if (pkey->version == 1) {
for(i = 0; i < num_attrs; i++) {
/* Search for a comment attribute */
if (attrs[i].name_len == (sizeof("comment") - 1) &&
strncmp(attrs[i].name, "comment", sizeof("comment") - 1) == 0) {
strncmp(attrs[i].name, "comment",
sizeof("comment") - 1) == 0) {
comment = (unsigned char *) attrs[i].value;
comment_len = attrs[i].value_len;
break;
@ -520,55 +628,77 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, uns
pkey->add_packet = LIBSSH2_ALLOC(session, packet_len);
if (!pkey->add_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"add\" packet", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for publickey \"add\" packet",
0);
return -1;
}
pkey->add_s = pkey->add_packet;
libssh2_htonu32(pkey->add_s, packet_len - 4); pkey->add_s += 4;
libssh2_htonu32(pkey->add_s, sizeof("add") - 1); pkey->add_s += 4;
memcpy(pkey->add_s, "add", sizeof("add") - 1); pkey->add_s += sizeof("add") - 1;
libssh2_htonu32(pkey->add_s, packet_len - 4);
pkey->add_s += 4;
libssh2_htonu32(pkey->add_s, sizeof("add") - 1);
pkey->add_s += 4;
memcpy(pkey->add_s, "add", sizeof("add") - 1);
pkey->add_s += sizeof("add") - 1;
if (pkey->version == 1) {
libssh2_htonu32(pkey->add_s, comment_len); pkey->add_s += 4;
libssh2_htonu32(pkey->add_s, comment_len);
pkey->add_s += 4;
if (comment) {
memcpy(pkey->add_s, comment, comment_len); pkey->add_s += comment_len;
memcpy(pkey->add_s, comment, comment_len);
pkey->add_s += comment_len;
}
libssh2_htonu32(pkey->add_s, name_len); pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len;
libssh2_htonu32(pkey->add_s, blob_len); pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len;
libssh2_htonu32(pkey->add_s, name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len);
pkey->add_s += name_len;
libssh2_htonu32(pkey->add_s, blob_len);
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
} else {
/* Version == 2 */
libssh2_htonu32(pkey->add_s, name_len); pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len;
libssh2_htonu32(pkey->add_s, blob_len); pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len;
libssh2_htonu32(pkey->add_s, name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len);
pkey->add_s += name_len;
libssh2_htonu32(pkey->add_s, blob_len);
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
*(pkey->add_s++) = overwrite ? 0x01 : 0;
libssh2_htonu32(pkey->add_s, num_attrs); pkey->add_s += 4;
libssh2_htonu32(pkey->add_s, num_attrs);
pkey->add_s += 4;
for(i = 0; i < num_attrs; i++) {
libssh2_htonu32(pkey->add_s, attrs[i].name_len); pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); pkey->add_s += attrs[i].name_len;
libssh2_htonu32(pkey->add_s, attrs[i].value_len); pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); pkey->add_s += attrs[i].value_len;
libssh2_htonu32(pkey->add_s, attrs[i].name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len);
pkey->add_s += attrs[i].name_len;
libssh2_htonu32(pkey->add_s, attrs[i].value_len);
pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len);
pkey->add_s += attrs[i].value_len;
*(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0;
}
}
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
name, blob_len, num_attrs);
pkey->add_state = libssh2_NB_state_created;
}
if (pkey->add_state == libssh2_NB_state_created) {
rc = libssh2_channel_write_ex(channel, 0, (char *)pkey->add_packet, (pkey->add_s - pkey->add_packet));
rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->add_packet,
(pkey->add_s - pkey->add_packet));
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if ((pkey->add_s - pkey->add_packet) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet", 0);
} else if ((pkey->add_s - pkey->add_packet) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey add packet", 0);
LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL;
return -1;
@ -588,13 +718,15 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, uns
return rc;
}
/* }}} */
/* {{{ libssh2_publickey_remove_ex
* Remove an existing publickey so that authentication can no longer be performed using it
*/
LIBSSH2_API int
libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
const unsigned char *name, unsigned long name_len,
const unsigned char *blob, unsigned long blob_len)
{
LIBSSH2_CHANNEL *channel = pkey->channel;
@ -608,31 +740,43 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len);
if (!pkey->remove_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"remove\" packet", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for publickey \"remove\" packet",
0);
return -1;
}
pkey->remove_s = pkey->remove_packet;
libssh2_htonu32(pkey->remove_s, packet_len - 4); pkey->remove_s += 4;
libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); pkey->remove_s += 4;
memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); pkey->remove_s += sizeof("remove") - 1;
libssh2_htonu32(pkey->remove_s, name_len); pkey->remove_s += 4;
memcpy(pkey->remove_s, name, name_len); pkey->remove_s += name_len;
libssh2_htonu32(pkey->remove_s, blob_len); pkey->remove_s += 4;
memcpy(pkey->remove_s, blob, blob_len); pkey->remove_s += blob_len;
libssh2_htonu32(pkey->remove_s, packet_len - 4);
pkey->remove_s += 4;
libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1);
pkey->remove_s += 4;
memcpy(pkey->remove_s, "remove", sizeof("remove") - 1);
pkey->remove_s += sizeof("remove") - 1;
libssh2_htonu32(pkey->remove_s, name_len);
pkey->remove_s += 4;
memcpy(pkey->remove_s, name, name_len);
pkey->remove_s += name_len;
libssh2_htonu32(pkey->remove_s, blob_len);
pkey->remove_s += 4;
memcpy(pkey->remove_s, blob, blob_len);
pkey->remove_s += blob_len;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len);
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Sending publickey \"remove\" packet: type=%s blob_len=%ld",
name, blob_len);
pkey->remove_state = libssh2_NB_state_created;
}
if (pkey->remove_state == libssh2_NB_state_created) {
rc = libssh2_channel_write_ex(channel, 0, (char *)pkey->remove_packet, (pkey->remove_s - pkey->remove_packet));
rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->remove_packet,
(pkey->remove_s - pkey->remove_packet));
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if ((pkey->remove_s - pkey->remove_packet) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0);
} else if ((pkey->remove_s - pkey->remove_packet) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey remove packet", 0);
LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL;
pkey->remove_state = libssh2_NB_state_idle;
@ -653,13 +797,15 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
return rc;
}
/* }}} */
/* {{{ libssh2_publickey_list_fetch
* Fetch a list of supported public key from a server
*/
LIBSSH2_API int
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list)
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
libssh2_publickey_list ** pkey_list)
{
LIBSSH2_CHANNEL *channel = pkey->channel;
LIBSSH2_SESSION *session = channel->session;
@ -673,22 +819,29 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
pkey->listFetch_data = NULL;
pkey->listFetch_s = pkey->listFetch_buffer;
libssh2_htonu32(pkey->listFetch_s, buffer_len - 4); pkey->listFetch_s += 4;
libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); pkey->listFetch_s += 4;
memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); pkey->listFetch_s += sizeof("list") - 1;
libssh2_htonu32(pkey->listFetch_s, buffer_len - 4);
pkey->listFetch_s += 4;
libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1);
pkey->listFetch_s += 4;
memcpy(pkey->listFetch_s, "list", sizeof("list") - 1);
pkey->listFetch_s += sizeof("list") - 1;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet");
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
"Sending publickey \"list\" packet");
pkey->listFetch_state = libssh2_NB_state_created;
}
if (pkey->listFetch_state == libssh2_NB_state_created) {
rc = libssh2_channel_write_ex(channel, 0, (char *)pkey->listFetch_buffer, (pkey->listFetch_s - pkey->listFetch_buffer));
rc = libssh2_channel_write_ex(channel, 0,
(char *) pkey->listFetch_buffer,
(pkey->listFetch_s -
pkey->listFetch_buffer));
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0);
} else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet", 0);
pkey->listFetch_state = libssh2_NB_state_idle;
return -1;
}
@ -697,18 +850,23 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
}
while (1) {
rc = libssh2_publickey_packet_receive(pkey, &pkey->listFetch_data, &pkey->listFetch_data_len);
rc = libssh2_publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from publickey subsystem",
0);
goto err_exit;
}
pkey->listFetch_s = pkey->listFetch_data;
if ((response = libssh2_publickey_response_id(&pkey->listFetch_s, pkey->listFetch_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0);
if ((response =
libssh2_publickey_response_id(&pkey->listFetch_s,
pkey->listFetch_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code", 0);
goto err_exit;
}
@ -719,14 +877,21 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
status = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
descr_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
descr = pkey->listFetch_s; pkey->listFetch_s += descr_len;
lang_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
lang = pkey->listFetch_s; pkey->listFetch_s += lang_len;
status = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr = pkey->listFetch_s;
pkey->listFetch_s += descr_len;
lang_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
lang = pkey->listFetch_s;
pkey->listFetch_s += lang_len;
if (pkey->listFetch_s > pkey->listFetch_data + pkey->listFetch_data_len) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0);
if (pkey->listFetch_s >
pkey->listFetch_data + pkey->listFetch_data_len) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet", 0);
goto err_exit;
}
@ -739,7 +904,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
return 0;
}
libssh2_publickey_status_error(pkey, session, status, descr, descr_len);
libssh2_publickey_status_error(pkey, session, status, descr,
descr_len);
goto err_exit;
}
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
@ -748,9 +914,14 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
libssh2_publickey_list *newlist;
/* Grow the key list if necessary */
max_keys += 8;
newlist = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list));
newlist =
LIBSSH2_REALLOC(session, list,
(max_keys +
1) * sizeof(libssh2_publickey_list));
if (!newlist) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey list", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for publickey list",
0);
goto err_exit;
}
list = newlist;
@ -758,12 +929,17 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
if (pkey->version == 1) {
unsigned long comment_len;
comment_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
comment_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
if (comment_len) {
list[keys].num_attrs = 1;
list[keys].attrs = LIBSSH2_ALLOC(session, sizeof(libssh2_publickey_attribute));
list[keys].attrs =
LIBSSH2_ALLOC(session,
sizeof(libssh2_publickey_attribute));
if (!list[keys].attrs) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey attributes", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for publickey attributes",
0);
goto err_exit;
}
list[keys].attrs[0].name = "comment";
@ -777,29 +953,45 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
list[keys].num_attrs = 0;
list[keys].attrs = NULL;
}
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len;
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len;
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].name = pkey->listFetch_s;
pkey->listFetch_s += list[keys].name_len;
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].blob = pkey->listFetch_s;
pkey->listFetch_s += list[keys].blob_len;
} else {
/* Version == 2 */
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len;
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len;
list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].name = pkey->listFetch_s;
pkey->listFetch_s += list[keys].name_len;
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].blob = pkey->listFetch_s;
pkey->listFetch_s += list[keys].blob_len;
list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
if (list[keys].num_attrs) {
list[keys].attrs = LIBSSH2_ALLOC(session, list[keys].num_attrs * sizeof(libssh2_publickey_attribute));
list[keys].attrs =
LIBSSH2_ALLOC(session,
list[keys].num_attrs *
sizeof(libssh2_publickey_attribute));
if (!list[keys].attrs) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey attributes", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for publickey attributes",
0);
goto err_exit;
}
for(i = 0; i < list[keys].num_attrs; i++) {
list[keys].attrs[i].name_len = libssh2_ntohu32(pkey->listFetch_s);
list[keys].attrs[i].name_len =
libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].attrs[i].name = (char *) pkey->listFetch_s;
pkey->listFetch_s += list[keys].attrs[i].name_len;
list[keys].attrs[i].value_len = libssh2_ntohu32(pkey->listFetch_s);
list[keys].attrs[i].value_len =
libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].attrs[i].value = (char *) pkey->listFetch_s;
pkey->listFetch_s += list[keys].attrs[i].value_len;
@ -817,7 +1009,9 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
break;
default:
/* Unknown/Unexpected */
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0);
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring",
0);
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
}
@ -835,12 +1029,15 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l
pkey->listFetch_state = libssh2_NB_state_idle;
return -1;
}
/* }}} */
/* {{{ libssh2_publickey_list_free
* Free a previously fetched list of public keys
*/
LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list)
LIBSSH2_API void
libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
libssh2_publickey_list * pkey_list)
{
LIBSSH2_SESSION *session = pkey->channel->session;
libssh2_publickey_list *p = pkey_list;
@ -855,12 +1052,14 @@ LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_pu
LIBSSH2_FREE(session, pkey_list);
}
/* }}} */
/* {{{ libssh2_publickey_shutdown
* Shutdown the publickey subsystem
*/
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
LIBSSH2_API int
libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
{
LIBSSH2_SESSION *session = pkey->channel->session;
@ -891,4 +1090,5 @@ LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
LIBSSH2_FREE(session, pkey);
return 0;
}
/* }}} */

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

@ -46,7 +46,8 @@
* otherwise the blocking error code would erase the true
* 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 rc;
@ -63,21 +64,28 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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) {
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;
}
if (sb) {
memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len);
memcpy(session->scpRecv_command, "scp -pf ",
sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
path_len);
} else {
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';
_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;
}
@ -85,18 +93,23 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
if (session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */
do {
session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT,
NULL, 0);
session->scpRecv_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
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);
session->scpRecv_command = NULL;
session->scpRecv_state = libssh2_NB_state_idle;
return NULL;
}
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
} else if (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
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) {
/* 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) {
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;
}
else if (rc) {
} else if (rc) {
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
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) {
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) {
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;
}
else if (rc != 1) {
} else if (rc != 1) {
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;
}
if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) {
if ((session->scpRecv_state == libssh2_NB_state_sent2)
|| (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb
&& (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) {
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) {
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;
}
else if (rc <= 0) {
} else if (rc <= 0) {
/* 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;
}
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
* 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_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1);
session->scpRecv_err_len =
libssh2_channel_packet_data_len(session->
scpRecv_channel, 0);
session->scpRecv_err_msg =
LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1);
if (!session->scpRecv_err_msg) {
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 */
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) {
/*
* 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);
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;
}
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;
goto scp_recv_error;
}
if ((session->scpRecv_response_len > 1) &&
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') ||
(session->scpRecv_response[session->scpRecv_response_len-1] > '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);
((session->
scpRecv_response[session->scpRecv_response_len - 1] <
'0')
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] >
'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;
}
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
if ((session->scpRecv_response_len < 9)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* 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;
}
/* Way too short to be an SCP response, or not done yet, short circuit */
@ -214,12 +265,21 @@ 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 */
while ((session->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';
while ((session->
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) {
/* 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;
}
@ -228,7 +288,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) {
/* 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;
}
@ -237,13 +299,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0;
session->scpRecv_mtime = strtol((char *) s, NULL, 10);
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;
}
s = (unsigned char *) strchr((char *) p, ' ');
if (!s || ((s - p) <= 0)) {
/* 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;
}
@ -252,7 +318,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) {
/* 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;
}
@ -261,7 +329,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0;
session->scpRecv_atime = strtol((char *) s, NULL, 10);
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;
}
@ -272,16 +342,20 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
}
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) {
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;
}
else if (rc != 1) {
} else if (rc != 1) {
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? */
break;
@ -297,42 +371,62 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
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) {
char *s, *p, *e = NULL;
if (session->scpRecv_state == libssh2_NB_state_sent5) {
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) {
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;
}
else if (rc <= 0) {
} else if (rc <= 0) {
/* 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;
}
session->scpRecv_response_len++;
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;
}
if ((session->scpRecv_response_len > 1) &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
(session->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);
(session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\r')
&& (session->
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;
}
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
if ((session->scpRecv_response_len < 7)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* 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;
}
/* Way too short to be an SCP response, or not done yet, short circuit */
@ -340,15 +434,22 @@ 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 */
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') ||
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) {
while ((session->
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';
session->scpRecv_response[session->scpRecv_response_len] =
'\0';
if (session->scpRecv_response_len < 6) {
/* 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;
}
@ -357,7 +458,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
p = strchr(s, ' ');
if (!p || ((p - s) <= 0)) {
/* 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;
}
@ -366,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0;
session->scpRecv_mode = strtol(s, &e, 8);
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;
}
s = strchr(p, ' ');
if (!s || ((s - p) <= 0)) {
/* 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);
goto scp_recv_error;
}
@ -383,7 +489,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0;
session->scpRecv_size = strtol(p, &e, 10);
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;
}
@ -394,15 +502,19 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
}
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) {
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;
}
else if (rc != 1) {
} else if (rc != 1) {
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? */
break;
@ -430,6 +542,7 @@ scp_recv_error:
session->scpRecv_state = libssh2_NB_state_idle;
return NULL;
}
/* }}} */
/* {{{ libssh2_scp_send_ex
@ -440,7 +553,8 @@ scp_recv_error:
* cause of the error.
*/
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);
unsigned const char *base;
@ -453,30 +567,39 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
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) {
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;
}
if (mtime || atime) {
memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len);
memcpy(session->scpSend_command, "scp -pt ",
sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
path_len);
} else {
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';
_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 */
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,
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
session->scpSend_channel =
libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it through */
@ -484,9 +607,10 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_idle;
return NULL;
}
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
} else if (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
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) {
/* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1,
(char *)session->scpSend_command, session->scpSend_command_len);
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpSend_command,
session->scpSend_command_len);
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;
}
else if (rc) {
} else if (rc) {
/* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command);
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;
}
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) {
/* 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) {
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;
}
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
goto scp_send_error;
}
if (mtime || atime) {
/* Send mtime and atime to be used for file */
session->scpSend_response_len = snprintf((char *)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_response_len =
snprintf((char *) 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;
@ -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 */
if (mtime || atime) {
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);
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;
}
else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0);
} else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file", 0);
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) {
/* 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) {
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;
}
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
goto scp_send_error;
}
@ -583,22 +720,27 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
base = (unsigned char *) path;
}
session->scpSend_response_len = snprintf((char *)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_response_len =
snprintf((char *) 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;
}
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);
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;
}
else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0);
} else if (rc != session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file", 0);
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) {
/* 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) {
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;
}
else if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
} else if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
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
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote", 0);
session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1);
session->scpSend_err_len =
libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg =
LIBSSH2_ALLOC(session, session->scpSend_err_len + 1);
if (!session->scpSend_err_msg) {
goto scp_send_error;
}
memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
/* 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) {
/*
* 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;
}
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;
goto scp_send_error;
}
@ -658,5 +807,5 @@ scp_send_error:
session->scpSend_state = libssh2_NB_state_idle;
return NULL;
}
/* }}} */
/* }}} */

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

@ -52,29 +52,35 @@
/* {{{ libssh2_default_alloc
*/
static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
static
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
{
(void) abstract;
return malloc(count);
}
/* }}} */
/* {{{ libssh2_default_free
*/
static LIBSSH2_FREE_FUNC(libssh2_default_free)
static
LIBSSH2_FREE_FUNC(libssh2_default_free)
{
(void) abstract;
free(ptr);
}
/* }}} */
/* {{{ libssh2_default_realloc
*/
static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
static
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
{
(void) abstract;
return realloc(ptr, count);
}
/* }}} */
/* {{{ libssh2_banner_receive
@ -82,7 +88,8 @@ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
* Allocate a buffer and store the banner in session->remote.banner
* Returns: 0 on success, PACKET_EAGAIN if read would block, 1 on failure
*/
static int libssh2_banner_receive(LIBSSH2_SESSION *session)
static int
libssh2_banner_receive(LIBSSH2_SESSION * session)
{
int ret;
int banner_len;
@ -96,10 +103,13 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
}
while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
((banner_len == 0) || (session->banner_TxRx_banner[banner_len-1] != '\n'))) {
((banner_len == 0)
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
char c = '\0';
ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
ret =
recv(session->socket_fd, &c, 1,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (ret < 0) {
#ifdef WIN32
@ -133,7 +143,8 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
}
}
if (ret <= 0) continue;
if (ret <= 0)
continue;
if (c == '\0') {
/* NULLs are not allowed in SSH banners */
@ -155,18 +166,22 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
session->banner_TxRx_state = libssh2_NB_state_idle;
session->banner_TxRx_total_send = 0;
if (!banner_len) return 1;
if (!banner_len)
return 1;
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
if (!session->remote.banner) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Error allocating space for remote banner", 0);
return 1;
}
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
session->remote.banner[banner_len] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner);
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s",
session->remote.banner);
return 0;
}
/* }}} */
/* {{{ libssh2_banner_send
@ -177,7 +192,8 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
* 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.
*/
static int libssh2_banner_send(LIBSSH2_SESSION *session)
static int
libssh2_banner_send(LIBSSH2_SESSION * session)
{
char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
@ -192,7 +208,6 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
banner_len = strlen((char *) session->local.banner);
banner = (char *) session->local.banner;
}
#ifdef LIBSSH2DEBUG
/* Hack and slash to avoid sending CRLF in debug output */
if (banner_len < 256) {
@ -203,13 +218,16 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
banner[255] = '\0';
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s",
banner_dup);
#endif
session->banner_TxRx_state = libssh2_NB_state_created;
}
ret = send(session->socket_fd, banner+session->banner_TxRx_total_send, banner_len-session->banner_TxRx_total_send,
ret =
send(session->socket_fd, banner + session->banner_TxRx_total_send,
banner_len - session->banner_TxRx_total_send,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret != (banner_len - session->banner_TxRx_total_send)) {
@ -229,6 +247,7 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
return 0;
}
/* }}} */
/*
@ -236,7 +255,8 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
* non-blocking mode based on the 'nonblock' boolean argument. This function
* is copied from the libcurl sources with permission.
*/
static int _libssh2_nonblock(int sockfd, /* operate on this */
static int
_libssh2_nonblock(int sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */ )
{
#undef SETBLOCK
@ -304,8 +324,9 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */
* _libssh2_get_socket_nonblocking() gets the given blocking or non-blocking
* state of the socket.
*/
static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
{
static int
_libssh2_get_socket_nonblocking(int sockfd)
{ /* operate on this */
#undef GETBLOCK
#define GETBLOCK 0
#ifdef HAVE_O_NONBLOCK
@ -326,7 +347,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
unsigned int option_value;
socklen_t option_len = sizeof(option_value);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&option_value, &option_len)) {
if (getsockopt
(sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
/* Assume blocking on error */
return 1;
}
@ -361,7 +383,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
/* {{{ libssh2_banner_set
* Set the local banner
*/
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
LIBSSH2_API int
libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
{
int banner_len = banner ? strlen(banner) : 0;
@ -376,19 +399,22 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
if (!session->local.banner) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for local banner", 0);
return -1;
}
memcpy(session->local.banner, banner, banner_len);
session->local.banner[banner_len] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s", session->local.banner);
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s",
session->local.banner);
session->local.banner[banner_len++] = '\r';
session->local.banner[banner_len++] = '\n';
session->local.banner[banner_len++] = '\0';
return 0;
}
/* }}} */
/* {{{ proto libssh2_session_init
@ -397,11 +423,10 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
* It's allowable (but unadvisable) to define some but not all of the malloc callbacks
* An additional pointer value may be optionally passed to be sent to the callbacks (so they know who's asking)
*/
LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
LIBSSH2_ALLOC_FUNC((*my_alloc)),
LIBSSH2_API LIBSSH2_SESSION *
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
LIBSSH2_FREE_FUNC((*my_free)),
LIBSSH2_REALLOC_FUNC((*my_realloc)),
void *abstract)
LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
{
LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
@ -425,11 +450,13 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
session->free = local_free;
session->realloc = local_realloc;
session->abstract = abstract;
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated");
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"New session resource allocated");
libssh2_crypto_init();
}
return session;
}
/* }}} */
/* {{{ libssh2_session_callback_set
@ -439,7 +466,8 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
* FIXME: this function relies on that we can typecast function pointers
* to void pointers, which isn't allowed in ISO C!
*/
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
LIBSSH2_API void *
libssh2_session_callback_set(LIBSSH2_SESSION * session,
int cbtype, void *callback)
{
void *oldcb;
@ -475,6 +503,7 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
return NULL;
}
/* }}} */
/* {{{ proto libssh2_session_startup
@ -484,7 +513,8 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
* callbacks in session
* socket *must* be populated with an opened and connected socket.
*/
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
LIBSSH2_API int
libssh2_session_startup(LIBSSH2_SESSION * session, int socket)
{
int rc;
@ -494,12 +524,14 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
/* FIXME: on some platforms (like win32) sockets are unsigned */
if (socket < 0) {
/* Did we forget something? */
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, "Bad socket provided", 0);
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
"Bad socket provided", 0);
return LIBSSH2_ERROR_SOCKET_NONE;
}
session->socket_fd = socket;
session->socket_block = !_libssh2_get_socket_nonblocking(session->socket_fd);
session->socket_block =
!_libssh2_get_socket_nonblocking(session->socket_fd);
if (session->socket_block) {
/*
* Since we can't be sure that we are in blocking or there
@ -517,12 +549,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
if (session->startup_state == libssh2_NB_state_created) {
rc = libssh2_banner_send(session);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending banner to remote host", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending banner to remote host", 0);
return LIBSSH2_ERROR_EAGAIN;
}
else if (rc) {
} else if (rc) {
/* Unable to send banner? */
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0);
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
"Error sending banner to remote host", 0);
return LIBSSH2_ERROR_BANNER_SEND;
}
@ -532,12 +565,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
if (session->startup_state == libssh2_NB_state_sent) {
rc = libssh2_banner_receive(session);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for banner", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for banner", 0);
return LIBSSH2_ERROR_EAGAIN;
}
else if (rc) {
} else if (rc) {
/* Unable to receive banner from remote */
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0);
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
"Timeout waiting for banner", 0);
return LIBSSH2_ERROR_BANNER_NONE;
}
@ -547,11 +581,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
if (session->startup_state == libssh2_NB_state_sent1) {
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block exchanging encryption keys", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block exchanging encryption keys", 0);
return LIBSSH2_ERROR_EAGAIN;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
"Unable to exchange encryption keys", 0);
return LIBSSH2_ERROR_KEX_FAILURE;
}
@ -559,24 +594,29 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
}
if (session->startup_state == libssh2_NB_state_sent2) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"Requesting userauth service");
/* Request the userauth service */
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1);
memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
libssh2_htonu32(session->startup_service + 1,
sizeof("ssh-userauth") - 1);
memcpy(session->startup_service + 5, "ssh-userauth",
sizeof("ssh-userauth") - 1);
session->startup_state = libssh2_NB_state_sent3;
}
if (session->startup_state == libssh2_NB_state_sent3) {
rc = libssh2_packet_write(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1);
rc = libssh2_packet_write(session, session->startup_service,
sizeof("ssh-userauth") + 5 - 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block asking for ssh-userauth service", 0);
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block asking for ssh-userauth service", 0);
return LIBSSH2_ERROR_EAGAIN;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to ask for ssh-userauth service", 0);
return LIBSSH2_ERROR_SOCKET_SEND;
}
@ -584,21 +624,25 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
}
if (session->startup_state == libssh2_NB_state_sent4) {
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT, &session->startup_data, &session->startup_data_len,
0, NULL, 0, &session->startup_req_state);
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT,
&session->startup_data,
&session->startup_data_len, 0, NULL, 0,
&session->startup_req_state);
if (rc == PACKET_EAGAIN) {
return LIBSSH2_ERROR_EAGAIN;
}
else if (rc) {
} else if (rc) {
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
session->startup_service_length = libssh2_ntohu32(session->startup_data + 1);
session->startup_service_length =
libssh2_ntohu32(session->startup_data + 1);
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) ||
strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) {
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1))
|| strncmp("ssh-userauth", (char *) session->startup_data + 5,
session->startup_service_length)) {
LIBSSH2_FREE(session, session->startup_data);
session->startup_data = NULL;
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0);
libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid response received from server", 0);
return LIBSSH2_ERROR_PROTO;
}
LIBSSH2_FREE(session, session->startup_data);
@ -612,18 +656,21 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
/* just for safety return some error */
return LIBSSH2_ERROR_INVAL;
}
/* }}} */
/* {{{ proto libssh2_session_free
* Frees the memory allocated to the session
* Also closes and frees any channels attached to this session
*/
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
LIBSSH2_API int
libssh2_session_free(LIBSSH2_SESSION * session)
{
int rc;
if (session->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner);
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
session->remote.banner);
session->state = libssh2_NB_state_created;
}
@ -673,11 +720,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
/* Client to Server */
/* crypt */
if (session->local.crypt && session->local.crypt->dtor) {
session->local.crypt->dtor(session, &session->local.crypt_abstract);
session->local.crypt->dtor(session,
&session->local.crypt_abstract);
}
/* comp */
if (session->local.comp && session->local.comp->dtor) {
session->local.comp->dtor(session, 1, &session->local.comp_abstract);
session->local.comp->dtor(session, 1,
&session->local.comp_abstract);
}
/* mac */
if (session->local.mac && session->local.mac->dtor) {
@ -687,11 +736,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
/* Server to Client */
/* crypt */
if (session->remote.crypt && session->remote.crypt->dtor) {
session->remote.crypt->dtor(session, &session->remote.crypt_abstract);
session->remote.crypt->dtor(session,
&session->remote.crypt_abstract);
}
/* comp */
if (session->remote.comp && session->remote.comp->dtor) {
session->remote.comp->dtor(session, 0, &session->remote.comp_abstract);
session->remote.comp->dtor(session, 0,
&session->remote.comp_abstract);
}
/* mac */
if (session->remote.mac && session->remote.mac->dtor) {
@ -840,18 +891,23 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
return 0;
}
/* }}} */
/* {{{ libssh2_session_disconnect_ex
*/
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang)
LIBSSH2_API int
libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
const char *description, const char *lang)
{
unsigned char *s;
unsigned long descr_len = 0, lang_len = 0;
int rc;
if (session->disconnect_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang);
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
description, lang);
if (description) {
descr_len = strlen(description);
}
@ -861,23 +917,29 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
/* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
session->disconnect_data_len = descr_len + lang_len + 13;
s = session->disconnect_data = LIBSSH2_ALLOC(session, session->disconnect_data_len);
s = session->disconnect_data =
LIBSSH2_ALLOC(session, session->disconnect_data_len);
if (!session->disconnect_data) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for disconnect packet",
0);
session->disconnect_state = libssh2_NB_state_idle;
return -1;
}
*(s++) = SSH_MSG_DISCONNECT;
libssh2_htonu32(s, reason); s += 4;
libssh2_htonu32(s, reason);
s += 4;
libssh2_htonu32(s, descr_len); s += 4;
libssh2_htonu32(s, descr_len);
s += 4;
if (description) {
memcpy(s, description, descr_len);
s += descr_len;
}
libssh2_htonu32(s, lang_len); s += 4;
libssh2_htonu32(s, lang_len);
s += 4;
if (lang) {
memcpy(s, lang, lang_len);
s += lang_len;
@ -886,7 +948,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
session->disconnect_state = libssh2_NB_state_created;
}
rc = libssh2_packet_write(session, session->disconnect_data, session->disconnect_data_len);
rc = libssh2_packet_write(session, session->disconnect_data,
session->disconnect_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
@ -897,6 +960,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
return 0;
}
/* }}} */
/* {{{ libssh2_session_methods
@ -904,7 +968,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
* NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string regardless of actual negotiation
* Strings should NOT be freed
*/
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type)
LIBSSH2_API const char *
libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
{
/* All methods have char *name as their first element */
const LIBSSH2_KEX_METHOD *method = NULL;
@ -951,27 +1016,32 @@ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int me
break;
default:
libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0);
libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid parameter specified for method_type", 0);
return NULL;
break;
}
if (!method) {
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No method negotiated", 0);
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
"No method negotiated", 0);
return NULL;
}
return method->name;
}
/* }}} */
/* {{{ libssh2_session_abstract
* Retrieve a pointer to the abstract property
*/
LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
LIBSSH2_API void **
libssh2_session_abstract(LIBSSH2_SESSION * session)
{
return &session->abstract;
}
/* }}} */
/* {{{ libssh2_session_last_error
@ -980,7 +1050,8 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
* Otherwise it is assumed to be owned by libssh2
*/
LIBSSH2_API int
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf)
libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
int *errmsg_len, int want_buf)
{
/* No error to report */
if (!session->err_code) {
@ -1001,8 +1072,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
}
if (errmsg) {
char *serrmsg = session->err_msg ? session->err_msg :
(char *)"";
char *serrmsg = session->err_msg ? session->err_msg : (char *) "";
int ownbuf = session->err_msg ? session->err_should_free : 0;
if (want_buf) {
@ -1029,6 +1099,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
return session->err_code;
}
/* }}} */
/* {{{ libssh2_session_last_error
@ -1039,13 +1110,15 @@ libssh2_session_last_errno(LIBSSH2_SESSION *session)
{
return session->err_code;
}
/* }}} */
/* {{{ libssh2_session_flag
* Set/Get session flags
* Passing flag==0 will avoid changing session->flags while still returning its current value
*/
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value)
LIBSSH2_API int
libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
{
if (value) {
session->flags |= flag;
@ -1055,16 +1128,19 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val
return session->flags;
}
/* }}} */
/* {{{ _libssh2_session_set_blocking
* Set a session's blocking mode on or off, return the previous status
* when this function is called.
*/
int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
int
_libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
{
int bl = session->socket_block;
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting blocking mode on session %d", blocking);
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Setting blocking mode on session %d", blocking);
if (blocking == session->socket_block) {
/* avoid if already correct */
return bl;
@ -1075,32 +1151,38 @@ int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
return bl;
}
/* }}} */
/* {{{ libssh2_session_set_blocking
* Set a channel's blocking mode on or off, similar to a socket's
* fcntl(fd, F_SETFL, O_NONBLOCK); type command
*/
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
LIBSSH2_API void
libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
{
(void) _libssh2_session_set_blocking(session, blocking);
}
/* }}} */
/* {{{ libssh2_session_get_blocking
* Returns a session's blocking mode on or off
*/
LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION *session)
LIBSSH2_API int
libssh2_session_get_blocking(LIBSSH2_SESSION * session)
{
return session->socket_block;
}
/* }}} */
/* {{{ libssh2_poll_channel_read
* Returns 0 if no data is waiting on channel,
* non-0 if data is available
*/
LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
LIBSSH2_API int
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
{
LIBSSH2_SESSION *session = channel->session;
LIBSSH2_PACKET *packet = session->packets.head;
@ -1108,8 +1190,9 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
while (packet) {
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) &&
(channel->local.id == libssh2_ntohu32(packet->data + 1))) ||
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (extended != 0) &&
(channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
&& (extended != 0)
&& (channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
/* Found data waiting to be read */
return 1;
}
@ -1118,32 +1201,38 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
return 0;
}
/* }}} */
/* {{{ libssh2_poll_channel_write
* Returns 0 if writing to channel would block,
* non-0 if data can be written without blocking
*/
static inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel)
static inline int
libssh2_poll_channel_write(LIBSSH2_CHANNEL * channel)
{
return channel->local.window_size ? 1 : 0;
}
/* }}} */
/* {{{ libssh2_poll_listener_queued
* Returns 0 if no connections are waiting to be accepted
* non-0 if one or more connections are available
*/
static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener)
static inline int
libssh2_poll_listener_queued(LIBSSH2_LISTENER * listener)
{
return listener->queue ? 1 : 0;
}
/* }}} */
/* {{{ libssh2_poll
* Poll sockets, channels, and listeners for activity
*/
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
LIBSSH2_API int
libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
{
long timeout_remaining;
unsigned int i, active_fds;
@ -1173,19 +1262,23 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
sockets[i].events = POLLIN;
sockets[i].revents = 0;
if (!session) session = fds[i].fd.channel->session;
if (!session)
session = fds[i].fd.channel->session;
break;
case LIBSSH2_POLLFD_LISTENER:
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
sockets[i].events = POLLIN;
sockets[i].revents = 0;
if (!session) session = fds[i].fd.listener->session;
if (!session)
session = fds[i].fd.listener->session;
break;
default:
if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
"Invalid descriptor passed to libssh2_poll()", 0);
if (session)
libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
"Invalid descriptor passed to libssh2_poll()",
0);
return -1;
}
}
@ -1217,14 +1310,16 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
if (fds[i].fd.channel->session->socket_fd > maxfd)
maxfd = fds[i].fd.channel->session->socket_fd;
if (!session) session = fds[i].fd.channel->session;
if (!session)
session = fds[i].fd.channel->session;
break;
case LIBSSH2_POLLFD_LISTENER:
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
if (fds[i].fd.listener->session->socket_fd > maxfd)
maxfd = fds[i].fd.listener->session->socket_fd;
if (!session) session = fds[i].fd.listener->session;
if (!session)
session = fds[i].fd.listener->session;
break;
default:
@ -1257,31 +1352,50 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
case LIBSSH2_POLLFD_CHANNEL:
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want to be ready for read */
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* Not yet known to be ready for read */
fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 0) ? LIBSSH2_POLLFD_POLLIN : 0;
fds[i].revents |=
libssh2_poll_channel_read(fds[i].fd.channel,
0) ?
LIBSSH2_POLLFD_POLLIN : 0;
}
if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && /* Want to be ready for extended read */
((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { /* Not yet known to be ready for extended read */
fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 1) ? LIBSSH2_POLLFD_POLLEXT : 0;
fds[i].revents |=
libssh2_poll_channel_read(fds[i].fd.channel,
1) ?
LIBSSH2_POLLFD_POLLEXT : 0;
}
if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && /* Want to be ready for write */
((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */
fds[i].revents |= libssh2_poll_channel_write(fds[i].fd.channel) ? LIBSSH2_POLLFD_POLLOUT : 0;
fds[i].revents |=
libssh2_poll_channel_write(fds[i].fd.
channel) ?
LIBSSH2_POLLFD_POLLOUT : 0;
}
if (fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) {
if (fds[i].fd.channel->remote.close
|| fds[i].fd.channel->local.close) {
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
}
if (fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
if (fds[i].fd.channel->session->socket_state ==
LIBSSH2_SOCKET_DISCONNECTED) {
fds[i].revents |=
LIBSSH2_POLLFD_CHANNEL_CLOSED |
LIBSSH2_POLLFD_SESSION_CLOSED;
}
break;
case LIBSSH2_POLLFD_LISTENER:
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */
fds[i].revents |= libssh2_poll_listener_queued(fds[i].fd.listener) ? LIBSSH2_POLLFD_POLLIN : 0;
fds[i].revents |=
libssh2_poll_listener_queued(fds[i].fd.
listener) ?
LIBSSH2_POLLFD_POLLIN : 0;
}
if (fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
if (fds[i].fd.listener->session->socket_state ==
LIBSSH2_SOCKET_DISCONNECTED) {
fds[i].revents |=
LIBSSH2_POLLFD_LISTENER_CLOSED |
LIBSSH2_POLLFD_SESSION_CLOSED;
}
break;
}
@ -1295,7 +1409,6 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
/* Don't block on the sockets if we have channels/listeners which are ready */
timeout_remaining = 0;
}
#ifdef HAVE_POLL
#ifdef HAVE_GETTIMEOFDAY
@ -1329,20 +1442,26 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
case LIBSSH2_POLLFD_CHANNEL:
if (sockets[i].events & POLLIN) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
while (libssh2_packet_read(fds[i].fd.channel->session)
> 0);
}
if (sockets[i].revents & POLLHUP) {
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
fds[i].revents |=
LIBSSH2_POLLFD_CHANNEL_CLOSED |
LIBSSH2_POLLFD_SESSION_CLOSED;
}
sockets[i].revents = 0;
break;
case LIBSSH2_POLLFD_LISTENER:
if (sockets[i].events & POLLIN) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
while (libssh2_packet_read(fds[i].fd.listener->session)
> 0);
}
if (sockets[i].revents & POLLHUP) {
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
fds[i].revents |=
LIBSSH2_POLLFD_LISTENER_CLOSED |
LIBSSH2_POLLFD_SESSION_CLOSED;
}
sockets[i].revents = 0;
break;
@ -1389,14 +1508,17 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
case LIBSSH2_POLLFD_CHANNEL:
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
while (libssh2_packet_read(fds[i].fd.channel->session)
> 0);
}
break;
case LIBSSH2_POLLFD_LISTENER:
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
if (FD_ISSET
(fds[i].fd.listener->session->socket_fd, &rfds)) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
while (libssh2_packet_read(fds[i].fd.listener->session)
> 0);
}
break;
}
@ -1407,5 +1529,5 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
return active_fds;
}
/* }}} */
/* }}} */

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

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

@ -48,9 +48,9 @@
#ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.'
static void debugdump(LIBSSH2_SESSION *session,
const char *desc, unsigned char *ptr,
unsigned long size)
static void
debugdump(LIBSSH2_SESSION * session,
const char *desc, unsigned char *ptr, unsigned long size)
{
size_t i;
size_t c;
@ -66,7 +66,7 @@ static void debugdump(LIBSSH2_SESSION *session,
for(i = 0; i < size; i += width) {
fprintf(stream, "%04lx: ", i);
fprintf(stream, "%04lx: ", (long)i);
/* hex not disabled, show it */
for(c = 0; c < width; c++) {
@ -95,7 +95,8 @@ static void debugdump(LIBSSH2_SESSION *session,
* returns PACKET_NONE on success and PACKET_FAIL on failure
*/
static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
static libssh2pack_t
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
unsigned char *dest, int len)
{
struct transportpacket *p = &session->packet;
@ -144,11 +145,11 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
if (encrypted) {
/* Calculate MAC hash */
session->remote.mac->hash(session,
macbuf, /* store hash here */
session->remote.mac->hash(session, macbuf, /* store hash here */
session->remote.seqno,
p->init, 5,
p->payload, session->fullpacket_payload_len,
p->payload,
session->fullpacket_payload_len,
&session->remote.mac_abstract);
/* 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;
/* Check for and deal with decompression */
if (session->remote.comp &&
strcmp(session->remote.comp->name, "none")) {
if (session->remote.comp && strcmp(session->remote.comp->name, "none")) {
unsigned char *data;
unsigned long data_len;
int free_payload = 1;
@ -178,7 +178,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
&data, &data_len,
LIBSSH2_PACKET_MAXDECOMP,
&free_payload,
p->payload, session->fullpacket_payload_len,
p->payload,
session->fullpacket_payload_len,
&session->remote.comp_abstract)) {
LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL;
@ -188,16 +189,14 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
LIBSSH2_FREE(session, p->payload);
p->payload = data;
session->fullpacket_payload_len = data_len;
}
else {
} else {
if (data == p->payload) {
/* It's not to be freed, because the
* compression layer reused payload, So let's
* do the same!
*/
session->fullpacket_payload_len = data_len;
}
else {
} else {
/* No comp_method actually lets this happen,
* 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 */
p->payload = LIBSSH2_ALLOC(session, data_len);
if (!p->payload) {
libssh2_error(session,
LIBSSH2_ERROR_ALLOC,
(char *)"Unable to allocate memory for copy of uncompressed data", 0);
libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
"Unable to allocate memory for copy of uncompressed data",
0);
return PACKET_ENOMEM;
}
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) {
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) {
return PACKET_EAGAIN;
}
else if (rc < 0) {
} else if (rc < 0) {
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
* "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;
struct transportpacket *p = &session->packet;
@ -324,7 +325,9 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
}
/* now read a big chunk from the network into the temp buffer */
nread = recv(session->socket_fd, &p->buf[remainbuf], PACKETBUFSIZE-remainbuf,
nread =
recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) {
/* check if this is due to EAGAIN and return
@ -382,7 +385,9 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* total_num is the number of bytes following the initial
(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:
*
@ -515,11 +520,14 @@ libssh2_packet_read_point1:
return PACKET_FAIL; /* we never reach this point */
}
/* }}} */
#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 length;
@ -545,15 +553,15 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
/* number of bytes left to send */
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) {
/* the remainder of the package was sent */
LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL;
p->ototal_num = 0;
}
else if (rc < 0) {
} else if (rc < 0) {
/* nothing was sent */
if (errno != EAGAIN) {
/* send failure! */
@ -562,7 +570,8 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
return PACKET_EAGAIN;
}
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length);
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
length);
p->osent += length; /* we sent away this much data */
return PACKET_NONE;
@ -577,9 +586,13 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
* 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.
*/
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 packet_length;
int total_length;
@ -608,7 +621,8 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
/* check if we should compress */
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->
comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
&free_data, data, data_len, &session->local.comp_abstract)) {
return PACKET_COMPRESS; /* compression failure */
}
@ -650,7 +664,8 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
packet_length += padding_length;
/* 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
send the whole one and thus need to keep it after this function
@ -678,14 +693,17 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
since that size includes the whole packet. The MAC is
calculated on the entire unencrypted packet, including all
fields except the MAC field itself. */
session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length,
NULL, 0, &session->local.mac_abstract);
session->local.mac->hash(session, p->outbuf + packet_length,
session->local.seqno, p->outbuf,
packet_length, NULL, 0,
&session->local.mac_abstract);
/* Encrypt the whole packet data, one block size at a time.
The MAC field is not encrypted. */
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
unsigned char *ptr = &p->outbuf[i];
if (session->local.crypt->crypt(session, ptr, &session->local.crypt_abstract))
if (session->local.crypt->
crypt(session, ptr, &session->local.crypt_abstract))
return PACKET_FAIL; /* encryption failure */
}
}

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