Compare commits
72 Commits
beforenb2-
...
RELEASE.0.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
74b12c3c7a | ||
![]() |
25adcc150e | ||
![]() |
639b29631a | ||
![]() |
7808cab1e4 | ||
![]() |
9dfd71121e | ||
![]() |
e555510008 | ||
![]() |
ba728148a9 | ||
![]() |
019cd1abc0 | ||
![]() |
0742a972c1 | ||
![]() |
ca616cea36 | ||
![]() |
8accb43cd6 | ||
![]() |
bc6ab7e0cb | ||
![]() |
363f5a690d | ||
![]() |
8223acec0a | ||
![]() |
136b2bfcdc | ||
![]() |
bc179b6e87 | ||
![]() |
d4648be5a6 | ||
![]() |
f71b59c900 | ||
![]() |
fbf9d7cebd | ||
![]() |
82d59f90e1 | ||
![]() |
cd077c350f | ||
![]() |
49fef5e598 | ||
![]() |
c5ba20a2c0 | ||
![]() |
6546a010a4 | ||
![]() |
e34baff2ca | ||
![]() |
ddb935af3d | ||
![]() |
12d6b04c80 | ||
![]() |
bc0578a34d | ||
![]() |
94585bf852 | ||
![]() |
9002319fc3 | ||
![]() |
e7e94c4079 | ||
![]() |
e7fdf3654c | ||
![]() |
5aa467cf54 | ||
![]() |
f599ec2b86 | ||
![]() |
d89e102b23 | ||
![]() |
e6daab80fa | ||
![]() |
2003dc1546 | ||
![]() |
94a2585e9e | ||
![]() |
61932dc560 | ||
![]() |
0dff967017 | ||
![]() |
f74a3fecc9 | ||
![]() |
70ea2c776e | ||
![]() |
72c8408a40 | ||
![]() |
3fbdf1a644 | ||
![]() |
2bb177d3e0 | ||
![]() |
8bc4fdc3b0 | ||
![]() |
eac8fcdd77 | ||
![]() |
fa0c6996ef | ||
![]() |
45e4ec255c | ||
![]() |
084500e9ca | ||
![]() |
3e0cc45d10 | ||
![]() |
3dece58b29 | ||
![]() |
e4ec1c9aa9 | ||
![]() |
607e5c55e0 | ||
![]() |
dde2b09496 | ||
![]() |
f35ab0d070 | ||
![]() |
041786732d | ||
![]() |
d073a4ea52 | ||
![]() |
a5109ee5ba | ||
![]() |
b12a16f89c | ||
![]() |
8b4df6a9ab | ||
![]() |
8466a826f1 | ||
![]() |
c39c618c62 | ||
![]() |
bdde6c3d60 | ||
![]() |
cf8f4d1818 | ||
![]() |
281283d252 | ||
![]() |
b2f3582a59 | ||
![]() |
bb32d080fa | ||
![]() |
eb39c0c091 | ||
![]() |
7d57222912 | ||
![]() |
d141ba49f3 | ||
![]() |
4b8db8c1ab |
2
AUTHORS
2
AUTHORS
@@ -1,5 +1,7 @@
|
|||||||
* Sara Golemon: Author / Project Manager
|
* Sara Golemon: Author / Project Manager
|
||||||
|
|
||||||
|
* James Housleys: Nonblocking conversion
|
||||||
|
|
||||||
* Simon Josefsson: libgcrypt support
|
* Simon Josefsson: libgcrypt support
|
||||||
|
|
||||||
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot artist
|
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot artist
|
||||||
|
39
ChangeLog
39
ChangeLog
@@ -1,3 +1,42 @@
|
|||||||
|
2007-06-23 James Housley <jim@thehousleys.net>
|
||||||
|
* Eberhard Mattes submitted a patch "According to RFC 4251,
|
||||||
|
a boolean value of true is encoded as 1, not as 0xff". Servers
|
||||||
|
should accept any non-zero value.
|
||||||
|
|
||||||
|
2007-06-22 James Housley <jim@thehousleys.net>
|
||||||
|
* Guenter Knauf submitted code for windows to detect
|
||||||
|
if the socket is blocking or not.
|
||||||
|
|
||||||
|
2007-06-15 James Housley <jim@thehousleys.net>
|
||||||
|
* Add libssh2_sftp_readdir_ex(), this function if passed the
|
||||||
|
extra parameters will be used to store the full directory
|
||||||
|
entry as provided by the server. Updated LIBSSH2_APINO to
|
||||||
|
200706151200 for this change.
|
||||||
|
|
||||||
|
2007-06-12 James Housley <jim@thehousleys.net>
|
||||||
|
|
||||||
|
* libssh2_publickey_shutdown(), libssh2_session_free() changed
|
||||||
|
to return an "int" to allow signaling of LIBSSH2_ERROR_EAGAIN.
|
||||||
|
|
||||||
|
* libssh2_scp_recv(), libssh2_scp_send_ex() and libssh2_sftp_init()
|
||||||
|
will loop in on libssh2_channel_free() when there is an error.
|
||||||
|
It is not possible to return LIBSSH2_ERROR_EAGAIN in this condition
|
||||||
|
in these 3 functions and not lose the original error code.
|
||||||
|
|
||||||
|
2007-06-10 James Housley <jim@thehousleys.net>
|
||||||
|
|
||||||
|
* The list of supported authentication types returned by
|
||||||
|
libssh2_userauth_list() is an internal buffer and is managed
|
||||||
|
by the library and should not be free()'d by the user.
|
||||||
|
|
||||||
|
2007-06-08 James Housley <jim@thehousleys.net>
|
||||||
|
|
||||||
|
* Convert all the code to properly work with a socket in
|
||||||
|
non-blocking mode. All functions either return
|
||||||
|
LIBSSH2_ERROR_EAGAIN or return NULL and set the error code
|
||||||
|
to be LIBSSH2_ERROR_EAGAIN instead of blocking, when in
|
||||||
|
non-blocking mode.
|
||||||
|
|
||||||
2007-03-27 Simon Josefsson <simon@josefsson.org>
|
2007-03-27 Simon Josefsson <simon@josefsson.org>
|
||||||
|
|
||||||
* NEWS: Add.
|
* NEWS: Add.
|
||||||
|
@@ -11,4 +11,6 @@ ACLOCAL_AMFLAGS = -I m4
|
|||||||
|
|
||||||
.PHONY: ChangeLog
|
.PHONY: ChangeLog
|
||||||
ChangeLog:
|
ChangeLog:
|
||||||
cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs
|
if test -f .cvsusers; then \
|
||||||
|
cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs; \
|
||||||
|
fi
|
||||||
|
20
NEWS
20
NEWS
@@ -1,5 +1,25 @@
|
|||||||
Version
|
Version
|
||||||
------------
|
------------
|
||||||
|
Added libssh2_sftp_readdir_ex() and updated LIBSSH2_APINO to
|
||||||
|
200706151200 (James Housley)
|
||||||
|
|
||||||
|
Converted all of the libssh2 code to be able to work in non-blocking
|
||||||
|
mode. This included some public API changes, listed below (James Housley)
|
||||||
|
Changed function return values:
|
||||||
|
int libssh2_session_free()
|
||||||
|
int libssh2_publickey_shutdown()
|
||||||
|
ssize_t libssh2_channel_read_ex()
|
||||||
|
ssize_t libssh2_channel_write_ex()
|
||||||
|
|
||||||
|
Added functions:
|
||||||
|
libssh2_session_last_errno(), libssh2_channel_handle_extended_data2(),
|
||||||
|
libssh2_channel_wait_closed(), libssh2_channel_wait_eof(),
|
||||||
|
libssh2_session_set_blocking()
|
||||||
|
|
||||||
|
Removed functions:
|
||||||
|
libssh2_channel_readnb_ex(), libssh2_channel_writenb_ex(),
|
||||||
|
libssh2_sftp_readnb(), libssh2_sftp_writenb(),
|
||||||
|
libssh2_sftp_mkdirnb_ex()
|
||||||
|
|
||||||
Added the following functions for non-blocking operations: (Daniel Stenberg)
|
Added the following functions for non-blocking operations: (Daniel Stenberg)
|
||||||
libssh2_channel_readnb_ex()
|
libssh2_channel_readnb_ex()
|
||||||
|
@@ -1,13 +1,63 @@
|
|||||||
# $Id: Makefile.am,v 1.5 2007/04/22 19:51:53 jehousley Exp $
|
# $Id: Makefile.am,v 1.26 2007/06/15 11:01:22 jehousley Exp $
|
||||||
|
|
||||||
EXTRA_DIST = template.3
|
EXTRA_DIST = template.3
|
||||||
|
|
||||||
dist_man_MANS = libssh2_channel_forward_accept.3 \
|
dist_man_MANS = \
|
||||||
libssh2_session_init.3 libssh2_channel_forward_listen_ex.3 \
|
libssh2_banner_set.3 \
|
||||||
libssh2_session_startup.3 libssh2_channel_read_ex.3 \
|
libssh2_channel_close.3 \
|
||||||
libssh2_sftp_init.3 libssh2_channel_readnb_ex.3 \
|
libssh2_channel_direct_tcpip_ex.3 \
|
||||||
libssh2_sftp_open_ex.3 libssh2_channel_set_blocking.3 \
|
libssh2_channel_eof.3 \
|
||||||
libssh2_session_free.3 libssh2_poll.3 libssh2_poll_channel_read.3 \
|
libssh2_channel_flush_ex.3 \
|
||||||
libssh2_sftp_read.3 libssh2_sftp_readnb.3 libssh2_sftp_readdir.3 \
|
libssh2_channel_forward_accept.3 \
|
||||||
libssh2_sftp_readdirnb.3 libssh2_sftp_mkdir_ex.3 \
|
libssh2_channel_forward_cancel.3 \
|
||||||
libssh2_sftp_mkdirnb_ex.3
|
libssh2_channel_forward_listen_ex.3 \
|
||||||
|
libssh2_channel_free.3 \
|
||||||
|
libssh2_channel_get_exit_status.3 \
|
||||||
|
libssh2_channel_handle_extended_data.3 \
|
||||||
|
libssh2_channel_handle_extended_data2.3 \
|
||||||
|
libssh2_channel_open_ex.3 \
|
||||||
|
libssh2_channel_process_startup.3 \
|
||||||
|
libssh2_channel_read_ex.3 \
|
||||||
|
libssh2_channel_request_pty_ex.3 \
|
||||||
|
libssh2_channel_send_eof.3 \
|
||||||
|
libssh2_channel_set_blocking.3 \
|
||||||
|
libssh2_channel_setenv_ex.3 \
|
||||||
|
libssh2_channel_wait_eof.3 \
|
||||||
|
libssh2_channel_x11_req_ex.3 \
|
||||||
|
libssh2_hostkey_hash.3 \
|
||||||
|
libssh2_scp_recv.3 \
|
||||||
|
libssh2_scp_send_ex.3 \
|
||||||
|
libssh2_session_abstract.3 \
|
||||||
|
libssh2_session_callback_set.3 \
|
||||||
|
libssh2_session_free.3 \
|
||||||
|
libssh2_session_disconnect_ex.3 \
|
||||||
|
libssh2_session_init.3 \
|
||||||
|
libssh2_session_last_errno.3 \
|
||||||
|
libssh2_session_last_error.3 \
|
||||||
|
libssh2_session_method_pref.3 \
|
||||||
|
libssh2_session_methods.3 \
|
||||||
|
libssh2_session_set_blocking.3 \
|
||||||
|
libssh2_session_startup.3 \
|
||||||
|
libssh2_poll.3 \
|
||||||
|
libssh2_poll_channel_read.3 \
|
||||||
|
libssh2_sftp_close_handle.3 \
|
||||||
|
libssh2_sftp_fstat_ex.3 \
|
||||||
|
libssh2_sftp_last_error.3 \
|
||||||
|
libssh2_sftp_init.3 \
|
||||||
|
libssh2_sftp_open_ex.3 \
|
||||||
|
libssh2_sftp_mkdir_ex.3 \
|
||||||
|
libssh2_sftp_read.3 \
|
||||||
|
libssh2_sftp_readdir.3 \
|
||||||
|
libssh2_sftp_rename_ex.3 \
|
||||||
|
libssh2_sftp_rmdir_ex.3 \
|
||||||
|
libssh2_sftp_seek.3 \
|
||||||
|
libssh2_sftp_shutdown.3 \
|
||||||
|
libssh2_sftp_stat_ex.3 \
|
||||||
|
libssh2_sftp_symlink_ex.3 \
|
||||||
|
libssh2_sftp_tell.3 \
|
||||||
|
libssh2_sftp_unlink_ex.3 \
|
||||||
|
libssh2_sftp_write.3 \
|
||||||
|
libssh2_userauth_authenticated.3 \
|
||||||
|
libssh2_userauth_list.3 \
|
||||||
|
libssh2_userauth_password_ex.3 \
|
||||||
|
libssh2_userauth_publickey_fromfile.3
|
||||||
|
32
docs/libssh2_banner_set.3
Normal file
32
docs/libssh2_banner_set.3
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
.\" $Id: libssh2_banner_set.3,v 1.1 2007/06/13 17:03:38 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_banner_set - set the SSH prococol banner for the local client
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIbanner\fP - A pointer to a user defined banner
|
||||||
|
|
||||||
|
Set the banner that will be sent to the remote host when the SSH session is
|
||||||
|
started with
|
||||||
|
.BR libssh2_session_startup(3)
|
||||||
|
. This is optional; a banner corresponding to the protocol and libssh2 version will be sent by default.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_startup(3)
|
31
docs/libssh2_channel_close.3
Normal file
31
docs/libssh2_channel_close.3
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.\" $Id: libssh2_channel_close.3,v 1.1 2007/06/13 17:03:38 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_close 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_close - close a channel<
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_close(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - active channel stream to set closed status on.
|
||||||
|
|
||||||
|
Close an active data channel. In practice this means sending an SSH_MSG_CLOSE
|
||||||
|
packet to the remote host which serves as instruction that no further data
|
||||||
|
will be sent to it. The remote host may still send data back until it sends
|
||||||
|
its own close message in response. To wait for the remote end to close its
|
||||||
|
connection as well, follow this command with
|
||||||
|
.BR libssh2_channel_wait_closed(3)
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_open(3)
|
39
docs/libssh2_channel_direct_tcpip_ex.3
Normal file
39
docs/libssh2_channel_direct_tcpip_ex.3
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
.\" $Id: libssh2_channel_direct_tcpip_ex.3,v 1.1 2007/06/13 17:22:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_direct_tcpip_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_direct_tcpip_ex - Tunnel a TCP connection through an SSH session
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport);
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_channel_direct_tcpip(LIBSSH2_SESSION *session, const char *host, int port);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
/fIsession/fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
/fIhost/fP - Third party host to connect to using the SSH host as a proxy.
|
||||||
|
|
||||||
|
/fIport/fP - Port on third party host to connect to.
|
||||||
|
|
||||||
|
/fIshost/fP - Host to tell the SSH server the connection originated on.
|
||||||
|
|
||||||
|
/fIsport/fP - Port to tell the SSH server the connection originated from.
|
||||||
|
|
||||||
|
Tunnel a TCP/IP connection through the SSH transport via the remote host to
|
||||||
|
a third party. Communication from the client to the SSH server remains
|
||||||
|
encrypted, communication from the server to the 3rd party host travels
|
||||||
|
in cleartext.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
18
docs/libssh2_channel_eof.3
Normal file
18
docs/libssh2_channel_eof.3
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
.\" $Id: libssh2_channel_eof.3,v 1.1 2007/06/13 17:22:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_eof 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_eof - check a channel's EOF status
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - active channel stream to set closed status on.
|
||||||
|
|
||||||
|
Check if the remote host has sent an EOF status for the selected stream.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Returns 1 if the remote host has sent EOF, otherwise 0.
|
34
docs/libssh2_channel_flush_ex.3
Normal file
34
docs/libssh2_channel_flush_ex.3
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
.\" $Id: libssh2_channel_flush_ex.3,v 1.1 2007/06/13 19:53:09 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_flush_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_flush_ex - flush a channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_flush(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_flush_stderr(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Active channel stream to flush.
|
||||||
|
|
||||||
|
\fIstreamid\fP - Specific substream number to flush. Groups of substreams may
|
||||||
|
be flushed by passing on of the following Constants.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA\fP: Flush all extended data substreams
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_FLUSH_ALL\fP: Flush all substreams
|
||||||
|
|
||||||
|
Flush the read buffer for a given channel instance. Individual substreams may
|
||||||
|
be flushed by number or using one of the provided macros.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
@@ -1,16 +1,21 @@
|
|||||||
.\" $Id: libssh2_channel_forward_accept.3,v 1.1 2006/12/21 14:09:12 bagder Exp $
|
.\" $Id: libssh2_channel_forward_accept.3,v 1.5 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_channel_forward_accept 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_channel_forward_accept 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_channel_forward_accept - accept a queued connection
|
libssh2_channel_forward_accept - accept a queued connection
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B #include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
|
||||||
|
|
||||||
.B LIBSSH2_CHANNEL * libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fIlistener\fP is a forwarding listener instance as returned by
|
\fIlistener\fP is a forwarding listener instance as returned by
|
||||||
\fBlibssh2_channel_forward_listen(3)\fP.
|
\fBlibssh2_channel_forward_listen(3)\fP.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A newly allocated channel instance or NULL on failure.
|
A newly allocated channel instance or NULL on failure.
|
||||||
.SH "SEE ALSO"
|
.SH ERRORS
|
||||||
.BI libssh2_channel_forward_listen(3)
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call
|
||||||
|
would block.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_forward_listen(3)
|
||||||
|
29
docs/libssh2_channel_forward_cancel.3
Normal file
29
docs/libssh2_channel_forward_cancel.3
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
.\" $Id: libssh2_channel_forward_cancel.3,v 1.1 2007/06/13 19:53:09 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_forward_cancel 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_forward_cancel - cancel a forwarded TCP port
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
/fIlistener/fP - Forwarding listener instance as returned by
|
||||||
|
.BR libssh2_channel_forward_listen(3)
|
||||||
|
|
||||||
|
Instruct the remote host to stop listening for new connections on a previously requested host/port.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_forward_listen(3)
|
@@ -1,19 +1,17 @@
|
|||||||
.\" $Id: libssh2_channel_forward_listen_ex.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
|
.\" $Id: libssh2_channel_forward_listen_ex.3,v 1.7 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_channel_forward_listen_ex 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_channel_forward_listen_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_channel_forward_listen_ex - listen to inbound connections
|
libssh2_channel_forward_listen_ex - listen to inbound connections
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
LIBSSH2_LISTENER * libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session,
|
LIBSSH2_LISTENER *
|
||||||
char *host,
|
libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, char *host, int port, int *bound_port, int queue_maxsize);
|
||||||
int port,
|
|
||||||
int *bound_port,
|
LIBSSH2_LISTENER *
|
||||||
int queue_maxsize);
|
libssh2_channel_forward_listen(LIBSSH2_SESSION *session, int port);
|
||||||
|
|
||||||
LIBSSH2_LISTENER * libssh2_channel_forward_listen(LIBSSH2_SESSION *session,
|
|
||||||
int port);
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Instruct the remote SSH server to begin listening for inbound TCP/IP
|
Instruct the remote SSH server to begin listening for inbound TCP/IP
|
||||||
connections. New connections will be queued by the library until accepted by
|
connections. New connections will be queued by the library until accepted by
|
||||||
@@ -36,5 +34,15 @@ rejecting further attempts.
|
|||||||
\fIlibssh2_channel_forward_listen(3)\fP is a macro.
|
\fIlibssh2_channel_forward_listen(3)\fP is a macro.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A newly allocated LIBSSH2_LISTENER instance or NULL on failure.
|
A newly allocated LIBSSH2_LISTENER instance or NULL on failure.
|
||||||
.SH "SEE ALSO"
|
.SH ERRORS
|
||||||
.BI libssh2_channel_forward_accept(3)
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_PROTO\fP - An invalid SSH protocol response was received on the socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_REQUEST_DENIED\fP - The remote server refused the request.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_forward_accept(3)
|
||||||
|
27
docs/libssh2_channel_free.3
Normal file
27
docs/libssh2_channel_free.3
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
.\" $Id: libssh2_channel_free.3,v 1.1 2007/06/13 20:09:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_free 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_free - free all resources associated with a channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_free(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Channel stream to free.
|
||||||
|
|
||||||
|
Release all resources associated with a channel stream. If the channel has
|
||||||
|
not yet been closed with
|
||||||
|
.BR libssh2_channel_close(3)
|
||||||
|
, it will be called automatically so that the remote end may know that it
|
||||||
|
can safely free its own resources.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_close(3)
|
20
docs/libssh2_channel_get_exit_status.3
Normal file
20
docs/libssh2_channel_get_exit_status.3
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.\" $Id: libssh2_channel_get_exit_status.3,v 1.1 2007/06/15 10:53:04 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_get_exit_status 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_get_exit_status - get the remote exit code
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel)
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Closed channel stream to retreive exit status from.
|
||||||
|
|
||||||
|
Returns the exit code raised by the process running on the remote host at
|
||||||
|
the other end of the named channel. Note that the exit status may not be
|
||||||
|
available if the remote end has not yet set its status to closed.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Returns 0 on failure, otherwise the \fIExit Status\fP reported by remote host
|
37
docs/libssh2_channel_handle_extended_data.3
Normal file
37
docs/libssh2_channel_handle_extended_data.3
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.\" $Id: libssh2_channel_handle_extended_data.3,v 1.1 2007/06/13 20:09:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_handle_extended_data 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_handle_extended_data - set extended data handling mode
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Active channel stream to change extended data handling on.
|
||||||
|
|
||||||
|
\fIignore_mode\fP - One of the three LIBSSH2_CHANNEL_EXTENDED_DATA_* Constants.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL\fP: Queue extended data for eventual
|
||||||
|
reading
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_MERGE\fP: Treat extended data and ordinary
|
||||||
|
data the same. Merge all substreams such that calls to
|
||||||
|
.BR libssh2_channel_read(3)
|
||||||
|
will pull from all substreams on a first-in/first-out basis.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE\fP: Discard all extended data as it
|
||||||
|
arrives.
|
||||||
|
|
||||||
|
Change how a channel deals with extended data packets. By default all
|
||||||
|
extended data is queued until read by
|
||||||
|
.BR libssh2_channel_read_ex(3)
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
None.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_handle_extended_data2(3)
|
||||||
|
.BR libssh2_channel_read_ex(3)
|
37
docs/libssh2_channel_handle_extended_data2.3
Normal file
37
docs/libssh2_channel_handle_extended_data2.3
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.\" $Id: libssh2_channel_handle_extended_data2.3,v 1.1 2007/06/13 20:09:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_handle_extended_data2 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_handle_extended_data2 - set extended data handling mode
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Active channel stream to change extended data handling on.
|
||||||
|
|
||||||
|
\fIignore_mode\fP - One of the three LIBSSH2_CHANNEL_EXTENDED_DATA_* Constants.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL\fP: Queue extended data for eventual
|
||||||
|
reading
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_MERGE\fP: Treat extended data and ordinary
|
||||||
|
data the same. Merge all substreams such that calls to
|
||||||
|
.BR libssh2_channel_read(3)
|
||||||
|
will pull from all substreams on a first-in/first-out basis.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE\fP: Discard all extended data as it
|
||||||
|
arrives.
|
||||||
|
|
||||||
|
Change how a channel deals with extended data packets. By default all
|
||||||
|
extended data is queued until read by
|
||||||
|
.BR libssh2_channel_read_ex(3)
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or LIBSSH2_ERROR_EAGAIN when it would otherwise block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_handle_extended_data(3)
|
||||||
|
.BR libssh2_channel_read_ex(3)
|
56
docs/libssh2_channel_open_ex.3
Normal file
56
docs/libssh2_channel_open_ex.3
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
.\" $Id: libssh2_channel_open_ex.3,v 1.1 2007/06/13 20:54:25 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_open_ex - establish a generic session channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len);
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_channel_open_session(session);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIchannel_type\fP - Channel type to open. Typically one of session,
|
||||||
|
direct-tcpip, or tcpip-forward. The SSH2 protocol allowed for additional
|
||||||
|
types including local, custom channel types.
|
||||||
|
|
||||||
|
\fIchannel_type_len\fP - Length of channel_type
|
||||||
|
|
||||||
|
\fIwindow_size\fP - Maximum amount of unacknowledged data remote host is
|
||||||
|
allowed to send before receiving an SSH_MSG_CHANNEL_WINDOW_ADJUST packet.
|
||||||
|
|
||||||
|
\fIpacket_size\fP - Maximum number of bytes remote host is allowed to send
|
||||||
|
in a single SSH_MSG_CHANNEL_DATA or SSG_MSG_CHANNEL_EXTENDED_DATA packet.
|
||||||
|
|
||||||
|
\fImessage\fP - Additional data as required by the selected channel_type.
|
||||||
|
|
||||||
|
\fImessage_len\fP - Length of message parameter.
|
||||||
|
|
||||||
|
Allocate a new channel for exchanging data with the server. This method is
|
||||||
|
typically called through its macroized form:
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
or via
|
||||||
|
.BR libssh2_channel_direct_tcpip(3)
|
||||||
|
or
|
||||||
|
.BR libssh2_channel_forward_listen(3)
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_FAILURE\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
Add related functions
|
49
docs/libssh2_channel_process_startup.3
Normal file
49
docs/libssh2_channel_process_startup.3
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
.\" $Id: libssh2_channel_process_startup.3,v 1.1 2007/06/13 20:54:25 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_process_startup 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_process_startup - request a shell on a channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_shell(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_exec(LIBSSH2_CHANNEL *channel, const char *message);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_subsystem(LIBSSH2_CHANNEL *channel, const char *message);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Active session channel instance.
|
||||||
|
|
||||||
|
\fIrequest\fP - Type of process to startup. The SSH2 protocol currently
|
||||||
|
defines shell, exec, and subsystem as standard process services.
|
||||||
|
|
||||||
|
\fIrequest_len\fP - Length of request parameter.
|
||||||
|
|
||||||
|
\fImessage\fP - Request specific message data to include.
|
||||||
|
|
||||||
|
\fImessage_len\fP - Length of message parameter.
|
||||||
|
|
||||||
|
Initiate a request on a session type channel such as returned by
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_open_session(3)
|
@@ -1,19 +1,20 @@
|
|||||||
.\" $Id: libssh2_channel_read_ex.3,v 1.5 2007/02/23 10:20:56 bagder Exp $
|
.\" $Id: libssh2_channel_read_ex.3,v 1.10 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_channel_read_ex 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_channel_read_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_channel_read_ex - read data from a channel stream
|
libssh2_channel_read_ex - read data from a channel stream
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
|
ssize_t
|
||||||
char *buf, size_t buflen);
|
libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen);
|
||||||
|
|
||||||
int libssh2_channel_read(LIBSSH2_CHANNEL *channel, char *buf,
|
ssize_t
|
||||||
size_t buflen);
|
libssh2_channel_read(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen);
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
libssh2_channel_read_stderr(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen);
|
||||||
|
|
||||||
int libssh2_channel_read_stderr(LIBSSH2_CHANNEL *channel, char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Attempt to read data from an active channel stream. All channel streams have
|
Attempt to read data from an active channel stream. All channel streams have
|
||||||
one standard I/O substream (stream_id == 0), and may have up to 2^32 extended
|
one standard I/O substream (stream_id == 0), and may have up to 2^32 extended
|
||||||
@@ -31,6 +32,13 @@ currently defines a stream ID of 1 to be the stderr substream.
|
|||||||
\fIlibssh2_channel_read(3)\fP and \fIlibssh2_channel_read_stderr(3)\fP are
|
\fIlibssh2_channel_read(3)\fP and \fIlibssh2_channel_read_stderr(3)\fP are
|
||||||
macros.
|
macros.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Actual number of bytes read or negative on failure.
|
Actual number of bytes read or negative on failure. It returns
|
||||||
.SH "SEE ALSO"
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_CLOSED\fP - The channel has been closed.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
.BR libssh2_poll_channel_read(3)
|
.BR libssh2_poll_channel_read(3)
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
.\" $Id: libssh2_channel_readnb_ex.3,v 1.2 2007/02/23 10:20:56 bagder Exp $
|
|
||||||
.\"
|
|
||||||
.TH libssh2_channel_read_ex 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
|
||||||
.SH NAME
|
|
||||||
libssh2_channel_read_ex - read data from a channel stream
|
|
||||||
.SH SYNOPSIS
|
|
||||||
#include <libssh2.h>
|
|
||||||
|
|
||||||
int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel, int stream_id,
|
|
||||||
char *buf, size_t buflen);
|
|
||||||
|
|
||||||
int libssh2_channel_readnb(LIBSSH2_CHANNEL *channel, char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
|
|
||||||
int libssh2_channel_readnb_stderr(LIBSSH2_CHANNEL *channel, char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Attempt to read data from an active channel stream. All channel streams have
|
|
||||||
one standard I/O substream (stream_id == 0), and may have up to 2^32 extended
|
|
||||||
data streams as identified by the selected \fIstream_id\fP. The SSH2 protocol
|
|
||||||
currently defines a stream ID of 1 to be the stderr substream.
|
|
||||||
|
|
||||||
\fIchannel\fP - active channel stream to read from.
|
|
||||||
|
|
||||||
\fIstream_id\fP - substream ID number (e.g. 0 or SSH_EXTENDED_DATA_STDERR)
|
|
||||||
|
|
||||||
\fIbuf\fP - pointer to storage buffer to read data into
|
|
||||||
|
|
||||||
\fIbuflen\fP - size of the buf storage
|
|
||||||
|
|
||||||
\fIlibssh2_channel_read(3)\fP and \fIlibssh2_channel_read_stderr(3)\fP are
|
|
||||||
macros.
|
|
||||||
.SH RETURN VALUE
|
|
||||||
Actual number of bytes read or negative on failure. It returns
|
|
||||||
LIBSSH2CHANNEL_EAGAIN when it would otherwise block. While
|
|
||||||
LIBSSH2CHANNEL_EAGAIN is a negative number, it isn't really a failure per se.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR libssh2_poll_channel_read(3)
|
|
||||||
|
|
52
docs/libssh2_channel_request_pty_ex.3
Normal file
52
docs/libssh2_channel_request_pty_ex.3
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.\" $Id: libssh2_channel_request_pty_ex.3,v 1.1 2007/06/13 21:07:59 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_request_pty_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_request_pty_ex - short function description
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_request_pty(LIBSSH2_CHANNEL *channel, char *term);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Previously opened channel instance such as returned by
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
|
||||||
|
\fIterm\fP - Terminal emulation (e.g. vt102, ansi, etc...)
|
||||||
|
|
||||||
|
\fIterm_len\fP - Length of term parameter
|
||||||
|
|
||||||
|
\fImodes\fP - Terminal mode modifier values
|
||||||
|
|
||||||
|
\fImodes_len\fP - Length of modes parameter.
|
||||||
|
|
||||||
|
\fIwidth\fP - Width of pty in characters
|
||||||
|
|
||||||
|
\fIheight\fP - Height of pty in characters
|
||||||
|
|
||||||
|
\fIwidth_px\fP - Width of pty in pixels
|
||||||
|
|
||||||
|
\fIheight_px\fP - Height of pty in pixels
|
||||||
|
|
||||||
|
Request a PTY on an established channel. Note that this does not make sense
|
||||||
|
for all channel types and may be ignored by the server despite returning
|
||||||
|
success.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_open_session(3)
|
26
docs/libssh2_channel_send_eof.3
Normal file
26
docs/libssh2_channel_send_eof.3
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.\" $Id: libssh2_channel_send_eof.3,v 1.1 2007/06/13 21:07:59 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_send_eof 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_send_eof - send EOF to remote server
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Tell the remote host that no further data will be sent on the specified
|
||||||
|
channel. Processes typically interpret this as a closed stdin descriptor.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_wait_eof(3)
|
||||||
|
.BR libssh2_channel_eof(3)
|
@@ -1,23 +1,28 @@
|
|||||||
.\" $Id: libssh2_channel_set_blocking.3,v 1.1 2006/12/21 14:09:13 bagder Exp $
|
.\" $Id: libssh2_channel_set_blocking.3,v 1.5 2007/06/14 17:23:13 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_channel_set_blocking 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_channel_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_channel_set_blocking - set or clear blocking mode on channel
|
libssh2_channel_set_blocking - set or clear blocking mode on channel
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
|
void
|
||||||
.SH DESCRIPTION
|
libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
|
||||||
Set or clear blocking mode on the selected channel. If a read is performed on
|
|
||||||
a channel with no data currently available, a blocking channel will wait for
|
|
||||||
data to arrive and return what it receives. A non-blocking channel will return
|
|
||||||
immediately with an empty buffer.
|
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
\fIchannel\fP - channel stream to set or clean blocking status on.
|
\fIchannel\fP - channel stream to set or clean blocking status on.
|
||||||
|
|
||||||
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
|
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
|
||||||
make it non-blocking.
|
make it non-blocking.
|
||||||
|
|
||||||
|
Currently this is just a short cut call to
|
||||||
|
.BR libssh2_session_set_blocking(3)
|
||||||
|
and therefore will affect the session and all channels.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
None
|
None
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BI libssh2_channel_read_ex(3)
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_set_blocking(3)
|
||||||
|
.BR libssh2_channel_read_ex(3)
|
||||||
|
.BR libssh2_channel_write_ex(3)
|
||||||
|
43
docs/libssh2_channel_setenv_ex.3
Normal file
43
docs/libssh2_channel_setenv_ex.3
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.\" $Id: libssh2_channel_setenv_ex.3,v 1.1 2007/06/13 21:30:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_setenv_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_setenv_ex - set an environment variable on the channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, unsigned int value_len);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_setenv(LIBSSH2_CHANNEL *channel, char *varname, const char *value);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Previously opened channel instance such as returned by
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
|
||||||
|
\fIvarname\fP - Name of environment variable to set on the remote
|
||||||
|
channel instance.
|
||||||
|
|
||||||
|
\fIvarname_len\fP - Length of passed varname parameter.
|
||||||
|
|
||||||
|
\fIvalue\fP - Value to set varname to.
|
||||||
|
|
||||||
|
\fIvalue_len\fP - Length of value parameter.
|
||||||
|
|
||||||
|
Set an environment variable in the remote channel's process space. Note that this does not make sense for all channel types and may be ignored by the server despite returning success.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_open_session(3)
|
21
docs/libssh2_channel_wait_eof.3
Normal file
21
docs/libssh2_channel_wait_eof.3
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.\" $Id: libssh2_channel_wait_eof.3,v 1.5 2007/06/13 16:41:33 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_wait_eof 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_wait_eof - wait for the remote to reply to an EOF request
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Wait for the remote end to acknowledge an EOF request.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_send_eof(3)
|
||||||
|
.BR libssh2_channel_eof(3)
|
@@ -1,19 +1,19 @@
|
|||||||
.\" $Id: libssh2_channel_write_ex.3,v 1.1 2007/02/23 10:20:56 bagder Exp $
|
.\" $Id: libssh2_channel_write_ex.3,v 1.5 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_channel_write_ex 3 "6 Feb 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_channel_write_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_channel_write_ex - write data to a channel stream blocking
|
libssh2_channel_write_ex - write data to a channel stream blocking
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id,
|
ssize_t
|
||||||
char *buf, size_t buflen);
|
libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen);
|
||||||
|
|
||||||
int libssh2_channel_write(LIBSSH2_CHANNEL *channel, char *buf,
|
ssize_t
|
||||||
size_t buflen);
|
libssh2_channel_write(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen);
|
||||||
|
|
||||||
int libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel, char *buf,
|
ssize_t
|
||||||
size_t buflen);
|
libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen);
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Write data to a channel stream. All channel streams have one standard I/O
|
Write data to a channel stream. All channel streams have one standard I/O
|
||||||
substream (stream_id == 0), and may have up to 2^32 extended data streams as
|
substream (stream_id == 0), and may have up to 2^32 extended data streams as
|
||||||
@@ -32,6 +32,16 @@ defines a stream ID of 1 to be the stderr substream.
|
|||||||
macros.
|
macros.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Actual number of bytes written or negative on failure.
|
Actual number of bytes written or negative on failure.
|
||||||
.SH "SEE ALSO"
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_CLOSED\fP - The channel has been closed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_EOF_SENT\fP - The channel has been requested to be closed.
|
||||||
|
.SH SEE ALSO
|
||||||
.BR libssh2_channel_open_session(3)
|
.BR libssh2_channel_open_session(3)
|
||||||
.BR libssh2_channel_read(3)
|
.BR libssh2_channel_read(3)
|
||||||
|
46
docs/libssh2_channel_x11_req_ex.3
Normal file
46
docs/libssh2_channel_x11_req_ex.3
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
.\" $Id: libssh2_channel_x11_req_ex.3,v 1.1 2007/06/13 21:30:15 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_x11_req_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_x11_req_ex - request an X11 forwarding channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_x11_req(LIBSSH2_CHANNEL *channel, int screen_number);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIchannel\fP - Previously opened channel instance such as returned by
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
|
||||||
|
\fIsingle_connection\fP - non-zero to only forward a single connection.
|
||||||
|
|
||||||
|
\fIauth_proto\fP - X11 authentication protocol to use
|
||||||
|
|
||||||
|
\fIauth_cookie\fP - the cookie (hexadecimal encoded).
|
||||||
|
|
||||||
|
\fIscreen_number\fP - the XLL screen to forward
|
||||||
|
|
||||||
|
Request an X11 forwarding on \fIchannel\fP. To use X11 forwarding,
|
||||||
|
.BR libssh2_session_callback_set(3)
|
||||||
|
must first be called to set \fBLIBSSH2_CALLBACK_X11/fP. This callback will
|
||||||
|
be invoked when the remote host accepts the X11 forwarding.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
.BR libssh2_session_callback_set(3)
|
29
docs/libssh2_hostkey_hash.3
Normal file
29
docs/libssh2_hostkey_hash.3
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
.\" $Id: libssh2_hostkey_hash.3,v 1.1 2007/06/14 14:56:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_hostkey_hash 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_hostkey_hash - return a hash of the remote host's key
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
const char *
|
||||||
|
libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIhash_type\fP - One of: \fBLIBSSH2_HOSTKEY_HASH_MD5\fP or
|
||||||
|
\fBLIBSSH2_HOSTKEY_HASH_SHA1\fP.
|
||||||
|
|
||||||
|
Returns the computed digest of the remote system's hostkey. The length of
|
||||||
|
the returned string is hash_type specific (e.g. 16 bytes for MD5,
|
||||||
|
20 bytes for SHA1).
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Computed hostkey hash value. or NULL if the session has not yet been started
|
||||||
|
up. (The hash consists of raw binary bytes, not hex digits, so is not
|
||||||
|
directly printable.)
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
@@ -1,4 +1,4 @@
|
|||||||
.\" $Id: libssh2_poll.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
|
.\" $Id: libssh2_poll.3,v 1.3 2007/06/13 12:51:11 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_poll 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_poll 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -15,5 +15,5 @@ to accommodate the disparate datatypes, POLLFD constants have been namespaced
|
|||||||
to avoid platform discrepancies, and revents has additional values defined.
|
to avoid platform discrepancies, and revents has additional values defined.
|
||||||
.SH "RETURN VALUE"
|
.SH "RETURN VALUE"
|
||||||
Number of fds with interesting events.
|
Number of fds with interesting events.
|
||||||
.SH "SEE ALSO"
|
.SH SEE ALSO
|
||||||
.BR libssh2_poll_channel_read(3)
|
.BR libssh2_poll_channel_read(3)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
.\" $Id: libssh2_poll_channel_read.3,v 1.1 2007/02/23 10:20:56 bagder Exp $
|
.\" $Id: libssh2_poll_channel_read.3,v 1.2 2007/06/13 12:51:11 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_poll_channel_read 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_poll_channel_read 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -14,5 +14,5 @@ packets are available to be processed. For full polling support, use
|
|||||||
\fIlibssh2_poll(3)\fP.
|
\fIlibssh2_poll(3)\fP.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Returns 1 when data is available and 0 otherwise.
|
Returns 1 when data is available and 0 otherwise.
|
||||||
.SH "SEE ALSO"
|
.SH SEE ALSO
|
||||||
.BR libssh2_poll(3)
|
.BR libssh2_poll(3)
|
||||||
|
40
docs/libssh2_scp_recv.3
Normal file
40
docs/libssh2_scp_recv.3
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
.\" $Id: libssh2_scp_recv.3,v 1.1 2007/06/14 14:56:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_scp_recv 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_scp_recv - request a remote file via SCP
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIpath\fP - Full path and filename of file to transfer
|
||||||
|
|
||||||
|
\fIsb\fP - Populated with remote file's size, mode, mtime, and atime
|
||||||
|
|
||||||
|
Request a file from the remote host via SCP. This
|
||||||
|
function acts as a wrapper calling
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
,
|
||||||
|
.BR libssh2_channel_exec(3)
|
||||||
|
, and negotiating rcp protocol handshakes.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SCP_PROTOCOL\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
.BR libssh2_channel_exec(3)
|
52
docs/libssh2_scp_send_ex.3
Normal file
52
docs/libssh2_scp_send_ex.3
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.\" $Id: libssh2_scp_send_ex.3,v 1.1 2007/06/14 14:56:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_scp_send_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_scp_send_ex - Send a file via SCP
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime);
|
||||||
|
|
||||||
|
LIBSSH2_CHANNEL *
|
||||||
|
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIpath\fP - Full path and filename of file to transfer
|
||||||
|
|
||||||
|
\fImode\fP - File access mode to create file with
|
||||||
|
|
||||||
|
\fIsize\fP - Size of file being transmitted (Must be known
|
||||||
|
ahead of time precisely)
|
||||||
|
|
||||||
|
\fImtime\fP - mtime to assign to file being created
|
||||||
|
|
||||||
|
\fIatime\fP - atime to assign to file being created (Set this and
|
||||||
|
mtime to zero to instruct remote host to use current time).
|
||||||
|
|
||||||
|
Send a file to the remote host via SCP. This function
|
||||||
|
acts as a wrapper calling
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
,
|
||||||
|
.BR libssh2_channel_exec(3)
|
||||||
|
, and negotiating rcp protocol handshakes.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SCP_PROTOCOL\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_open_session(3)
|
||||||
|
.BR libssh2_channel_exec(3)
|
26
docs/libssh2_session_abstract.3
Normal file
26
docs/libssh2_session_abstract.3
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.\" $Id: libssh2_session_abstract.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_abstract 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_abstract - return a pointer to a session's abstract pointer
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
void **
|
||||||
|
libssh2_session_abstract(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init_ex(3)
|
||||||
|
|
||||||
|
Return a pointer to where the abstract pointer provided to
|
||||||
|
.BR libssh2_session_init_ex(3)
|
||||||
|
is stored. By providing a doubly de-referenced pointer, the internal
|
||||||
|
storage of the session instance may be modified in place.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
A pointer to session internal storage whos contents point to previously
|
||||||
|
provided abstract data.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init_ex(3)
|
30
docs/libssh2_session_callback_set.3
Normal file
30
docs/libssh2_session_callback_set.3
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
.\" $Id: libssh2_session_callback_set.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_callback_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_callback_set - set a callback function
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
void *
|
||||||
|
libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIcbtype\fP - Callback type. One of the types listed in Callback Types.
|
||||||
|
|
||||||
|
\fIcallback\fP - Pointer to custom callback function. The prototype for
|
||||||
|
this function must match the associated callback declaration macro.
|
||||||
|
|
||||||
|
Sets a custom callback handler for a previously initialized session
|
||||||
|
object. Callbacks are triggered by the receipt of special packets at
|
||||||
|
the Transport layer. To disable a callback, set it to NULL.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Pointer to previous callback handler. Returns NULL if no
|
||||||
|
prior callback handler was set.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
40
docs/libssh2_session_disconnect_ex.3
Normal file
40
docs/libssh2_session_disconnect_ex.3
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
.\" $Id: libssh2_session_disconnect_ex.3,v 1.4 2007/06/13 16:41:33 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_disconnect_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_disconnect_ex - terminate transport layer
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_session_disconnect(LIBSSH2_SESSION *session, const char *description);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIreason\fP - One of the Disconnect Reason constants.
|
||||||
|
|
||||||
|
\fIdescription\fP - Human readable reason for disconnection.
|
||||||
|
|
||||||
|
\fIlang\fP - Localization string describing the langauge/encoding of the description provided.
|
||||||
|
|
||||||
|
Send a disconnect message to the remote host associated with \fIsession\fP,
|
||||||
|
along with a \fIreason\fP symbol and a verbose \fIdescription\fP.
|
||||||
|
|
||||||
|
As a convenience, the macro
|
||||||
|
.BR libssh2_session_disconnect(3)
|
||||||
|
is provided. It calls
|
||||||
|
.BR libssh2_session_disconnect_ex(3)
|
||||||
|
with \fIreason\fP set to SSH_DISCONNECT_BY_APPLICATION
|
||||||
|
and \fIlang\fP set to an empty string.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
@@ -1,17 +1,21 @@
|
|||||||
.\" $Id: libssh2_session_free.3,v 1.1 2006/12/21 14:09:13 bagder Exp $
|
.\" $Id: libssh2_session_free.3,v 1.4 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_session_free 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_session_free 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_session_free - frees resources associated with a session instance
|
libssh2_session_free - frees resources associated with a session instance
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
void libssh2_session_free(LIBSSH2_SESSION *session);
|
int
|
||||||
|
libssh2_session_free(LIBSSH2_SESSION *session);
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Frees resources associated with a session instance. Typically called after
|
Frees resources associated with a session instance. Typically called after
|
||||||
\fIlibssh2_session_disconnect(3)\fP.
|
.BR libssh2_session_disconnect(3)
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
None
|
Return 0 on success or negative on failure. It returns
|
||||||
.SH "SEE ALSO"
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
.BI libssh2_session_init(3),
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
.BI libssh2_session_disconnect(3)
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
.BR libssh2_session_disconnect(3)
|
||||||
|
@@ -1,19 +1,34 @@
|
|||||||
.\" $Id: libssh2_session_init.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
|
.\" $Id: libssh2_session_init.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_session_init 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_session_init_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_session_init - initializes an SSH session object
|
libssh2_session_init_ex - initializes an SSH session object
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
LIBSSH2_SESSION *libssh2_session_init_ex(
|
LIBSSH2_SESSION *
|
||||||
LIBSSH2_ALLOC_FUNC((*myalloc)),
|
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*myalloc)), LIBSSH2_FREE_FUNC((*myfree)), LIBSSH2_REALLOC_FUNC((*myrealloc)), void *abstract);
|
||||||
LIBSSH2_FREE_FUNC((*myfree)),
|
|
||||||
LIBSSH2_REALLOC_FUNC((*myrealloc)),
|
LIBSSH2_SESSION *
|
||||||
void *abstract);
|
libssh2_session_init(void);
|
||||||
|
|
||||||
LIBSSH2_SESSION *libssh2_session_init(void);
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
\fImyalloc\fP - Custom allocator function. Refer to the section on Callbacks
|
||||||
|
for implementing an allocator callback. Pass a value of NULL to use the
|
||||||
|
default system allocator.
|
||||||
|
|
||||||
|
\fImyfree\fP - Custom de-allocator function. Refer to the section on Callbacks
|
||||||
|
for implementing a deallocator callback. Pass a value of NULL to use the
|
||||||
|
default system deallocator.
|
||||||
|
|
||||||
|
\fImyrealloc\fP - Custom re-allocator function. Refer to the section on
|
||||||
|
Callbacks for implementing a reallocator callback. Pass a value of NULL to
|
||||||
|
use the default system reallocator.
|
||||||
|
|
||||||
|
\fIabstract\fP - Arbitrary pointer to application specific callback data.
|
||||||
|
This value will be passed to any callback function associated with the named
|
||||||
|
session instance.
|
||||||
|
|
||||||
Initializes an SSH session object. By default system memory allocators
|
Initializes an SSH session object. By default system memory allocators
|
||||||
(malloc(), free(), realloc()) will be used for any dynamically allocated memory
|
(malloc(), free(), realloc()) will be used for any dynamically allocated memory
|
||||||
blocks. Alternate memory allocation functions may be specified using the
|
blocks. Alternate memory allocation functions may be specified using the
|
||||||
@@ -24,6 +39,6 @@ This method must be called first, prior to configuring session options or
|
|||||||
starting up an SSH session with a remote server.
|
starting up an SSH session with a remote server.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Pointer to a newly allocated LIBSSH2_SESSION instance, or NULL on errors.
|
Pointer to a newly allocated LIBSSH2_SESSION instance, or NULL on errors.
|
||||||
.SH "SEE ALSO"
|
.SH SEE ALSO
|
||||||
.BI libssh2_session_free(3),
|
.BR libssh2_session_free(3)
|
||||||
.BI libssh2_session_startup(3)
|
.BR libssh2_session_startup(3)
|
||||||
|
22
docs/libssh2_session_last_errno.3
Normal file
22
docs/libssh2_session_last_errno.3
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
.\" $Id: libssh2_session_last_errno.3,v 1.1 2007/06/13 23:02:08 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_last_errno 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_last_errno - get the most recent error number
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_session_last_errno(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
Determine the most recent error condition.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Numeric error code corresponding to the the Error Code constants.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_last_error(3)
|
33
docs/libssh2_session_last_error.3
Normal file
33
docs/libssh2_session_last_error.3
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
.\" $Id: libssh2_session_last_error.3,v 1.1 2007/06/13 23:02:08 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_last_error - get the most recent error
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIerrmsg\fP - If not NULL, is populated by reference with the human
|
||||||
|
readable form of the most recent error message.
|
||||||
|
|
||||||
|
\fIerrmsg_len\fP - If not NULL, is populated by reference with the length
|
||||||
|
of errmsg. (The string is NUL-terminated, so the length is only useful as
|
||||||
|
an optimization, to avoid calling strlen.)
|
||||||
|
|
||||||
|
\fIwant_buf\fP - If set to a non-zero value, "ownership" of the errmsg
|
||||||
|
buffer will be given to the calling scope. If necessary, the errmsg buffer
|
||||||
|
will be duplicated.
|
||||||
|
|
||||||
|
Determine the most recent error condition and its cause.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Numeric error code corresponding to the the Error Code constants.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_last_errno(3)
|
42
docs/libssh2_session_method_pref.3
Normal file
42
docs/libssh2_session_method_pref.3
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
.\" $Id: libssh2_session_method_pref.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_method_pref 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_method_pref - set preferred key exchange method
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fImethod_type\fP - One of the Method Type constants.
|
||||||
|
|
||||||
|
\fIprefs\fP - Coma delimited list of preferred methods to use with
|
||||||
|
the most preferred listed first and the least preferred listed last.
|
||||||
|
If a method is listed which is not supported by libssh2 it will be
|
||||||
|
ignored and not sent to the remote host during protocol negotiation.
|
||||||
|
|
||||||
|
Set preferred methods to be negotiated. These
|
||||||
|
preferrences must be set prior to calling
|
||||||
|
.BR libssh2_session_startup(3)
|
||||||
|
as they are used during the protocol initiation phase.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_INVAL\fP - The requested method type was invalid.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_METHOD_NOT_SUPPORTED\fP - The requested method is not supported.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
.BR libssh2_session_startup(3)
|
29
docs/libssh2_session_methods.3
Normal file
29
docs/libssh2_session_methods.3
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
.\" $Id: libssh2_session_methods.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_methods 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_methods - return the currently active algorithms
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
const char *
|
||||||
|
libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fImethod_type\fP - One of the Method Type constants.
|
||||||
|
|
||||||
|
Return the actual method negotiated for a particular transport parameter.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Negotiated method or NULL if the session has not yet been started.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_INVAL\fP - The requested method type was invalid.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_METHOD_NONE\fP -
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
32
docs/libssh2_session_set_blocking.3
Normal file
32
docs/libssh2_session_set_blocking.3
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
.\" $Id: libssh2_session_set_blocking.3,v 1.1 2007/06/14 17:23:13 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_set_blocking - set or clear blocking mode on session
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
|
||||||
|
make it non-blocking.
|
||||||
|
|
||||||
|
Set or clear blocking mode on the selected on the sessoin. This will
|
||||||
|
instantly affect any channels associtated with this session. If a read is
|
||||||
|
performed on a session with no data currently available, a blocking
|
||||||
|
session will wait for data to arrive and return what it receives.
|
||||||
|
A non-blocking session will return immediately with an empty buffer.
|
||||||
|
If a write is performed on a session with
|
||||||
|
no room for more data, a blocking session will wait for room. A non-blocking
|
||||||
|
session will return immediately without writing anything.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
None
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
@@ -1,16 +1,42 @@
|
|||||||
.\" $Id: libssh2_session_startup.3,v 1.2 2007/01/02 05:47:00 gusarov Exp $
|
.\" $Id: libssh2_session_startup.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_session_startup 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_session_startup 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_session_startup - begin transport layer
|
libssh2_session_startup - begin transport layer
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
int libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
|
int
|
||||||
|
libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIsocket\fP - Connected socket descriptor. Typically a TCP connection
|
||||||
|
though the protocol allows for any reliable transport and the library will
|
||||||
|
attempt to use any berkeley socket.
|
||||||
|
|
||||||
Begin transport layer protocol negotiation with the connected host.
|
Begin transport layer protocol negotiation with the connected host.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
0 on success, \-1 on failure
|
Returns 0 on success, negative on failure.
|
||||||
.SH "SEE ALSO"
|
.SH ERRORS
|
||||||
.BI libssh2_session_free(3),
|
\fILIBSSH2_ERROR_SOCKET_NONE\fP - The socket is invalid.
|
||||||
.BI libssh2_session_init(3)
|
|
||||||
|
\fILIBSSH2_ERROR_BANNER_SEND\fP - Unable to send banner to remote host.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_KEX_FAILURE\fP - >Encryption key exchange with the remote
|
||||||
|
host failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_DISCONNECT\fP - The socket was disconnected.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_PROTO\fP - An invalid SSH protocol response was received on
|
||||||
|
the socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_free(3)
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
52
docs/libssh2_sftp_close_handle.3
Normal file
52
docs/libssh2_sftp_close_handle.3
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.\" $Id: libssh2_sftp_close_handle.3,v 1.1 2007/06/14 15:45:03 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_close_handle 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_close_handle - close filehandle
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_close(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_closedir(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP - SFTP File Handle as returned by
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
or
|
||||||
|
.BR libssh2_sftp_opendir(3)
|
||||||
|
|
||||||
|
Close an active LIBSSH2_SFTP_HANDLE. Because files and directories
|
||||||
|
share the same underlying storage mechanism these methods may be used
|
||||||
|
interchangably. It is recommended that
|
||||||
|
.BR libssh2_sftp_close()
|
||||||
|
be used for files and that
|
||||||
|
.BR libssh2_sftp_closedir()
|
||||||
|
be used for directories so that future changes in the library
|
||||||
|
may cause minimal disruption.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
.BR libssh2_sftp_opendir(3)
|
49
docs/libssh2_sftp_fstat_ex.3
Normal file
49
docs/libssh2_sftp_fstat_ex.3
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
.\" $Id: libssh2_sftp_fstat_ex.3,v 1.1 2007/06/14 15:45:03 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_fstat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_fstat_ex - get or set attributes on a file handle
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat)
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs)
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_fsetstat(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs)
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP - SFTP File Handle as returned by
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
|
||||||
|
\fIattrs\fP - Pointer to attribute structure to set file metadata
|
||||||
|
from or into depending on the value of setstat.
|
||||||
|
|
||||||
|
\fIsetstat\fP - When non-zero, the file's metadata will be updated
|
||||||
|
with the data found in attrs according to the values of attrs->flags
|
||||||
|
and other relevant member attributes.
|
||||||
|
|
||||||
|
Get or Set statbuf type data for a given LIBSSH2_SFTP_HANDLE instance.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_open(3)
|
@@ -1,21 +1,41 @@
|
|||||||
.\" $Id: libssh2_sftp_init.3,v 1.2 2007/04/22 17:18:03 jehousley Exp $
|
.\" $Id: libssh2_sftp_init.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_init 3 "23 Jan 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_init -
|
libssh2_sftp_init -
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
|
LIBSSH2_SFTP *
|
||||||
|
libssh2_sftp_init(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
Open a channel and initialize the SFTP subsystem. Although the SFTP subsystem
|
Open a channel and initialize the SFTP subsystem. Although the SFTP subsystem
|
||||||
operates over the same type of channel as those exported by the Channel API,
|
operates over the same type of channel as those exported by the Channel API,
|
||||||
the protocol itself implements its own unique binary packet protocol which
|
the protocol itself implements its own unique binary packet protocol which
|
||||||
must be managed with the libssh2_sftp_*() family of functions. When an SFTP
|
must be managed with the libssh2_sftp_*() family of functions. When an SFTP
|
||||||
session is complete, it must be destroyed using the
|
session is complete, it must be destroyed using the
|
||||||
\fIlibssh2_sftp_shutdown(3)\fP function.
|
.BR libssh2_sftp_shutdown(3)
|
||||||
|
function.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to the newly allocated SFTP instance or NULL on failure.
|
A pointer to the newly allocated SFTP instance or NULL on failure.
|
||||||
.SH "SEE ALSO"
|
.SH ERRORS
|
||||||
.BI libssh2_sftp_shutdown(3), libssh2_sftp_open_ex(3)
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to be
|
||||||
|
returned by the server.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_shutdown(3)
|
||||||
|
.BR libssh2_sftp_open_ex(3)
|
||||||
|
23
docs/libssh2_sftp_last_error.3
Normal file
23
docs/libssh2_sftp_last_error.3
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
.\" $Id: libssh2_sftp_last_error.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_last_error - return the last SFTP-specific error code
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
Determines the last error code produced by the SFTP layer.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Current error code state of the SFTP instance.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
@@ -1,26 +1,46 @@
|
|||||||
.\" $Id: libssh2_sftp_mkdir_ex.3,v 1.1 2007/04/22 19:51:53 jehousley Exp $
|
.\" $Id: libssh2_sftp_mkdir_ex.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_mkdir_ex 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_mkdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_mkdir_ex - create a directory on the remote file system
|
libssh2_sftp_mkdir_ex - create a directory on the remote file system
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path,
|
int
|
||||||
unsigned int path_len, long mode);
|
libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, long mode);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fIsftp\fP SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP.
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
\fIpath\fP full path of the new directory to create. Note that the new
|
\fIpath\fP - full path of the new directory to create. Note that the new
|
||||||
directory's parents must all exist priot to making this call.
|
directory's parents must all exist priot to making this call.
|
||||||
|
|
||||||
\fIpath_len\fP length of the full path of the new directory to create.
|
\fIpath_len\fP - length of the full path of the new directory to create.
|
||||||
|
|
||||||
\fImode\fP directory creation mode (e.g. 0755).
|
\fImode\fP - directory creation mode (e.g. 0755).
|
||||||
|
|
||||||
|
Create a directory on the remote file system.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
0 on success, or -1 on failure.
|
Return 0 on success or negative on failure.
|
||||||
.SH "SEE ALSO"
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to be
|
||||||
|
returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
.BR libssh2_sftp_opendir(3)
|
.BR libssh2_sftp_opendir(3)
|
||||||
|
@@ -1,29 +0,0 @@
|
|||||||
.\" $Id: libssh2_sftp_mkdirnb_ex.3,v 1.1 2007/04/22 19:51:54 jehousley Exp $
|
|
||||||
.\"
|
|
||||||
.TH libssh2_sftp_mkdir_ex 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
|
|
||||||
.SH NAME
|
|
||||||
libssh2_sftp_mkdir_ex - create a directory on the remote file system in
|
|
||||||
non-blocking mode
|
|
||||||
.SH SYNOPSIS
|
|
||||||
#include <libssh2.h>
|
|
||||||
#include <libssh2_sftp.h>
|
|
||||||
|
|
||||||
int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path,
|
|
||||||
unsigned int path_len, long mode);
|
|
||||||
|
|
||||||
.SH DESCRIPTION
|
|
||||||
\fIsftp\fP SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP.
|
|
||||||
|
|
||||||
\fIpath\fP full path of the new directory to create. Note that the new
|
|
||||||
directory's parents must all exist priot to making this call.
|
|
||||||
|
|
||||||
\fIpath_len\fP length of the full path of the new directory to create.
|
|
||||||
|
|
||||||
\fImode\fP directory creation mode (e.g. 0755).
|
|
||||||
|
|
||||||
.SH RETURN VALUE
|
|
||||||
0 on success, or -1 on failure. It returns LIBSSH2CHANNEL_EAGAIN when
|
|
||||||
it would otherwise block. While LIBSSH2CHANNEL_EAGAIN is a negative
|
|
||||||
number, it isn't really a failure per se.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR libssh2_sftp_opendir(3)
|
|
@@ -1,23 +1,24 @@
|
|||||||
.\" $Id: libssh2_sftp_open_ex.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
|
.\" $Id: libssh2_sftp_open_ex.3,v 1.8 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_open_ex 3 "23 Jan 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_open -
|
libssh2_sftp_open -
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
|
LIBSSH2_SFTP_HANDLE *
|
||||||
char *filename, int filename_len,
|
libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type);
|
||||||
unsigned long flags, long mode, int open_type);
|
|
||||||
|
|
||||||
LIBSSH2_SFTP_HANDLE *libssh2_sftp_open(LIBSSH2_SFTP *sftp,
|
LIBSSH2_SFTP_HANDLE *
|
||||||
char *filename, unsigned long flags, long mode);
|
libssh2_sftp_open(LIBSSH2_SFTP *sftp, const char *filename, unsigned long flags, long mode);
|
||||||
|
|
||||||
|
LIBSSH2_SFTP_HANDLE *
|
||||||
|
libssh2_sftp_opendir(LIBSSH2_SFTP *sftp, const char *path);
|
||||||
|
|
||||||
LIBSSH2_SFTP_HANDLE *libssh2_sftp_opendir(LIBSSH2_SFTP *sftp,
|
|
||||||
char *path);
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fIsftp\fP - SFTP instance as returned by libssh2_sftp_init().
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
\fIfilename\fP - Remote file/directory resource to open
|
\fIfilename\fP - Remote file/directory resource to open
|
||||||
|
|
||||||
@@ -34,6 +35,19 @@ LIBSSH2_SFTP_OPENDIR (to open a directory).
|
|||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to the newly created LIBSSH2_SFTP_HANDLE instance or NULL on
|
A pointer to the newly created LIBSSH2_SFTP_HANDLE instance or NULL on
|
||||||
failure.
|
failure.
|
||||||
.SH "SEE ALSO"
|
.SH ERRORS
|
||||||
.BI libssh_sftp_close(3)
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to be
|
||||||
|
returned by the server.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh_sftp_close(3)
|
||||||
|
|
||||||
|
@@ -1,27 +1,47 @@
|
|||||||
.\" $Id: libssh2_sftp_read.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
|
.\" $Id: libssh2_sftp_read.3,v 1.8 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_read 3 "6 Feb 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_read 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_read - read data from an SFTP handle
|
libssh2_sftp_read - read data from an SFTP handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
|
ssize_t
|
||||||
char *buffer, size_t buffer_maxlen);
|
libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen);
|
||||||
.SH DESCRIPTION
|
|
||||||
Reads a block of data from an LIBSSH2_SFTP_HANDLE. This method is modelled
|
|
||||||
after the POSIX \Iread(3)\fP function and uses the same calling
|
|
||||||
semantics. \fIlibssh2_sftp_read(3)\fP will attempt to read as much as possible
|
|
||||||
however it may not fill all of buffer if the file pointer reaches the end or
|
|
||||||
if further reads would cause the socket to block.
|
|
||||||
|
|
||||||
\fIhandle\fP is the SFTP File Handle as returned by \fIlibssh2_sftp_open(3)\fP.
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP is the SFTP File Handle as returned by
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
|
||||||
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
|
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
|
||||||
|
|
||||||
\fIbuffer_maxlen\fP bytes to read data into.
|
\fIbuffer_maxlen\fP bytes to read data into.
|
||||||
|
|
||||||
|
Reads a block of data from an LIBSSH2_SFTP_HANDLE. This method is modelled
|
||||||
|
after the POSIX
|
||||||
|
.BR read(2)
|
||||||
|
function and uses the same calling semantics.
|
||||||
|
.BR libssh2_sftp_read(3)
|
||||||
|
will attempt to read as much as possible however it may not fill all of
|
||||||
|
buffer if the file pointer reaches the end or
|
||||||
|
if further reads would cause the socket to block.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Number of bytes actually populated into buffer, or -1 on failure.
|
Number of bytes actually populated into buffer, or negative on failure.
|
||||||
.SH "SEE ALSO"
|
It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to be
|
||||||
|
returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
.BR libssh2_sftp_open(3)
|
.BR libssh2_sftp_open(3)
|
||||||
.BR libssh2_sftp_readnb(3)
|
.BR libssh2_sftp_readnb(3)
|
||||||
|
@@ -1,35 +1,60 @@
|
|||||||
.\" $Id: libssh2_sftp_readdir.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
|
.\" $Id: libssh2_sftp_readdir.3,v 1.9 2007/06/15 17:22:49 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_readdir 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_readdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_readdir - read directory data from an SFTP handle
|
libssh2_sftp_readdir_ex - read directory data from an SFTP handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
int
|
||||||
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, char *longentry, size_t longentry_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Read a block of data from a LIBSSH2_SFTP_HANDLE. This method is modeled
|
\fIhandle\fP - is the SFTP File Handle as returned by
|
||||||
after the POSIX \fIreaddir(3)\fP however, it uses a variable sized directory
|
.BR libssh2_sftp_diropen(3)
|
||||||
entry (filename) buffer and returns statbuf type data in the same call.
|
|
||||||
|
|
||||||
\fIhandle\fP is the SFTP File Handle as returned by
|
\fIbuffer\fP - is a pointer to a pre-allocated buffer of at least
|
||||||
\fIlibssh2_sftp_diropen(3)\fP.
|
|
||||||
|
|
||||||
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
|
|
||||||
\fIbuffer_maxlen\fP bytes to read data into.
|
\fIbuffer_maxlen\fP bytes to read data into.
|
||||||
|
|
||||||
\fIbuffer_maxlen\fP is the length of buffer in bytes. If the length of the
|
\fIbuffer_maxlen\fP - is the length of buffer in bytes. If the length of the
|
||||||
filename is longer than the space provided by buffer_maxlen it will be
|
filename is longer than the space provided by buffer_maxlen it will be
|
||||||
truncated to fit.
|
truncated to fit.
|
||||||
|
|
||||||
\fIattrs\fP is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate
|
\fIlongentry\fP - is a pointer to a pre-allocated buffer of at least
|
||||||
|
\fIlongentry_maxlen\fP bytes to read data into.
|
||||||
|
|
||||||
|
\fIlongentry_maxlen\fP - is the length of longentry in bytes. If the length
|
||||||
|
of the full directory entry is longer than the space provided by
|
||||||
|
longentry_maxlen it will be truncated to fit.
|
||||||
|
|
||||||
|
\fIattrs\fP - is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate
|
||||||
statbuf style data into.
|
statbuf style data into.
|
||||||
|
|
||||||
|
Read a block of data from a LIBSSH2_SFTP_HANDLE. This method is modeled
|
||||||
|
after the POSIX
|
||||||
|
.BR readdir(2)
|
||||||
|
however, it uses a variable sized directory entry (filename) buffer and
|
||||||
|
returns statbuf type data in the same call.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Number of bytes actually populated into buffer, or -1 on failure.
|
Number of bytes actually populated into buffer, or -1 on failure. It returns
|
||||||
.SH "SEE ALSO"
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to be
|
||||||
|
returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
.BR libssh2_sftp_opendir(3)
|
.BR libssh2_sftp_opendir(3)
|
||||||
.BR libssh2_sftp_readdirnb(3)
|
.BR libssh2_sftp_closedir(3)
|
||||||
|
@@ -1,40 +0,0 @@
|
|||||||
.\" $Id: libssh2_sftp_readdirnb.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
|
|
||||||
.\"
|
|
||||||
.TH libssh2_sftp_readdir 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
|
|
||||||
.SH NAME
|
|
||||||
libssh2_sftp_readdirnb - read directory data from an SFTP handle non-blocking
|
|
||||||
.SH SYNOPSIS
|
|
||||||
#include <libssh2.h>
|
|
||||||
#include <libssh2_sftp.h>
|
|
||||||
|
|
||||||
int libssh2_sftp_readdirnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
|
||||||
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
|
||||||
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Read a block of data from a LIBSSH2_SFTP_HANDLE non-blocking. This method is
|
|
||||||
modeled after the POSIX \fIreaddir(3)\fP however, it uses a variable sized
|
|
||||||
directory entry (filename) buffer and returns statbuf type data in the same
|
|
||||||
call.
|
|
||||||
|
|
||||||
\fIhandle\fP is the SFTP File Handle as returned by
|
|
||||||
\fIlibssh2_sftp_diropen(3)\fP.
|
|
||||||
|
|
||||||
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
|
|
||||||
\fIbuffer_maxlen\fP bytes to read data into.
|
|
||||||
|
|
||||||
\fIbuffer_maxlen\fP is the length of buffer in bytes. If the length of the
|
|
||||||
filename is longer than the space provided by buffer_maxlen it will be
|
|
||||||
truncated to fit.
|
|
||||||
|
|
||||||
\fIattrs\fP is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate
|
|
||||||
statbuf style data into.
|
|
||||||
|
|
||||||
.SH RETURN VALUE
|
|
||||||
Number of bytes actually populated into buffer, or negative on failure. It
|
|
||||||
returns LIBSSH2CHANNEL_EAGAIN when it would otherwise block. While
|
|
||||||
LIBSSH2CHANNEL_EAGAIN is a negative number, it isn't really a failure per se.
|
|
||||||
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR libssh2_sftp_opendir(3)
|
|
||||||
.BR libssh2_sftp_readdirnb(3)
|
|
@@ -1,29 +0,0 @@
|
|||||||
.\" $Id: libssh2_sftp_readnb.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
|
|
||||||
.\"
|
|
||||||
.TH libssh2_sftp_read 3 "6 Feb 2007" "libssh2 0.15" "libssh2 manual"
|
|
||||||
.SH NAME
|
|
||||||
libssh2_sftp_readnb - read data from an SFTP handle non-blocking
|
|
||||||
.SH SYNOPSIS
|
|
||||||
#include <libssh2.h>
|
|
||||||
#include <libssh2_sftp.h>
|
|
||||||
|
|
||||||
ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle,
|
|
||||||
char *buffer, size_t buffer_maxlen);
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Reads a block of data from an LIBSSH2_SFTP_HANDLE non-blocking. This method is
|
|
||||||
modelled after the POSIX \Iread(3)\fP function and uses the same calling
|
|
||||||
semantics. \fIlibssh2_sftp_read(3)\fP will attempt to read as much as possible
|
|
||||||
however it may not fill all of buffer if the file pointer reaches the end or
|
|
||||||
if further reads would cause the socket to block.
|
|
||||||
|
|
||||||
\fIhandle\fP is the SFTP File Handle as returned by \fIlibssh2_sftp_open(3)\fP.
|
|
||||||
|
|
||||||
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
|
|
||||||
\fIbuffer_maxlen\fP bytes to read data into.
|
|
||||||
.SH RETURN VALUE
|
|
||||||
Number of bytes actually populated into buffer, or negative on failure. It
|
|
||||||
returns LIBSSH2CHANNEL_EAGAIN when it would otherwise block. While
|
|
||||||
LIBSSH2CHANNEL_EAGAIN is a negative number, it isn't really a failure per se.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR libssh2_sftp_read(3)
|
|
||||||
.BR libssh2_sftp_open(3)
|
|
58
docs/libssh2_sftp_rename_ex.3
Normal file
58
docs/libssh2_sftp_rename_ex.3
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
.\" $Id: libssh2_sftp_rename_ex.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_rename_ex - rename a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int source_filename_len, const char *dest_filename, unsigned int dest_filename_len, long flags);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, const char *dest_filename);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
\fIsourcefile\fP - Path and name of the existing filesystem entry
|
||||||
|
|
||||||
|
\fIsourcefile_len\fP - Length of the path and name of the existing
|
||||||
|
filesystem entry
|
||||||
|
|
||||||
|
\fIdestfile\fP - Path and name of the target filesystem entry
|
||||||
|
|
||||||
|
\fIdestfile_len\fP - Length of the path and name of the target
|
||||||
|
filesystem entry
|
||||||
|
|
||||||
|
\fIflags\fP -
|
||||||
|
Bitmask flags made up of LIBSSH2_SFTP_RENAME_* constants.
|
||||||
|
|
||||||
|
Rename a filesystem object on the remote filesystem. The semantics of
|
||||||
|
this command typically include the ability to move a filsystem object
|
||||||
|
between folders and/or filesystem mounts. If the LIBSSH2_SFTP_RENAME_OVERWRITE
|
||||||
|
flag is not set and the destfile entry already exists, the operation
|
||||||
|
will fail. Use of the other two flags indicate a preference (but not a
|
||||||
|
requirement) for the remote end to perform an atomic rename operation
|
||||||
|
and/or using native system calls when possible.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
43
docs/libssh2_sftp_rmdir_ex.3
Normal file
43
docs/libssh2_sftp_rmdir_ex.3
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.\" $Id: libssh2_sftp_rmdir_ex.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_rmdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_rmdir_ex - rename a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
\fIsourcefile\fP - Full path of the existing directory to remove.
|
||||||
|
|
||||||
|
\fIsourcefile_len\fP - Length of the full path of the existing directory to remove.
|
||||||
|
|
||||||
|
Remove a directory from the remote file system.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
26
docs/libssh2_sftp_seek.3
Normal file
26
docs/libssh2_sftp_seek.3
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.\" $Id: libssh2_sftp_seek.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_seek 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_seek - set the read/write position indicator within a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP - SFTP File Handle as returned by
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
|
||||||
|
\fIoffset\fP - Number of bytes from the beginning of file to seek to.
|
||||||
|
|
||||||
|
Move the file handle's internal pointer to an arbitrary location.
|
||||||
|
Note that libssh2 implements file pointers as a localized concept to make
|
||||||
|
file access appear more POSIX like. No packets are exchanged with the server
|
||||||
|
during a seek operation. The localized file pointer is simply used as a
|
||||||
|
convenience offset during read/write operations.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_open(3)
|
26
docs/libssh2_sftp_shutdown.3
Normal file
26
docs/libssh2_sftp_shutdown.3
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.\" $Id: libssh2_sftp_shutdown.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_shutdown 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_shutdown - shut down an SFTP session
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
Destroys a previously initialized SFTP session and frees all resources
|
||||||
|
associated with it.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
62
docs/libssh2_sftp_stat_ex.3
Normal file
62
docs/libssh2_sftp_stat_ex.3
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
.\" $Id: libssh2_sftp_stat_ex.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_stat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_stat_ex - rename a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_lstat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_setstat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
\fIpath\fP - Remote filesystem object to stat/lstat/setstat.
|
||||||
|
|
||||||
|
\fIpath_len\fP - Lenght of the name of the remote filesystem object
|
||||||
|
to stat/lstat/setstat.
|
||||||
|
|
||||||
|
\fIstat_type\fP - One of the three constants specifying the type of
|
||||||
|
stat operation to perform.
|
||||||
|
|
||||||
|
\fIattrs\fP - Pointer to attribute structure to set file metadata
|
||||||
|
from or into depending on the value of stat_type.
|
||||||
|
|
||||||
|
Get or Set statbuf type data on a remote filesystem object. When
|
||||||
|
getting statbuf data,
|
||||||
|
.BR libssh2_sftp_stat(3)
|
||||||
|
will follow all symlinks, while
|
||||||
|
.BR libssh2_sftp_lstat(3)
|
||||||
|
will return data about the object encountered, even if that object
|
||||||
|
happens to be a symlink.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
70
docs/libssh2_sftp_symlink_ex.3
Normal file
70
docs/libssh2_sftp_symlink_ex.3
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.\" $Id: libssh2_sftp_symlink_ex.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_symlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_symlink_ex - read or set a symbolic link
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_symlink(LIBSSH2_SFTP *sftp, const char *path, char *target);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_readlink(LIBSSH2_SFTP *sftp, const char *path, char *target, unsigned int target_len);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_realpath(LIBSSH2_SFTP *sftp, const char *path, char *target, unsigned int target_len);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
\fIpath\fP - Remote filesystem object to create a symlink from or resolve.
|
||||||
|
|
||||||
|
\fIpath_len\fP - Length of the name of the remote filesystem object to
|
||||||
|
create a symlink from or resolve.
|
||||||
|
|
||||||
|
\fItarget\fP -
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_SFTP_SYMLINK\fP: Remote filesystem object to link to.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_SFTP_READLINK\fP: Pre-allocated buffer to resolve symlink target into.
|
||||||
|
.br
|
||||||
|
\fBLIBSSH2_SFTP_REALPATH\fP: Pre-allocated buffer to resolve realpath target into.
|
||||||
|
|
||||||
|
\fItarget_len\fP - Length of the name of the remote filesystem target object.
|
||||||
|
|
||||||
|
\fIlink_type\fP - One of the three previously mentioned constants which
|
||||||
|
determines the resulting behavior of this function.
|
||||||
|
|
||||||
|
.BR libssh2_sftp_symlink(3)
|
||||||
|
: Create a symbolic link between two filesystem objects.
|
||||||
|
.br
|
||||||
|
.BR libssh2_sftp_readlink(3)
|
||||||
|
: Resolve a symbolic link filesystem object to its next target.
|
||||||
|
.br
|
||||||
|
.BR libssh2_sftp_realpath(3)
|
||||||
|
: Resolve a complex, relative, or symlinked filepath to its effective target.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
26
docs/libssh2_sftp_tell.3
Normal file
26
docs/libssh2_sftp_tell.3
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.\" $Id: libssh2_sftp_tell.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_tell 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_tell - get the current read/write position indicator for a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
size_t
|
||||||
|
libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP - SFTP File Handle as returned by
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
|
||||||
|
Identify the current offset of the file handle's internal pointer. Note
|
||||||
|
that the SSH2 protocol does not have a notion of file pointers and that
|
||||||
|
libssh2 implements this using a localized file pointer which is updated
|
||||||
|
with each read/write call.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Current offset from beginning of file in bytes.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_open(3)
|
44
docs/libssh2_sftp_unlink_ex.3
Normal file
44
docs/libssh2_sftp_unlink_ex.3
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
.\" $Id: libssh2_sftp_unlink_ex.3,v 1.1 2007/06/14 16:46:14 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_unlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_unlink_ex - rename a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
|
\fIfilename\fP - Path and name of the existing filesystem entry
|
||||||
|
|
||||||
|
\fIfilename_len\fP - Length of the path and name of the existing
|
||||||
|
filesystem entry
|
||||||
|
|
||||||
|
Unlink (delete) a file from the remote filesystem.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_init(3)
|
41
docs/libssh2_sftp_write.3
Normal file
41
docs/libssh2_sftp_write.3
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
.\" $Id: libssh2_sftp_write.3,v 1.1 2007/06/14 16:46:14 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_rename_ex - rename a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP - SFTP File Handle as returned by
|
||||||
|
.BR libssh2_sftp_open(3)
|
||||||
|
|
||||||
|
\fIbuffer\fP - Pre-initialized data buffer to write to the LIBSSH2_SFTP_HANDLE.
|
||||||
|
|
||||||
|
\fIcount\fP - Number of bytes from buffer to write. Note that it may not
|
||||||
|
be possible to write all bytes as requested.
|
||||||
|
|
||||||
|
Write a block of data to a LIBSSH2_SFTP_HANDLE. This method is modeled after the POSIX write() function and uses the same calling semantics.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Actual number of bytes written or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||||
|
received on the socket, or an SFTP operation caused an errorcode to
|
||||||
|
be returned by the server.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_open(3)
|
22
docs/libssh2_userauth_authenticated.3
Normal file
22
docs/libssh2_userauth_authenticated.3
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
.\" $Id: libssh2_userauth_authenticated.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_userauth_authenticated 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_userauth_authenticated - return authentication status
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
Indicates whether or not the named session has been successfully authenticated.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Returns 1 if authenticated and 0 if not.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
43
docs/libssh2_userauth_list.3
Normal file
43
docs/libssh2_userauth_list.3
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.\" $Id: libssh2_userauth_list.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_userauth_list 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_userauth_list - list the authentication methods supported by a server
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIusername\fP - Username which will be used while authenticating. Note
|
||||||
|
that most server implementations do not permit attempting authentication
|
||||||
|
with different usernames between requests. Therefore this must be the
|
||||||
|
same username you will use on later userauth calls.
|
||||||
|
|
||||||
|
\fIusername_len\fP - Length of username parameter.
|
||||||
|
|
||||||
|
Send a \fBSSH_USERAUTH_NONE\fP request to the remote host. Unless the
|
||||||
|
remote host is configured to accept none as a viable authentication
|
||||||
|
scheme (unlikely), it will return \fBSSH_USERAUTH_FAILURE\fB along with a
|
||||||
|
listing of what authentication schemes it does support. In the unlikely
|
||||||
|
event that none authentication succeeds, this method with return NULL. This
|
||||||
|
case may be distinguished from faily by examining
|
||||||
|
.BR libssh2_userauth_authenticated(3)
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
On success a comma delimited list of supported authentication schemes. This list is
|
||||||
|
internally managed by libssh2. On failure ruturns NULL.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
50
docs/libssh2_userauth_password_ex.3
Normal file
50
docs/libssh2_userauth_password_ex.3
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
.\" $Id: libssh2_userauth_password_ex.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_userauth_password_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_userauth_password_ex - authenticate a session with username and password
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_password(LIBSSH2_SESSION *session, const char *username, const char *password);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIusername\fP - Name of user to attempt plain password authentication for.
|
||||||
|
|
||||||
|
\fIusername_len\fP - Length of username parameter.
|
||||||
|
|
||||||
|
\fIpassword\fP - Password to use for authenticating username.
|
||||||
|
|
||||||
|
\fIpassword_len\fP - Length of password parameter.
|
||||||
|
|
||||||
|
\fIpasswd_change_cb\fP - If the host accepts authentication but
|
||||||
|
requests that the password be changed, this callback will be issued.
|
||||||
|
If no callback is defined, but server required password change,
|
||||||
|
authentication will fail.
|
||||||
|
|
||||||
|
Attempt basic password authentication. Note that many SSH servers
|
||||||
|
which appear to support ordinary password authentication actually have
|
||||||
|
it disabled and use Keyboard Interactive authentication (routed via
|
||||||
|
PAM or another authentication backed) instead.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_PASSWORD_EXPIRED\fP -
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
51
docs/libssh2_userauth_publickey_fromfile.3
Normal file
51
docs/libssh2_userauth_publickey_fromfile.3
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
.\" $Id: libssh2_userauth_publickey_fromfile.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_userauth_publickey_fromfile 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_userauth_publickey_fromfile - authenticate a session with a public key, read from a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *publickey, const char *privatekey, const char *passphrase);
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, const char *publickey, const char *privatekey, const char *passphrase);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIusername\fP - Remote user name to authenticate as.
|
||||||
|
|
||||||
|
\fIusername_len\fP - Length of username.
|
||||||
|
|
||||||
|
\fIpublickey\fP - Path and name of public key file. (e.g. /etc/ssh/hostkey.pub)
|
||||||
|
|
||||||
|
\fIprivatekey\fP - Path and name of private key file. (e.g. /etc/ssh/hostkey)
|
||||||
|
|
||||||
|
\fIpassphrase\fP - Passphrase to use when decoding private key file.
|
||||||
|
|
||||||
|
Attempt public key authentication using a PEM encoded private key file stored on disk
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED\fP - >The username/public key
|
||||||
|
combination was invalid.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
|
||||||
|
combination was invalid, or the signature for the supplied public
|
||||||
|
key was invalid.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
@@ -1,15 +1,22 @@
|
|||||||
.\" $Id: template.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
|
.\" $Id: template.3,v 1.4 2007/06/13 16:41:33 jehousley Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_template 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_template 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_template - short function description
|
libssh2_template - short function description
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
void libssh2_template(void);
|
void
|
||||||
|
libssh2_template(void);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Long text describing the function and its input arguments.
|
Long text describing the function and its input arguments.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Describe what the function returns.
|
Describe what the function returns.
|
||||||
.SH "SEE ALSO"
|
|
||||||
|
.SH ERRORS
|
||||||
|
Add error codes
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
Add related functions
|
Add related functions
|
||||||
|
@@ -3,6 +3,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
|||||||
# samples
|
# samples
|
||||||
noinst_PROGRAMS = ssh2 \
|
noinst_PROGRAMS = ssh2 \
|
||||||
scp scp_nonblock \
|
scp scp_nonblock \
|
||||||
|
scp_write scp_write_nonblock \
|
||||||
sftp sftp_nonblock \
|
sftp sftp_nonblock \
|
||||||
sftp_write sftp_write_nonblock \
|
sftp_write sftp_write_nonblock \
|
||||||
sftp_mkdir sftp_mkdir_nonblock \
|
sftp_mkdir sftp_mkdir_nonblock \
|
||||||
@@ -18,6 +19,10 @@ scp_SOURCES = scp.c
|
|||||||
|
|
||||||
scp_nonblock_SOURCES = scp_nonblock.c
|
scp_nonblock_SOURCES = scp_nonblock.c
|
||||||
|
|
||||||
|
scp_write_SOURCES = scp_write.c
|
||||||
|
|
||||||
|
scp_write_nonblock_SOURCES = scp_write_nonblock.c
|
||||||
|
|
||||||
sftp_SOURCES = sftp.c
|
sftp_SOURCES = sftp.c
|
||||||
|
|
||||||
sftp_nonblock_SOURCES = sftp_nonblock.c
|
sftp_nonblock_SOURCES = sftp_nonblock.c
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: scp.c,v 1.6 2007/04/26 23:59:14 gknauf Exp $
|
* $Id: scp.c,v 1.7 2007/06/06 12:34:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do a simple SCP transfer.
|
* Sample showing how to do a simple SCP transfer.
|
||||||
*/
|
*/
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -31,6 +34,7 @@
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
unsigned long hostaddr;
|
||||||
int sock, i, auth_pw = 1;
|
int sock, i, auth_pw = 1;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
const char *fingerprint;
|
const char *fingerprint;
|
||||||
@@ -49,6 +53,21 @@ int main(int argc, char *argv[])
|
|||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
hostaddr = inet_addr(argv[1]);
|
||||||
|
} else {
|
||||||
|
hostaddr = htonl(0x7F000001);
|
||||||
|
}
|
||||||
|
if (argc > 2) {
|
||||||
|
username = argv[2];
|
||||||
|
}
|
||||||
|
if (argc > 3) {
|
||||||
|
password = argv[3];
|
||||||
|
}
|
||||||
|
if (argc > 4) {
|
||||||
|
scppath = argv[4];
|
||||||
|
}
|
||||||
|
|
||||||
/* Ultra basic "connect to port 22 on localhost"
|
/* Ultra basic "connect to port 22 on localhost"
|
||||||
* Your code is responsible for creating the socket establishing the
|
* Your code is responsible for creating the socket establishing the
|
||||||
* connection
|
* connection
|
||||||
@@ -57,7 +76,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = htons(22);
|
sin.sin_port = htons(22);
|
||||||
sin.sin_addr.s_addr = htonl(0x7F000001);
|
sin.sin_addr.s_addr = hostaddr;
|
||||||
if (connect(sock, (struct sockaddr*)(&sin),
|
if (connect(sock, (struct sockaddr*)(&sin),
|
||||||
sizeof(struct sockaddr_in)) != 0) {
|
sizeof(struct sockaddr_in)) != 0) {
|
||||||
fprintf(stderr, "failed to connect!\n");
|
fprintf(stderr, "failed to connect!\n");
|
||||||
@@ -70,9 +89,6 @@ int main(int argc, char *argv[])
|
|||||||
if(!session)
|
if(!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* trace transport layer stuff*/
|
|
||||||
libssh2_trace(session, LIBSSH2_TRACE_TRANS);
|
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
@@ -88,26 +104,16 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 16; i++) {
|
for(i = 0; i < 16; i++) {
|
||||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if(argc > 1) {
|
|
||||||
username = argv[1];
|
|
||||||
}
|
|
||||||
if(argc > 2) {
|
|
||||||
password = argv[2];
|
|
||||||
}
|
|
||||||
if(argc > 3) {
|
|
||||||
scppath = argv[3];
|
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -116,7 +122,7 @@ int main(int argc, char *argv[])
|
|||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,11 +146,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
rc = libssh2_channel_read(channel, mem, amount);
|
rc = libssh2_channel_read(channel, mem, amount);
|
||||||
if(rc == amount) {
|
if(rc == amount) {
|
||||||
write(2, mem, rc);
|
write(1, mem, rc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "libssh2_channel_read() failed: %d\n",
|
fprintf(stderr, "libssh2_channel_read() failed: %d\n", rc);
|
||||||
rc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
got += rc;
|
got += rc;
|
||||||
@@ -165,6 +170,6 @@ int main(int argc, char *argv[])
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: scp_nonblock.c,v 1.3 2007/04/26 23:59:14 gknauf Exp $
|
* $Id: scp_nonblock.c,v 1.5 2007/06/08 13:33:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SCP transfers in a non-blocking manner.
|
* Sample showing how to do SCP transfers in a non-blocking manner.
|
||||||
*/
|
*/
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -31,6 +34,7 @@
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
unsigned long hostaddr;
|
||||||
int sock, i, auth_pw = 1;
|
int sock, i, auth_pw = 1;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
const char *fingerprint;
|
const char *fingerprint;
|
||||||
@@ -49,6 +53,21 @@ int main(int argc, char *argv[])
|
|||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
hostaddr = inet_addr(argv[1]);
|
||||||
|
} else {
|
||||||
|
hostaddr = htonl(0x7F000001);
|
||||||
|
}
|
||||||
|
if (argc > 2) {
|
||||||
|
username = argv[2];
|
||||||
|
}
|
||||||
|
if (argc > 3) {
|
||||||
|
password = argv[3];
|
||||||
|
}
|
||||||
|
if (argc > 4) {
|
||||||
|
scppath = argv[4];
|
||||||
|
}
|
||||||
|
|
||||||
/* Ultra basic "connect to port 22 on localhost"
|
/* Ultra basic "connect to port 22 on localhost"
|
||||||
* Your code is responsible for creating the socket establishing the
|
* Your code is responsible for creating the socket establishing the
|
||||||
* connection
|
* connection
|
||||||
@@ -57,9 +76,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = htons(22);
|
sin.sin_port = htons(22);
|
||||||
sin.sin_addr.s_addr = htonl(0x7F000001);
|
sin.sin_addr.s_addr = hostaddr;
|
||||||
if (connect(sock, (struct sockaddr*)(&sin),
|
if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
|
||||||
sizeof(struct sockaddr_in)) != 0) {
|
|
||||||
fprintf(stderr, "failed to connect!\n");
|
fprintf(stderr, "failed to connect!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -74,16 +92,18 @@ int main(int argc, char *argv[])
|
|||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance */
|
||||||
*/
|
|
||||||
session = libssh2_session_init();
|
session = libssh2_session_init();
|
||||||
if (!session)
|
if (!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
rc = libssh2_session_startup(session, sock);
|
while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -95,46 +115,41 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 16; i++) {
|
for(i = 0; i < 16; i++) {
|
||||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if(argc > 1) {
|
|
||||||
username = argv[1];
|
|
||||||
}
|
|
||||||
if(argc > 2) {
|
|
||||||
password = argv[2];
|
|
||||||
}
|
|
||||||
if(argc > 3) {
|
|
||||||
scppath = argv[3];
|
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
printf("Authentication by password failed.\n");
|
if (rc) {
|
||||||
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username,
|
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
printf("\tAuthentication by public key failed\n");
|
if (rc) {
|
||||||
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request a file via SCP */
|
/* Request a file via SCP */
|
||||||
|
fprintf(stderr, "libssh2_scp_recv()!\n");
|
||||||
|
do {
|
||||||
channel = libssh2_scp_recv(session, scppath, &fileinfo);
|
channel = libssh2_scp_recv(session, scppath, &fileinfo);
|
||||||
|
|
||||||
if (!channel) {
|
if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to open a session\n");
|
fprintf(stderr, "Unable to open a session\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!channel);
|
||||||
fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n");
|
fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n");
|
||||||
|
|
||||||
while(got < fileinfo.st_size) {
|
while(got < fileinfo.st_size) {
|
||||||
@@ -152,14 +167,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* loop until we block */
|
/* loop until we block */
|
||||||
rc = libssh2_channel_readnb(channel, mem, amount);
|
rc = libssh2_channel_read(channel, mem, amount);
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
write(2, mem, rc);
|
write(1, mem, rc);
|
||||||
got += rc;
|
got += rc;
|
||||||
}
|
}
|
||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
|
|
||||||
if(rc == LIBSSH2CHANNEL_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
/* this is due to blocking that would occur otherwise
|
/* this is due to blocking that would occur otherwise
|
||||||
so we loop on this condition */
|
so we loop on this condition */
|
||||||
|
|
||||||
@@ -186,8 +201,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
|
|
||||||
libssh2_session_disconnect(session,
|
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
||||||
"Normal Shutdown, Thank you for playing");
|
|
||||||
libssh2_session_free(session);
|
libssh2_session_free(session);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -197,6 +211,6 @@ int main(int argc, char *argv[])
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
201
example/simple/scp_write.c
Normal file
201
example/simple/scp_write.c
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* $Id: scp_write.c,v 1.1 2007/06/06 12:34:08 jehousley Exp $
|
||||||
|
*
|
||||||
|
* Sample showing how to do a simple SCP transfer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_config.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
# ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
# include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned long hostaddr;
|
||||||
|
int sock, i, auth_pw = 1;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
const char *fingerprint;
|
||||||
|
LIBSSH2_SESSION *session;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
char *username=(char *)"username";
|
||||||
|
char *password=(char *)"password";
|
||||||
|
char *loclfile=(char *)"scp_write.c";
|
||||||
|
char *scppath=(char *)"/tmp/TEST";
|
||||||
|
FILE *local;
|
||||||
|
int rc;
|
||||||
|
char mem[1024];
|
||||||
|
size_t nread;
|
||||||
|
char *ptr;
|
||||||
|
struct stat fileinfo;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WSADATA wsadata;
|
||||||
|
|
||||||
|
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
hostaddr = inet_addr(argv[1]);
|
||||||
|
} else {
|
||||||
|
hostaddr = htonl(0x7F000001);
|
||||||
|
}
|
||||||
|
if (argc > 2) {
|
||||||
|
username = argv[2];
|
||||||
|
}
|
||||||
|
if (argc > 3) {
|
||||||
|
password = argv[3];
|
||||||
|
}
|
||||||
|
if(argc > 4) {
|
||||||
|
loclfile = argv[4];
|
||||||
|
}
|
||||||
|
if (argc > 5) {
|
||||||
|
scppath = argv[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
local = fopen(loclfile, "rb");
|
||||||
|
if (!local) {
|
||||||
|
fprintf(stderr, "Can't local file %s\n", loclfile);
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat(loclfile, &fileinfo);
|
||||||
|
|
||||||
|
/* Ultra basic "connect to port 22 on localhost"
|
||||||
|
* Your code is responsible for creating the socket establishing the
|
||||||
|
* connection
|
||||||
|
*/
|
||||||
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = htons(22);
|
||||||
|
sin.sin_addr.s_addr = hostaddr;
|
||||||
|
if (connect(sock, (struct sockaddr*)(&sin),
|
||||||
|
sizeof(struct sockaddr_in)) != 0) {
|
||||||
|
fprintf(stderr, "failed to connect!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a session instance
|
||||||
|
*/
|
||||||
|
session = libssh2_session_init();
|
||||||
|
if(!session)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
|
* and setup crypto, compression, and MAC layers
|
||||||
|
*/
|
||||||
|
rc = libssh2_session_startup(session, sock);
|
||||||
|
if(rc) {
|
||||||
|
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point we havn't yet authenticated. The first thing to do
|
||||||
|
* is check the hostkey's fingerprint against our known hosts Your app
|
||||||
|
* may have it hard coded, may go to a file, may present it to the
|
||||||
|
* user, that's your call
|
||||||
|
*/
|
||||||
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
|
fprintf(stderr, "Fingerprint: ");
|
||||||
|
for(i = 0; i < 16; i++) {
|
||||||
|
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
if (auth_pw) {
|
||||||
|
/* We could authenticate via password */
|
||||||
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Or by public key */
|
||||||
|
if (libssh2_userauth_publickey_fromfile(session, username,
|
||||||
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
|
"/home/username/.ssh/id_rsa",
|
||||||
|
password)) {
|
||||||
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//libssh2_trace(session, 0xFFFF);
|
||||||
|
|
||||||
|
/* Request a file via SCP */
|
||||||
|
channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode, (unsigned long)fileinfo.st_size);
|
||||||
|
|
||||||
|
if (!channel) {
|
||||||
|
fprintf(stderr, "Unable to open a session\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "SCP session waiting to send file\n");
|
||||||
|
do {
|
||||||
|
nread = fread(mem, 1, sizeof(mem), local);
|
||||||
|
if (nread <= 0) {
|
||||||
|
/* end of file */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr = mem;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* write data in a loop until we block */
|
||||||
|
rc = libssh2_channel_write(channel, ptr, nread);
|
||||||
|
ptr += rc;
|
||||||
|
nread -= nread;
|
||||||
|
} while (rc > 0);
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
fprintf(stderr, "Sending EOF\n");
|
||||||
|
libssh2_channel_send_eof(channel);
|
||||||
|
|
||||||
|
fprintf(stderr, "Waiting for EOF\n");
|
||||||
|
libssh2_channel_wait_eof(channel);
|
||||||
|
|
||||||
|
fprintf(stderr, "Waiting for channel to close\n");
|
||||||
|
libssh2_channel_wait_closed(channel);
|
||||||
|
|
||||||
|
// fprintf(stderr, "Closing channel\n");
|
||||||
|
// libssh2_channel_close(channel);
|
||||||
|
|
||||||
|
libssh2_channel_free(channel);
|
||||||
|
channel = NULL;
|
||||||
|
|
||||||
|
shutdown:
|
||||||
|
|
||||||
|
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
||||||
|
libssh2_session_free(session);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
Sleep(1000);
|
||||||
|
closesocket(sock);
|
||||||
|
#else
|
||||||
|
sleep(1);
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "all done\n");
|
||||||
|
return 0;
|
||||||
|
}
|
222
example/simple/scp_write_nonblock.c
Normal file
222
example/simple/scp_write_nonblock.c
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* $Id: scp_write_nonblock.c,v 1.2 2007/06/08 13:33:08 jehousley Exp $
|
||||||
|
*
|
||||||
|
* Sample showing how to do a simple SCP transfer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_config.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
# ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
# include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned long hostaddr;
|
||||||
|
int sock, i, auth_pw = 1;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
const char *fingerprint;
|
||||||
|
LIBSSH2_SESSION *session;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
char *username=(char *)"username";
|
||||||
|
char *password=(char *)"password";
|
||||||
|
char *loclfile=(char *)"scp_write.c";
|
||||||
|
char *scppath=(char *)"/tmp/TEST";
|
||||||
|
FILE *local;
|
||||||
|
int rc;
|
||||||
|
char mem[1024];
|
||||||
|
size_t nread;
|
||||||
|
char *ptr;
|
||||||
|
struct stat fileinfo;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WSADATA wsadata;
|
||||||
|
|
||||||
|
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
hostaddr = inet_addr(argv[1]);
|
||||||
|
} else {
|
||||||
|
hostaddr = htonl(0x7F000001);
|
||||||
|
}
|
||||||
|
if (argc > 2) {
|
||||||
|
username = argv[2];
|
||||||
|
}
|
||||||
|
if (argc > 3) {
|
||||||
|
password = argv[3];
|
||||||
|
}
|
||||||
|
if(argc > 4) {
|
||||||
|
loclfile = argv[4];
|
||||||
|
}
|
||||||
|
if (argc > 5) {
|
||||||
|
scppath = argv[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
local = fopen(loclfile, "rb");
|
||||||
|
if (!local) {
|
||||||
|
fprintf(stderr, "Can't local file %s\n", loclfile);
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat(loclfile, &fileinfo);
|
||||||
|
|
||||||
|
/* Ultra basic "connect to port 22 on localhost"
|
||||||
|
* Your code is responsible for creating the socket establishing the
|
||||||
|
* connection
|
||||||
|
*/
|
||||||
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = htons(22);
|
||||||
|
sin.sin_addr.s_addr = hostaddr;
|
||||||
|
if (connect(sock, (struct sockaddr*)(&sin),
|
||||||
|
sizeof(struct sockaddr_in)) != 0) {
|
||||||
|
fprintf(stderr, "failed to connect!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We set the socket non-blocking. We do it after the connect just to
|
||||||
|
simplify the example code. */
|
||||||
|
#ifdef F_SETFL
|
||||||
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#else
|
||||||
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Create a session instance
|
||||||
|
*/
|
||||||
|
session = libssh2_session_init();
|
||||||
|
if(!session)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
|
* and setup crypto, compression, and MAC layers
|
||||||
|
*/
|
||||||
|
while ((rc = libssh2_session_startup(session, sock))
|
||||||
|
== LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if(rc) {
|
||||||
|
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point we havn't yet authenticated. The first thing to do
|
||||||
|
* is check the hostkey's fingerprint against our known hosts Your app
|
||||||
|
* may have it hard coded, may go to a file, may present it to the
|
||||||
|
* user, that's your call
|
||||||
|
*/
|
||||||
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
|
fprintf(stderr, "Fingerprint: ");
|
||||||
|
for(i = 0; i < 16; i++) {
|
||||||
|
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
if (auth_pw) {
|
||||||
|
/* We could authenticate via password */
|
||||||
|
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Or by public key */
|
||||||
|
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||||
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
|
"/home/username/.ssh/id_rsa",
|
||||||
|
password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// libssh2_trace(session, 0xFF7D);
|
||||||
|
|
||||||
|
/* Request a file via SCP */
|
||||||
|
do {
|
||||||
|
channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode, (unsigned long)fileinfo.st_size);
|
||||||
|
|
||||||
|
if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
|
fprintf(stderr, "Unable to open a session\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
} while (!channel);
|
||||||
|
|
||||||
|
fprintf(stderr, "SCP session waiting to send file\n");
|
||||||
|
do {
|
||||||
|
nread = fread(mem, 1, sizeof(mem), local);
|
||||||
|
if (nread <= 0) {
|
||||||
|
/* end of file */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr = mem;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* write data in a loop until we block */
|
||||||
|
while ((rc = libssh2_channel_write(channel, ptr, nread)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "ERROR %d\n", rc);
|
||||||
|
}
|
||||||
|
ptr += rc;
|
||||||
|
nread -= rc;
|
||||||
|
} while (nread > 0);
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
fprintf(stderr, "Sending EOF\n");
|
||||||
|
while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
fprintf(stderr, "Waiting for EOF\n");
|
||||||
|
while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
fprintf(stderr, "Waiting for channel to close\n");
|
||||||
|
while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
// fprintf(stderr, "Closing channel\n");
|
||||||
|
// while (libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
libssh2_channel_free(channel);
|
||||||
|
channel = NULL;
|
||||||
|
|
||||||
|
shutdown:
|
||||||
|
|
||||||
|
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
libssh2_session_free(session);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
Sleep(1000);
|
||||||
|
closesocket(sock);
|
||||||
|
#else
|
||||||
|
sleep(1);
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "all done\n");
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp.c,v 1.7 2007/04/26 23:59:14 gknauf Exp $
|
* $Id: sftp.c,v 1.8 2007/06/06 12:34:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP transfers.
|
* Sample showing how to do SFTP transfers.
|
||||||
*
|
*
|
||||||
@@ -94,6 +94,9 @@ int main(int argc, char *argv[])
|
|||||||
if(!session)
|
if(!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are blocking */
|
||||||
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
@@ -103,22 +106,25 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||||
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
/* At this point we havn't yet authenticated. The first thing to do
|
/* At this point we havn't yet authenticated. The first thing to do
|
||||||
* is check the hostkey's fingerprint against our known hosts Your app
|
* is check the hostkey's fingerprint against our known hosts Your app
|
||||||
* may have it hard coded, may go to a file, may present it to the
|
* may have it hard coded, may go to a file, may present it to the
|
||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 16; i++) {
|
for(i = 0; i < 16; i++) {
|
||||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -127,7 +133,7 @@ int main(int argc, char *argv[])
|
|||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +147,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||||
libssh2_sftp_set_blocking(sftp_session, 1);
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open()!\n");
|
fprintf(stderr, "libssh2_sftp_open()!\n");
|
||||||
/* Request a file via SFTP */
|
/* Request a file via SFTP */
|
||||||
@@ -160,7 +166,7 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, "libssh2_sftp_read()!\n");
|
fprintf(stderr, "libssh2_sftp_read()!\n");
|
||||||
rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
|
rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
write(2, mem, rc);
|
write(1, mem, rc);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -181,6 +187,6 @@ int main(int argc, char *argv[])
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_RW_nonblock.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftp_RW_nonblock.c,v 1.7 2007/06/08 13:33:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
||||||
*
|
*
|
||||||
@@ -106,6 +106,8 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
/* At this point we havn't yet authenticated. The first thing to do
|
/* At this point we havn't yet authenticated. The first thing to do
|
||||||
* is check the hostkey's fingerprint against our known hosts Your app
|
* is check the hostkey's fingerprint against our known hosts Your app
|
||||||
* may have it hard coded, may go to a file, may present it to the
|
* may have it hard coded, may go to a file, may present it to the
|
||||||
@@ -173,8 +175,7 @@ int main(int argc, char *argv[])
|
|||||||
do {
|
do {
|
||||||
do {
|
do {
|
||||||
/* read in a loop until we block */
|
/* read in a loop until we block */
|
||||||
rc = libssh2_sftp_readnb(sftp_handle, mem,
|
rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
|
||||||
sizeof(mem));
|
|
||||||
fprintf(stderr, "libssh2_sftp_read returned %d\n",
|
fprintf(stderr, "libssh2_sftp_read returned %d\n",
|
||||||
rc);
|
rc);
|
||||||
|
|
||||||
@@ -186,7 +187,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
|
|
||||||
if(rc != LIBSSH2SFTP_EAGAIN) {
|
if(rc != LIBSSH2_ERROR_EAGAIN) {
|
||||||
/* error or end of file */
|
/* error or end of file */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -239,13 +240,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
/* write data in a loop until we block */
|
/* write data in a loop until we block */
|
||||||
rc = libssh2_sftp_writenb(sftp_handle, ptr,
|
rc = libssh2_sftp_write(sftp_handle, ptr,
|
||||||
nread);
|
nread);
|
||||||
ptr += rc;
|
ptr += rc;
|
||||||
nread -= nread;
|
nread -= nread;
|
||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
|
|
||||||
if(rc != LIBSSH2SFTP_EAGAIN) {
|
if(rc != LIBSSH2_ERROR_EAGAIN) {
|
||||||
/* error or end of file */
|
/* error or end of file */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_mkdir.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftp_mkdir.c,v 1.4 2007/06/06 12:34:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP mkdir
|
* Sample showing how to do SFTP mkdir
|
||||||
*
|
*
|
||||||
@@ -138,7 +138,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||||
libssh2_sftp_set_blocking(sftp_session, 1);
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_mkdir()!\n");
|
fprintf(stderr, "libssh2_sftp_mkdir()!\n");
|
||||||
/* Make a directory via SFTP */
|
/* Make a directory via SFTP */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_mkdir_nonblock.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftp_mkdir_nonblock.c,v 1.6 2007/06/08 13:33:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP non-blocking mkdir.
|
* Sample showing how to do SFTP non-blocking mkdir.
|
||||||
*
|
*
|
||||||
@@ -148,15 +148,15 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
libssh2_sftp_set_blocking(sftp_session, 0);
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_mkdirnb()!\n");
|
fprintf(stderr, "libssh2_sftp_mkdirnb()!\n");
|
||||||
/* Make a directory via SFTP */
|
/* Make a directory via SFTP */
|
||||||
while ((rc = libssh2_sftp_mkdirnb(sftp_session, sftppath,
|
while ((rc = libssh2_sftp_mkdir(sftp_session, sftppath,
|
||||||
LIBSSH2_SFTP_S_IRWXU|
|
LIBSSH2_SFTP_S_IRWXU|
|
||||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
|
||||||
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH))
|
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH))
|
||||||
== LIBSSH2SFTP_EAGAIN) {
|
== LIBSSH2_ERROR_EAGAIN) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_nonblock.c,v 1.7 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftp_nonblock.c,v 1.10 2007/06/08 13:33:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP non-blocking transfers.
|
* Sample showing how to do SFTP non-blocking transfers.
|
||||||
*
|
*
|
||||||
@@ -98,16 +98,18 @@ int main(int argc, char *argv[])
|
|||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance */
|
||||||
*/
|
|
||||||
session = libssh2_session_init();
|
session = libssh2_session_init();
|
||||||
if (!session)
|
if (!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
rc = libssh2_session_startup(session, sock);
|
while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -119,60 +121,63 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 16; i++) {
|
for(i = 0; i < 16; i++) {
|
||||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
printf("Authentication by password failed.\n");
|
if (rc) {
|
||||||
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username,
|
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
printf("\tAuthentication by public key failed\n");
|
if (rc) {
|
||||||
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||||
|
do {
|
||||||
sftp_session = libssh2_sftp_init(session);
|
sftp_session = libssh2_sftp_init(session);
|
||||||
|
|
||||||
if (!sftp_session) {
|
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to init SFTP session\n");
|
fprintf(stderr, "Unable to init SFTP session\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!sftp_session);
|
||||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
|
||||||
libssh2_sftp_set_blocking(sftp_session, 0);
|
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open()!\n");
|
fprintf(stderr, "libssh2_sftp_open()!\n");
|
||||||
/* Request a file via SFTP */
|
/* Request a file via SFTP */
|
||||||
sftp_handle =
|
do {
|
||||||
libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
|
sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
|
||||||
|
|
||||||
if (!sftp_handle) {
|
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to open file with SFTP\n");
|
fprintf(stderr, "Unable to open file with SFTP\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!sftp_handle);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
|
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
|
||||||
do {
|
do {
|
||||||
char mem[1024];
|
char mem[1024];
|
||||||
|
|
||||||
/* loop until we fail */
|
/* loop until we fail */
|
||||||
fprintf(stderr, "libssh2_sftp_readnb()!\n");
|
fprintf(stderr, "libssh2_sftp_readnb()!\n");
|
||||||
while ((rc = libssh2_sftp_readnb(sftp_handle, mem, sizeof(mem))) == LIBSSH2SFTP_EAGAIN) {
|
while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
write(2, mem, rc);
|
write(1, mem, rc);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -183,7 +188,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
|
|
||||||
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
|
||||||
libssh2_session_free(session);
|
libssh2_session_free(session);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -193,6 +198,6 @@ int main(int argc, char *argv[])
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_write.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftp_write.c,v 1.4 2007/06/06 12:34:09 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP write transfers.
|
* Sample showing how to do SFTP write transfers.
|
||||||
*
|
*
|
||||||
@@ -106,6 +106,9 @@ int main(int argc, char *argv[])
|
|||||||
if(!session)
|
if(!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are blocking */
|
||||||
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
@@ -144,6 +147,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//libssh2_trace(session, 0xFFFF);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||||
sftp_session = libssh2_sftp_init(session);
|
sftp_session = libssh2_sftp_init(session);
|
||||||
|
|
||||||
@@ -153,13 +158,13 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||||
libssh2_sftp_set_blocking(sftp_session, 1);
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open()!\n");
|
fprintf(stderr, "libssh2_sftp_open()!\n");
|
||||||
/* Request a file via SFTP */
|
/* Request a file via SFTP */
|
||||||
sftp_handle =
|
sftp_handle =
|
||||||
libssh2_sftp_open(sftp_session, sftppath,
|
libssh2_sftp_open(sftp_session, sftppath,
|
||||||
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
|
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
||||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_write_nonblock.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftp_write_nonblock.c,v 1.7 2007/06/08 13:33:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP non-blocking write transfers.
|
* Sample showing how to do SFTP non-blocking write transfers.
|
||||||
*
|
*
|
||||||
@@ -116,10 +116,14 @@ int main(int argc, char *argv[])
|
|||||||
if (!session)
|
if (!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
rc = libssh2_session_startup(session, sock);
|
while ((rc = libssh2_session_startup(session, sock))
|
||||||
|
== LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -139,44 +143,51 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if (rc) {
|
||||||
printf("Authentication by password failed.\n");
|
printf("Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username,
|
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if (rc) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
printf("\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||||
|
do {
|
||||||
sftp_session = libssh2_sftp_init(session);
|
sftp_session = libssh2_sftp_init(session);
|
||||||
|
|
||||||
if (!sftp_session) {
|
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to init SFTP session\n");
|
fprintf(stderr, "Unable to init SFTP session\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!sftp_session);
|
||||||
|
|
||||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
libssh2_sftp_set_blocking(sftp_session, 0);
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open()!\n");
|
fprintf(stderr, "libssh2_sftp_open()!\n");
|
||||||
/* Request a file via SFTP */
|
/* Request a file via SFTP */
|
||||||
|
do {
|
||||||
sftp_handle =
|
sftp_handle =
|
||||||
libssh2_sftp_open(sftp_session, sftppath,
|
libssh2_sftp_open(sftp_session, sftppath,
|
||||||
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
|
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
||||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
||||||
|
|
||||||
if (!sftp_handle) {
|
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to open file with SFTP\n");
|
fprintf(stderr, "Unable to open file with SFTP\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!sftp_handle);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
|
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
|
||||||
do {
|
do {
|
||||||
nread = fread(mem, 1, sizeof(mem), local);
|
nread = fread(mem, 1, sizeof(mem), local);
|
||||||
@@ -188,7 +199,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
/* write data in a loop until we block */
|
/* write data in a loop until we block */
|
||||||
while ((rc = libssh2_sftp_writenb(sftp_handle, ptr, nread)) == LIBSSH2SFTP_EAGAIN) {
|
while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
ptr += rc;
|
ptr += rc;
|
||||||
@@ -202,7 +213,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
|
|
||||||
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
|
||||||
libssh2_session_free(session);
|
libssh2_session_free(session);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftpdir.c,v 1.4 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftpdir.c,v 1.6 2007/06/15 17:22:49 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample doing an SFTP directory listing.
|
* Sample doing an SFTP directory listing.
|
||||||
*
|
*
|
||||||
@@ -114,7 +114,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if ((i = libssh2_userauth_password(session, username, password))) {
|
||||||
printf("Authentication by password failed.\n");
|
printf("Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||||
libssh2_sftp_set_blocking(sftp_session, 1);
|
libssh2_session_set_blocking(session, 1);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_opendir()!\n");
|
fprintf(stderr, "libssh2_sftp_opendir()!\n");
|
||||||
/* Request a dir listing via SFTP */
|
/* Request a dir listing via SFTP */
|
||||||
@@ -151,15 +151,19 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
|
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
|
||||||
do {
|
do {
|
||||||
char mem[512];
|
char mem[512];
|
||||||
|
char longentry[512];
|
||||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||||
|
|
||||||
/* loop until we fail */
|
/* loop until we fail */
|
||||||
rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem),
|
rc = libssh2_sftp_readdir_ex(sftp_handle, mem, sizeof(mem),
|
||||||
&attrs);
|
longentry, sizeof(longentry), &attrs);
|
||||||
if(rc > 0) {
|
if(rc > 0) {
|
||||||
/* rc is the length of the file name in the mem
|
/* rc is the length of the file name in the mem
|
||||||
buffer */
|
buffer */
|
||||||
|
|
||||||
|
if (longentry[0] != '\0') {
|
||||||
|
printf("%s\n", longentry);
|
||||||
|
} else {
|
||||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
|
if(attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
|
||||||
/* this should check what permissions it
|
/* this should check what permissions it
|
||||||
is and print the output accordingly */
|
is and print the output accordingly */
|
||||||
@@ -188,6 +192,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("%s\n", mem);
|
printf("%s\n", mem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftpdir_nonblock.c,v 1.4 2007/04/26 23:59:15 gknauf Exp $
|
* $Id: sftpdir_nonblock.c,v 1.7 2007/06/08 13:33:08 jehousley Exp $
|
||||||
*
|
*
|
||||||
* Sample doing an SFTP directory listing.
|
* Sample doing an SFTP directory listing.
|
||||||
*
|
*
|
||||||
@@ -101,10 +101,13 @@ int main(int argc, char *argv[])
|
|||||||
if(!session)
|
if(!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||||
|
libssh2_session_set_blocking(session, 0);
|
||||||
|
|
||||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||||
* and setup crypto, compression, and MAC layers
|
* and setup crypto, compression, and MAC layers
|
||||||
*/
|
*/
|
||||||
rc = libssh2_session_startup(session, sock);
|
while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -124,40 +127,43 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
printf("Authentication by password failed.\n");
|
if (rc) {
|
||||||
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username,
|
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) == LIBSSH2_ERROR_EAGAIN);
|
||||||
printf("\tAuthentication by public key failed\n");
|
if (rc) {
|
||||||
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||||
|
do {
|
||||||
sftp_session = libssh2_sftp_init(session);
|
sftp_session = libssh2_sftp_init(session);
|
||||||
|
|
||||||
if (!sftp_session) {
|
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to init SFTP session\n");
|
fprintf(stderr, "Unable to init SFTP session\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!sftp_session);
|
||||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
|
||||||
libssh2_sftp_set_blocking(sftp_session, 0);
|
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_opendir()!\n");
|
fprintf(stderr, "libssh2_sftp_opendir()!\n");
|
||||||
/* Request a dir listing via SFTP */
|
/* Request a dir listing via SFTP */
|
||||||
|
do {
|
||||||
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
|
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
|
||||||
|
|
||||||
if (!sftp_handle) {
|
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
fprintf(stderr, "Unable to open dir with SFTP\n");
|
fprintf(stderr, "Unable to open dir with SFTP\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
} while (!sftp_handle);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
|
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
|
||||||
do {
|
do {
|
||||||
@@ -165,7 +171,7 @@ int main(int argc, char *argv[])
|
|||||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||||
|
|
||||||
/* loop until we fail */
|
/* loop until we fail */
|
||||||
while ((rc = libssh2_sftp_readdirnb(sftp_handle, mem, sizeof(mem), &attrs)) == LIBSSH2SFTP_EAGAIN) {
|
while ((rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem), &attrs)) == LIBSSH2_ERROR_EAGAIN) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if(rc > 0) {
|
if(rc > 0) {
|
||||||
@@ -198,7 +204,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("%s\n", mem);
|
printf("%s\n", mem);
|
||||||
}
|
}
|
||||||
else if (rc == LIBSSH2SFTP_EAGAIN) {
|
else if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
/* blocking */
|
/* blocking */
|
||||||
fprintf(stderr, "Blocking\n");
|
fprintf(stderr, "Blocking\n");
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# fetch libssh2 version number from input file and write them to STDOUT
|
# fetch libssh2 version number from input file and write them to STDOUT
|
||||||
BEGIN {
|
BEGIN {
|
||||||
while ((getline < ARGV[1]) > 0) {
|
while ((getline < ARGV[1]) > 0) {
|
||||||
if (match ($0, /^#define LIBSSH2_VERSION[\s|\t]+"[^"]+"/)) {
|
if (match ($0, /^#define LIBSSH2_VERSION[ |\t]+"[^"]+"/)) {
|
||||||
my_ver_str = substr($3, 2, length($3) - 2);
|
my_ver_str = substr($3, 2, length($3) - 2);
|
||||||
split(my_ver_str, v, ".");
|
split(my_ver_str, v, ".");
|
||||||
if (v[3])
|
if (v[3])
|
||||||
|
@@ -45,6 +45,7 @@ extern "C" {
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
/* Allow alternate API prefix from CFLAGS or calling app */
|
/* Allow alternate API prefix from CFLAGS or calling app */
|
||||||
#ifndef LIBSSH2_API
|
#ifndef LIBSSH2_API
|
||||||
@@ -76,7 +77,7 @@ typedef long long libssh2_int64_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LIBSSH2_VERSION "0.15-CVS"
|
#define LIBSSH2_VERSION "0.15-CVS"
|
||||||
#define LIBSSH2_APINO 200507211326
|
#define LIBSSH2_APINO 200706151200
|
||||||
|
|
||||||
/* Part of every banner, user specified or not */
|
/* Part of every banner, user specified or not */
|
||||||
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
|
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
|
||||||
@@ -222,6 +223,7 @@ typedef struct _LIBSSH2_POLLFD {
|
|||||||
#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
|
#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
|
||||||
|
|
||||||
/* Error Codes (defined by libssh2) */
|
/* Error Codes (defined by libssh2) */
|
||||||
|
#define LIBSSH2_ERROR_NONE 0
|
||||||
#define LIBSSH2_ERROR_SOCKET_NONE -1
|
#define LIBSSH2_ERROR_SOCKET_NONE -1
|
||||||
#define LIBSSH2_ERROR_BANNER_NONE -2
|
#define LIBSSH2_ERROR_BANNER_NONE -2
|
||||||
#define LIBSSH2_ERROR_BANNER_SEND -3
|
#define LIBSSH2_ERROR_BANNER_SEND -3
|
||||||
@@ -258,6 +260,7 @@ typedef struct _LIBSSH2_POLLFD {
|
|||||||
#define LIBSSH2_ERROR_INVAL -34
|
#define LIBSSH2_ERROR_INVAL -34
|
||||||
#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35
|
#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35
|
||||||
#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36
|
#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36
|
||||||
|
#define LIBSSH2_ERROR_EAGAIN -37
|
||||||
|
|
||||||
/* Session API */
|
/* Session API */
|
||||||
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_API LIBSSH2_SESSION *libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), LIBSSH2_FREE_FUNC((*my_free)), LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract);
|
||||||
@@ -270,13 +273,14 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
|||||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
|
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
|
||||||
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);
|
||||||
#define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
|
#define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
|
||||||
LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session);
|
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs);
|
LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs);
|
||||||
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);
|
||||||
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
|
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
|
||||||
|
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -324,6 +328,9 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
|||||||
|
|
||||||
#define SSH_EXTENDED_DATA_STDERR 1
|
#define SSH_EXTENDED_DATA_STDERR 1
|
||||||
|
|
||||||
|
/* Returned by any function that would block during a read/write opperation */
|
||||||
|
#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||||
|
|
||||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len);
|
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len);
|
||||||
#define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
|
#define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
|
||||||
|
|
||||||
@@ -351,50 +358,37 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const
|
|||||||
#define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
|
#define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
|
||||||
#define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
|
#define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
|
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen);
|
||||||
int stream_id, char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel,
|
|
||||||
int stream_id, char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
|
|
||||||
/* This is a public error code from libssh2_channel_read() that is returned
|
|
||||||
when it would otherwise block. */
|
|
||||||
#define LIBSSH2CHANNEL_EAGAIN -2
|
|
||||||
|
|
||||||
#define libssh2_channel_read(channel, buf, buflen) \
|
#define libssh2_channel_read(channel, buf, buflen) \
|
||||||
libssh2_channel_read_ex((channel), 0, (buf), (buflen))
|
libssh2_channel_read_ex((channel), 0, (buf), (buflen))
|
||||||
#define libssh2_channel_read_stderr(channel, buf, buflen) libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
|
#define libssh2_channel_read_stderr(channel, buf, buflen) \
|
||||||
#define libssh2_channel_readnb(channel, buf, buflen) \
|
libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
|
||||||
libssh2_channel_readnb_ex((channel), 0, (buf), (buflen))
|
|
||||||
|
|
||||||
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_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial);
|
LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial);
|
||||||
#define libssh2_channel_window_read(channel) libssh2_channel_window_read_ex((channel), NULL, NULL)
|
#define libssh2_channel_window_read(channel) \
|
||||||
|
libssh2_channel_window_read_ex((channel), NULL, NULL)
|
||||||
|
|
||||||
LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force);
|
LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force);
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
|
LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen);
|
||||||
int stream_id, const char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
LIBSSH2_API int libssh2_channel_writenb_ex(LIBSSH2_CHANNEL *channel,
|
|
||||||
int stream_id, const char *buf,
|
|
||||||
size_t buflen);
|
|
||||||
|
|
||||||
#define libssh2_channel_write(channel, buf, buflen) \
|
#define libssh2_channel_write(channel, buf, buflen) \
|
||||||
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
|
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
|
||||||
#define libssh2_channel_writenb(channel, buf, buflen) \
|
#define libssh2_channel_write_stderr(channel, buf, buflen) \
|
||||||
libssh2_channel_writenb_ex((channel), 0, (buf), (buflen))
|
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
|
||||||
#define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
|
|
||||||
|
|
||||||
LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial);
|
LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial);
|
||||||
#define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL)
|
#define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL)
|
||||||
|
|
||||||
|
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, int blocking);
|
||||||
|
LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session);
|
||||||
|
|
||||||
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
|
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
|
||||||
LIBSSH2_API int libssh2_channel_get_blocking(LIBSSH2_CHANNEL *channel);
|
|
||||||
|
|
||||||
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||||
|
LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||||
/* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1
|
/* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1
|
||||||
* Future uses should use libssh2_channel_handle_extended_data() directly
|
* Future uses should use libssh2_channel_handle_extended_data() directly
|
||||||
* if LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read (FIFO) from the standard data channel
|
* if LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read (FIFO) from the standard data channel
|
||||||
@@ -411,6 +405,7 @@ LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel);
|
|||||||
|
|
||||||
LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
|
LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
|
||||||
LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
|
LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
|
||||||
|
LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel);
|
||||||
LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel);
|
LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel);
|
||||||
LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
|
LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
|
||||||
LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel);
|
LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel);
|
||||||
|
@@ -92,7 +92,7 @@ LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsig
|
|||||||
LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list);
|
LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list);
|
||||||
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_API void libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
|
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@@ -166,40 +166,40 @@ struct _LIBSSH2_SFTP_ATTRIBUTES {
|
|||||||
#define LIBSSH2_FX_NO_MEDIA 13
|
#define LIBSSH2_FX_NO_MEDIA 13
|
||||||
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14
|
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14
|
||||||
#define LIBSSH2_FX_QUOTA_EXCEEDED 15
|
#define LIBSSH2_FX_QUOTA_EXCEEDED 15
|
||||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16
|
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 /* Initial mis-spelling */
|
||||||
#define LIBSSH2_FX_LOCK_CONFlICT 17
|
#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16
|
||||||
|
#define LIBSSH2_FX_LOCK_CONFlICT 17 /* Initial mis-spelling */
|
||||||
|
#define LIBSSH2_FX_LOCK_CONFLICT 17
|
||||||
#define LIBSSH2_FX_DIR_NOT_EMPTY 18
|
#define LIBSSH2_FX_DIR_NOT_EMPTY 18
|
||||||
#define LIBSSH2_FX_NOT_A_DIRECTORY 19
|
#define LIBSSH2_FX_NOT_A_DIRECTORY 19
|
||||||
#define LIBSSH2_FX_INVALID_FILENAME 20
|
#define LIBSSH2_FX_INVALID_FILENAME 20
|
||||||
#define LIBSSH2_FX_LINK_LOOP 21
|
#define LIBSSH2_FX_LINK_LOOP 21
|
||||||
|
|
||||||
|
/* Returned by any function that would block during a read/write opperation */
|
||||||
|
#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||||
|
|
||||||
/* SFTP API */
|
/* SFTP API */
|
||||||
LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
|
LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
|
||||||
LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
|
LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
|
||||||
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
||||||
|
|
||||||
/* File / Directory Ops */
|
/* File / Directory Ops */
|
||||||
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type);
|
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len,
|
||||||
#define libssh2_sftp_open(sftp, filename, flags, mode) libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE)
|
unsigned long flags, long mode, int open_type);
|
||||||
#define libssh2_sftp_opendir(sftp, path) libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR)
|
#define libssh2_sftp_open(sftp, filename, flags, mode) \
|
||||||
|
libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE)
|
||||||
|
#define libssh2_sftp_opendir(sftp, path) \
|
||||||
|
libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR)
|
||||||
|
|
||||||
/* This is a public error code from libssh2_sftp_read() that is returned
|
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen);
|
||||||
when it would otherwise block. */
|
|
||||||
#define LIBSSH2SFTP_EAGAIN -2
|
|
||||||
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
|
|
||||||
char *buffer, size_t buffer_maxlen);
|
|
||||||
LIBSSH2_API ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle,
|
|
||||||
char *buffer, size_t buffer_maxlen);
|
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen,
|
||||||
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
char *longentry, size_t longentry_maxlen,
|
||||||
LIBSSH2_API int libssh2_sftp_readdirnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||||
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
|
||||||
|
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, (attrs))
|
||||||
|
|
||||||
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
|
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
|
||||||
const char *buffer, size_t count);
|
|
||||||
LIBSSH2_API ssize_t libssh2_sftp_writenb(LIBSSH2_SFTP_HANDLE *handle,
|
|
||||||
const char *buffer, size_t count);
|
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
||||||
@@ -228,8 +228,6 @@ LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename,
|
|||||||
|
|
||||||
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
|
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
|
||||||
#define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
|
#define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
|
||||||
LIBSSH2_API int libssh2_sftp_mkdirnb_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
|
|
||||||
#define libssh2_sftp_mkdirnb(sftp, path, mode) libssh2_sftp_mkdirnb_ex((sftp), (path), strlen(path), (mode))
|
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
|
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
|
||||||
#define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
|
#define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
|
||||||
@@ -244,9 +242,6 @@ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, un
|
|||||||
#define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK)
|
#define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK)
|
||||||
#define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH)
|
#define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH)
|
||||||
|
|
||||||
LIBSSH2_API void libssh2_sftp_set_blocking(LIBSSH2_SFTP *session, int blocking);
|
|
||||||
LIBSSH2_API int libssh2_sftp_get_blocking(LIBSSH2_SFTP *session);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
##
|
##
|
||||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||||
##
|
##
|
||||||
## $Id: Makefile.netware,v 1.6 2007/04/21 20:15:33 gknauf Exp $
|
## $Id: Makefile.netware,v 1.9 2007/06/20 23:44:58 gknauf Exp $
|
||||||
#
|
#
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
@@ -468,13 +468,13 @@ libssh2.imp: Makefile.netware
|
|||||||
@echo $(DL) libssh2_channel_open_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_open_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_process_startup,$(DL) >> $@
|
@echo $(DL) libssh2_channel_process_startup,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_read_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_read_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_readnb_ex,$(DL) >> $@
|
|
||||||
@echo $(DL) libssh2_channel_request_pty_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_request_pty_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_send_eof,$(DL) >> $@
|
@echo $(DL) libssh2_channel_send_eof,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_set_blocking,$(DL) >> $@
|
@echo $(DL) libssh2_channel_set_blocking,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_setenv_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_setenv_ex,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_channel_wait_closed,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_channel_wait_eof,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_writenb_ex,$(DL) >> $@
|
|
||||||
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
|
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
|
||||||
@@ -483,9 +483,11 @@ libssh2.imp: Makefile.netware
|
|||||||
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_last_error,$(DL) >> $@
|
@echo $(DL) libssh2_session_last_error,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_method_pref,$(DL) >> $@
|
@echo $(DL) libssh2_session_method_pref,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_methods,$(DL) >> $@
|
@echo $(DL) libssh2_session_methods,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_session_set_blocking,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_startup,$(DL) >> $@
|
@echo $(DL) libssh2_session_startup,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_close_handle,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_close_handle,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_fstat_ex,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_fstat_ex,$(DL) >> $@
|
||||||
@@ -494,8 +496,7 @@ libssh2.imp: Makefile.netware
|
|||||||
@echo $(DL) libssh2_sftp_mkdir_ex,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_mkdir_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_open_ex,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_open_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_read,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_read,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_readdir,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_readdir_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_readnb,$(DL) >> $@
|
|
||||||
@echo $(DL) libssh2_sftp_rename_ex,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_rename_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_rmdir_ex,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_rmdir_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_seek,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_seek,$(DL) >> $@
|
||||||
@@ -505,7 +506,6 @@ libssh2.imp: Makefile.netware
|
|||||||
@echo $(DL) libssh2_sftp_tell,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_tell,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_unlink_ex,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_unlink_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_write,$(DL) >> $@
|
@echo $(DL) libssh2_sftp_write,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_sftp_writenb,$(DL) >> $@
|
|
||||||
@echo $(DL) libssh2_trace,$(DL) >> $@
|
@echo $(DL) libssh2_trace,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_userauth_authenticated,$(DL) >> $@
|
@echo $(DL) libssh2_userauth_authenticated,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
|
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
|
||||||
|
1401
src/channel.c
1401
src/channel.c
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,8 @@
|
|||||||
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
|
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
|
||||||
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
|
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
|
||||||
*/
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
# include <sys/poll.h>
|
# include <sys/poll.h>
|
||||||
#else
|
#else
|
||||||
@@ -65,8 +67,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libssh2.h"
|
#include "libssh2.h"
|
||||||
|
#include "libssh2_publickey.h"
|
||||||
|
#include "libssh2_sftp.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
/* Needed for struct iovec on some platforms */
|
||||||
|
#ifdef HAVE_SYS_UIO_H
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
@@ -74,6 +81,9 @@
|
|||||||
#ifdef HAVE_SYS_IOCTL_H
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBSSH2_LIBGCRYPT
|
#ifdef LIBSSH2_LIBGCRYPT
|
||||||
#include "libgcrypt.h"
|
#include "libgcrypt.h"
|
||||||
@@ -115,6 +125,112 @@ typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
|
|||||||
typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
|
typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
|
||||||
typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
|
typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
|
||||||
|
|
||||||
|
typedef int libssh2pack_t;
|
||||||
|
|
||||||
|
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_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 kmdhgGPsha1kex_state_t {
|
||||||
|
libssh2_nonblocking_states state;
|
||||||
|
unsigned char *e_packet;
|
||||||
|
unsigned char *s_packet;
|
||||||
|
unsigned char *tmp;
|
||||||
|
unsigned char h_sig_comp[SHA_DIGEST_LENGTH];
|
||||||
|
unsigned char c;
|
||||||
|
unsigned long e_packet_len;
|
||||||
|
unsigned long s_packet_len;
|
||||||
|
unsigned long 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;
|
||||||
|
unsigned long f_value_len;
|
||||||
|
unsigned long k_value_len;
|
||||||
|
unsigned long h_sig_len;
|
||||||
|
libssh2_sha1_ctx exchange_hash;
|
||||||
|
packet_require_state_t req_state;
|
||||||
|
libssh2_nonblocking_states burn_state;
|
||||||
|
} kmdhgGPsha1kex_state_t;
|
||||||
|
|
||||||
|
typedef struct key_exchange_state_low_t {
|
||||||
|
libssh2_nonblocking_states state;
|
||||||
|
packet_require_state_t req_state;
|
||||||
|
kmdhgGPsha1kex_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;
|
||||||
|
unsigned long request_len;
|
||||||
|
unsigned long 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;
|
||||||
|
unsigned long data_len;
|
||||||
|
unsigned char *oldlocal;
|
||||||
|
unsigned long 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;
|
||||||
|
} 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;
|
||||||
|
} packet_x11_open_state_t;
|
||||||
|
|
||||||
struct _LIBSSH2_PACKET {
|
struct _LIBSSH2_PACKET {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
|
|
||||||
@@ -153,13 +269,12 @@ struct _LIBSSH2_CHANNEL {
|
|||||||
unsigned char *channel_type;
|
unsigned char *channel_type;
|
||||||
unsigned channel_type_len;
|
unsigned channel_type_len;
|
||||||
|
|
||||||
int blocking;
|
|
||||||
|
|
||||||
/* channel's program exit status */
|
/* channel's program exit status */
|
||||||
int exit_status;
|
int exit_status;
|
||||||
|
|
||||||
libssh2_channel_data local, remote;
|
libssh2_channel_data local, remote;
|
||||||
unsigned long adjust_queue; /* Amount of bytes to be refunded to receive window (but not yet sent) */
|
/* Amount of bytes to be refunded to receive window (but not yet sent) */
|
||||||
|
unsigned long adjust_queue;
|
||||||
|
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
@@ -167,6 +282,77 @@ struct _LIBSSH2_CHANNEL {
|
|||||||
|
|
||||||
void *abstract;
|
void *abstract;
|
||||||
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
||||||
|
|
||||||
|
/* State variables used in libssh2_channel_setenv_ex() */
|
||||||
|
libssh2_nonblocking_states setenv_state;
|
||||||
|
unsigned char *setenv_packet;
|
||||||
|
unsigned long 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_nonblocking_states reqPTY_state;
|
||||||
|
unsigned char *reqPTY_packet;
|
||||||
|
unsigned long 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;
|
||||||
|
unsigned long 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;
|
||||||
|
unsigned long 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;
|
||||||
|
unsigned long flush_refund_bytes;
|
||||||
|
unsigned long 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;
|
||||||
|
LIBSSH2_PACKET *read_packet;
|
||||||
|
LIBSSH2_PACKET *read_next;
|
||||||
|
int read_block;
|
||||||
|
int read_bytes_read;
|
||||||
|
uint32_t read_local_id;
|
||||||
|
int read_want;
|
||||||
|
int read_unlink_packet;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_channel_write_ex() */
|
||||||
|
libssh2_nonblocking_states write_state;
|
||||||
|
unsigned char *write_packet;
|
||||||
|
unsigned char *write_s;
|
||||||
|
unsigned long write_packet_len;
|
||||||
|
unsigned long write_bufwrote;
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _LIBSSH2_CHANNEL_BRIGADE {
|
struct _LIBSSH2_CHANNEL_BRIGADE {
|
||||||
@@ -184,6 +370,11 @@ struct _LIBSSH2_LISTENER {
|
|||||||
int queue_maxsize;
|
int queue_maxsize;
|
||||||
|
|
||||||
LIBSSH2_LISTENER *prev, *next;
|
LIBSSH2_LISTENER *prev, *next;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_channel_forward_cancel() */
|
||||||
|
libssh2_nonblocking_states chanFwdCncl_state;
|
||||||
|
unsigned char *chanFwdCncl_data;
|
||||||
|
size_t chanFwdCncl_data_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _libssh2_endpoint_data {
|
typedef struct _libssh2_endpoint_data {
|
||||||
@@ -246,6 +437,138 @@ struct transportpacket {
|
|||||||
unsigned long osent; /* number of bytes already sent */
|
unsigned long osent; /* number of bytes already sent */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _LIBSSH2_PUBLICKEY {
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
unsigned long version;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_publickey_packet_receive() */
|
||||||
|
libssh2_nonblocking_states receive_state;
|
||||||
|
unsigned char *receive_packet;
|
||||||
|
unsigned long 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;
|
||||||
|
unsigned long listFetch_data_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP_HANDLE {
|
||||||
|
LIBSSH2_SFTP *sftp;
|
||||||
|
LIBSSH2_SFTP_HANDLE *prev, *next;
|
||||||
|
|
||||||
|
char *handle;
|
||||||
|
int handle_len;
|
||||||
|
|
||||||
|
char handle_type;
|
||||||
|
|
||||||
|
union _libssh2_sftp_handle_data {
|
||||||
|
struct _libssh2_sftp_handle_file_data {
|
||||||
|
libssh2_uint64_t offset;
|
||||||
|
} file;
|
||||||
|
struct _libssh2_sftp_handle_dir_data {
|
||||||
|
unsigned long names_left;
|
||||||
|
void *names_packet;
|
||||||
|
char *next_name;
|
||||||
|
} dir;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_close_handle() */
|
||||||
|
libssh2_nonblocking_states close_state;
|
||||||
|
unsigned long close_request_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _LIBSSH2_SFTP {
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
|
||||||
|
unsigned long request_id, version;
|
||||||
|
|
||||||
|
LIBSSH2_PACKET_BRIGADE packets;
|
||||||
|
|
||||||
|
LIBSSH2_SFTP_HANDLE *handles;
|
||||||
|
|
||||||
|
unsigned long last_errno;
|
||||||
|
|
||||||
|
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
|
||||||
|
unsigned char *partial_packet; /* The data */
|
||||||
|
unsigned long partial_len; /* Desired number of bytes */
|
||||||
|
unsigned long partial_received; /* Bytes received so far */
|
||||||
|
|
||||||
|
/* Time that libssh2_sftp_packet_requirev() started reading */
|
||||||
|
time_t requirev_start;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_open_ex() */
|
||||||
|
libssh2_nonblocking_states open_state;
|
||||||
|
unsigned char *open_packet;
|
||||||
|
ssize_t open_packet_len;
|
||||||
|
unsigned long open_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_read() */
|
||||||
|
libssh2_nonblocking_states read_state;
|
||||||
|
unsigned char *read_packet;
|
||||||
|
unsigned long read_request_id;
|
||||||
|
size_t read_total_read;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_readdir() */
|
||||||
|
libssh2_nonblocking_states readdir_state;
|
||||||
|
unsigned char *readdir_packet;
|
||||||
|
unsigned long readdir_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_write() */
|
||||||
|
libssh2_nonblocking_states write_state;
|
||||||
|
unsigned char *write_packet;
|
||||||
|
unsigned long write_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_fstat_ex() */
|
||||||
|
libssh2_nonblocking_states fstat_state;
|
||||||
|
unsigned char *fstat_packet;
|
||||||
|
unsigned long fstat_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_unlink_ex() */
|
||||||
|
libssh2_nonblocking_states unlink_state;
|
||||||
|
unsigned char *unlink_packet;
|
||||||
|
unsigned long unlink_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_rename_ex() */
|
||||||
|
libssh2_nonblocking_states rename_state;
|
||||||
|
unsigned char *rename_packet;
|
||||||
|
unsigned char *rename_s;
|
||||||
|
unsigned long rename_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_mkdir() */
|
||||||
|
libssh2_nonblocking_states mkdir_state;
|
||||||
|
unsigned char *mkdir_packet;
|
||||||
|
unsigned long mkdir_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_rmdir() */
|
||||||
|
libssh2_nonblocking_states rmdir_state;
|
||||||
|
unsigned char *rmdir_packet;
|
||||||
|
unsigned long rmdir_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_stat() */
|
||||||
|
libssh2_nonblocking_states stat_state;
|
||||||
|
unsigned char *stat_packet;
|
||||||
|
unsigned long stat_request_id;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_symlink() */
|
||||||
|
libssh2_nonblocking_states symlink_state;
|
||||||
|
unsigned char *symlink_packet;
|
||||||
|
unsigned long symlink_request_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
|
||||||
|
|
||||||
struct _LIBSSH2_SESSION {
|
struct _LIBSSH2_SESSION {
|
||||||
/* Memory management callbacks */
|
/* Memory management callbacks */
|
||||||
void *abstract;
|
void *abstract;
|
||||||
@@ -319,6 +642,163 @@ struct _LIBSSH2_SESSION {
|
|||||||
#ifdef LIBSSH2DEBUG
|
#ifdef LIBSSH2DEBUG
|
||||||
int showmask; /* what debug/trace messages to display */
|
int showmask; /* what debug/trace messages to display */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* State variables used in libssh2_banner_send() */
|
||||||
|
libssh2_nonblocking_states banner_TxRx_state;
|
||||||
|
char banner_TxRx_banner[256];
|
||||||
|
ssize_t banner_TxRx_total_send;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_kexinit() */
|
||||||
|
libssh2_nonblocking_states kexinit_state;
|
||||||
|
unsigned char *kexinit_data;
|
||||||
|
size_t kexinit_data_len;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_session_startup() */
|
||||||
|
libssh2_nonblocking_states startup_state;
|
||||||
|
unsigned char *startup_data;
|
||||||
|
unsigned long startup_data_len;
|
||||||
|
unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1];
|
||||||
|
unsigned long startup_service_length;
|
||||||
|
packet_require_state_t startup_req_state;
|
||||||
|
key_exchange_state_t startup_key_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_session_free() */
|
||||||
|
libssh2_nonblocking_states free_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_session_disconnect_ex() */
|
||||||
|
libssh2_nonblocking_states disconnect_state;
|
||||||
|
unsigned char *disconnect_data;
|
||||||
|
unsigned long disconnect_data_len;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_packet_read() */
|
||||||
|
libssh2_nonblocking_states readPack_state;
|
||||||
|
int readPack_encrypted;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_userauth_list() */
|
||||||
|
libssh2_nonblocking_states userauth_list_state;
|
||||||
|
unsigned char *userauth_list_data;
|
||||||
|
unsigned long userauth_list_data_len;
|
||||||
|
packet_requirev_state_t userauth_list_packet_requirev_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_userauth_password_ex() */
|
||||||
|
libssh2_nonblocking_states userauth_pswd_state;
|
||||||
|
unsigned char *userauth_pswd_data;
|
||||||
|
unsigned char userauth_pswd_data0;
|
||||||
|
unsigned long userauth_pswd_data_len;
|
||||||
|
char *userauth_pswd_newpw;
|
||||||
|
int userauth_pswd_newpw_len;
|
||||||
|
packet_requirev_state_t userauth_pswd_packet_requirev_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_userauth_hostbased_fromfile_ex() */
|
||||||
|
libssh2_nonblocking_states userauth_host_state;
|
||||||
|
unsigned char *userauth_host_data;
|
||||||
|
unsigned long userauth_host_data_len;
|
||||||
|
unsigned char *userauth_host_packet;
|
||||||
|
unsigned long userauth_host_packet_len;
|
||||||
|
unsigned char *userauth_host_method;
|
||||||
|
unsigned long userauth_host_method_len;
|
||||||
|
unsigned char *userauth_host_s;
|
||||||
|
packet_requirev_state_t userauth_host_packet_requirev_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_userauth_publickey_fromfile_ex() */
|
||||||
|
libssh2_nonblocking_states userauth_pblc_state;
|
||||||
|
unsigned char *userauth_pblc_data;
|
||||||
|
unsigned long userauth_pblc_data_len;
|
||||||
|
unsigned char *userauth_pblc_packet;
|
||||||
|
unsigned long userauth_pblc_packet_len;
|
||||||
|
unsigned char *userauth_pblc_method;
|
||||||
|
unsigned long userauth_pblc_method_len;
|
||||||
|
unsigned char *userauth_pblc_s;
|
||||||
|
unsigned char *userauth_pblc_b;
|
||||||
|
packet_requirev_state_t userauth_pblc_packet_requirev_state;
|
||||||
|
|
||||||
|
/* State variables used in llibssh2_userauth_keyboard_interactive_ex() */
|
||||||
|
libssh2_nonblocking_states userauth_kybd_state;
|
||||||
|
unsigned char *userauth_kybd_data;
|
||||||
|
unsigned long userauth_kybd_data_len;
|
||||||
|
unsigned char *userauth_kybd_packet;
|
||||||
|
unsigned long userauth_kybd_packet_len;
|
||||||
|
unsigned int userauth_kybd_auth_name_len;
|
||||||
|
char *userauth_kybd_auth_name;
|
||||||
|
unsigned userauth_kybd_auth_instruction_len;
|
||||||
|
char *userauth_kybd_auth_instruction;
|
||||||
|
unsigned int userauth_kybd_num_prompts;
|
||||||
|
int userauth_kybd_auth_failure;
|
||||||
|
LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts;
|
||||||
|
LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses;
|
||||||
|
packet_requirev_state_t userauth_kybd_packet_requirev_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_channel_open_ex() */
|
||||||
|
libssh2_nonblocking_states open_state;
|
||||||
|
packet_requirev_state_t open_packet_requirev_state;
|
||||||
|
LIBSSH2_CHANNEL *open_channel;
|
||||||
|
unsigned char *open_packet;
|
||||||
|
unsigned long open_packet_len;
|
||||||
|
unsigned char *open_data;
|
||||||
|
unsigned long open_data_len;
|
||||||
|
unsigned long open_local_channel;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_channel_direct_tcpip_ex() */
|
||||||
|
libssh2_nonblocking_states direct_state;
|
||||||
|
unsigned char *direct_message;
|
||||||
|
unsigned long direct_host_len;
|
||||||
|
unsigned long direct_shost_len;
|
||||||
|
unsigned long direct_message_len;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_channel_forward_listen_ex() */
|
||||||
|
libssh2_nonblocking_states fwdLstn_state;
|
||||||
|
unsigned char *fwdLstn_packet;
|
||||||
|
unsigned long fwdLstn_host_len;
|
||||||
|
unsigned long fwdLstn_packet_len;
|
||||||
|
packet_requirev_state_t fwdLstn_packet_requirev_state;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_publickey_init() */
|
||||||
|
libssh2_nonblocking_states pkeyInit_state;
|
||||||
|
LIBSSH2_PUBLICKEY *pkeyInit_pkey;
|
||||||
|
LIBSSH2_CHANNEL *pkeyInit_channel;
|
||||||
|
unsigned char *pkeyInit_data;
|
||||||
|
unsigned long pkeyInit_data_len;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_packet_add() */
|
||||||
|
libssh2_nonblocking_states packAdd_state;
|
||||||
|
LIBSSH2_PACKET *packAdd_packet;
|
||||||
|
LIBSSH2_CHANNEL *packAdd_channel;
|
||||||
|
unsigned long packAdd_data_head;
|
||||||
|
key_exchange_state_t packAdd_key_state;
|
||||||
|
packet_queue_listener_state_t packAdd_Qlstn_state;
|
||||||
|
packet_x11_open_state_t packAdd_x11open_state;
|
||||||
|
|
||||||
|
/* State variables used in fullpacket() */
|
||||||
|
libssh2_nonblocking_states fullpacket_state;
|
||||||
|
int fullpacket_macstate;
|
||||||
|
int fullpacket_payload_len;
|
||||||
|
libssh2pack_t fullpacket_packet_type;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_sftp_init() */
|
||||||
|
libssh2_nonblocking_states sftpInit_state;
|
||||||
|
LIBSSH2_SFTP *sftpInit_sftp;
|
||||||
|
LIBSSH2_CHANNEL *sftpInit_channel;
|
||||||
|
unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + version_id(4) */
|
||||||
|
|
||||||
|
/* State variables used in libssh2_scp_recv() */
|
||||||
|
libssh2_nonblocking_states scpRecv_state;
|
||||||
|
unsigned char *scpRecv_command;
|
||||||
|
unsigned long scpRecv_command_len;
|
||||||
|
unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
||||||
|
unsigned long scpRecv_response_len;
|
||||||
|
long scpRecv_mode;
|
||||||
|
long scpRecv_size;
|
||||||
|
long scpRecv_mtime;
|
||||||
|
long scpRecv_atime;
|
||||||
|
LIBSSH2_CHANNEL *scpRecv_channel;
|
||||||
|
|
||||||
|
/* State variables used in libssh2_scp_send_ex() */
|
||||||
|
libssh2_nonblocking_states scpSend_state;
|
||||||
|
unsigned char *scpSend_command;
|
||||||
|
unsigned long scpSend_command_len;
|
||||||
|
unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
||||||
|
unsigned long scpSend_response_len;
|
||||||
|
LIBSSH2_CHANNEL *scpSend_channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* session.state bits */
|
/* session.state bits */
|
||||||
@@ -342,7 +822,7 @@ struct _LIBSSH2_KEX_METHOD {
|
|||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
|
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
|
||||||
int (*exchange_keys)(LIBSSH2_SESSION *session);
|
int (*exchange_keys)(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state);
|
||||||
|
|
||||||
long flags;
|
long flags;
|
||||||
};
|
};
|
||||||
@@ -451,7 +931,7 @@ static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
|||||||
session->err_code = errcode; \
|
session->err_code = errcode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LIBSSH2_DEBUG_ENABLED */
|
#endif /* ! LIBSSH2DEBUG */
|
||||||
|
|
||||||
|
|
||||||
#define LIBSSH2_SOCKET_UNKNOWN 1
|
#define LIBSSH2_SOCKET_UNKNOWN 1
|
||||||
@@ -534,52 +1014,36 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds);
|
|||||||
/* CAUTION: some of these error codes are returned in the public API and is
|
/* CAUTION: some of these error codes are returned in the public API and is
|
||||||
there known with other #defined names from the public header file. They
|
there known with other #defined names from the public header file. They
|
||||||
should not be changed. */
|
should not be changed. */
|
||||||
typedef int libssh2pack_t;
|
|
||||||
|
|
||||||
#define PACKET_TIMEOUT -7
|
#define PACKET_TIMEOUT -7
|
||||||
#define PACKET_BADUSE -6
|
#define PACKET_BADUSE -6
|
||||||
#define PACKET_COMPRESS -5
|
#define PACKET_COMPRESS -5
|
||||||
#define PACKET_TOOBIG -4
|
#define PACKET_TOOBIG -4
|
||||||
#define PACKET_ENOMEM -3
|
#define PACKET_ENOMEM -3
|
||||||
#define PACKET_EAGAIN -2
|
#define PACKET_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||||
#define PACKET_FAIL -1
|
#define PACKET_FAIL -1
|
||||||
#define PACKET_NONE 0
|
#define PACKET_NONE 0
|
||||||
|
|
||||||
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session);
|
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
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,
|
||||||
#define libssh2_packet_ask(session, packet_type, data, data_len, poll_socket) \
|
unsigned char **data, unsigned long *data_len,
|
||||||
libssh2_packet_ask_ex((session), (packet_type), (data), (data_len), 0, NULL, 0, (poll_socket))
|
unsigned long match_ofs,
|
||||||
|
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_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);
|
||||||
#define libssh2_packet_askv(session, packet_types, data, data_len, 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);
|
||||||
libssh2_packet_askv_ex((session), (packet_types), (data), (data_len), 0, NULL, 0, (poll_socket))
|
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_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);
|
int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state);
|
||||||
#define libssh2_packet_require(session, packet_type, data, data_len) \
|
|
||||||
libssh2_packet_require_ex((session), (packet_type), (data), (data_len), 0, NULL, 0)
|
|
||||||
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);
|
|
||||||
#define libssh2_packet_requirev(session, packet_types, data, data_len) \
|
|
||||||
libssh2_packet_requirev_ex((session), (packet_types), (data), (data_len), 0, NULL, 0)
|
|
||||||
int libssh2_packet_burn(LIBSSH2_SESSION *session);
|
|
||||||
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 libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate);
|
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate);
|
||||||
int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange);
|
int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, key_exchange_state_t *state);
|
||||||
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session);
|
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session);
|
||||||
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id);
|
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id);
|
||||||
ssize_t _libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
|
|
||||||
int stream_id, char *buf, size_t buflen);
|
|
||||||
#define _libssh2_channel_read(channel, buf, buflen) \
|
|
||||||
_libssh2_channel_read_ex((channel), 0, (buf), (buflen))
|
|
||||||
#undef libssh2_channel_read /* never use this internally */
|
|
||||||
#define libssh2_channel_read fix this code
|
|
||||||
|
|
||||||
int _libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
|
|
||||||
int stream_id,
|
|
||||||
const char *buf, size_t buflen);
|
|
||||||
#define _libssh2_channel_write(channel, buf, buflen) \
|
|
||||||
_libssh2_channel_write_ex((channel), 0, (buf), (buflen))
|
|
||||||
|
|
||||||
/* this is the lib-internal set blocking function */
|
/* this is the lib-internal set blocking function */
|
||||||
int _libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
|
int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking);
|
||||||
|
|
||||||
/* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */
|
/* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */
|
||||||
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
|
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
|
||||||
|
821
src/packet.c
821
src/packet.c
File diff suppressed because it is too large
Load Diff
510
src/publickey.c
510
src/publickey.c
@@ -38,11 +38,6 @@
|
|||||||
#include "libssh2_priv.h"
|
#include "libssh2_priv.h"
|
||||||
#include "libssh2_publickey.h"
|
#include "libssh2_publickey.h"
|
||||||
|
|
||||||
struct _LIBSSH2_PUBLICKEY {
|
|
||||||
LIBSSH2_CHANNEL *channel;
|
|
||||||
unsigned long version;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LIBSSH2_PUBLICKEY_VERSION 2
|
#define LIBSSH2_PUBLICKEY_VERSION 2
|
||||||
|
|
||||||
/* Numericised response codes -- Not IETF standard, just a local representation */
|
/* Numericised response codes -- Not IETF standard, just a local representation */
|
||||||
@@ -95,7 +90,9 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
|
|||||||
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \""
|
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \""
|
||||||
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \""
|
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \""
|
||||||
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
|
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
|
||||||
static void libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, int status, const unsigned char *message, int message_len)
|
static void
|
||||||
|
libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, int status,
|
||||||
|
const unsigned char *message, int message_len)
|
||||||
{
|
{
|
||||||
const char *status_text;
|
const char *status_text;
|
||||||
int status_text_len;
|
int status_text_len;
|
||||||
@@ -139,34 +136,52 @@ static void libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH
|
|||||||
/* {{{ libssh2_publickey_packet_receive
|
/* {{{ libssh2_publickey_packet_receive
|
||||||
* Read a packet from the subsystem
|
* Read a packet from the subsystem
|
||||||
*/
|
*/
|
||||||
static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, unsigned long *data_len)
|
static int
|
||||||
|
libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, unsigned long *data_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
unsigned char buffer[4];
|
unsigned char buffer[4];
|
||||||
unsigned long packet_len;
|
int rc;
|
||||||
unsigned char *packet;
|
|
||||||
|
|
||||||
if (_libssh2_channel_read(channel, (char *)buffer, 4) != 4) {
|
if (pkey->receive_state == libssh2_NB_state_idle) {
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_len = libssh2_ntohu32(buffer);
|
pkey->receive_packet_len = libssh2_ntohu32(buffer);
|
||||||
packet = LIBSSH2_ALLOC(session, packet_len);
|
pkey->receive_packet = LIBSSH2_ALLOC(session, pkey->receive_packet_len);
|
||||||
if (!packet) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_libssh2_channel_read(channel, (char *)packet, packet_len) != packet_len) {
|
pkey->receive_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkey->receive_state == libssh2_NB_state_sent) {
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, pkey->receive_packet);
|
||||||
|
pkey->receive_packet = NULL;
|
||||||
|
pkey->receive_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*data = packet;
|
*data = pkey->receive_packet;
|
||||||
*data_len = packet_len;
|
*data_len = pkey->receive_packet_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkey->receive_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -214,9 +229,14 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
|
|||||||
unsigned char *data, *s;
|
unsigned char *data, *s;
|
||||||
unsigned long data_len;
|
unsigned long data_len;
|
||||||
int response;
|
int response;
|
||||||
|
int rc;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) {
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -278,39 +298,71 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
|
|||||||
*/
|
*/
|
||||||
LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
||||||
{
|
{
|
||||||
LIBSSH2_PUBLICKEY *pkey = NULL;
|
/* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */
|
||||||
LIBSSH2_CHANNEL *channel = NULL;
|
|
||||||
unsigned char buffer[19];
|
unsigned char buffer[19];
|
||||||
/* packet_len(4) +
|
unsigned char *s;
|
||||||
version_len(4) +
|
|
||||||
"version"(7) +
|
|
||||||
version_num(4) */
|
|
||||||
unsigned char *s, *data = NULL;
|
|
||||||
unsigned long data_len;
|
|
||||||
int response;
|
int response;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (session->pkeyInit_state == libssh2_NB_state_idle) {
|
||||||
|
session->pkeyInit_data = NULL;
|
||||||
|
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");
|
||||||
|
|
||||||
channel = libssh2_channel_open_session(session);
|
session->pkeyInit_state = libssh2_NB_state_allocated;
|
||||||
if (!channel) {
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
/* The error state is already set, so leave it */
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
if (libssh2_channel_subsystem(channel, "publickey")) {
|
} while (!session->pkeyInit_channel);
|
||||||
|
|
||||||
|
session->pkeyInit_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->pkeyInit_state == libssh2_NB_state_sent) {
|
||||||
|
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);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem", 0);
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
libssh2_channel_set_blocking(channel, 1);
|
session->pkeyInit_state = libssh2_NB_state_sent1;
|
||||||
libssh2_channel_handle_extended_data(channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
|
}
|
||||||
|
|
||||||
pkey = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
|
if (session->pkeyInit_state == libssh2_NB_state_sent1) {
|
||||||
if (!pkey) {
|
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);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
pkey->channel = channel;
|
memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
|
||||||
pkey->version = 0;
|
session->pkeyInit_pkey->channel = session->pkeyInit_channel;
|
||||||
|
session->pkeyInit_pkey->version = 0;
|
||||||
|
|
||||||
s = buffer;
|
s = buffer;
|
||||||
libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); s += 4;
|
libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); s += 4;
|
||||||
@@ -318,20 +370,40 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
|||||||
memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1;
|
memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1;
|
||||||
libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4;
|
libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4;
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support", (int)LIBSSH2_PUBLICKEY_VERSION);
|
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support",
|
||||||
if ((s - buffer) != libssh2_channel_write(channel, (char*)buffer, (s - buffer))) {
|
(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));
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->pkeyInit_state = libssh2_NB_state_sent3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->pkeyInit_state == libssh2_NB_state_sent3) {
|
||||||
while (1) {
|
while (1) {
|
||||||
if (libssh2_publickey_packet_receive(pkey, &data, &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);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = data;
|
s = session->pkeyInit_data;
|
||||||
if ((response = libssh2_publickey_response_id(&s, data_len)) < 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);
|
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@@ -349,7 +421,7 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
|||||||
lang_len = libssh2_ntohu32(s); s += 4;
|
lang_len = libssh2_ntohu32(s); s += 4;
|
||||||
lang = s; s += lang_len;
|
lang = s; s += lang_len;
|
||||||
|
|
||||||
if (s > data + data_len) {
|
if (s > session->pkeyInit_data + session->pkeyInit_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);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@@ -357,35 +429,51 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
|||||||
libssh2_publickey_status_error(NULL, session, status, descr, descr_len);
|
libssh2_publickey_status_error(NULL, session, status, descr, descr_len);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
|
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
|
||||||
/* What we want */
|
/* What we want */
|
||||||
pkey->version = libssh2_ntohu32(s);
|
session->pkeyInit_pkey->version = libssh2_ntohu32(s);
|
||||||
if (pkey->version > LIBSSH2_PUBLICKEY_VERSION) {
|
if (session->pkeyInit_pkey->version > LIBSSH2_PUBLICKEY_VERSION) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", pkey->version);
|
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu",
|
||||||
pkey->version = LIBSSH2_PUBLICKEY_VERSION;
|
session->pkeyInit_pkey->version);
|
||||||
|
session->pkeyInit_pkey->version = LIBSSH2_PUBLICKEY_VERSION;
|
||||||
}
|
}
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", pkey->version);
|
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu",
|
||||||
LIBSSH2_FREE(session, data);
|
session->pkeyInit_pkey->version);
|
||||||
return pkey;
|
LIBSSH2_FREE(session, session->pkeyInit_data);
|
||||||
|
session->pkeyInit_data = NULL;
|
||||||
|
session->pkeyInit_state = libssh2_NB_state_idle;
|
||||||
|
return session->pkeyInit_pkey;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Unknown/Unexpected */
|
/* Unknown/Unexpected */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0);
|
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
|
||||||
LIBSSH2_FREE(session, data);
|
"Unexpected publickey subsystem response, ignoring", 0);
|
||||||
data = NULL;
|
LIBSSH2_FREE(session, session->pkeyInit_data);
|
||||||
|
session->pkeyInit_data = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Never reached except by direct goto */
|
/* Never reached except by direct goto */
|
||||||
err_exit:
|
err_exit:
|
||||||
if (channel) {
|
session->pkeyInit_state = libssh2_NB_state_sent4;
|
||||||
libssh2_channel_close(channel);
|
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);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if (pkey) {
|
|
||||||
LIBSSH2_FREE(session, pkey);
|
|
||||||
}
|
}
|
||||||
if (data) {
|
if (session->pkeyInit_pkey) {
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, session->pkeyInit_pkey);
|
||||||
|
session->pkeyInit_pkey = NULL;
|
||||||
}
|
}
|
||||||
|
if (session->pkeyInit_data) {
|
||||||
|
LIBSSH2_FREE(session, session->pkeyInit_data);
|
||||||
|
session->pkeyInit_data = NULL;
|
||||||
|
}
|
||||||
|
session->pkeyInit_state = libssh2_NB_state_idle;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -393,25 +481,23 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
|||||||
/* {{{ libssh2_publickey_add_ex
|
/* {{{ libssh2_publickey_add_ex
|
||||||
* Add a new public key entry
|
* Add a new public key entry
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
|
LIBSSH2_API int
|
||||||
const unsigned char *blob, unsigned long blob_len, char overwrite,
|
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
|
||||||
unsigned long num_attrs, const libssh2_publickey_attribute attrs[])
|
const unsigned char *blob, unsigned long blob_len, char overwrite, unsigned long num_attrs,
|
||||||
|
const libssh2_publickey_attribute attrs[])
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
unsigned char *packet = NULL, *s;
|
/* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} blob_len(4) + {blob} */
|
||||||
unsigned long i, packet_len = 19 + name_len + blob_len;
|
unsigned long i, packet_len = 19 + name_len + blob_len;
|
||||||
unsigned char *comment = NULL;
|
unsigned char *comment = NULL;
|
||||||
unsigned long comment_len = 0;
|
unsigned long comment_len = 0;
|
||||||
/* packet_len(4) +
|
int rc;
|
||||||
add_len(4) +
|
|
||||||
"add"(3) +
|
|
||||||
name_len(4) +
|
|
||||||
{name}
|
|
||||||
blob_len(4) +
|
|
||||||
{blob} */
|
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s pubickey", name);
|
if (pkey->add_state == libssh2_NB_state_idle) {
|
||||||
|
pkey->add_packet = NULL;
|
||||||
|
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey", name);
|
||||||
|
|
||||||
if (pkey->version == 1) {
|
if (pkey->version == 1) {
|
||||||
for(i = 0; i < num_attrs; i++) {
|
for(i = 0; i < num_attrs; i++) {
|
||||||
@@ -432,139 +518,196 @@ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = LIBSSH2_ALLOC(session, packet_len);
|
pkey->add_packet = LIBSSH2_ALLOC(session, packet_len);
|
||||||
if (!packet) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = packet;
|
pkey->add_s = pkey->add_packet;
|
||||||
libssh2_htonu32(s, packet_len - 4); s += 4;
|
libssh2_htonu32(pkey->add_s, packet_len - 4); pkey->add_s += 4;
|
||||||
libssh2_htonu32(s, sizeof("add") - 1); s += 4;
|
libssh2_htonu32(pkey->add_s, sizeof("add") - 1); pkey->add_s += 4;
|
||||||
memcpy(s, "add", sizeof("add") - 1); s += sizeof("add") - 1;
|
memcpy(pkey->add_s, "add", sizeof("add") - 1); pkey->add_s += sizeof("add") - 1;
|
||||||
if (pkey->version == 1) {
|
if (pkey->version == 1) {
|
||||||
libssh2_htonu32(s, comment_len); s += 4;
|
libssh2_htonu32(pkey->add_s, comment_len); pkey->add_s += 4;
|
||||||
if (comment) {
|
if (comment) {
|
||||||
memcpy(s, comment, comment_len); s += comment_len;
|
memcpy(pkey->add_s, comment, comment_len); pkey->add_s += comment_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
libssh2_htonu32(s, name_len); s += 4;
|
libssh2_htonu32(pkey->add_s, name_len); pkey->add_s += 4;
|
||||||
memcpy(s, name, name_len); s += name_len;
|
memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len;
|
||||||
libssh2_htonu32(s, blob_len); s += 4;
|
libssh2_htonu32(pkey->add_s, blob_len); pkey->add_s += 4;
|
||||||
memcpy(s, blob, blob_len); s += blob_len;
|
memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len;
|
||||||
} else {
|
} else {
|
||||||
/* Version == 2 */
|
/* Version == 2 */
|
||||||
|
|
||||||
libssh2_htonu32(s, name_len); s += 4;
|
libssh2_htonu32(pkey->add_s, name_len); pkey->add_s += 4;
|
||||||
memcpy(s, name, name_len); s += name_len;
|
memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len;
|
||||||
libssh2_htonu32(s, blob_len); s += 4;
|
libssh2_htonu32(pkey->add_s, blob_len); pkey->add_s += 4;
|
||||||
memcpy(s, blob, blob_len); s += blob_len;
|
memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len;
|
||||||
*(s++) = overwrite ? 0xFF : 0;
|
*(pkey->add_s++) = overwrite ? 0x01 : 0;
|
||||||
libssh2_htonu32(s, num_attrs); s += 4;
|
libssh2_htonu32(pkey->add_s, num_attrs); pkey->add_s += 4;
|
||||||
for(i = 0; i < num_attrs; i++) {
|
for(i = 0; i < num_attrs; i++) {
|
||||||
libssh2_htonu32(s, attrs[i].name_len); s += 4;
|
libssh2_htonu32(pkey->add_s, attrs[i].name_len); pkey->add_s += 4;
|
||||||
memcpy(s, attrs[i].name, attrs[i].name_len); s += attrs[i].name_len;
|
memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); pkey->add_s += attrs[i].name_len;
|
||||||
libssh2_htonu32(s, attrs[i].value_len); s += 4;
|
libssh2_htonu32(pkey->add_s, attrs[i].value_len); pkey->add_s += 4;
|
||||||
memcpy(s, attrs[i].value, attrs[i].value_len); s += attrs[i].value_len;
|
memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); pkey->add_s += attrs[i].value_len;
|
||||||
*(s++) = attrs[i].mandatory ? 0xFF : 0;
|
*(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
|
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
|
||||||
"Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
|
|
||||||
name, blob_len, num_attrs);
|
name, blob_len, num_attrs);
|
||||||
if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) {
|
|
||||||
|
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));
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, pkey->add_packet);
|
||||||
|
pkey->add_packet = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, pkey->add_packet);
|
||||||
packet = NULL;
|
pkey->add_packet = NULL;
|
||||||
|
|
||||||
return libssh2_publickey_response_success(pkey);
|
pkey->add_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = libssh2_publickey_response_success(pkey);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkey->add_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_publickey_remove_ex
|
/* {{{ libssh2_publickey_remove_ex
|
||||||
* Remove an existing publickey so that authentication can no longer be performed using it
|
* 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_API int
|
||||||
|
libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
|
||||||
const unsigned char *blob, unsigned long blob_len)
|
const unsigned char *blob, unsigned long blob_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
unsigned char *s, *packet = NULL;
|
/* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + blob_len(4) + {blob} */
|
||||||
unsigned long packet_len = 22 + name_len + blob_len;
|
unsigned long packet_len = 22 + name_len + blob_len;
|
||||||
/* packet_len(4) +
|
int rc;
|
||||||
remove_len(4) +
|
|
||||||
"remove"(6) +
|
|
||||||
name_len(4) +
|
|
||||||
{name}
|
|
||||||
blob_len(4) +
|
|
||||||
{blob} */
|
|
||||||
|
|
||||||
packet = LIBSSH2_ALLOC(session, packet_len);
|
if (pkey->remove_state == libssh2_NB_state_idle) {
|
||||||
if (!packet) {
|
pkey->remove_packet = NULL;
|
||||||
|
|
||||||
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = packet;
|
pkey->remove_s = pkey->remove_packet;
|
||||||
libssh2_htonu32(s, packet_len - 4); s += 4;
|
libssh2_htonu32(pkey->remove_s, packet_len - 4); pkey->remove_s += 4;
|
||||||
libssh2_htonu32(s, sizeof("remove") - 1); s += 4;
|
libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); pkey->remove_s += 4;
|
||||||
memcpy(s, "remove", sizeof("remove") - 1); s += sizeof("remove") - 1;
|
memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); pkey->remove_s += sizeof("remove") - 1;
|
||||||
libssh2_htonu32(s, name_len); s += 4;
|
libssh2_htonu32(pkey->remove_s, name_len); pkey->remove_s += 4;
|
||||||
memcpy(s, name, name_len); s += name_len;
|
memcpy(pkey->remove_s, name, name_len); pkey->remove_s += name_len;
|
||||||
libssh2_htonu32(s, blob_len); s += 4;
|
libssh2_htonu32(pkey->remove_s, blob_len); pkey->remove_s += 4;
|
||||||
memcpy(s, blob, blob_len); s += blob_len;
|
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);
|
||||||
if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) {
|
|
||||||
|
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));
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, pkey->remove_packet);
|
||||||
|
pkey->remove_packet = NULL;
|
||||||
|
pkey->remove_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, pkey->remove_packet);
|
||||||
packet = NULL;
|
pkey->remove_packet = NULL;
|
||||||
|
|
||||||
return libssh2_publickey_response_success(pkey);
|
pkey->remove_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = libssh2_publickey_response_success(pkey);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkey->remove_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_publickey_list_fetch
|
/* {{{ libssh2_publickey_list_fetch
|
||||||
* Fetch a list of supported public key from a server
|
* 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_API int
|
||||||
|
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list)
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
libssh2_publickey_list *list = NULL;
|
libssh2_publickey_list *list = NULL;
|
||||||
unsigned char *s, buffer[12], *data = NULL;
|
unsigned long buffer_len = 12, keys = 0, max_keys = 0, i;
|
||||||
unsigned long buffer_len = 12, keys = 0, max_keys = 0, data_len, i;
|
/* 12 = packet_len(4) + list_len(4) + "list"(4) */
|
||||||
/* packet_len(4) +
|
|
||||||
list_len(4) +
|
|
||||||
"list"(4) */
|
|
||||||
int response;
|
int response;
|
||||||
|
int rc;
|
||||||
|
|
||||||
s = buffer;
|
if (pkey->listFetch_state == libssh2_NB_state_idle) {
|
||||||
libssh2_htonu32(s, buffer_len - 4); s += 4;
|
pkey->listFetch_data = NULL;
|
||||||
libssh2_htonu32(s, sizeof("list") - 1); s += 4;
|
|
||||||
memcpy(s, "list", sizeof("list") - 1); s += sizeof("list") - 1;
|
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_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet");
|
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet");
|
||||||
if ((s - buffer) != libssh2_channel_write(channel, (char *)buffer, (s - buffer))) {
|
|
||||||
|
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));
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0);
|
||||||
|
pkey->listFetch_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkey->listFetch_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (libssh2_publickey_packet_receive(pkey, &data, &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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = data;
|
pkey->listFetch_s = pkey->listFetch_data;
|
||||||
if ((response = libssh2_publickey_response_id(&s, data_len)) < 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);
|
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@@ -576,21 +719,23 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
|
|||||||
unsigned long status, descr_len, lang_len;
|
unsigned long status, descr_len, lang_len;
|
||||||
unsigned char *descr, *lang;
|
unsigned char *descr, *lang;
|
||||||
|
|
||||||
status = libssh2_ntohu32(s); s += 4;
|
status = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
descr_len = libssh2_ntohu32(s); s += 4;
|
descr_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
descr = s; s += descr_len;
|
descr = pkey->listFetch_s; pkey->listFetch_s += descr_len;
|
||||||
lang_len = libssh2_ntohu32(s); s += 4;
|
lang_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
lang = s; s += lang_len;
|
lang = pkey->listFetch_s; pkey->listFetch_s += lang_len;
|
||||||
|
|
||||||
if (s > data + data_len) {
|
if (pkey->listFetch_s > pkey->listFetch_data + pkey->listFetch_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);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
|
if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, pkey->listFetch_data);
|
||||||
|
pkey->listFetch_data = NULL;
|
||||||
*pkey_list = list;
|
*pkey_list = list;
|
||||||
*num_keys = keys;
|
*num_keys = keys;
|
||||||
|
pkey->listFetch_state = libssh2_NB_state_idle;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +758,7 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
|
|||||||
if (pkey->version == 1) {
|
if (pkey->version == 1) {
|
||||||
unsigned long comment_len;
|
unsigned long comment_len;
|
||||||
|
|
||||||
comment_len = libssh2_ntohu32(s); s += 4;
|
comment_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
if (comment_len) {
|
if (comment_len) {
|
||||||
list[keys].num_attrs = 1;
|
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));
|
||||||
@@ -623,26 +768,26 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
|
|||||||
}
|
}
|
||||||
list[keys].attrs[0].name = "comment";
|
list[keys].attrs[0].name = "comment";
|
||||||
list[keys].attrs[0].name_len = sizeof("comment") - 1;
|
list[keys].attrs[0].name_len = sizeof("comment") - 1;
|
||||||
list[keys].attrs[0].value = (char *)s;
|
list[keys].attrs[0].value = (char *)pkey->listFetch_s;
|
||||||
list[keys].attrs[0].value_len = comment_len;
|
list[keys].attrs[0].value_len = comment_len;
|
||||||
list[keys].attrs[0].mandatory = 0;
|
list[keys].attrs[0].mandatory = 0;
|
||||||
|
|
||||||
s += comment_len;
|
pkey->listFetch_s += comment_len;
|
||||||
} else {
|
} else {
|
||||||
list[keys].num_attrs = 0;
|
list[keys].num_attrs = 0;
|
||||||
list[keys].attrs = NULL;
|
list[keys].attrs = NULL;
|
||||||
}
|
}
|
||||||
list[keys].name_len = libssh2_ntohu32(s); s += 4;
|
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
list[keys].name = s; s += list[keys].name_len;
|
list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len;
|
||||||
list[keys].blob_len = libssh2_ntohu32(s); s += 4;
|
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
list[keys].blob = s; s += list[keys].blob_len;
|
list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len;
|
||||||
} else {
|
} else {
|
||||||
/* Version == 2 */
|
/* Version == 2 */
|
||||||
list[keys].name_len = libssh2_ntohu32(s); s += 4;
|
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
list[keys].name = s; s += list[keys].name_len;
|
list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len;
|
||||||
list[keys].blob_len = libssh2_ntohu32(s); s += 4;
|
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
list[keys].blob = s; s += list[keys].blob_len;
|
list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len;
|
||||||
list[keys].num_attrs = libssh2_ntohu32(s); s += 4;
|
list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4;
|
||||||
if (list[keys].num_attrs) {
|
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) {
|
if (!list[keys].attrs) {
|
||||||
@@ -650,37 +795,44 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
|
|||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
for(i = 0; i < list[keys].num_attrs; i++) {
|
for(i = 0; i < list[keys].num_attrs; i++) {
|
||||||
list[keys].attrs[i].name_len = libssh2_ntohu32(s); s += 4;
|
list[keys].attrs[i].name_len = libssh2_ntohu32(pkey->listFetch_s);
|
||||||
list[keys].attrs[i].name = (char *)s; s += list[keys].attrs[i].name_len;
|
pkey->listFetch_s += 4;
|
||||||
list[keys].attrs[i].value_len = libssh2_ntohu32(s); s += 4;
|
list[keys].attrs[i].name = (char *)pkey->listFetch_s;
|
||||||
list[keys].attrs[i].value = (char *)s; s += list[keys].attrs[i].value_len;
|
pkey->listFetch_s += list[keys].attrs[i].name_len;
|
||||||
|
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;
|
||||||
list[keys].attrs[i].mandatory = 0; /* actually an ignored value */
|
list[keys].attrs[i].mandatory = 0; /* actually an ignored value */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
list[keys].attrs = NULL;
|
list[keys].attrs = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list[keys].packet = data; /* To be FREEd in libssh2_publickey_list_free() */
|
list[keys].packet = pkey->listFetch_data; /* To be FREEd in libssh2_publickey_list_free() */
|
||||||
keys++;
|
keys++;
|
||||||
|
|
||||||
list[keys].packet = NULL; /* Terminate the list */
|
list[keys].packet = NULL; /* Terminate the list */
|
||||||
data = NULL;
|
pkey->listFetch_data = NULL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unknown/Unexpected */
|
/* 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);
|
LIBSSH2_FREE(session, pkey->listFetch_data);
|
||||||
|
pkey->listFetch_data = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only reached via explicit goto */
|
/* Only reached via explicit goto */
|
||||||
err_exit:
|
err_exit:
|
||||||
if (data) {
|
if (pkey->listFetch_data) {
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, pkey->listFetch_data);
|
||||||
|
pkey->listFetch_data = NULL;
|
||||||
}
|
}
|
||||||
if (list) {
|
if (list) {
|
||||||
libssh2_publickey_list_free(pkey, list);
|
libssh2_publickey_list_free(pkey, list);
|
||||||
}
|
}
|
||||||
|
pkey->listFetch_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -708,11 +860,35 @@ LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_pu
|
|||||||
/* {{{ libssh2_publickey_shutdown
|
/* {{{ libssh2_publickey_shutdown
|
||||||
* Shutdown the publickey subsystem
|
* Shutdown the publickey subsystem
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API void libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
|
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = pkey->channel->session;
|
LIBSSH2_SESSION *session = pkey->channel->session;
|
||||||
|
|
||||||
libssh2_channel_free(pkey->channel);
|
/*
|
||||||
|
* Make sure all memory used in the state variables are free
|
||||||
|
*/
|
||||||
|
if (pkey->receive_packet) {
|
||||||
|
LIBSSH2_FREE(session, pkey->receive_packet);
|
||||||
|
pkey->receive_packet = NULL;
|
||||||
|
}
|
||||||
|
if (pkey->add_packet) {
|
||||||
|
LIBSSH2_FREE(session, pkey->add_packet);
|
||||||
|
pkey->add_packet = NULL;
|
||||||
|
}
|
||||||
|
if (pkey->remove_packet) {
|
||||||
|
LIBSSH2_FREE(session, pkey->remove_packet);
|
||||||
|
pkey->remove_packet = NULL;
|
||||||
|
}
|
||||||
|
if (pkey->listFetch_data) {
|
||||||
|
LIBSSH2_FREE(session, pkey->listFetch_data);
|
||||||
|
pkey->listFetch_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libssh2_channel_free(pkey->channel) == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, pkey);
|
LIBSSH2_FREE(session, pkey);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
524
src/scp.c
524
src/scp.c
@@ -39,392 +39,564 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
|
|
||||||
|
|
||||||
/* {{{ libssh2_scp_recv
|
/* {{{ libssh2_scp_recv
|
||||||
* [BLOCKING]
|
|
||||||
* Open a channel and request a remote file via SCP
|
* Open a channel and request a remote file via SCP
|
||||||
|
*
|
||||||
|
* NOTE: Will block in a busy loop on error. This has to be done,
|
||||||
|
* otherwise the blocking error code would erase the true
|
||||||
|
* cause of the error.
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session,
|
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb)
|
||||||
const char *path,
|
|
||||||
struct stat *sb)
|
|
||||||
{
|
{
|
||||||
int path_len = strlen(path);
|
int path_len = strlen(path);
|
||||||
unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
int rc;
|
||||||
unsigned long command_len = path_len + sizeof("scp -f "), response_len;
|
|
||||||
LIBSSH2_CHANNEL *channel;
|
if (session->scpRecv_state == libssh2_NB_state_idle) {
|
||||||
long mode = 0, size = 0, mtime = 0, atime = 0;
|
session->scpRecv_mode = 0;
|
||||||
|
session->scpRecv_size = 0;
|
||||||
|
session->scpRecv_mtime = 0;
|
||||||
|
session->scpRecv_atime = 0;
|
||||||
|
|
||||||
|
session->scpRecv_command_len = path_len + sizeof("scp -f ");
|
||||||
|
|
||||||
if (sb) {
|
if (sb) {
|
||||||
command_len++;
|
session->scpRecv_command_len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
command = LIBSSH2_ALLOC(session, command_len);
|
session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len);
|
||||||
if (!command) {
|
if (!session->scpRecv_command) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0);
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for SCP session", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (sb) {
|
if (sb) {
|
||||||
memcpy(command, "scp -pf ", sizeof("scp -pf ") - 1);
|
memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1);
|
||||||
memcpy(command + sizeof("scp -pf ") - 1, path, path_len);
|
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len);
|
||||||
} else {
|
} else {
|
||||||
memcpy(command, "scp -f ", sizeof("scp -f ") - 1);
|
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
|
||||||
memcpy(command + sizeof("scp -f ") - 1, path, path_len);
|
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, path_len);
|
||||||
}
|
}
|
||||||
command[command_len - 1] = '\0';
|
session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
|
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
|
||||||
/* Allocate a channel */
|
|
||||||
if ((channel = libssh2_channel_open_session(session)) == NULL) {
|
|
||||||
LIBSSH2_FREE(session, command);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* Use blocking I/O for negotiation phase */
|
|
||||||
libssh2_channel_set_blocking(channel, 1);
|
|
||||||
|
|
||||||
/* Request SCP for the desired file */
|
session->scpRecv_state = libssh2_NB_state_created;
|
||||||
if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) {
|
}
|
||||||
LIBSSH2_FREE(session, command);
|
|
||||||
libssh2_channel_free(channel);
|
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);
|
||||||
|
if (!session->scpRecv_channel) {
|
||||||
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, command);
|
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!session->scpRecv_channel);
|
||||||
|
|
||||||
|
session->scpRecv_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
|
LIBSSH2_FREE(session, session->scpRecv_command);
|
||||||
|
session->scpRecv_command = NULL;
|
||||||
|
goto scp_recv_error;
|
||||||
|
}
|
||||||
|
LIBSSH2_FREE(session, session->scpRecv_command);
|
||||||
|
session->scpRecv_command = NULL;
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
|
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
|
||||||
/* SCP ACK */
|
/* SCP ACK */
|
||||||
response[0] = '\0';
|
session->scpRecv_response[0] = '\0';
|
||||||
if (libssh2_channel_write(channel, response, 1) != 1) {
|
|
||||||
libssh2_channel_free(channel);
|
session->scpRecv_state = libssh2_NB_state_sent1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->scpRecv_state == libssh2_NB_state_sent1) {
|
||||||
|
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
else if (rc != 1) {
|
||||||
|
goto scp_recv_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse SCP response */
|
/* Parse SCP response */
|
||||||
response_len = 0;
|
session->scpRecv_response_len = 0;
|
||||||
while (sb && (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) {
|
|
||||||
unsigned char *s, *p;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = _libssh2_channel_read(channel, response + response_len, 1);
|
session->scpRecv_state = libssh2_NB_state_sent2;
|
||||||
if(rc <= 0) {
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (rc <= 0) {
|
||||||
/* Timeout, give up */
|
/* Timeout, give up */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
response_len++;
|
session->scpRecv_response_len++;
|
||||||
|
|
||||||
if (response[0] != 'T') {
|
if (session->scpRecv_response[0] != 'T') {
|
||||||
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);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((response_len > 1) &&
|
if ((session->scpRecv_response_len > 1) &&
|
||||||
((response[response_len-1] < '0') || (response[response_len-1] > '9')) &&
|
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') ||
|
||||||
(response[response_len-1] != ' ') &&
|
(session->scpRecv_response[session->scpRecv_response_len-1] > '9')) &&
|
||||||
(response[response_len-1] != '\r') &&
|
(session->scpRecv_response[session->scpRecv_response_len-1] != ' ') &&
|
||||||
(response[response_len-1] != '\n')) {
|
(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);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((response_len < 9) || (response[response_len-1] != '\n')) {
|
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||||
if (response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||||
/* You had your chance */
|
/* You had your chance */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
/* Way too short to be an SCP response, or not done yet, short circuit */
|
/* Way too short to be an SCP response, or not done yet, short circuit */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
||||||
while ((response[response_len-1] == '\r') || (response[response_len-1] == '\n')) response_len--;
|
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) session->scpRecv_response_len--;
|
||||||
response[response_len] = '\0';
|
session->scpRecv_response[session->scpRecv_response_len] = '\0';
|
||||||
|
|
||||||
if (response_len < 8) {
|
if (session->scpRecv_response_len < 8) {
|
||||||
/* EOL came too soon */
|
/* EOL came too soon */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s = response + 1;
|
s = session->scpRecv_response + 1;
|
||||||
|
|
||||||
p = strchr(s, ' ');
|
p = (unsigned char *)strchr((char *)s, ' ');
|
||||||
if (!p || ((p - s) <= 0)) {
|
if (!p || ((p - s) <= 0)) {
|
||||||
/* No spaces or space in the wrong spot */
|
/* No spaces or space in the wrong spot */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*(p++) = '\0';
|
*(p++) = '\0';
|
||||||
/* Make sure we don't get fooled by leftover values */
|
/* Make sure we don't get fooled by leftover values */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
mtime = strtol(s, NULL, 10);
|
session->scpRecv_mtime = strtol((char *)s, NULL, 10);
|
||||||
if (errno) {
|
if (errno) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
s = strchr(p, ' ');
|
s = (unsigned char *)strchr((char *)p, ' ');
|
||||||
if (!s || ((s - p) <= 0)) {
|
if (!s || ((s - p) <= 0)) {
|
||||||
/* No spaces or space in the wrong spot */
|
/* No spaces or space in the wrong spot */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore mtime.usec */
|
/* Ignore mtime.usec */
|
||||||
s++;
|
s++;
|
||||||
p = strchr(s, ' ');
|
p = (unsigned char *)strchr((char *)s, ' ');
|
||||||
if (!p || ((p - s) <= 0)) {
|
if (!p || ((p - s) <= 0)) {
|
||||||
/* No spaces or space in the wrong spot */
|
/* No spaces or space in the wrong spot */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*(p++) = '\0';
|
*(p++) = '\0';
|
||||||
/* Make sure we don't get fooled by leftover values */
|
/* Make sure we don't get fooled by leftover values */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
atime = strtol(s, NULL, 10);
|
session->scpRecv_atime = strtol((char *)s, NULL, 10);
|
||||||
if (errno) {
|
if (errno) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SCP ACK */
|
/* SCP ACK */
|
||||||
response[0] = '\0';
|
session->scpRecv_response[0] = '\0';
|
||||||
if (libssh2_channel_write(channel, response, 1) != 1) {
|
|
||||||
libssh2_channel_free(channel);
|
session->scpRecv_state = libssh2_NB_state_sent3;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", mtime, atime);
|
if (session->scpRecv_state == libssh2_NB_state_sent3) {
|
||||||
|
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);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (rc != 1) {
|
||||||
|
goto scp_recv_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime);
|
||||||
|
|
||||||
/* We *should* check that atime.usec is valid, but why let that stop use? */
|
/* We *should* check that atime.usec is valid, but why let that stop use? */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
response_len = 0;
|
session->scpRecv_state = libssh2_NB_state_sent4;
|
||||||
while (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
}
|
||||||
|
|
||||||
|
if (session->scpRecv_state == libssh2_NB_state_sent4) {
|
||||||
|
session->scpRecv_response_len = 0;
|
||||||
|
|
||||||
|
session->scpRecv_state = libssh2_NB_state_sent5;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
char *s, *p, *e = NULL;
|
||||||
|
|
||||||
if (_libssh2_channel_read(channel, response + response_len, 1) <= 0) {
|
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);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (rc <= 0) {
|
||||||
/* Timeout, give up */
|
/* Timeout, give up */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
response_len++;
|
session->scpRecv_response_len++;
|
||||||
|
|
||||||
if (response[0] != 'C') {
|
if (session->scpRecv_response[0] != 'C') {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((response_len > 1) &&
|
if ((session->scpRecv_response_len > 1) &&
|
||||||
(response[response_len-1] != '\r') &&
|
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
|
||||||
(response[response_len-1] != '\n') &&
|
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n') &&
|
||||||
((response[response_len-1] < 32) || (response[response_len-1] > 126))) {
|
((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);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((response_len < 7) || (response[response_len-1] != '\n')) {
|
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||||
if (response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||||
/* You had your chance */
|
/* You had your chance */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
/* Way too short to be an SCP response, or not done yet, short circuit */
|
/* Way too short to be an SCP response, or not done yet, short circuit */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
||||||
while ((response[response_len-1] == '\r') || (response[response_len-1] == '\n')) response_len--;
|
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') ||
|
||||||
response[response_len] = '\0';
|
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) {
|
||||||
|
session->scpRecv_response_len--;
|
||||||
|
}
|
||||||
|
session->scpRecv_response[session->scpRecv_response_len] = '\0';
|
||||||
|
|
||||||
if (response_len < 6) {
|
if (session->scpRecv_response_len < 6) {
|
||||||
/* EOL came too soon */
|
/* EOL came too soon */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s = response + 1;
|
s = (char *)session->scpRecv_response + 1;
|
||||||
|
|
||||||
p = strchr(s, ' ');
|
p = strchr(s, ' ');
|
||||||
if (!p || ((p - s) <= 0)) {
|
if (!p || ((p - s) <= 0)) {
|
||||||
/* No spaces or space in the wrong spot */
|
/* No spaces or space in the wrong spot */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*(p++) = '\0';
|
*(p++) = '\0';
|
||||||
/* Make sure we don't get fooled by leftover values */
|
/* Make sure we don't get fooled by leftover values */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
mode = strtol(s, &e, 8);
|
session->scpRecv_mode = strtol(s, &e, 8);
|
||||||
if ((e && *e) || errno) {
|
if ((e && *e) || errno) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s = strchr(p, ' ');
|
s = strchr(p, ' ');
|
||||||
if (!s || ((s - p) <= 0)) {
|
if (!s || ((s - p) <= 0)) {
|
||||||
/* No spaces or space in the wrong spot */
|
/* No spaces or space in the wrong spot */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed",
|
||||||
libssh2_channel_free(channel);
|
0);
|
||||||
return NULL;
|
goto scp_recv_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(s++) = '\0';
|
*(s++) = '\0';
|
||||||
/* Make sure we don't get fooled by leftover values */
|
/* Make sure we don't get fooled by leftover values */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
size = strtol(p, &e, 10);
|
session->scpRecv_size = strtol(p, &e, 10);
|
||||||
if ((e && *e) || errno) {
|
if ((e && *e) || errno) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_recv_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SCP ACK */
|
/* SCP ACK */
|
||||||
response[0] = '\0';
|
session->scpRecv_response[0] = '\0';
|
||||||
if (libssh2_channel_write(channel, response, 1) != 1) {
|
|
||||||
libssh2_channel_free(channel);
|
session->scpRecv_state = libssh2_NB_state_sent6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->scpRecv_state == libssh2_NB_state_sent6) {
|
||||||
|
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mod = 0%lo size = %ld", mode, size);
|
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);
|
||||||
|
|
||||||
/* We *should* check that basename is valid, but why let that stop us? */
|
/* We *should* check that basename is valid, but why let that stop us? */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session->scpRecv_state = libssh2_NB_state_sent7;
|
||||||
|
}
|
||||||
|
|
||||||
if (sb) {
|
if (sb) {
|
||||||
memset(sb, 0, sizeof(struct stat));
|
memset(sb, 0, sizeof(struct stat));
|
||||||
|
|
||||||
sb->st_mtime = mtime;
|
sb->st_mtime = session->scpRecv_mtime;
|
||||||
sb->st_atime = atime;
|
sb->st_atime = session->scpRecv_atime;
|
||||||
sb->st_size = size;
|
sb->st_size = session->scpRecv_size;
|
||||||
sb->st_mode = mode;
|
sb->st_mode = session->scpRecv_mode;
|
||||||
}
|
}
|
||||||
/* Revert to non-blocking and let the data BEGIN! */
|
|
||||||
libssh2_channel_set_blocking(channel, 0);
|
|
||||||
|
|
||||||
return channel;
|
session->scpRecv_state = libssh2_NB_state_idle;
|
||||||
|
return session->scpRecv_channel;
|
||||||
|
|
||||||
|
scp_recv_error:
|
||||||
|
while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN);
|
||||||
|
session->scpRecv_channel = NULL;
|
||||||
|
session->scpRecv_state = libssh2_NB_state_idle;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_scp_send_ex
|
/* {{{ libssh2_scp_send_ex
|
||||||
* Send a file using SCP
|
* Send a file using SCP
|
||||||
|
*
|
||||||
|
* NOTE: Will block in a busy loop on error. This has to be done,
|
||||||
|
* otherwise the blocking error code would erase the true
|
||||||
|
* 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_API LIBSSH2_CHANNEL *
|
||||||
|
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime)
|
||||||
{
|
{
|
||||||
int path_len = strlen(path);
|
int path_len = strlen(path);
|
||||||
unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
|
||||||
unsigned long response_len, command_len = path_len + sizeof("scp -t ");
|
|
||||||
unsigned const char *base;
|
unsigned const char *base;
|
||||||
LIBSSH2_CHANNEL *channel;
|
int rc;
|
||||||
|
|
||||||
|
if (session->scpSend_state == libssh2_NB_state_idle) {
|
||||||
|
session->scpSend_command_len = path_len + sizeof("scp -t ");
|
||||||
|
|
||||||
if (mtime || atime) {
|
if (mtime || atime) {
|
||||||
command_len++;
|
session->scpSend_command_len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
command = LIBSSH2_ALLOC(session, command_len);
|
session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len);
|
||||||
if (!command) {
|
if (!session->scpSend_command) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0);
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mtime || atime) {
|
if (mtime || atime) {
|
||||||
memcpy(command, "scp -pt ", sizeof("scp -pt ") - 1);
|
memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1);
|
||||||
memcpy(command + sizeof("scp -pt ") - 1, path, path_len);
|
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len);
|
||||||
} else {
|
} else {
|
||||||
memcpy(command, "scp -t ", sizeof("scp -t ") - 1);
|
memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1);
|
||||||
memcpy(command + sizeof("scp -t ") - 1, path, path_len);
|
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, path_len);
|
||||||
}
|
}
|
||||||
command[command_len - 1] = '\0';
|
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
|
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
|
||||||
/* Allocate a channel */
|
/* Allocate a channel */
|
||||||
if ((channel = libssh2_channel_open_session(session)) == NULL) {
|
|
||||||
|
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);
|
||||||
|
if (!session->scpSend_channel) {
|
||||||
|
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||||
/* previous call set libssh2_session_last_error(), pass it through */
|
/* previous call set libssh2_session_last_error(), pass it through */
|
||||||
LIBSSH2_FREE(session, command);
|
LIBSSH2_FREE(session, session->scpSend_command);
|
||||||
|
session->scpSend_command = NULL;
|
||||||
|
session->scpSend_state = libssh2_NB_state_idle;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Use blocking I/O for negotiation phase */
|
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||||
libssh2_channel_set_blocking(channel, 1);
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session->scpSend_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->scpSend_state == libssh2_NB_state_sent) {
|
||||||
/* Request SCP for the desired file */
|
/* Request SCP for the desired file */
|
||||||
if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) {
|
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1,
|
||||||
/* previous call set libssh2_session_last_error(), pass it through */
|
(char *)session->scpSend_command, session->scpSend_command_len);
|
||||||
LIBSSH2_FREE(session, command);
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_channel_free(channel);
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, command);
|
else if (rc) {
|
||||||
|
/* previous call set libssh2_session_last_error(), pass it through */
|
||||||
|
LIBSSH2_FREE(session, session->scpSend_command);
|
||||||
|
session->scpSend_command = NULL;
|
||||||
|
goto scp_send_error;
|
||||||
|
}
|
||||||
|
LIBSSH2_FREE(session, session->scpSend_command);
|
||||||
|
session->scpSend_command = NULL;
|
||||||
|
|
||||||
|
session->scpSend_state = libssh2_NB_state_sent1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->scpSend_state == libssh2_NB_state_sent1) {
|
||||||
/* Wait for ACK */
|
/* Wait for ACK */
|
||||||
if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) {
|
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_channel_free(channel);
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||||
|
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_state = libssh2_NB_state_sent2;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send mtime and atime to be used for file */
|
/* Send mtime and atime to be used for file */
|
||||||
if (mtime || atime) {
|
if (mtime || atime) {
|
||||||
response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, atime);
|
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response);
|
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
|
||||||
|
session->scpSend_response_len);
|
||||||
if (libssh2_channel_write(channel, response, response_len) != response_len) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_send_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->scpSend_state = libssh2_NB_state_sent3;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Wait for ACK */
|
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||||
if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) {
|
|
||||||
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);
|
||||||
libssh2_channel_free(channel);
|
goto scp_send_error;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
session->scpSend_state = libssh2_NB_state_sent4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
||||||
|
session->scpSend_state = libssh2_NB_state_sent4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session->scpSend_state == libssh2_NB_state_sent4) {
|
||||||
/* Send mode, size, and basename */
|
/* Send mode, size, and basename */
|
||||||
base = strrchr(path, '/');
|
base = (unsigned char *)strrchr(path, '/');
|
||||||
if (base) {
|
if (base) {
|
||||||
base++;
|
base++;
|
||||||
} else {
|
} else {
|
||||||
base = path;
|
base = (unsigned char *)path;
|
||||||
}
|
}
|
||||||
|
|
||||||
response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, (unsigned long)size, base);
|
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response);
|
"C0%o %lu %s\n", mode, (unsigned long)size, base);
|
||||||
if (libssh2_channel_write(channel, response, response_len) != response_len) {
|
_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,
|
||||||
|
session->scpSend_response_len);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
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);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0);
|
||||||
libssh2_channel_free(channel);
|
goto scp_send_error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->scpSend_state = libssh2_NB_state_sent6;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for ACK */
|
/* Wait for ACK */
|
||||||
if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) {
|
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_channel_free(channel);
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||||
|
goto scp_send_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ready to start, switch to non-blocking and let calling app send file */
|
session->scpSend_state = libssh2_NB_state_idle;
|
||||||
libssh2_channel_set_blocking(channel, 0);
|
|
||||||
|
|
||||||
return channel;
|
return session->scpSend_channel;
|
||||||
|
|
||||||
|
scp_send_error:
|
||||||
|
while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN);
|
||||||
|
session->scpSend_channel = NULL;
|
||||||
|
session->scpSend_state = libssh2_NB_state_idle;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
570
src/session.c
570
src/session.c
@@ -41,6 +41,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifdef HAVE_GETTIMEOFDAY
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@@ -76,17 +77,24 @@ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
|||||||
/* {{{ libssh2_banner_receive
|
/* {{{ libssh2_banner_receive
|
||||||
* Wait for a hello from the remote host
|
* Wait for a hello from the remote host
|
||||||
* Allocate a buffer and store the banner in session->remote.banner
|
* Allocate a buffer and store the banner in session->remote.banner
|
||||||
* Returns: 0 on success, 1 on failure
|
* 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)
|
||||||
{
|
{
|
||||||
char banner[256];
|
|
||||||
int banner_len = 0;
|
|
||||||
|
|
||||||
while ((banner_len < (int)sizeof(banner)) &&
|
|
||||||
((banner_len == 0) || (banner[banner_len-1] != '\n'))) {
|
|
||||||
char c = '\0';
|
|
||||||
int ret;
|
int ret;
|
||||||
|
int banner_len;
|
||||||
|
|
||||||
|
if (session->banner_TxRx_state == libssh2_NB_state_idle) {
|
||||||
|
banner_len = 0;
|
||||||
|
|
||||||
|
session->banner_TxRx_state = libssh2_NB_state_created;
|
||||||
|
} else {
|
||||||
|
banner_len = session->banner_TxRx_total_send;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((banner_len < (int)sizeof(session->banner_TxRx_banner)) &&
|
||||||
|
((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));
|
||||||
|
|
||||||
@@ -96,20 +104,28 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
case WSAEWOULDBLOCK:
|
case WSAEWOULDBLOCK:
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WSAENOTSOCK:
|
case WSAENOTSOCK:
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WSAENOTCONN:
|
case WSAENOTCONN:
|
||||||
case WSAECONNABORTED:
|
case WSAECONNABORTED:
|
||||||
errno = WSAENOTCONN;
|
errno = WSAENOTCONN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WSAEINTR:
|
case WSAEINTR:
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
if (errno != EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
/* Some kinda error, but don't break for non-blocking issues */
|
session->banner_TxRx_total_send = banner_len;
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
} else {
|
||||||
|
/* Some kinda error */
|
||||||
|
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||||
|
session->banner_TxRx_total_send = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,17 +134,24 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
if (c == '\0') {
|
if (c == '\0') {
|
||||||
/* NULLs are not allowed in SSH banners */
|
/* NULLs are not allowed in SSH banners */
|
||||||
|
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||||
|
session->banner_TxRx_total_send = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
banner[banner_len++] = c;
|
session->banner_TxRx_banner[banner_len++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (banner_len &&
|
while (banner_len &&
|
||||||
((banner[banner_len-1] == '\n') || (banner[banner_len-1] == '\r'))) {
|
((session->banner_TxRx_banner[banner_len-1] == '\n') ||
|
||||||
|
(session->banner_TxRx_banner[banner_len-1] == '\r'))) {
|
||||||
banner_len--;
|
banner_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From this point on, we are done here */
|
||||||
|
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);
|
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
|
||||||
@@ -136,7 +159,7 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy(session->remote.banner, banner, banner_len);
|
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
|
||||||
session->remote.banner[banner_len] = '\0';
|
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;
|
return 0;
|
||||||
@@ -145,22 +168,30 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
/* {{{ libssh2_banner_send
|
/* {{{ libssh2_banner_send
|
||||||
* Send the default banner, or the one set via libssh2_setopt_string
|
* Send the default banner, or the one set via libssh2_setopt_string
|
||||||
|
*
|
||||||
|
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
|
||||||
|
* call this function again as soon as it is likely that more data can be
|
||||||
|
* 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;
|
char *banner = (char *)LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
|
||||||
int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
|
int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
|
||||||
|
ssize_t ret;
|
||||||
|
#ifdef LIBSSH2DEBUG
|
||||||
|
char banner_dup[256];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (session->banner_TxRx_state == libssh2_NB_state_idle) {
|
||||||
if (session->local.banner) {
|
if (session->local.banner) {
|
||||||
/* setopt_string will have given us our \r\n characters */
|
/* setopt_string will have given us our \r\n characters */
|
||||||
banner_len = strlen((char *)session->local.banner);
|
banner_len = strlen((char *)session->local.banner);
|
||||||
banner = (char *)session->local.banner;
|
banner = (char *)session->local.banner;
|
||||||
}
|
}
|
||||||
#ifdef LIBSSH2DEBUG
|
|
||||||
{
|
|
||||||
/* Hack and slash to avoid sending CRLF in debug output */
|
|
||||||
char banner_dup[256];
|
|
||||||
|
|
||||||
|
#ifdef LIBSSH2DEBUG
|
||||||
|
/* Hack and slash to avoid sending CRLF in debug output */
|
||||||
if (banner_len < 256) {
|
if (banner_len < 256) {
|
||||||
memcpy(banner_dup, banner, banner_len - 2);
|
memcpy(banner_dup, banner, banner_len - 2);
|
||||||
banner_dup[banner_len - 2] = '\0';
|
banner_dup[banner_len - 2] = '\0';
|
||||||
@@ -170,13 +201,160 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (send(session->socket_fd, banner, banner_len, LIBSSH2_SOCKET_SEND_FLAGS(session)) == banner_len) ? 0 : 1;
|
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,
|
||||||
|
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||||
|
|
||||||
|
if (ret != (banner_len-session->banner_TxRx_total_send)) {
|
||||||
|
if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) {
|
||||||
|
/* the whole packet could not be sent, save the what was */
|
||||||
|
session->banner_TxRx_total_send += ret;
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||||
|
session->banner_TxRx_total_send = 0;
|
||||||
|
return PACKET_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the state back to idle */
|
||||||
|
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||||
|
session->banner_TxRx_total_send = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _libssh2_nonblock() sets the given socket to either blocking or
|
||||||
|
* 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 */
|
||||||
|
int nonblock /* TRUE or FALSE */)
|
||||||
|
{
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 0
|
||||||
|
#ifdef HAVE_O_NONBLOCK
|
||||||
|
/* most recent unix versions */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
flags = fcntl(sockfd, F_GETFL, 0);
|
||||||
|
if (nonblock)
|
||||||
|
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
else
|
||||||
|
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||||
|
/* older unix versions */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
flags = nonblock;
|
||||||
|
return ioctl(sockfd, FIONBIO, &flags);
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||||
|
/* Windows? */
|
||||||
|
unsigned long flags;
|
||||||
|
flags = nonblock;
|
||||||
|
|
||||||
|
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||||
|
/* presumably for Amiga */
|
||||||
|
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||||
|
/* BeOS */
|
||||||
|
long b = nonblock ? 1 : 0;
|
||||||
|
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||||
|
return 0; /* returns success */
|
||||||
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SETBLOCK == 0)
|
||||||
|
#error "no non-blocking method was found/used/set"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _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 */
|
||||||
|
{
|
||||||
|
#undef GETBLOCK
|
||||||
|
#define GETBLOCK 0
|
||||||
|
#ifdef HAVE_O_NONBLOCK
|
||||||
|
/* most recent unix versions */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
|
||||||
|
/* Assume blocking on error */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return (flags & O_NONBLOCK);
|
||||||
|
#undef GETBLOCK
|
||||||
|
#define GETBLOCK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
|
||||||
|
/* Windows? */
|
||||||
|
unsigned int option_value;
|
||||||
|
socklen_t option_len = sizeof(option_value);
|
||||||
|
|
||||||
|
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&option_value, &option_len)) {
|
||||||
|
/* Assume blocking on error */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return (int)option_value;
|
||||||
|
#undef GETBLOCK
|
||||||
|
#define GETBLOCK 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
|
||||||
|
/* BeOS */
|
||||||
|
long b;
|
||||||
|
if (getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) {
|
||||||
|
/* Assume blocking on error */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return (int)b;
|
||||||
|
#undef GETBLOCK
|
||||||
|
#define GETBLOCK 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||||
|
return 1; /* returns blocking */
|
||||||
|
#undef GETBLOCK
|
||||||
|
#define GETBLOCK 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GETBLOCK == 0)
|
||||||
|
#error "no non-blocking method was found/used/get"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{ libssh2_banner_set
|
/* {{{ libssh2_banner_set
|
||||||
* Set the local banner
|
* Set the local banner
|
||||||
*/
|
*/
|
||||||
@@ -195,15 +373,13 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
|||||||
|
|
||||||
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
|
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
|
||||||
if (!session->local.banner) {
|
if (!session->local.banner) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner", 0);
|
||||||
"Unable to allocate memory for local banner", 0);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(session->local.banner, banner, banner_len);
|
memcpy(session->local.banner, banner, banner_len);
|
||||||
session->local.banner[banner_len] = '\0';
|
session->local.banner[banner_len] = '\0';
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s", session->local.banner);
|
||||||
"Setting local Banner: %s", session->local.banner);
|
|
||||||
session->local.banner[banner_len++] = '\r';
|
session->local.banner[banner_len++] = '\r';
|
||||||
session->local.banner[banner_len++] = '\n';
|
session->local.banner[banner_len++] = '\n';
|
||||||
session->local.banner[banner_len++] = '\0';
|
session->local.banner[banner_len++] = '\0';
|
||||||
@@ -229,12 +405,15 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
|||||||
LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
|
LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
if (my_alloc)
|
if (my_alloc) {
|
||||||
local_alloc = my_alloc;
|
local_alloc = my_alloc;
|
||||||
if (my_free)
|
}
|
||||||
|
if (my_free) {
|
||||||
local_free = my_free;
|
local_free = my_free;
|
||||||
if (my_realloc)
|
}
|
||||||
|
if (my_realloc) {
|
||||||
local_realloc = my_realloc;
|
local_realloc = my_realloc;
|
||||||
|
}
|
||||||
|
|
||||||
session = local_alloc(sizeof(LIBSSH2_SESSION), abstract);
|
session = local_alloc(sizeof(LIBSSH2_SESSION), abstract);
|
||||||
if (session) {
|
if (session) {
|
||||||
@@ -243,8 +422,7 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
|||||||
session->free = local_free;
|
session->free = local_free;
|
||||||
session->realloc = local_realloc;
|
session->realloc = local_realloc;
|
||||||
session->abstract = abstract;
|
session->abstract = abstract;
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated");
|
||||||
"New session resource allocated");
|
|
||||||
libssh2_crypto_init ();
|
libssh2_crypto_init ();
|
||||||
}
|
}
|
||||||
return session;
|
return session;
|
||||||
@@ -255,9 +433,7 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
|||||||
* Set (or reset) a callback function
|
* Set (or reset) a callback function
|
||||||
* Returns the prior address
|
* Returns the prior address
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback)
|
||||||
int cbtype,
|
|
||||||
void *callback)
|
|
||||||
{
|
{
|
||||||
void *oldcb;
|
void *oldcb;
|
||||||
|
|
||||||
@@ -303,89 +479,156 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
|||||||
*/
|
*/
|
||||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||||
{
|
{
|
||||||
unsigned char *data;
|
|
||||||
unsigned long data_len;
|
|
||||||
unsigned char service[sizeof("ssh-userauth") + 5 - 1];
|
|
||||||
unsigned long service_length;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (session->startup_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||||
"session_startup for socket %d", socket);
|
"session_startup for socket %d", socket);
|
||||||
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
||||||
if (socket < 0) {
|
if (socket < 0) {
|
||||||
/* Did we forget something? */
|
/* Did we forget something? */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, "Bad socket provided", 0);
|
||||||
"Bad socket provided", 0);
|
|
||||||
return LIBSSH2_ERROR_SOCKET_NONE;
|
return LIBSSH2_ERROR_SOCKET_NONE;
|
||||||
}
|
}
|
||||||
session->socket_fd = socket;
|
session->socket_fd = socket;
|
||||||
|
|
||||||
|
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
|
||||||
|
* was an error detecting the state, so set to blocking to
|
||||||
|
* be sure
|
||||||
|
*/
|
||||||
|
_libssh2_nonblock(session->socket_fd, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
session->startup_state = libssh2_NB_state_created;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Liveness check */
|
/* TODO: Liveness check */
|
||||||
if (libssh2_banner_send(session)) {
|
|
||||||
|
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);
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
/* Unable to send banner? */
|
/* Unable to send banner? */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0);
|
||||||
"Error sending banner to remote host", 0);
|
|
||||||
return LIBSSH2_ERROR_BANNER_SEND;
|
return LIBSSH2_ERROR_BANNER_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libssh2_banner_receive(session)) {
|
session->startup_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
/* Unable to receive banner from remote */
|
/* Unable to receive banner from remote */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
|
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0);
|
||||||
"Timeout waiting for banner", 0);
|
|
||||||
return LIBSSH2_ERROR_BANNER_NONE;
|
return LIBSSH2_ERROR_BANNER_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_kex_exchange(session, 0);
|
session->startup_state = libssh2_NB_state_sent1;
|
||||||
if(rc) {
|
}
|
||||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
|
||||||
"Unable to exchange encryption keys", 0);
|
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);
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
|
||||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
session->startup_state = libssh2_NB_state_sent2;
|
||||||
"Requesting userauth service");
|
}
|
||||||
|
|
||||||
|
if (session->startup_state == libssh2_NB_state_sent2) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
|
||||||
|
|
||||||
/* Request the userauth service */
|
/* Request the userauth service */
|
||||||
service[0] = SSH_MSG_SERVICE_REQUEST;
|
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
|
||||||
libssh2_htonu32(service + 1, sizeof("ssh-userauth") - 1);
|
libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1);
|
||||||
memcpy(service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
||||||
if (libssh2_packet_write(session, service,
|
|
||||||
sizeof("ssh-userauth") + 5 - 1)) {
|
session->startup_state = libssh2_NB_state_sent3;
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
}
|
||||||
"Unable to ask for ssh-userauth service", 0);
|
|
||||||
|
if (session->startup_state == libssh2_NB_state_sent3) {
|
||||||
|
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);
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
|
||||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, &data,
|
session->startup_state = libssh2_NB_state_sent4;
|
||||||
&data_len);
|
}
|
||||||
if(rc) {
|
|
||||||
|
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);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
else if (rc) {
|
||||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||||
}
|
}
|
||||||
service_length = libssh2_ntohu32(data + 1);
|
session->startup_service_length = libssh2_ntohu32(session->startup_data + 1);
|
||||||
|
|
||||||
if ((service_length != (sizeof("ssh-userauth") - 1)) ||
|
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) ||
|
||||||
strncmp("ssh-userauth", (char *)data + 5, service_length)) {
|
strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) {
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, session->startup_data);
|
||||||
libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
session->startup_data = NULL;
|
||||||
"Invalid response received from server", 0);
|
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0);
|
||||||
return LIBSSH2_ERROR_PROTO;
|
return LIBSSH2_ERROR_PROTO;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, session->startup_data);
|
||||||
|
session->startup_data = NULL;
|
||||||
|
|
||||||
|
session->startup_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* just for safety return some error */
|
||||||
|
return LIBSSH2_ERROR_INVAL;
|
||||||
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto libssh2_session_free
|
/* {{{ proto libssh2_session_free
|
||||||
* Frees the memory allocated to the session
|
* Frees the memory allocated to the session
|
||||||
* Also closes and frees any channels attached to this session
|
* Also closes and frees any channels attached to this session
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API void 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->free_state == libssh2_NB_state_created) {
|
||||||
while (session->channels.head) {
|
while (session->channels.head) {
|
||||||
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
||||||
|
|
||||||
libssh2_channel_free(session->channels.head);
|
rc = libssh2_channel_free(session->channels.head);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
if (tmp == session->channels.head) {
|
if (tmp == session->channels.head) {
|
||||||
/* channel_free couldn't do it's job, perform a messy cleanup */
|
/* channel_free couldn't do it's job, perform a messy cleanup */
|
||||||
tmp = session->channels.head;
|
tmp = session->channels.head;
|
||||||
@@ -400,8 +643,18 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->state == libssh2_NB_state_sent) {
|
||||||
while (session->listeners) {
|
while (session->listeners) {
|
||||||
libssh2_channel_forward_cancel(session->listeners);
|
rc = libssh2_channel_forward_cancel(session->listeners);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session->state = libssh2_NB_state_sent1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||||
@@ -486,6 +739,73 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
LIBSSH2_FREE(session, session->remote.lang_prefs);
|
LIBSSH2_FREE(session, session->remote.lang_prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure all memory used in the state variables are free
|
||||||
|
*/
|
||||||
|
if (session->startup_data) {
|
||||||
|
LIBSSH2_FREE(session, session->startup_data);
|
||||||
|
}
|
||||||
|
if (session->disconnect_data) {
|
||||||
|
LIBSSH2_FREE(session, session->disconnect_data);
|
||||||
|
}
|
||||||
|
if (session->userauth_list_data) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||||
|
}
|
||||||
|
if (session->userauth_pswd_data) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_pswd_data);
|
||||||
|
}
|
||||||
|
if (session->userauth_pswd_newpw) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_pswd_newpw);
|
||||||
|
}
|
||||||
|
if (session->userauth_host_packet) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_host_packet);
|
||||||
|
}
|
||||||
|
if (session->userauth_host_method) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_host_method);
|
||||||
|
}
|
||||||
|
if (session->userauth_host_data) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_host_data);
|
||||||
|
}
|
||||||
|
if (session->userauth_pblc_data) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_pblc_data);
|
||||||
|
}
|
||||||
|
if (session->userauth_pblc_packet) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_pblc_packet);
|
||||||
|
}
|
||||||
|
if (session->userauth_pblc_method) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_pblc_method);
|
||||||
|
}
|
||||||
|
if (session->userauth_kybd_data) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_kybd_data);
|
||||||
|
}
|
||||||
|
if (session->userauth_kybd_packet) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_kybd_packet);
|
||||||
|
}
|
||||||
|
if (session->userauth_kybd_auth_instruction) {
|
||||||
|
LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction);
|
||||||
|
}
|
||||||
|
if (session->open_packet) {
|
||||||
|
LIBSSH2_FREE(session, session->open_packet);
|
||||||
|
}
|
||||||
|
if (session->open_data) {
|
||||||
|
LIBSSH2_FREE(session, session->open_data);
|
||||||
|
}
|
||||||
|
if (session->direct_message) {
|
||||||
|
LIBSSH2_FREE(session, session->direct_message);
|
||||||
|
}
|
||||||
|
if (session->fwdLstn_packet) {
|
||||||
|
LIBSSH2_FREE(session, session->fwdLstn_packet);
|
||||||
|
}
|
||||||
|
if (session->pkeyInit_data) {
|
||||||
|
LIBSSH2_FREE(session, session->pkeyInit_data);
|
||||||
|
}
|
||||||
|
if (session->scpRecv_command) {
|
||||||
|
LIBSSH2_FREE(session, session->scpRecv_command);
|
||||||
|
}
|
||||||
|
if (session->scpSend_command) {
|
||||||
|
LIBSSH2_FREE(session, session->scpSend_command);
|
||||||
|
}
|
||||||
|
|
||||||
/* Cleanup any remaining packets */
|
/* Cleanup any remaining packets */
|
||||||
while (session->packets.head) {
|
while (session->packets.head) {
|
||||||
LIBSSH2_PACKET *tmp = session->packets.head;
|
LIBSSH2_PACKET *tmp = session->packets.head;
|
||||||
@@ -499,6 +819,8 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, session);
|
LIBSSH2_FREE(session, session);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -506,9 +828,11 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
*/
|
*/
|
||||||
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, *data;
|
unsigned char *s;
|
||||||
unsigned long data_len, descr_len = 0, lang_len = 0;
|
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) {
|
if (description) {
|
||||||
descr_len = strlen(description);
|
descr_len = strlen(description);
|
||||||
@@ -516,11 +840,13 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
|||||||
if (lang) {
|
if (lang) {
|
||||||
lang_len = strlen(lang);
|
lang_len = strlen(lang);
|
||||||
}
|
}
|
||||||
data_len = descr_len + lang_len + 13; /* packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
|
/* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
|
||||||
|
session->disconnect_data_len = descr_len + lang_len + 13;
|
||||||
|
|
||||||
s = data = LIBSSH2_ALLOC(session, data_len);
|
s = session->disconnect_data = LIBSSH2_ALLOC(session, session->disconnect_data_len);
|
||||||
if (!data) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,9 +865,17 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
|||||||
s += lang_len;
|
s += lang_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
libssh2_packet_write(session, data, data_len);
|
session->disconnect_state = libssh2_NB_state_created;
|
||||||
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
rc = libssh2_packet_write(session, session->disconnect_data, session->disconnect_data_len);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, session->disconnect_data);
|
||||||
|
session->disconnect_data = NULL;
|
||||||
|
session->disconnect_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -561,33 +895,43 @@ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int me
|
|||||||
case LIBSSH2_METHOD_KEX:
|
case LIBSSH2_METHOD_KEX:
|
||||||
method = session->kex;
|
method = session->kex;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_HOSTKEY:
|
case LIBSSH2_METHOD_HOSTKEY:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->hostkey;
|
method = (LIBSSH2_KEX_METHOD*)session->hostkey;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_CRYPT_CS:
|
case LIBSSH2_METHOD_CRYPT_CS:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->local.crypt;
|
method = (LIBSSH2_KEX_METHOD*)session->local.crypt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_CRYPT_SC:
|
case LIBSSH2_METHOD_CRYPT_SC:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->remote.crypt;
|
method = (LIBSSH2_KEX_METHOD*)session->remote.crypt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_MAC_CS:
|
case LIBSSH2_METHOD_MAC_CS:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->local.mac;
|
method = (LIBSSH2_KEX_METHOD*)session->local.mac;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_MAC_SC:
|
case LIBSSH2_METHOD_MAC_SC:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->remote.mac;
|
method = (LIBSSH2_KEX_METHOD*)session->remote.mac;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_COMP_CS:
|
case LIBSSH2_METHOD_COMP_CS:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->local.comp;
|
method = (LIBSSH2_KEX_METHOD*)session->local.comp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_COMP_SC:
|
case LIBSSH2_METHOD_COMP_SC:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->remote.comp;
|
method = (LIBSSH2_KEX_METHOD*)session->remote.comp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_LANG_CS:
|
case LIBSSH2_METHOD_LANG_CS:
|
||||||
return "";
|
return "";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_LANG_SC:
|
case LIBSSH2_METHOD_LANG_SC:
|
||||||
return "";
|
return "";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return NULL;
|
||||||
@@ -618,8 +962,7 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
|
|||||||
* Otherwise it is assumed to be owned by libssh2
|
* Otherwise it is assumed to be owned by libssh2
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg,
|
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf)
|
||||||
int *errmsg_len, int want_buf)
|
|
||||||
{
|
{
|
||||||
/* No error to report */
|
/* No error to report */
|
||||||
if (!session->err_code) {
|
if (!session->err_code) {
|
||||||
@@ -670,6 +1013,16 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg,
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ libssh2_session_last_error
|
||||||
|
* Returns error code
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_session_last_errno(LIBSSH2_SESSION *session)
|
||||||
|
{
|
||||||
|
return session->err_code;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_session_flag
|
/* {{{ libssh2_session_flag
|
||||||
* Set/Get session flags
|
* Set/Get session flags
|
||||||
* Passing flag==0 will avoid changing session->flags while still returning its current value
|
* Passing flag==0 will avoid changing session->flags while still returning its current value
|
||||||
@@ -686,6 +1039,45 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ _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 bl = session->socket_block;
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting blocking mode on session %d", blocking);
|
||||||
|
if (blocking == session->socket_block) {
|
||||||
|
/* avoid if already correct */
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
session->socket_block = blocking;
|
||||||
|
|
||||||
|
_libssh2_nonblock(session->socket_fd, !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)
|
||||||
|
{
|
||||||
|
(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)
|
||||||
|
{
|
||||||
|
return session->socket_block;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_poll_channel_read
|
/* {{{ libssh2_poll_channel_read
|
||||||
* Returns 0 if no data is waiting on channel,
|
* Returns 0 if no data is waiting on channel,
|
||||||
* non-0 if data is available
|
* non-0 if data is available
|
||||||
@@ -696,8 +1088,10 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
|
|||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = session->packets.head;
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) ||
|
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) &&
|
||||||
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (extended != 0) && (channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
|
(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 */
|
/* Found data waiting to be read */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -731,8 +1125,7 @@ static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener)
|
|||||||
/* {{{ libssh2_poll
|
/* {{{ libssh2_poll
|
||||||
* Poll sockets, channels, and listeners for activity
|
* Poll sockets, channels, and listeners for activity
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||||
long timeout)
|
|
||||||
{
|
{
|
||||||
long timeout_remaining;
|
long timeout_remaining;
|
||||||
unsigned int i, active_fds;
|
unsigned int i, active_fds;
|
||||||
@@ -753,20 +1146,24 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
|||||||
sockets[i].events = fds[i].events;
|
sockets[i].events = fds[i].events;
|
||||||
sockets[i].revents = 0;
|
sockets[i].revents = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_CHANNEL:
|
case LIBSSH2_POLLFD_CHANNEL:
|
||||||
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
|
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
|
||||||
sockets[i].events = POLLIN;
|
sockets[i].events = POLLIN;
|
||||||
sockets[i].revents = 0;
|
sockets[i].revents = 0;
|
||||||
if (!session) session = fds[i].fd.channel->session;
|
if (!session) session = fds[i].fd.channel->session;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
|
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
|
||||||
sockets[i].events = POLLIN;
|
sockets[i].events = POLLIN;
|
||||||
sockets[i].revents = 0;
|
sockets[i].revents = 0;
|
||||||
if (!session) session = fds[i].fd.listener->session;
|
if (!session) session = fds[i].fd.listener->session;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -791,18 +1188,22 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
|||||||
if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket;
|
if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_CHANNEL:
|
case LIBSSH2_POLLFD_CHANNEL:
|
||||||
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
|
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 (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;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
|
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 (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;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -845,6 +1246,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
|||||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */
|
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_POLLFD_POLLIN) == 0)) { /* No connections known of yet */
|
||||||
@@ -955,12 +1357,14 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
|||||||
active_fds++;
|
active_fds++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_CHANNEL:
|
case LIBSSH2_POLLFD_CHANNEL:
|
||||||
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
|
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
|
||||||
/* Spin session until no data available */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
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 */
|
/* Spin session until no data available */
|
||||||
|
1309
src/sftp.c
1309
src/sftp.c
File diff suppressed because it is too large
Load Diff
214
src/transport.c
214
src/transport.c
@@ -66,7 +66,7 @@ static void debugdump(LIBSSH2_SESSION *session,
|
|||||||
|
|
||||||
for(i=0; i<size; i+= width) {
|
for(i=0; i<size; i+= width) {
|
||||||
|
|
||||||
fprintf(stream, "%04x: ", i);
|
fprintf(stream, "%04lx: ", i);
|
||||||
|
|
||||||
/* hex not disabled, show it */
|
/* hex not disabled, show it */
|
||||||
for(c = 0; c < width; c++) {
|
for(c = 0; c < width; c++) {
|
||||||
@@ -130,14 +130,16 @@ static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
|
|||||||
* fullpacket() gets called when a full packet has been received and properly
|
* fullpacket() gets called when a full packet has been received and properly
|
||||||
* collected.
|
* collected.
|
||||||
*/
|
*/
|
||||||
static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
static libssh2pack_t
|
||||||
int encrypted /* 1 or 0 */)
|
fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||||
{
|
{
|
||||||
unsigned char macbuf[MAX_MACSIZE];
|
unsigned char macbuf[MAX_MACSIZE];
|
||||||
struct transportpacket *p = &session->packet;
|
struct transportpacket *p = &session->packet;
|
||||||
int payload_len = p->packet_length-1;
|
int rc;
|
||||||
libssh2pack_t packet_type;
|
|
||||||
int macstate = LIBSSH2_MAC_CONFIRMED;
|
if (session->fullpacket_state == libssh2_NB_state_idle) {
|
||||||
|
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
|
||||||
|
session->fullpacket_payload_len = p->packet_length-1;
|
||||||
|
|
||||||
if (encrypted) {
|
if (encrypted) {
|
||||||
|
|
||||||
@@ -146,7 +148,7 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
macbuf, /* store hash here */
|
macbuf, /* store hash here */
|
||||||
session->remote.seqno,
|
session->remote.seqno,
|
||||||
p->init, 5,
|
p->init, 5,
|
||||||
p->payload, payload_len,
|
p->payload, session->fullpacket_payload_len,
|
||||||
&session->remote.mac_abstract);
|
&session->remote.mac_abstract);
|
||||||
|
|
||||||
/* Compare the calculated hash with the MAC we just read from
|
/* Compare the calculated hash with the MAC we just read from
|
||||||
@@ -154,16 +156,16 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
* buffer. Note that 'payload_len' here is the packet_length
|
* buffer. Note that 'payload_len' here is the packet_length
|
||||||
* field which includes the padding but not the MAC.
|
* field which includes the padding but not the MAC.
|
||||||
*/
|
*/
|
||||||
if(memcmp(macbuf, p->payload + payload_len,
|
if (memcmp(macbuf, p->payload + session->fullpacket_payload_len,
|
||||||
session->remote.mac->mac_len)) {
|
session->remote.mac->mac_len)) {
|
||||||
macstate = LIBSSH2_MAC_INVALID;
|
session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->remote.seqno++;
|
session->remote.seqno++;
|
||||||
|
|
||||||
/* ignore the padding */
|
/* ignore the padding */
|
||||||
payload_len -= p->padding_length;
|
session->fullpacket_payload_len -= p->padding_length;
|
||||||
|
|
||||||
/* Check for and deal with decompression */
|
/* Check for and deal with decompression */
|
||||||
if (session->remote.comp &&
|
if (session->remote.comp &&
|
||||||
@@ -176,7 +178,7 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
&data, &data_len,
|
&data, &data_len,
|
||||||
LIBSSH2_PACKET_MAXDECOMP,
|
LIBSSH2_PACKET_MAXDECOMP,
|
||||||
&free_payload,
|
&free_payload,
|
||||||
p->payload, payload_len,
|
p->payload, session->fullpacket_payload_len,
|
||||||
&session->remote.comp_abstract)) {
|
&session->remote.comp_abstract)) {
|
||||||
LIBSSH2_FREE(session, p->payload);
|
LIBSSH2_FREE(session, p->payload);
|
||||||
return PACKET_FAIL;
|
return PACKET_FAIL;
|
||||||
@@ -185,7 +187,7 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
if (free_payload) {
|
if (free_payload) {
|
||||||
LIBSSH2_FREE(session, p->payload);
|
LIBSSH2_FREE(session, p->payload);
|
||||||
p->payload = data;
|
p->payload = data;
|
||||||
payload_len = data_len;
|
session->fullpacket_payload_len = data_len;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (data == p->payload) {
|
if (data == p->payload) {
|
||||||
@@ -193,7 +195,7 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
* compression layer reused payload, So let's
|
* compression layer reused payload, So let's
|
||||||
* do the same!
|
* do the same!
|
||||||
*/
|
*/
|
||||||
payload_len = data_len;
|
session->fullpacket_payload_len = data_len;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* No comp_method actually lets this happen,
|
/* No comp_method actually lets this happen,
|
||||||
@@ -211,19 +213,32 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
return PACKET_ENOMEM;
|
return PACKET_ENOMEM;
|
||||||
}
|
}
|
||||||
memcpy(p->payload, data, data_len);
|
memcpy(p->payload, data, data_len);
|
||||||
payload_len = data_len;
|
session->fullpacket_payload_len = data_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_type = p->payload[0];
|
session->fullpacket_packet_type = p->payload[0];
|
||||||
|
|
||||||
debugdump(session, "libssh2_packet_read() plain",
|
debugdump(session, "libssh2_packet_read() plain",
|
||||||
p->payload, payload_len);
|
p->payload, session->fullpacket_payload_len);
|
||||||
if (libssh2_packet_add(session, p->payload, payload_len, macstate) < 0)
|
|
||||||
return PACKET_FAIL;
|
|
||||||
|
|
||||||
return packet_type;
|
session->fullpacket_state = libssh2_NB_state_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->fullpacket_state == libssh2_NB_state_created) {
|
||||||
|
rc = libssh2_packet_add(session, p->payload, session->fullpacket_payload_len, session->fullpacket_macstate);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
else if (rc < 0) {
|
||||||
|
return PACKET_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session->fullpacket_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
return session->fullpacket_packet_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,7 +246,7 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
* Collect a packet into the input brigade
|
* Collect a packet into the input brigade
|
||||||
* block only controls whether or not to wait for a packet to start,
|
* block only controls whether or not to wait for a packet to start,
|
||||||
* Once a packet starts, libssh2 will block until it is complete
|
* Once a packet starts, libssh2 will block until it is complete
|
||||||
|
*
|
||||||
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
|
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
|
||||||
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
|
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
|
||||||
* packet.
|
* packet.
|
||||||
@@ -241,7 +256,6 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
|
|||||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||||
{
|
{
|
||||||
libssh2pack_t rc;
|
libssh2pack_t rc;
|
||||||
@@ -255,20 +269,28 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
int minimum;
|
int minimum;
|
||||||
int encrypted = 1;
|
int encrypted = 1;
|
||||||
|
|
||||||
do {
|
/*
|
||||||
|
* =============================== NOTE ===============================
|
||||||
|
* I know this is very ugly and not a really good use of "goto", but
|
||||||
|
* this case statement would be even uglier to do it any other way
|
||||||
|
*/
|
||||||
|
if (session->readPack_state == libssh2_NB_state_jump1) {
|
||||||
|
session->readPack_state = libssh2_NB_state_idle;
|
||||||
|
encrypted = session->readPack_encrypted;
|
||||||
|
goto libssh2_packet_read_point1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||||
return PACKET_NONE;
|
return PACKET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||||
blocksize = session->remote.crypt->blocksize;
|
blocksize = session->remote.crypt->blocksize;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
encrypted = 0; /* not encrypted */
|
encrypted = 0; /* not encrypted */
|
||||||
blocksize = 5; /* not strictly true, but we can use 5
|
blocksize = 5; /* not strictly true, but we can use 5 here to
|
||||||
here to make the checks below work
|
make the checks below work fine still */
|
||||||
fine still */
|
|
||||||
}
|
}
|
||||||
minimum = p->total_num ? p->total_num - p->data_num : blocksize;
|
minimum = p->total_num ? p->total_num - p->data_num : blocksize;
|
||||||
|
|
||||||
@@ -285,28 +307,24 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
/* if remainbuf turns negative we have a bad internal error */
|
/* if remainbuf turns negative we have a bad internal error */
|
||||||
assert(remainbuf >= 0);
|
assert(remainbuf >= 0);
|
||||||
|
|
||||||
while(remainbuf < minimum) {
|
if (remainbuf < minimum) {
|
||||||
/* While there is too little data to deal with, read
|
/* If we have less than a minimum left, it is too
|
||||||
more */
|
little data to deal with, read more */
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
|
|
||||||
/* move any remainder to the start of the buffer so
|
/* move any remainder to the start of the buffer so
|
||||||
that we can do a full refill */
|
that we can do a full refill */
|
||||||
if (remainbuf) {
|
if (remainbuf) {
|
||||||
memmove(p->buf, &p->buf[p->readidx],
|
memmove(p->buf, &p->buf[p->readidx], remainbuf);
|
||||||
remainbuf);
|
|
||||||
p->readidx = 0;
|
p->readidx = 0;
|
||||||
p->writeidx = remainbuf;
|
p->writeidx = remainbuf;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* nothing to move, just zero the indexes */
|
/* nothing to move, just zero the indexes */
|
||||||
p->readidx = p->writeidx = 0;
|
p->readidx = p->writeidx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now read a big chunk from the network into the temp
|
/* now read a big chunk from the network into the temp buffer */
|
||||||
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));
|
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
/* check if this is due to EAGAIN and return
|
/* check if this is due to EAGAIN and return
|
||||||
@@ -329,23 +347,25 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
/* how much data to deal with from the buffer */
|
/* how much data to deal with from the buffer */
|
||||||
numbytes = remainbuf;
|
numbytes = remainbuf;
|
||||||
|
|
||||||
|
if (numbytes < blocksize) {
|
||||||
|
/* we can't act on anything less than blocksize */
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!p->total_num) {
|
if (!p->total_num) {
|
||||||
/* No payload package area allocated yet. To know the
|
/* No payload package area allocated yet. To know the
|
||||||
size of this payload, we need to decrypt the first
|
size of this payload, we need to decrypt the first
|
||||||
blocksize data. */
|
blocksize data. */
|
||||||
|
|
||||||
if (encrypted) {
|
if (encrypted) {
|
||||||
rc = decrypt(session, &p->buf[p->readidx],
|
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
|
||||||
block, blocksize);
|
|
||||||
if (rc != PACKET_NONE) {
|
if (rc != PACKET_NONE) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
/* save the first 5 bytes of the decrypted
|
/* save the first 5 bytes of the decrypted package, to be
|
||||||
package, to be used in the hash calculation
|
used in the hash calculation later down. */
|
||||||
later down. */
|
|
||||||
memcpy(p->init, &p->buf[p->readidx], 5);
|
memcpy(p->init, &p->buf[p->readidx], 5);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* the data is plain, just copy it verbatim to
|
/* the data is plain, just copy it verbatim to
|
||||||
the working block buffer */
|
the working block buffer */
|
||||||
memcpy(block, &p->buf[p->readidx], blocksize);
|
memcpy(block, &p->buf[p->readidx], blocksize);
|
||||||
@@ -355,16 +375,14 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
p->readidx += blocksize;
|
p->readidx += blocksize;
|
||||||
|
|
||||||
/* we now have the initial blocksize bytes decrypted,
|
/* we now have the initial blocksize bytes decrypted,
|
||||||
and we can extract packet and padding length from it
|
* and we can extract packet and padding length from it
|
||||||
*/
|
*/
|
||||||
p->packet_length = libssh2_ntohu32(block);
|
p->packet_length = libssh2_ntohu32(block);
|
||||||
p->padding_length = block[4];
|
p->padding_length = block[4];
|
||||||
|
|
||||||
/* total_num is the number of bytes following the
|
/* total_num is the number of bytes following the initial
|
||||||
initial (5 bytes) packet length and padding length
|
(5 bytes) packet length and padding length fields */
|
||||||
fields */
|
p->total_num = p->packet_length -1 + (encrypted ? session->remote.mac->mac_len : 0);
|
||||||
p->total_num = p->packet_length -1 +
|
|
||||||
(encrypted?session->remote.mac->mac_len:0);
|
|
||||||
|
|
||||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||||
*
|
*
|
||||||
@@ -392,8 +410,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
the blocksize from the temporary buffer to
|
the blocksize from the temporary buffer to
|
||||||
the start of the decrypted buffer */
|
the start of the decrypted buffer */
|
||||||
memcpy(p->wptr, &block[5], blocksize-5);
|
memcpy(p->wptr, &block[5], blocksize-5);
|
||||||
p->wptr += blocksize-5; /* advance write
|
p->wptr += blocksize-5; /* advance write pointer */
|
||||||
pointer */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init the data_num field to the number of bytes of
|
/* init the data_num field to the number of bytes of
|
||||||
@@ -409,9 +426,8 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
remainpack = p->total_num - p->data_num;
|
remainpack = p->total_num - p->data_num;
|
||||||
|
|
||||||
if (numbytes > remainpack) {
|
if (numbytes > remainpack) {
|
||||||
/* if we have more data in the buffer than what is
|
/* if we have more data in the buffer than what is going into this
|
||||||
going into this particular packet, we limit this
|
particular packet, we limit this round to this packet only */
|
||||||
round to this packet only */
|
|
||||||
numbytes = remainpack;
|
numbytes = remainpack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,10 +442,8 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
total minus the skip margin, we should lower the
|
total minus the skip margin, we should lower the
|
||||||
amount to decrypt even more */
|
amount to decrypt even more */
|
||||||
if ((p->data_num + numbytes) > (p->total_num - skip)) {
|
if ((p->data_num + numbytes) > (p->total_num - skip)) {
|
||||||
numdecrypt = (p->total_num - skip) -
|
numdecrypt = (p->total_num - skip) - p->data_num;
|
||||||
p->data_num;
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
int frac;
|
int frac;
|
||||||
numdecrypt = numbytes;
|
numdecrypt = numbytes;
|
||||||
frac = numdecrypt % blocksize;
|
frac = numdecrypt % blocksize;
|
||||||
@@ -442,8 +456,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
numbytes = 0;
|
numbytes = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* unencrypted data should not be decrypted at all */
|
/* unencrypted data should not be decrypted at all */
|
||||||
numdecrypt = 0;
|
numdecrypt = 0;
|
||||||
}
|
}
|
||||||
@@ -451,8 +464,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
/* if there are bytes to decrypt, do that */
|
/* if there are bytes to decrypt, do that */
|
||||||
if (numdecrypt > 0) {
|
if (numdecrypt > 0) {
|
||||||
/* now decrypt the lot */
|
/* now decrypt the lot */
|
||||||
rc = decrypt(session, &p->buf[p->readidx],
|
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
||||||
p->wptr, numdecrypt);
|
|
||||||
if (rc != PACKET_NONE) {
|
if (rc != PACKET_NONE) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -487,7 +499,13 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
if (!remainpack) {
|
if (!remainpack) {
|
||||||
/* we have a full packet */
|
/* we have a full packet */
|
||||||
|
libssh2_packet_read_point1:
|
||||||
rc = fullpacket(session, encrypted);
|
rc = fullpacket(session, encrypted);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
session->readPack_encrypted = encrypted;
|
||||||
|
session->readPack_state = libssh2_NB_state_jump1;
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
p->total_num = 0; /* no packet buffer available */
|
p->total_num = 0; /* no packet buffer available */
|
||||||
|
|
||||||
@@ -501,10 +519,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
#ifndef OLDSEND
|
#ifndef OLDSEND
|
||||||
|
|
||||||
static libssh2pack_t send_existing(LIBSSH2_SESSION *session,
|
static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len, ssize_t *ret)
|
||||||
unsigned char *data,
|
|
||||||
unsigned long data_len,
|
|
||||||
ssize_t *ret)
|
|
||||||
{
|
{
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
ssize_t length;
|
ssize_t length;
|
||||||
@@ -517,11 +532,11 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session,
|
|||||||
|
|
||||||
/* send as much as possible of the existing packet */
|
/* send as much as possible of the existing packet */
|
||||||
if ((data != p->odata) || (data_len != p->olen)) {
|
if ((data != p->odata) || (data_len != p->olen)) {
|
||||||
/* When we are about to complete the sending of a packet, it
|
/* When we are about to complete the sending of a packet, it is vital
|
||||||
is vital that the caller doesn't try to send a
|
that the caller doesn't try to send a new/different packet since
|
||||||
new/different packet since we don't add this one up until
|
we don't add this one up until the previous one has been sent. To
|
||||||
the previous one has been sent. To make the caller really
|
make the caller really notice his/hers flaw, we return error for
|
||||||
notice his/hers flaw, we return error for this case */
|
this case */
|
||||||
return PACKET_BADUSE;
|
return PACKET_BADUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,9 +545,7 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session,
|
|||||||
/* number of bytes left to send */
|
/* number of bytes left to send */
|
||||||
length = p->ototal_num - p->osent;
|
length = p->ototal_num - p->osent;
|
||||||
|
|
||||||
rc = send(session->socket_fd,
|
rc = send(session->socket_fd, &p->outbuf[p->osent], length, LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||||
&p->outbuf[p->osent],
|
|
||||||
length, LIBSSH2_SOCKET_SEND_FLAGS(session));
|
|
||||||
|
|
||||||
if (rc == length) {
|
if (rc == length) {
|
||||||
/* the remainder of the package was sent */
|
/* the remainder of the package was sent */
|
||||||
@@ -549,8 +562,7 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session,
|
|||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugdump(session, "libssh2_packet_write send()",
|
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length);
|
||||||
&p->outbuf[p->osent], length);
|
|
||||||
p->osent += length; /* we sent away this much data */
|
p->osent += length; /* we sent away this much data */
|
||||||
|
|
||||||
return PACKET_NONE;
|
return PACKET_NONE;
|
||||||
@@ -565,12 +577,9 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session,
|
|||||||
* sent, and this function should then be called with the same argument set
|
* sent, and this function should then be called with the same argument set
|
||||||
* (same data pointer and same data_len) until zero or failure is returned.
|
* (same data pointer and same data_len) until zero or failure is returned.
|
||||||
*/
|
*/
|
||||||
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data,
|
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len)
|
||||||
unsigned long data_len)
|
|
||||||
{
|
{
|
||||||
int blocksize =
|
int blocksize = (session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->blocksize : 8;
|
||||||
(session->state & LIBSSH2_STATE_NEWKEYS) ?
|
|
||||||
session->local.crypt->blocksize : 8;
|
|
||||||
int padding_length;
|
int padding_length;
|
||||||
int packet_length;
|
int packet_length;
|
||||||
int total_length;
|
int total_length;
|
||||||
@@ -591,17 +600,16 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data,
|
|||||||
|
|
||||||
/* FIRST, check if we have a pending write to complete */
|
/* FIRST, check if we have a pending write to complete */
|
||||||
rc = send_existing(session, data, data_len, &ret);
|
rc = send_existing(session, data, data_len, &ret);
|
||||||
if(rc || ret)
|
if (rc || ret) {
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0;
|
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0;
|
||||||
|
|
||||||
/* check if we should compress */
|
/* check if we should compress */
|
||||||
if (encrypted && strcmp(session->local.comp->name, "none")) {
|
if (encrypted && strcmp(session->local.comp->name, "none")) {
|
||||||
if (session->local.comp->comp(session, 1, &data, &data_len,
|
if (session->local.comp->comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
|
||||||
LIBSSH2_PACKET_MAXCOMP,
|
&free_data, data, data_len, &session->local.comp_abstract)) {
|
||||||
&free_data, data, data_len,
|
|
||||||
&session->local.comp_abstract)) {
|
|
||||||
return PACKET_COMPRESS; /* compression failure */
|
return PACKET_COMPRESS; /* compression failure */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -611,8 +619,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data,
|
|||||||
MUST be a multiple of the cipher block size or 8, whichever is
|
MUST be a multiple of the cipher block size or 8, whichever is
|
||||||
larger. */
|
larger. */
|
||||||
|
|
||||||
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize ==
|
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
|
||||||
0 */
|
|
||||||
|
|
||||||
packet_length = data_len + 1 + 4; /* 1 is for padding_length field
|
packet_length = data_len + 1 + 4; /* 1 is for padding_length field
|
||||||
4 for the packet_length field */
|
4 for the packet_length field */
|
||||||
@@ -643,8 +650,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data,
|
|||||||
packet_length += padding_length;
|
packet_length += padding_length;
|
||||||
|
|
||||||
/* append the MAC length to the total_length size */
|
/* append the MAC length to the total_length size */
|
||||||
total_length = packet_length +
|
total_length = packet_length + (encrypted?session->local.mac->mac_len:0);
|
||||||
(encrypted?session->local.mac->mac_len:0);
|
|
||||||
|
|
||||||
/* allocate memory to store the outgoing packet in, in case we can't
|
/* allocate memory to store the outgoing packet in, in case we can't
|
||||||
send the whole one and thus need to keep it after this function
|
send the whole one and thus need to keep it after this function
|
||||||
@@ -672,36 +678,28 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data,
|
|||||||
since that size includes the whole packet. The MAC is
|
since that size includes the whole packet. The MAC is
|
||||||
calculated on the entire unencrypted packet, including all
|
calculated on the entire unencrypted packet, including all
|
||||||
fields except the MAC field itself. */
|
fields except the MAC field itself. */
|
||||||
session->local.mac->hash(session,
|
session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length,
|
||||||
p->outbuf + packet_length,
|
NULL, 0, &session->local.mac_abstract);
|
||||||
session->local.seqno,
|
|
||||||
p->outbuf, packet_length,
|
|
||||||
NULL, 0,
|
|
||||||
&session->local.mac_abstract);
|
|
||||||
|
|
||||||
/* Encrypt the whole packet data, one block size at a time.
|
/* Encrypt the whole packet data, one block size at a time.
|
||||||
The MAC field is not encrypted. */
|
The MAC field is not encrypted. */
|
||||||
for(i=0; i < packet_length;
|
for(i=0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||||
i += session->local.crypt->blocksize) {
|
|
||||||
unsigned char *ptr = &p->outbuf[i];
|
unsigned char *ptr = &p->outbuf[i];
|
||||||
if(session->local.crypt->crypt(session, ptr,
|
if (session->local.crypt->crypt(session, ptr, &session->local.crypt_abstract))
|
||||||
&session->local.crypt_abstract))
|
|
||||||
return PACKET_FAIL; /* encryption failure */
|
return PACKET_FAIL; /* encryption failure */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->local.seqno++;
|
session->local.seqno++;
|
||||||
|
|
||||||
ret = send(session->socket_fd, p->outbuf,
|
ret = send(session->socket_fd, p->outbuf, total_length,
|
||||||
total_length, LIBSSH2_SOCKET_SEND_FLAGS(session));
|
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||||
|
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
debugdump(session, "libssh2_packet_write send()",
|
debugdump(session, "libssh2_packet_write send()", p->outbuf, ret);
|
||||||
p->outbuf, ret);
|
|
||||||
}
|
}
|
||||||
if (ret != total_length) {
|
if (ret != total_length) {
|
||||||
if((ret > 0 ) ||
|
if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) {
|
||||||
((ret == -1) && (errno == EAGAIN))) {
|
|
||||||
/* the whole packet could not be sent, save the rest */
|
/* the whole packet could not be sent, save the rest */
|
||||||
p->odata = orgdata;
|
p->odata = orgdata;
|
||||||
p->olen = orgdata_len;
|
p->olen = orgdata_len;
|
||||||
|
861
src/userauth.c
861
src/userauth.c
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@ static inline int usleep(int udelay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
|
||||||
/* Compile in zlib support */
|
/* Compile in zlib support */
|
||||||
#define LIBSSH2_HAVE_ZLIB 1
|
#define LIBSSH2_HAVE_ZLIB 1
|
||||||
|
Reference in New Issue
Block a user