mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 02:38:09 +09:00
Compare commits
31 Commits
release-0-
...
release-0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4d1d8b684 | ||
|
|
10e27f26be | ||
|
|
9791bc3eeb | ||
|
|
4ad7828797 | ||
|
|
af8315b9ce | ||
|
|
94fdcf7a2a | ||
|
|
59a95fc3a7 | ||
|
|
c1729c36d9 | ||
|
|
23efab0f8f | ||
|
|
e50752a925 | ||
|
|
fd45c1b36b | ||
|
|
5080671581 | ||
|
|
e67fafd60f | ||
|
|
a2a98fb5bc | ||
|
|
e2480fbaba | ||
|
|
23e6b36209 | ||
|
|
541b38b772 | ||
|
|
a85a4cc192 | ||
|
|
54ef77123a | ||
|
|
4c679fd8a6 | ||
|
|
21d918c68a | ||
|
|
544fc28e6b | ||
|
|
601081ebb6 | ||
|
|
22d975a24b | ||
|
|
aeb9f3e389 | ||
|
|
d3a4e01137 | ||
|
|
a1b9ae5048 | ||
|
|
a375ebe29b | ||
|
|
b2f49a6a93 | ||
|
|
99fb5987ce | ||
|
|
be389dd644 |
@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
|||||||
|
|
||||||
set(APPLICATION_VERSION_MAJOR "0")
|
set(APPLICATION_VERSION_MAJOR "0")
|
||||||
set(APPLICATION_VERSION_MINOR "4")
|
set(APPLICATION_VERSION_MINOR "4")
|
||||||
set(APPLICATION_VERSION_PATCH "4")
|
set(APPLICATION_VERSION_PATCH "5")
|
||||||
|
|
||||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINO
|
|||||||
# Increment AGE. Set REVISION to 0
|
# Increment AGE. Set REVISION to 0
|
||||||
# If the source code was changed, but there were no interface changes:
|
# If the source code was changed, but there were no interface changes:
|
||||||
# Increment REVISION.
|
# Increment REVISION.
|
||||||
set(LIBRARY_VERSION "4.1.1")
|
set(LIBRARY_VERSION "4.1.2")
|
||||||
set(LIBRARY_SOVERSION "4")
|
set(LIBRARY_SOVERSION "4")
|
||||||
|
|
||||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
|||||||
### versions
|
### versions
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "4")
|
set(CPACK_PACKAGE_VERSION_MINOR "4")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "4")
|
set(CPACK_PACKAGE_VERSION_PATCH "5")
|
||||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
version 0.4.5 (released 2010-07-13)
|
||||||
|
* Added option to bind a client to an ip address.
|
||||||
|
* Fixed the ssh socket polling function.
|
||||||
|
* Fixed Windows related bugs in bsd_poll().
|
||||||
|
* Fixed serveral build warnings.
|
||||||
|
|
||||||
version 0.4.4 (released 2010-06-01)
|
version 0.4.4 (released 2010-06-01)
|
||||||
* Fixed a bug in the expand function for escape sequences.
|
* Fixed a bug in the expand function for escape sequences.
|
||||||
* Fixed a bug in the tilde expand function.
|
* Fixed a bug in the tilde expand function.
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
/* libssh version */
|
/* libssh version */
|
||||||
#define LIBSSH_VERSION_MAJOR 0
|
#define LIBSSH_VERSION_MAJOR 0
|
||||||
#define LIBSSH_VERSION_MINOR 4
|
#define LIBSSH_VERSION_MINOR 4
|
||||||
#define LIBSSH_VERSION_MICRO 4
|
#define LIBSSH_VERSION_MICRO 5
|
||||||
|
|
||||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||||
LIBSSH_VERSION_MINOR, \
|
LIBSSH_VERSION_MINOR, \
|
||||||
@@ -119,10 +119,16 @@ typedef struct ssh_string_struct* ssh_string;
|
|||||||
|
|
||||||
/* Socket type */
|
/* Socket type */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define socket_t SOCKET
|
#ifndef socket_t
|
||||||
#else
|
typedef SOCKET socket_t;
|
||||||
|
#endif /* socket_t */
|
||||||
|
#else /* _WIN32 */
|
||||||
|
#ifndef socket_t
|
||||||
typedef int socket_t;
|
typedef int socket_t;
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#define SSH_INVALID_SOCKET ((socket_t) -1)
|
||||||
|
|
||||||
/* the offsets of methods */
|
/* the offsets of methods */
|
||||||
enum ssh_kex_types_e {
|
enum ssh_kex_types_e {
|
||||||
@@ -265,7 +271,8 @@ enum ssh_options_e {
|
|||||||
SSH_OPTIONS_CIPHERS_S_C,
|
SSH_OPTIONS_CIPHERS_S_C,
|
||||||
SSH_OPTIONS_COMPRESSION_C_S,
|
SSH_OPTIONS_COMPRESSION_C_S,
|
||||||
SSH_OPTIONS_COMPRESSION_S_C,
|
SSH_OPTIONS_COMPRESSION_S_C,
|
||||||
SSH_OPTIONS_PROXYCOMMAND
|
SSH_OPTIONS_PROXYCOMMAND,
|
||||||
|
SSH_OPTIONS_BINDADDR
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -38,6 +38,45 @@ typedef struct ssh_pollfd_struct {
|
|||||||
short revents; /* returned events */
|
short revents; /* returned events */
|
||||||
} ssh_pollfd_t;
|
} ssh_pollfd_t;
|
||||||
|
|
||||||
|
typedef unsigned long int nfds_t;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#ifndef POLLRDNORM
|
||||||
|
#define POLLRDNORM 0x0100
|
||||||
|
#endif
|
||||||
|
#ifndef POLLRDBAND
|
||||||
|
#define POLLRDBAND 0x0200
|
||||||
|
#endif
|
||||||
|
#ifndef POLLIN
|
||||||
|
#define POLLIN (POLLRDNORM | POLLRDBAND)
|
||||||
|
#endif
|
||||||
|
#ifndef POLLPRI
|
||||||
|
#define POLLPRI 0x0400
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef POLLWRNORM
|
||||||
|
#define POLLWRNORM 0x0010
|
||||||
|
#endif
|
||||||
|
#ifndef POLLOUT
|
||||||
|
#define POLLOUT (POLLWRNORM)
|
||||||
|
#endif
|
||||||
|
#ifndef POLLWRBAND
|
||||||
|
#define POLLWRBAND 0x0020
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef POLLERR
|
||||||
|
#define POLLERR 0x0001
|
||||||
|
#endif
|
||||||
|
#ifndef POLLHUP
|
||||||
|
#define POLLHUP 0x0002
|
||||||
|
#endif
|
||||||
|
#ifndef POLLNVAL
|
||||||
|
#define POLLNVAL 0x0004
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
/* poll.c */
|
/* poll.c */
|
||||||
#ifndef POLLIN
|
#ifndef POLLIN
|
||||||
#define POLLIN 0x001 /* There is data to read. */
|
#define POLLIN 0x001 /* There is data to read. */
|
||||||
@@ -72,8 +111,7 @@ typedef struct ssh_pollfd_struct {
|
|||||||
#define POLLWRBAND 0x200 /* mapped to write fds_set */
|
#define POLLWRBAND 0x200 /* mapped to write fds_set */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* WIN32 */
|
||||||
typedef unsigned long int nfds_t;
|
|
||||||
#endif /* HAVE_POLL */
|
#endif /* HAVE_POLL */
|
||||||
|
|
||||||
void ssh_poll_init(void);
|
void ssh_poll_init(void);
|
||||||
@@ -92,7 +130,7 @@ typedef struct ssh_poll_handle_struct *ssh_poll_handle;
|
|||||||
* @return 0 on success, < 0 if you removed the poll object from
|
* @return 0 on success, < 0 if you removed the poll object from
|
||||||
* it's poll context.
|
* it's poll context.
|
||||||
*/
|
*/
|
||||||
typedef int (*ssh_poll_callback)(ssh_poll_handle p, int fd, int revents,
|
typedef int (*ssh_poll_callback)(ssh_poll_handle p, socket_t fd, int revents,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ struct ssh_session_struct {
|
|||||||
#endif
|
#endif
|
||||||
char *username;
|
char *username;
|
||||||
char *host;
|
char *host;
|
||||||
char *bindaddr; /* TODO: check if needed */
|
char *bindaddr; /* bind the client to an ip addr */
|
||||||
char *xbanner; /* TODO: looks like it is not needed */
|
char *xbanner; /* TODO: looks like it is not needed */
|
||||||
struct ssh_list *identity;
|
struct ssh_list *identity;
|
||||||
char *sshdir;
|
char *sshdir;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ int ssh_socket_read(struct socket *s, void *buffer, int len);
|
|||||||
int ssh_socket_write(struct socket *s,const void *buffer, int len);
|
int ssh_socket_write(struct socket *s,const void *buffer, int len);
|
||||||
int ssh_socket_is_open(struct socket *s);
|
int ssh_socket_is_open(struct socket *s);
|
||||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set);
|
int ssh_socket_fd_isset(struct socket *s, fd_set *set);
|
||||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max);
|
void ssh_socket_fd_set(struct socket *s, fd_set *set, socket_t *max_fd);
|
||||||
int ssh_socket_completeread(struct socket *s, void *buffer, uint32_t len);
|
int ssh_socket_completeread(struct socket *s, void *buffer, uint32_t len);
|
||||||
int ssh_socket_completewrite(struct socket *s, const void *buffer, uint32_t len);
|
int ssh_socket_completewrite(struct socket *s, const void *buffer, uint32_t len);
|
||||||
int ssh_socket_wait_for_data(struct socket *s, ssh_session session, uint32_t len);
|
int ssh_socket_wait_for_data(struct socket *s, ssh_session session, uint32_t len);
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <poll.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -54,6 +53,7 @@
|
|||||||
#include "libssh/buffer.h"
|
#include "libssh/buffer.h"
|
||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/keys.h"
|
#include "libssh/keys.h"
|
||||||
|
#include "libssh/poll.h"
|
||||||
|
|
||||||
/* macro to check for "agent failure" message */
|
/* macro to check for "agent failure" message */
|
||||||
#define agent_failed(x) \
|
#define agent_failed(x) \
|
||||||
@@ -85,8 +85,8 @@ static size_t atomicio(struct socket *s, void *buf, size_t n, int do_read) {
|
|||||||
char *b = buf;
|
char *b = buf;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
struct pollfd pfd;
|
ssh_pollfd_t pfd;
|
||||||
int fd = ssh_socket_get_fd(s);
|
socket_t fd = ssh_socket_get_fd(s);
|
||||||
|
|
||||||
pfd.fd = fd;
|
pfd.fd = fd;
|
||||||
pfd.events = do_read ? POLLIN : POLLOUT;
|
pfd.events = do_read ? POLLIN : POLLOUT;
|
||||||
@@ -107,7 +107,7 @@ static size_t atomicio(struct socket *s, void *buf, size_t n, int do_read) {
|
|||||||
#else
|
#else
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
#endif
|
#endif
|
||||||
(void) poll(&pfd, 1, -1);
|
(void) ssh_poll(&pfd, 1, -1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -2160,7 +2160,7 @@ int channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
fd_set rset;
|
fd_set rset;
|
||||||
fd_set wset;
|
fd_set wset;
|
||||||
fd_set eset;
|
fd_set eset;
|
||||||
int fdmax = -1;
|
socket_t max_fd = SSH_INVALID_SOCKET;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -2228,24 +2228,24 @@ int channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
|||||||
|
|
||||||
for (i = 0; readchans[i] != NULL; i++) {
|
for (i = 0; readchans[i] != NULL; i++) {
|
||||||
if (!ssh_socket_fd_isset(readchans[i]->session->socket, &rset)) {
|
if (!ssh_socket_fd_isset(readchans[i]->session->socket, &rset)) {
|
||||||
ssh_socket_fd_set(readchans[i]->session->socket, &rset, &fdmax);
|
ssh_socket_fd_set(readchans[i]->session->socket, &rset, &max_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; writechans[i] != NULL; i++) {
|
for (i = 0; writechans[i] != NULL; i++) {
|
||||||
if (!ssh_socket_fd_isset(writechans[i]->session->socket, &wset)) {
|
if (!ssh_socket_fd_isset(writechans[i]->session->socket, &wset)) {
|
||||||
ssh_socket_fd_set(writechans[i]->session->socket, &wset, &fdmax);
|
ssh_socket_fd_set(writechans[i]->session->socket, &wset, &max_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; exceptchans[i] != NULL; i++) {
|
for (i = 0; exceptchans[i] != NULL; i++) {
|
||||||
if (!ssh_socket_fd_isset(exceptchans[i]->session->socket, &eset)) {
|
if (!ssh_socket_fd_isset(exceptchans[i]->session->socket, &eset)) {
|
||||||
ssh_socket_fd_set(exceptchans[i]->session->socket, &eset, &fdmax);
|
ssh_socket_fd_set(exceptchans[i]->session->socket, &eset, &max_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Here we go */
|
/* Here we go */
|
||||||
rc = select(fdmax, &rset, &wset, &eset, timeout);
|
rc = select(max_fd, &rset, &wset, &eset, timeout);
|
||||||
/* Leave if select was interrupted */
|
/* Leave if select was interrupted */
|
||||||
if (rc == EINTR) {
|
if (rc == EINTR) {
|
||||||
SAFE_FREE(rchans);
|
SAFE_FREE(rchans);
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ int ssh_service_request(ssh_session session, const char *service) {
|
|||||||
int ssh_connect(ssh_session session) {
|
int ssh_connect(ssh_session session) {
|
||||||
int ssh1 = 0;
|
int ssh1 = 0;
|
||||||
int ssh2 = 0;
|
int ssh2 = 0;
|
||||||
int fd = -1;
|
socket_t fd = SSH_INVALID_SOCKET;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
@@ -498,7 +498,7 @@ int ssh_connect(ssh_session session) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if (session->fd == -1 && session->host == NULL &&
|
if (session->fd == SSH_INVALID_SOCKET && session->host == NULL &&
|
||||||
session->ProxyCommand == NULL) {
|
session->ProxyCommand == NULL) {
|
||||||
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
||||||
leave_function();
|
leave_function();
|
||||||
@@ -512,7 +512,7 @@ int ssh_connect(ssh_session session) {
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->fd != -1) {
|
if (session->fd != SSH_INVALID_SOCKET) {
|
||||||
fd = session->fd;
|
fd = session->fd;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
} else if (session->ProxyCommand != NULL) {
|
} else if (session->ProxyCommand != NULL) {
|
||||||
@@ -522,7 +522,7 @@ int ssh_connect(ssh_session session) {
|
|||||||
fd = ssh_connect_host(session, session->host, session->bindaddr,
|
fd = ssh_connect_host(session, session->host, session->bindaddr,
|
||||||
session->port, session->timeout, session->timeout_usec);
|
session->port, session->timeout, session->timeout_usec);
|
||||||
}
|
}
|
||||||
if (fd < 0) {
|
if (fd == SSH_INVALID_SOCKET) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,10 +283,12 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SOC_UNSUPPORTED:
|
case SOC_UNSUPPORTED:
|
||||||
fprintf(stderr, "Unsupported option: %s, line: %d\n", keyword, count);
|
ssh_log(session, SSH_LOG_RARE, "Unsupported option: %s, line: %d\n",
|
||||||
|
keyword, count);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "ERROR - unimplemented opcode: %d\n", opcode);
|
ssh_set_error(session, SSH_FATAL, "ERROR - unimplemented opcode: %d\n",
|
||||||
|
opcode);
|
||||||
SAFE_FREE(x);
|
SAFE_FREE(x);
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
|||||||
fd_set *readfds, struct timeval *timeout) {
|
fd_set *readfds, struct timeval *timeout) {
|
||||||
struct timeval zerotime;
|
struct timeval zerotime;
|
||||||
fd_set localset, localset2;
|
fd_set localset, localset2;
|
||||||
|
socket_t f;
|
||||||
int rep;
|
int rep;
|
||||||
int set;
|
int set;
|
||||||
int i;
|
int i;
|
||||||
@@ -430,8 +431,8 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
|||||||
|
|
||||||
/* Look into the localset for active fd */
|
/* Look into the localset for active fd */
|
||||||
set = 0;
|
set = 0;
|
||||||
for (i = 0; (i < maxfd) && !set; i++) {
|
for (f = 0; (f < maxfd) && !set; f++) {
|
||||||
if (FD_ISSET(i, &localset)) {
|
if (FD_ISSET(f, &localset)) {
|
||||||
set = 1;
|
set = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,9 +494,9 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
|||||||
outchannels[j] = NULL;
|
outchannels[j] = NULL;
|
||||||
|
|
||||||
FD_ZERO(&localset2);
|
FD_ZERO(&localset2);
|
||||||
for (i = 0; i < maxfd; i++) {
|
for (f = 0; f < maxfd; f++) {
|
||||||
if (FD_ISSET(i, readfds) && FD_ISSET(i, &localset)) {
|
if (FD_ISSET(f, readfds) && FD_ISSET(i, &localset)) {
|
||||||
FD_SET(i, &localset2);
|
FD_SET(f, &localset2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -187,6 +187,9 @@ int ssh_options_set_algo(ssh_session session, int algo,
|
|||||||
* set the hostname as the hostname is used as a key in
|
* set the hostname as the hostname is used as a key in
|
||||||
* the known_host mechanism.
|
* the known_host mechanism.
|
||||||
*
|
*
|
||||||
|
* - SSH_OPTIONS_BINDADDR:
|
||||||
|
* The address to bind the client to (string).
|
||||||
|
*
|
||||||
* - SSH_OPTIONS_USER:
|
* - SSH_OPTIONS_USER:
|
||||||
* The username for authentication (string).\n
|
* The username for authentication (string).\n
|
||||||
* \n
|
* \n
|
||||||
@@ -397,6 +400,18 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
session->fd = *x & 0xffff;
|
session->fd = *x & 0xffff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SSH_OPTIONS_BINDADDR:
|
||||||
|
if (value == NULL) {
|
||||||
|
ssh_set_error_invalid(session, __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
q = strdup(value);
|
||||||
|
if (q == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SAFE_FREE(session->bindaddr);
|
||||||
|
session->bindaddr = q;
|
||||||
|
break;
|
||||||
case SSH_OPTIONS_USER:
|
case SSH_OPTIONS_USER:
|
||||||
SAFE_FREE(session->username);
|
SAFE_FREE(session->username);
|
||||||
if (value == NULL) { /* set default username */
|
if (value == NULL) { /* set default username */
|
||||||
|
|||||||
@@ -71,28 +71,38 @@ int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
typedef int (*poll_fn)(ssh_pollfd_t *, nfds_t, int);
|
||||||
|
static poll_fn win_poll;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef STRICT
|
#ifndef STRICT
|
||||||
#define STRICT
|
#define STRICT
|
||||||
#endif
|
#endif /* STRICT */
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
|
||||||
#define WS2_LIBRARY "ws2_32.dll"
|
#define WS2_LIBRARY "ws2_32.dll"
|
||||||
typedef int (*poll_fn)(ssh_pollfd_t *, nfds_t, int);
|
|
||||||
|
|
||||||
static poll_fn win_poll;
|
|
||||||
static HINSTANCE hlib;
|
static HINSTANCE hlib;
|
||||||
|
|
||||||
#else
|
#else /* _WIN32 */
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a poll(2)-emulation using select for systems not providing a native
|
||||||
|
* poll implementation.
|
||||||
|
*
|
||||||
|
* Keep in mind that select is terribly inefficient. The interface is simply not
|
||||||
|
* meant to be used with maximum descriptor value greater, say, 32 or so. With
|
||||||
|
* a value as high as 1024 on Linux you'll pay dearly in every single call.
|
||||||
|
* poll() will be orders of magnitude faster.
|
||||||
|
*/
|
||||||
static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||||
fd_set readfds, writefds, exceptfds;
|
fd_set readfds, writefds, exceptfds;
|
||||||
struct timeval tv, *ptv;
|
struct timeval tv, *ptv;
|
||||||
@@ -110,10 +120,16 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
|||||||
FD_ZERO (&exceptfds);
|
FD_ZERO (&exceptfds);
|
||||||
|
|
||||||
/* compute fd_sets and find largest descriptor */
|
/* compute fd_sets and find largest descriptor */
|
||||||
for (max_fd = -1, i = 0; i < nfds; i++) {
|
for (rc = -1, max_fd = 0, i = 0; i < nfds; i++) {
|
||||||
if (fds[i].fd < 0) {
|
if (fds[i].fd == SSH_INVALID_SOCKET) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32
|
||||||
|
if (fds[i].fd >= FD_SETSIZE) {
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fds[i].events & (POLLIN | POLLRDNORM)) {
|
if (fds[i].events & (POLLIN | POLLRDNORM)) {
|
||||||
FD_SET (fds[i].fd, &readfds);
|
FD_SET (fds[i].fd, &readfds);
|
||||||
@@ -124,15 +140,16 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
|||||||
if (fds[i].events & (POLLPRI | POLLRDBAND)) {
|
if (fds[i].events & (POLLPRI | POLLRDBAND)) {
|
||||||
FD_SET (fds[i].fd, &exceptfds);
|
FD_SET (fds[i].fd, &exceptfds);
|
||||||
}
|
}
|
||||||
if (fds[i].fd >= max_fd &&
|
if (fds[i].fd > max_fd &&
|
||||||
(fds[i].events & (POLLIN | POLLOUT | POLLPRI |
|
(fds[i].events & (POLLIN | POLLOUT | POLLPRI |
|
||||||
POLLRDNORM | POLLRDBAND |
|
POLLRDNORM | POLLRDBAND |
|
||||||
POLLWRNORM | POLLWRBAND))) {
|
POLLWRNORM | POLLWRBAND))) {
|
||||||
max_fd = fds[i].fd;
|
max_fd = fds[i].fd;
|
||||||
|
rc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_fd == -1) {
|
if (max_fd == SSH_INVALID_SOCKET || rc == -1) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -162,14 +179,16 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
|||||||
if (FD_ISSET(fds[i].fd, &readfds)) {
|
if (FD_ISSET(fds[i].fd, &readfds)) {
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
char data[64] = {0};
|
char data[64] = {0};
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* support for POLLHUP */
|
/* support for POLLHUP */
|
||||||
|
ret = recv(fds[i].fd, data, 64, MSG_PEEK);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if ((recv(fds[i].fd, data, 64, MSG_PEEK) == -1) &&
|
if ((ret == -1) &&
|
||||||
(errno == WSAESHUTDOWN || errno == WSAECONNRESET ||
|
(errno == WSAESHUTDOWN || errno == WSAECONNRESET ||
|
||||||
errno == WSAECONNABORTED || errno == WSAENETRESET)) {
|
errno == WSAECONNABORTED || errno == WSAENETRESET)) {
|
||||||
#else
|
#else
|
||||||
if ((recv(fds[i].fd, data, 64, MSG_PEEK) == -1) &&
|
if ((ret == -1) &&
|
||||||
(errno == ESHUTDOWN || errno == ECONNRESET ||
|
(errno == ESHUTDOWN || errno == ECONNRESET ||
|
||||||
errno == ECONNABORTED || errno == ENETRESET)) {
|
errno == ECONNABORTED || errno == ENETRESET)) {
|
||||||
#endif
|
#endif
|
||||||
@@ -201,10 +220,12 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
|||||||
void ssh_poll_init(void) {
|
void ssh_poll_init(void) {
|
||||||
poll_fn wsa_poll = NULL;
|
poll_fn wsa_poll = NULL;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
hlib = LoadLibrary(WS2_LIBRARY);
|
hlib = LoadLibrary(WS2_LIBRARY);
|
||||||
if (hlib != NULL) {
|
if (hlib != NULL) {
|
||||||
wsa_poll = (poll_fn) GetProcAddress(hlib, "WSAPoll");
|
wsa_poll = (poll_fn) GetProcAddress(hlib, "WSAPoll");
|
||||||
}
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
if (wsa_poll == NULL) {
|
if (wsa_poll == NULL) {
|
||||||
win_poll = bsd_poll;
|
win_poll = bsd_poll;
|
||||||
@@ -389,7 +410,7 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx) {
|
|||||||
used = ctx->polls_used;
|
used = ctx->polls_used;
|
||||||
for (i = 0; i < used; ) {
|
for (i = 0; i < used; ) {
|
||||||
ssh_poll_handle p = ctx->pollptrs[i];
|
ssh_poll_handle p = ctx->pollptrs[i];
|
||||||
int fd = ctx->pollfds[i].fd;
|
socket_t fd = ctx->pollfds[i].fd;
|
||||||
|
|
||||||
/* force poll object removal */
|
/* force poll object removal */
|
||||||
if (p->cb(p, fd, POLLERR, p->cb_data) < 0) {
|
if (p->cb(p, fd, POLLERR, p->cb_data) < 0) {
|
||||||
@@ -437,7 +458,7 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size) {
|
|||||||
* @return 0 on success, < 0 on error
|
* @return 0 on success, < 0 on error
|
||||||
*/
|
*/
|
||||||
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p) {
|
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p) {
|
||||||
int fd;
|
socket_t fd;
|
||||||
|
|
||||||
if (p->ctx != NULL) {
|
if (p->ctx != NULL) {
|
||||||
/* already attached to a context */
|
/* already attached to a context */
|
||||||
@@ -516,7 +537,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) {
|
|||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
ssh_poll_handle p = ctx->pollptrs[i];
|
ssh_poll_handle p = ctx->pollptrs[i];
|
||||||
int fd = ctx->pollfds[i].fd;
|
socket_t fd = ctx->pollfds[i].fd;
|
||||||
int revents = ctx->pollfds[i].revents;
|
int revents = ctx->pollfds[i].revents;
|
||||||
|
|
||||||
if (p->cb(p, fd, revents, p->cb_data) < 0) {
|
if (p->cb(p, fd, revents, p->cb_data) < 0) {
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ ssh_bind ssh_bind_new(void) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ZERO_STRUCTP(ptr);
|
ZERO_STRUCTP(ptr);
|
||||||
ptr->bindfd = -1;
|
ptr->bindfd = SSH_INVALID_SOCKET;
|
||||||
ptr->bindport= 22;
|
ptr->bindport= 22;
|
||||||
ptr->log_verbosity = 0;
|
ptr->log_verbosity = 0;
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ ssh_bind ssh_bind_new(void) {
|
|||||||
|
|
||||||
int ssh_bind_listen(ssh_bind sshbind) {
|
int ssh_bind_listen(ssh_bind sshbind) {
|
||||||
const char *host;
|
const char *host;
|
||||||
int fd;
|
socket_t fd;
|
||||||
|
|
||||||
if (ssh_init() < 0) {
|
if (ssh_init() < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -185,10 +185,10 @@ void ssh_bind_fd_toaccept(ssh_bind sshbind) {
|
|||||||
int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
||||||
ssh_private_key dsa = NULL;
|
ssh_private_key dsa = NULL;
|
||||||
ssh_private_key rsa = NULL;
|
ssh_private_key rsa = NULL;
|
||||||
int fd = -1;
|
socket_t fd = SSH_INVALID_SOCKET;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (sshbind->bindfd < 0) {
|
if (sshbind->bindfd == SSH_INVALID_SOCKET) {
|
||||||
ssh_set_error(sshbind, SSH_FATAL,
|
ssh_set_error(sshbind, SSH_FATAL,
|
||||||
"Can't accept new clients on a not bound socket.");
|
"Can't accept new clients on a not bound socket.");
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@@ -219,7 +219,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fd = accept(sshbind->bindfd, NULL, NULL);
|
fd = accept(sshbind->bindfd, NULL, NULL);
|
||||||
if (fd < 0) {
|
if (fd == SSH_INVALID_SOCKET) {
|
||||||
ssh_set_error(sshbind, SSH_FATAL,
|
ssh_set_error(sshbind, SSH_FATAL,
|
||||||
"Accepting a new connection: %s",
|
"Accepting a new connection: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -284,7 +284,7 @@ void ssh_bind_free(ssh_bind sshbind){
|
|||||||
close(sshbind->bindfd);
|
close(sshbind->bindfd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
sshbind->bindfd = -1;
|
sshbind->bindfd = SSH_INVALID_SOCKET;
|
||||||
|
|
||||||
/* options */
|
/* options */
|
||||||
SAFE_FREE(sshbind->banner);
|
SAFE_FREE(sshbind->banner);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
extern const char **environ;
|
extern char **environ;
|
||||||
#endif
|
#endif
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/socket.h"
|
#include "libssh/socket.h"
|
||||||
@@ -72,8 +72,9 @@ int ssh_socket_init(void) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_poll_init();
|
|
||||||
#endif
|
#endif
|
||||||
|
ssh_poll_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -87,7 +88,7 @@ struct socket *ssh_socket_new(ssh_session session) {
|
|||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
s->fd = -1;
|
s->fd = SSH_INVALID_SOCKET;
|
||||||
s->last_errno = -1;
|
s->last_errno = -1;
|
||||||
s->session = session;
|
s->session = session;
|
||||||
s->in_buffer = buffer_new();
|
s->in_buffer = buffer_new();
|
||||||
@@ -129,20 +130,20 @@ int ssh_socket_unix(struct socket *s, const char *path) {
|
|||||||
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", path);
|
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", path);
|
||||||
|
|
||||||
s->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
s->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (s->fd < 0) {
|
if (s->fd == SSH_INVALID_SOCKET) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcntl(s->fd, F_SETFD, 1) == -1) {
|
if (fcntl(s->fd, F_SETFD, 1) == -1) {
|
||||||
close(s->fd);
|
close(s->fd);
|
||||||
s->fd = -1;
|
s->fd = SSH_INVALID_SOCKET;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect(s->fd, (struct sockaddr *) &sunaddr,
|
if (connect(s->fd, (struct sockaddr *) &sunaddr,
|
||||||
sizeof(sunaddr)) < 0) {
|
sizeof(sunaddr)) < 0) {
|
||||||
close(s->fd);
|
close(s->fd);
|
||||||
s->fd = -1;
|
s->fd = SSH_INVALID_SOCKET;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ void ssh_socket_close(struct socket *s){
|
|||||||
close(s->fd);
|
close(s->fd);
|
||||||
s->last_errno = errno;
|
s->last_errno = errno;
|
||||||
#endif
|
#endif
|
||||||
s->fd=-1;
|
s->fd = SSH_INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ socket_t ssh_socket_get_fd(struct socket *s) {
|
|||||||
* \brief returns nonzero if the socket is open
|
* \brief returns nonzero if the socket is open
|
||||||
*/
|
*/
|
||||||
int ssh_socket_is_open(struct socket *s) {
|
int ssh_socket_is_open(struct socket *s) {
|
||||||
return s->fd != -1;
|
return s->fd != SSH_INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* \internal
|
/* \internal
|
||||||
@@ -242,22 +243,22 @@ static int ssh_socket_unbuffered_write(struct socket *s, const void *buffer,
|
|||||||
* \brief returns nonzero if the current socket is in the fd_set
|
* \brief returns nonzero if the current socket is in the fd_set
|
||||||
*/
|
*/
|
||||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set) {
|
int ssh_socket_fd_isset(struct socket *s, fd_set *set) {
|
||||||
if(s->fd == -1) {
|
if(s->fd == SSH_INVALID_SOCKET) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return FD_ISSET(s->fd,set);
|
return FD_ISSET(s->fd,set);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* \internal
|
/* \internal
|
||||||
* \brief sets the current fd in a fd_set and updates the fd_max
|
* \brief sets the current fd in a fd_set and updates the max_fd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max) {
|
void ssh_socket_fd_set(struct socket *s, fd_set *set, socket_t *max_fd) {
|
||||||
if (s->fd == -1)
|
if (s->fd == SSH_INVALID_SOCKET)
|
||||||
return;
|
return;
|
||||||
FD_SET(s->fd,set);
|
FD_SET(s->fd,set);
|
||||||
if (s->fd >= *fd_max) {
|
if (s->fd >= 0 && s->fd != SSH_INVALID_SOCKET) {
|
||||||
*fd_max = s->fd + 1;
|
*max_fd = s->fd + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +441,7 @@ int ssh_socket_wait_for_data(struct socket *s, ssh_session session, uint32_t len
|
|||||||
if (ssh_socket_is_open(session->socket)) {
|
if (ssh_socket_is_open(session->socket)) {
|
||||||
r = ssh_socket_unbuffered_read(session->socket, buffer, sizeof(buffer));
|
r = ssh_socket_unbuffered_read(session->socket, buffer, sizeof(buffer));
|
||||||
} else {
|
} else {
|
||||||
r =- 1;
|
r = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
@@ -487,7 +488,8 @@ int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
|||||||
if (!s->data_to_write) {
|
if (!s->data_to_write) {
|
||||||
fd->events |= POLLOUT;
|
fd->events |= POLLOUT;
|
||||||
}
|
}
|
||||||
|
/* do not do poll if fd->events is empty, we already know the response */
|
||||||
|
if(fd->events != 0){
|
||||||
/* Make the call, and listen for errors */
|
/* Make the call, and listen for errors */
|
||||||
rc = ssh_poll(fd, 1, 0);
|
rc = ssh_poll(fd, 1, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -495,6 +497,7 @@ int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
|||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!s->data_to_read) {
|
if (!s->data_to_read) {
|
||||||
s->data_to_read = fd->revents & POLLIN;
|
s->data_to_read = fd->revents & POLLIN;
|
||||||
@@ -547,7 +550,7 @@ int ssh_socket_nonblocking_flush(struct socket *s) {
|
|||||||
buffer_get_rest_len(s->out_buffer));
|
buffer_get_rest_len(s->out_buffer));
|
||||||
} else {
|
} else {
|
||||||
/* write failed */
|
/* write failed */
|
||||||
w =- 1;
|
w = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w < 0) {
|
if (w < 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user