libssh2/src/libssh2_priv.h

1063 lines
36 KiB
C
Raw Normal View History

2010-03-19 09:14:21 +01:00
/* Copyright (c) 2004-2008, 2010, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2014 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
2004-12-07 21:17:20 +00:00
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef LIBSSH2_PRIV_H
#define LIBSSH2_PRIV_H 1
2005-01-01 23:38:34 +00:00
#define LIBSSH2_LIBRARY
2004-12-07 21:17:20 +00:00
#include "libssh2_config.h"
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
2008-11-20 10:29:01 +00:00
#include <stdio.h>
#include <time.h>
/* The following CPP block should really only be in session.c and
packet.c. However, AIX have #define's for 'events' and 'revents'
and we are using those names in libssh2.h, so we need to include
the AIX headers first, to make sure all code is compiled with
consistent names of these fields. While arguable the best would to
change libssh2.h to use other names, that would break backwards
compatibility. For more information, see:
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
*/
#ifdef HAVE_POLL
# include <sys/poll.h>
#else
# if defined(HAVE_SELECT) && !defined(WIN32)
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
# else
# include <sys/time.h>
# include <sys/types.h>
# endif
# endif
#endif
/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
2004-12-07 21:17:20 +00:00
#include "libssh2.h"
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"
#include "misc.h" /* for the linked list stuff */
2004-12-07 21:17:20 +00:00
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifdef _MSC_VER
/* "inline" keyword is valid only with C++ engine! */
#define inline __inline
#endif
/* Provide iovec / writev on WIN32 platform. */
#ifdef WIN32
struct iovec {
size_t iov_len;
void * iov_base;
};
static inline int writev(int sock, struct iovec *iov, int nvecs)
{
DWORD ret;
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
return ret;
}
return -1;
}
#endif /* WIN32 */
#include "crypto.h"
2004-12-07 21:17:20 +00:00
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
/* RFC4253 section 6.1 Maximum Packet Length says:
*
* "All implementations MUST be able to process packets with
* uncompressed payload length of 32768 bytes or less and
* total packet size of 35000 bytes or less (including length,
* padding length, payload, padding, and MAC.)."
*/
#define MAX_SSH_PACKET_LEN 35000
#define MAX_SHA_DIGEST_LEN SHA256_DIGEST_LENGTH
#define LIBSSH2_ALLOC(session, count) \
session->alloc((count), &(session)->abstract)
#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count)
#define LIBSSH2_REALLOC(session, ptr, count) \
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
session->alloc((count), &(session)->abstract))
#define LIBSSH2_FREE(session, ptr) \
session->free((ptr), &(session)->abstract)
#define LIBSSH2_IGNORE(session, data, datalen) \
session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_DEBUG(session, always_display, message, message_len, \
language, language_len) \
session->ssh_msg_debug((session), (always_display), (message), \
(message_len), (language), (language_len), \
&(session)->abstract)
2011-08-25 22:41:17 +02:00
#define LIBSSH2_DISCONNECT(session, reason, message, message_len, \
language, language_len) \
session->ssh_msg_disconnect((session), (reason), (message), \
(message_len), (language), (language_len), \
&(session)->abstract)
#define LIBSSH2_MACERROR(session, data, datalen) \
session->macerror((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_X11_OPEN(channel, shost, sport) \
channel->session->x11(((channel)->session), (channel), \
(shost), (sport), (&(channel)->session->abstract))
#define LIBSSH2_CHANNEL_CLOSE(session, channel) \
channel->close_cb((session), &(session)->abstract, \
(channel), &(channel)->abstract)
#define LIBSSH2_SEND_FD(session, fd, buffer, length, flags) \
session->send(fd, buffer, length, flags, &session->abstract)
#define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) \
session->recv(fd, buffer, length, flags, &session->abstract)
#define LIBSSH2_SEND(session, buffer, length, flags) \
LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags)
#define LIBSSH2_RECV(session, buffer, length, flags) \
LIBSSH2_RECV_FD(session, session->socket_fd, buffer, length, flags)
typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD;
typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD;
typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD;
2004-12-07 21:17:20 +00:00
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
2004-12-07 21:17:20 +00:00
typedef enum
{
libssh2_NB_state_idle = 0,
libssh2_NB_state_allocated,
libssh2_NB_state_created,
libssh2_NB_state_sent,
libssh2_NB_state_sent1,
libssh2_NB_state_sent2,
libssh2_NB_state_sent3,
libssh2_NB_state_sent4,
libssh2_NB_state_sent5,
libssh2_NB_state_sent6,
libssh2_NB_state_sent7,
libssh2_NB_state_jump1,
libssh2_NB_state_jump2,
libssh2_NB_state_jump3,
libssh2_NB_state_jump4,
libssh2_NB_state_jump5,
libssh2_NB_state_end
} libssh2_nonblocking_states;
typedef struct packet_require_state_t
{
libssh2_nonblocking_states state;
time_t start;
} packet_require_state_t;
typedef struct packet_requirev_state_t
{
time_t start;
} packet_requirev_state_t;
typedef struct kmdhgGPshakex_state_t
{
libssh2_nonblocking_states state;
unsigned char *e_packet;
unsigned char *s_packet;
unsigned char *tmp;
unsigned char h_sig_comp[MAX_SHA_DIGEST_LEN];
unsigned char c;
size_t e_packet_len;
size_t s_packet_len;
size_t tmp_len;
_libssh2_bn_ctx *ctx;
_libssh2_bn *x;
_libssh2_bn *e;
_libssh2_bn *f;
_libssh2_bn *k;
unsigned char *s;
unsigned char *f_value;
unsigned char *k_value;
unsigned char *h_sig;
size_t f_value_len;
size_t k_value_len;
size_t h_sig_len;
void *exchange_hash;
packet_require_state_t req_state;
libssh2_nonblocking_states burn_state;
} kmdhgGPshakex_state_t;
typedef struct key_exchange_state_low_t
{
libssh2_nonblocking_states state;
packet_require_state_t req_state;
kmdhgGPshakex_state_t exchange_state;
_libssh2_bn *p; /* SSH2 defined value (p_value) */
_libssh2_bn *g; /* SSH2 defined value (2) */
unsigned char request[13];
unsigned char *data;
size_t request_len;
size_t data_len;
} key_exchange_state_low_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;
unsigned char *data;
size_t data_len;
unsigned char *oldlocal;
size_t oldlocal_len;
} key_exchange_state_t;
#define FwdNotReq "Forward not requested"
typedef struct packet_queue_listener_state_t
{
libssh2_nonblocking_states state;
unsigned char packet[17 + (sizeof(FwdNotReq) - 1)];
unsigned char *host;
unsigned char *shost;
uint32_t sender_channel;
uint32_t initial_window_size;
uint32_t packet_size;
uint32_t port;
uint32_t sport;
uint32_t host_len;
uint32_t shost_len;
LIBSSH2_CHANNEL *channel;
} packet_queue_listener_state_t;
#define X11FwdUnAvil "X11 Forward Unavailable"
typedef struct packet_x11_open_state_t
{
libssh2_nonblocking_states state;
unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)];
unsigned char *shost;
uint32_t sender_channel;
uint32_t initial_window_size;
uint32_t packet_size;
uint32_t sport;
uint32_t shost_len;
LIBSSH2_CHANNEL *channel;
} packet_x11_open_state_t;
struct _LIBSSH2_PACKET
{
struct list_node node; /* linked list header */
/* the raw unencrypted payload */
unsigned char *data;
size_t data_len;
2004-12-07 21:17:20 +00:00
/* Where to start reading data from,
* used for channel data that's been partially consumed */
size_t data_head;
2004-12-07 21:17:20 +00:00
};
typedef struct _libssh2_channel_data
{
/* Identifier */
uint32_t id;
2004-12-07 21:17:20 +00:00
/* Limits and restrictions */
uint32_t window_size_initial, window_size, packet_size;
2004-12-07 21:17:20 +00:00
/* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */
char close, eof, extended_data_ignore_mode;
2004-12-07 21:17:20 +00:00
} libssh2_channel_data;
struct _LIBSSH2_CHANNEL
{
struct list_node node;
unsigned char *channel_type;
unsigned channel_type_len;
2004-12-07 21:17:20 +00:00
/* channel's program exit status */
int exit_status;
/* channel's program exit signal (without the SIG prefix) */
char *exit_signal;
libssh2_channel_data local, remote;
/* Amount of bytes to be refunded to receive window (but not yet sent) */
uint32_t adjust_queue;
/* Data immediately available for reading */
uint32_t read_avail;
2004-12-07 21:17:20 +00:00
LIBSSH2_SESSION *session;
2004-12-07 21:17:20 +00:00
void *abstract;
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
/* State variables used in libssh2_channel_setenv_ex() */
libssh2_nonblocking_states setenv_state;
unsigned char *setenv_packet;
size_t setenv_packet_len;
unsigned char setenv_local_channel[4];
packet_requirev_state_t setenv_packet_requirev_state;
/* State variables used in libssh2_channel_request_pty_ex()
libssh2_channel_request_pty_size_ex() */
libssh2_nonblocking_states reqPTY_state;
unsigned char reqPTY_packet[41 + 256];
size_t reqPTY_packet_len;
unsigned char reqPTY_local_channel[4];
packet_requirev_state_t reqPTY_packet_requirev_state;
/* State variables used in libssh2_channel_x11_req_ex() */
libssh2_nonblocking_states reqX11_state;
unsigned char *reqX11_packet;
size_t reqX11_packet_len;
unsigned char reqX11_local_channel[4];
packet_requirev_state_t reqX11_packet_requirev_state;
/* State variables used in libssh2_channel_process_startup() */
libssh2_nonblocking_states process_state;
unsigned char *process_packet;
size_t process_packet_len;
unsigned char process_local_channel[4];
packet_requirev_state_t process_packet_requirev_state;
/* State variables used in libssh2_channel_flush_ex() */
libssh2_nonblocking_states flush_state;
size_t flush_refund_bytes;
size_t flush_flush_bytes;
/* State variables used in libssh2_channel_receive_window_adjust() */
libssh2_nonblocking_states adjust_state;
unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
/* State variables used in libssh2_channel_read_ex() */
libssh2_nonblocking_states read_state;
uint32_t read_local_id;
/* State variables used in libssh2_channel_write_ex() */
libssh2_nonblocking_states write_state;
unsigned char write_packet[13];
size_t write_packet_len;
size_t write_bufwrite;
/* State variables used in libssh2_channel_close() */
libssh2_nonblocking_states close_state;
unsigned char close_packet[5];
/* State variables used in libssh2_channel_wait_closedeof() */
libssh2_nonblocking_states wait_eof_state;
/* State variables used in libssh2_channel_wait_closed() */
libssh2_nonblocking_states wait_closed_state;
/* State variables used in libssh2_channel_free() */
libssh2_nonblocking_states free_state;
/* State variables used in libssh2_channel_handle_extended_data2() */
libssh2_nonblocking_states extData2_state;
2004-12-07 21:17:20 +00:00
};
struct _LIBSSH2_LISTENER
{
struct list_node node; /* linked list header */
LIBSSH2_SESSION *session;
2004-12-29 19:26:28 +00:00
char *host;
int port;
2004-12-29 19:26:28 +00:00
/* a list of CHANNELs for this listener */
struct list_head queue;
int queue_size;
int queue_maxsize;
2004-12-29 19:26:28 +00:00
/* State variables used in libssh2_channel_forward_cancel() */
libssh2_nonblocking_states chanFwdCncl_state;
unsigned char *chanFwdCncl_data;
size_t chanFwdCncl_data_len;
2004-12-29 19:26:28 +00:00
};
typedef struct _libssh2_endpoint_data
{
unsigned char *banner;
2004-12-07 21:17:20 +00:00
unsigned char *kexinit;
size_t kexinit_len;
2004-12-07 21:17:20 +00:00
const LIBSSH2_CRYPT_METHOD *crypt;
void *crypt_abstract;
2004-12-07 21:17:20 +00:00
const struct _LIBSSH2_MAC_METHOD *mac;
uint32_t seqno;
void *mac_abstract;
2004-12-07 21:17:20 +00:00
const LIBSSH2_COMP_METHOD *comp;
void *comp_abstract;
2004-12-07 21:17:20 +00:00
/* Method Preferences -- NULL yields "load order" */
char *crypt_prefs;
char *mac_prefs;
char *comp_prefs;
char *lang_prefs;
2004-12-07 21:17:20 +00:00
} libssh2_endpoint_data;
#define PACKETBUFSIZE (1024*16)
struct transportpacket
{
/* ------------- for incoming data --------------- */
unsigned char buf[PACKETBUFSIZE];
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
still encrypted */
size_t writeidx; /* at what array index we do the next write into
the buffer */
size_t readidx; /* at what array index we do the next read from
the buffer */
uint32_t packet_length; /* the most recent packet_length as read from the
network data */
uint8_t padding_length; /* the most recent padding_length as read from the
network data */
size_t data_num; /* How much of the total package that has been read
so far. */
size_t total_num; /* How much a total package is supposed to be, in
number of bytes. A full package is
packet_length + padding_length + 4 +
mac_length. */
unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC()
area to which we write decrypted data */
unsigned char *wptr; /* write pointer into the payload to where we
are currently writing decrypted data */
/* ------------- for outgoing data --------------- */
unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* area for the outgoing data */
int ototal_num; /* size of outbuf in number of bytes */
const unsigned char *odata; /* original pointer to the data */
size_t olen; /* original size of the data we stored in
outbuf */
size_t osent; /* number of bytes already sent */
};
struct _LIBSSH2_PUBLICKEY
{
LIBSSH2_CHANNEL *channel;
uint32_t version;
/* State variables used in libssh2_publickey_packet_receive() */
libssh2_nonblocking_states receive_state;
unsigned char *receive_packet;
size_t receive_packet_len;
/* State variables used in libssh2_publickey_add_ex() */
libssh2_nonblocking_states add_state;
unsigned char *add_packet;
unsigned char *add_s;
/* State variables used in libssh2_publickey_remove_ex() */
libssh2_nonblocking_states remove_state;
unsigned char *remove_packet;
unsigned char *remove_s;
/* State variables used in libssh2_publickey_list_fetch() */
libssh2_nonblocking_states listFetch_state;
unsigned char *listFetch_s;
unsigned char listFetch_buffer[12];
unsigned char *listFetch_data;
size_t listFetch_data_len;
};
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
struct flags {
int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */
int compress; /* LIBSSH2_FLAG_COMPRESS */
};
struct _LIBSSH2_SESSION
{
/* Memory management callbacks */
void *abstract;
LIBSSH2_ALLOC_FUNC((*alloc));
LIBSSH2_REALLOC_FUNC((*realloc));
LIBSSH2_FREE_FUNC((*free));
/* Other callbacks */
LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore));
LIBSSH2_DEBUG_FUNC((*ssh_msg_debug));
LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
LIBSSH2_MACERROR_FUNC((*macerror));
LIBSSH2_X11_OPEN_FUNC((*x11));
LIBSSH2_SEND_FUNC((*send));
LIBSSH2_RECV_FUNC((*recv));
/* Method preferences -- NULL yields "load order" */
char *kex_prefs;
char *hostkey_prefs;
int state;
/* Flag options */
struct flags flag;
/* Agreed Key Exchange Method */
const LIBSSH2_KEX_METHOD *kex;
unsigned int burn_optimistic_kexinit:1;
unsigned char *session_id;
uint32_t session_id_len;
/* this is set to TRUE if a blocking API behavior is requested */
int api_block_mode;
/* Timeout used when blocking API behavior is active */
long api_timeout;
/* Server's public key */
const LIBSSH2_HOSTKEY_METHOD *hostkey;
void *server_hostkey_abstract;
/* Either set with libssh2_session_hostkey() (for server mode)
* Or read from server in (eg) KEXDH_INIT (for client mode)
*/
unsigned char *server_hostkey;
uint32_t server_hostkey_len;
#if LIBSSH2_MD5
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
int server_hostkey_md5_valid;
#endif /* ! LIBSSH2_MD5 */
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
int server_hostkey_sha1_valid;
2004-12-07 21:17:20 +00:00
/* (remote as source of data -- packet_read ) */
libssh2_endpoint_data remote;
2004-12-07 21:17:20 +00:00
/* (local as source of data -- packet_write ) */
libssh2_endpoint_data local;
2004-12-07 21:17:20 +00:00
/* Inbound Data linked list -- Sometimes the packet that comes in isn't the
packet we're ready for */
struct list_head packets;
2004-12-07 21:17:20 +00:00
/* Active connection channels */
struct list_head channels;
uint32_t next_channel;
2004-12-07 21:17:20 +00:00