初始提交:terminalX 可运行态(M0/M1/M1.5 已真机验证)
- M0: libghostty SSH 终端(渲染/输入/连接)+ 白屏修复(OutputGate) + 会话状态机/自动重连 - M1: tsnet 用户态组网 + SSH-over-tsnet(fd 桥),shell 级真机验证;R5(Go+gvisor+C+++Swift 同进程) retire - M1.5: tmux -CC 原生 tab(MVP) - 结构: packages/(TXCore·TXTransport), apps/TerminalX, vendor/(libghostty-spm/libssh2/mbedtls/tsnet-bridge), artifacts/ - 文档: CLAUDE.md + docs/HANDOFF.md(新会话入口) - 环境: 认证代理→依赖 vendor 本地化;Go 在 ~/.local/go;仅模拟器/未签名 - 待续: M2 mosh, tmux 多 pane, M4 安全(host key/SE) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
32
vendor/libssh2/example/.gitignore
vendored
Normal file
32
vendor/libssh2/example/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
Makefile.inc.cmake
|
||||
*.gcno
|
||||
*.gcda
|
||||
stamp-h2
|
||||
direct_tcpip
|
||||
scp
|
||||
scp_nonblock
|
||||
scp_write
|
||||
scp_write_nonblock
|
||||
sftp
|
||||
sftp_RW_nonblock
|
||||
sftp_append
|
||||
sftp_mkdir
|
||||
sftp_mkdir_nonblock
|
||||
sftp_nonblock
|
||||
sftp_write
|
||||
sftp_write_nonblock
|
||||
sftp_write_sliding
|
||||
sftpdir
|
||||
sftpdir_nonblock
|
||||
ssh2
|
||||
ssh2_agent
|
||||
ssh2_agent_forwarding
|
||||
ssh2_echo
|
||||
ssh2_exec
|
||||
subsystem_netconf
|
||||
tcpip-forward
|
||||
x11
|
||||
61
vendor/libssh2/example/CMakeLists.txt
vendored
Normal file
61
vendor/libssh2/example/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
# Copyright (C) Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
# Copyright (C) Viktor Szakats
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
include(CopyRuntimeDependencies)
|
||||
|
||||
list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET})
|
||||
|
||||
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
# Get 'noinst_PROGRAMS' variable
|
||||
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
|
||||
foreach(_example IN LISTS noinst_PROGRAMS)
|
||||
add_executable(${_example} "${_example}.c")
|
||||
list(APPEND _example_targets ${_example})
|
||||
# to find generated header
|
||||
target_include_directories(${_example} PRIVATE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../src"
|
||||
"../src")
|
||||
target_link_libraries(${_example} ${LIB_SELECTED} ${LIBSSH2_LIBS})
|
||||
set_target_properties(${_example} PROPERTIES UNITY_BUILD OFF)
|
||||
endforeach()
|
||||
|
||||
add_target_to_copy_dependencies(
|
||||
TARGET copy_example_dependencies
|
||||
DEPENDENCIES ${RUNTIME_DEPENDENCIES}
|
||||
BEFORE_TARGETS ${_example_targets})
|
||||
14
vendor/libssh2/example/Makefile.am
vendored
Normal file
14
vendor/libssh2/example/Makefile.am
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright (C) The libssh2 project and its contributors.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
# Get noing_PROGRAMS
|
||||
include Makefile.inc
|
||||
|
||||
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top_srcdir)/include
|
||||
LDADD = $(top_builddir)/src/libssh2.la
|
||||
|
||||
# This might hold -Werror
|
||||
AM_CFLAGS = @LIBSSH2_CFLAG_EXTRAS@
|
||||
28
vendor/libssh2/example/Makefile.inc
vendored
Normal file
28
vendor/libssh2/example/Makefile.inc
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Copyright (C) The libssh2 project and its contributors.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
direct_tcpip \
|
||||
scp \
|
||||
scp_nonblock \
|
||||
scp_write \
|
||||
scp_write_nonblock \
|
||||
sftp \
|
||||
sftp_RW_nonblock \
|
||||
sftp_append \
|
||||
sftp_mkdir \
|
||||
sftp_mkdir_nonblock \
|
||||
sftp_nonblock \
|
||||
sftp_write \
|
||||
sftp_write_nonblock \
|
||||
sftp_write_sliding \
|
||||
sftpdir \
|
||||
sftpdir_nonblock \
|
||||
ssh2 \
|
||||
ssh2_agent \
|
||||
ssh2_agent_forwarding \
|
||||
ssh2_echo \
|
||||
ssh2_exec \
|
||||
subsystem_netconf \
|
||||
tcpip-forward \
|
||||
x11
|
||||
358
vendor/libssh2/example/direct_tcpip.c
vendored
Normal file
358
vendor/libssh2/example/direct_tcpip.c
vendored
Normal file
@@ -0,0 +1,358 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h> /* for socklen_t */
|
||||
#define recv(s, b, l, f) recv((s), (b), (int)(l), (f))
|
||||
#define send(s, b, l, f) send((s), (b), (int)(l), (f))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (in_addr_t)~0
|
||||
#endif
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "";
|
||||
|
||||
static const char *server_ip = "127.0.0.1";
|
||||
|
||||
static const char *local_listenip = "127.0.0.1";
|
||||
static int local_listenport = 2222;
|
||||
|
||||
static const char *remote_desthost = "localhost"; /* resolved by the server */
|
||||
static int remote_destport = 22;
|
||||
|
||||
enum {
|
||||
AUTH_NONE = 0,
|
||||
AUTH_PASSWORD = 1,
|
||||
AUTH_PUBLICKEY = 2
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, auth = AUTH_NONE;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
const char *shost;
|
||||
int sport;
|
||||
struct timeval tv;
|
||||
ssize_t len, wr;
|
||||
char buf[16384];
|
||||
libssh2_socket_t sock;
|
||||
libssh2_socket_t listensock = LIBSSH2_INVALID_SOCKET;
|
||||
libssh2_socket_t forwardsock = LIBSSH2_INVALID_SOCKET;
|
||||
|
||||
#ifdef _WIN32
|
||||
char sockopt;
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
int sockopt;
|
||||
#endif
|
||||
|
||||
if(argc > 1)
|
||||
server_ip = argv[1];
|
||||
if(argc > 2)
|
||||
username = argv[2];
|
||||
if(argc > 3)
|
||||
password = argv[3];
|
||||
if(argc > 4)
|
||||
local_listenip = argv[4];
|
||||
if(argc > 5)
|
||||
local_listenport = atoi(argv[5]);
|
||||
if(argc > 6)
|
||||
remote_desthost = argv[6];
|
||||
if(argc > 7)
|
||||
remote_destport = atoi(argv[7]);
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = inet_addr(server_ip);
|
||||
if(INADDR_NONE == sin.sin_addr.s_addr) {
|
||||
fprintf(stderr, "inet_addr: Invalid IP address '%s'\n", server_ip);
|
||||
goto shutdown;
|
||||
}
|
||||
sin.sin_port = htons(22);
|
||||
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
|
||||
fprintf(stderr, "Failed to connect to %s.\n", inet_ntoa(sin.sin_addr));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Error when starting up SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++)
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(strstr(userauthlist, "password"))
|
||||
auth |= AUTH_PASSWORD;
|
||||
if(strstr(userauthlist, "publickey"))
|
||||
auth |= AUTH_PUBLICKEY;
|
||||
|
||||
/* check for options */
|
||||
if(argc > 8) {
|
||||
if((auth & AUTH_PASSWORD) && !strcmp(argv[8], "-p"))
|
||||
auth = AUTH_PASSWORD;
|
||||
if((auth & AUTH_PUBLICKEY) && !strcmp(argv[8], "-k"))
|
||||
auth = AUTH_PUBLICKEY;
|
||||
}
|
||||
|
||||
if(auth & AUTH_PASSWORD) {
|
||||
if(libssh2_userauth_password(session, username, password)) {
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
else if(auth & AUTH_PUBLICKEY) {
|
||||
if(libssh2_userauth_publickey_fromfile(session, username,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "No supported authentication methods found.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(listensock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open listen socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons((unsigned short)local_listenport);
|
||||
sin.sin_addr.s_addr = inet_addr(local_listenip);
|
||||
if(INADDR_NONE == sin.sin_addr.s_addr) {
|
||||
fprintf(stderr, "failed in inet_addr().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
sockopt = 1;
|
||||
setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt,
|
||||
sizeof(sockopt));
|
||||
sinlen = sizeof(sin);
|
||||
if(-1 == bind(listensock, (struct sockaddr *)&sin, sinlen)) {
|
||||
fprintf(stderr, "failed to bind().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
if(-1 == listen(listensock, 2)) {
|
||||
fprintf(stderr, "failed to listen().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Waiting for TCP connection on %s:%d...\n",
|
||||
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
|
||||
|
||||
forwardsock = accept(listensock, (struct sockaddr *)&sin, &sinlen);
|
||||
if(forwardsock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to accept forward socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
shost = inet_ntoa(sin.sin_addr);
|
||||
sport = ntohs(sin.sin_port);
|
||||
|
||||
fprintf(stderr, "Forwarding connection from %s:%d here to remote %s:%d\n",
|
||||
shost, sport, remote_desthost, remote_destport);
|
||||
|
||||
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
|
||||
remote_destport, shost, sport);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Could not open the direct-tcpip channel.\n"
|
||||
"(Note that this can be a problem at the server."
|
||||
" Please review the server logs.)\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Must use non-blocking IO hereafter due to the current libssh2 API */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
for(;;) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(forwardsock, &fds);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000;
|
||||
rc = select((int)(forwardsock + 1), &fds, NULL, NULL, &tv);
|
||||
if(-1 == rc) {
|
||||
fprintf(stderr, "failed to select().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
if(rc && FD_ISSET(forwardsock, &fds)) {
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
len = recv(forwardsock, buf, sizeof(buf), 0);
|
||||
if(len < 0) {
|
||||
fprintf(stderr, "failed to recv().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else if(len == 0) {
|
||||
fprintf(stderr, "The client at %s:%d disconnected.\n", shost,
|
||||
sport);
|
||||
goto shutdown;
|
||||
}
|
||||
wr = 0;
|
||||
while(wr < len) {
|
||||
ssize_t nwritten = libssh2_channel_write(channel,
|
||||
buf + wr,
|
||||
(size_t)(len - wr));
|
||||
if(nwritten == LIBSSH2_ERROR_EAGAIN) {
|
||||
continue;
|
||||
}
|
||||
if(nwritten < 0) {
|
||||
fprintf(stderr, "libssh2_channel_write: %ld\n",
|
||||
(long)nwritten);
|
||||
goto shutdown;
|
||||
}
|
||||
wr += nwritten;
|
||||
}
|
||||
}
|
||||
for(;;) {
|
||||
len = libssh2_channel_read(channel, buf, sizeof(buf));
|
||||
if(LIBSSH2_ERROR_EAGAIN == len)
|
||||
break;
|
||||
else if(len < 0) {
|
||||
fprintf(stderr, "libssh2_channel_read: %ld", (long)len);
|
||||
goto shutdown;
|
||||
}
|
||||
wr = 0;
|
||||
while(wr < len) {
|
||||
ssize_t nsent = send(forwardsock, buf + wr,
|
||||
(size_t)(len - wr), 0);
|
||||
if(nsent <= 0) {
|
||||
fprintf(stderr, "failed to send().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
wr += nsent;
|
||||
}
|
||||
if(libssh2_channel_eof(channel)) {
|
||||
fprintf(stderr, "The server at %s:%d disconnected.\n",
|
||||
remote_desthost, remote_destport);
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shutdown:
|
||||
|
||||
if(forwardsock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(forwardsock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(forwardsock);
|
||||
}
|
||||
|
||||
if(listensock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(listensock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(listensock);
|
||||
}
|
||||
|
||||
if(channel)
|
||||
libssh2_channel_free(channel);
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
197
vendor/libssh2/example/scp.c
vendored
Normal file
197
vendor/libssh2/example/scp.c
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define write(f, b, c) write((f), (b), (unsigned int)(c))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *scppath = "/tmp/TEST";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
libssh2_struct_stat fileinfo;
|
||||
libssh2_struct_stat_size got = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* Request a file via SCP */
|
||||
channel = libssh2_scp_recv2(session, scppath, &fileinfo);
|
||||
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Unable to open a session: %d\n",
|
||||
libssh2_session_last_errno(session));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
while(got < fileinfo.st_size) {
|
||||
char mem[1024];
|
||||
int amount = sizeof(mem);
|
||||
ssize_t nread;
|
||||
|
||||
if((fileinfo.st_size - got) < amount) {
|
||||
amount = (int)(fileinfo.st_size - got);
|
||||
}
|
||||
|
||||
nread = libssh2_channel_read(channel, mem, (size_t)amount);
|
||||
if(nread > 0) {
|
||||
write(1, mem, (size_t)nread);
|
||||
}
|
||||
else if(nread < 0) {
|
||||
fprintf(stderr, "libssh2_channel_read() failed: %ld\n",
|
||||
(long)nread);
|
||||
break;
|
||||
}
|
||||
got += nread;
|
||||
}
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
307
vendor/libssh2/example/scp_nonblock.c
vendored
Normal file
307
vendor/libssh2/example/scp_nonblock.c
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SCP transfers in a non-blocking manner.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./scp_nonblock 192.168.0.1 user password /tmp/secrets
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define write(f, b, c) write((f), (b), (unsigned int)(c))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *scppath = "/tmp/TEST";
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
/* diff in ms */
|
||||
static long tvdiff(struct timeval newer, struct timeval older)
|
||||
{
|
||||
return (newer.tv_sec - older.tv_sec) * 1000 +
|
||||
(newer.tv_usec - older.tv_usec) / 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
libssh2_struct_stat fileinfo;
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval start;
|
||||
struct timeval end;
|
||||
long time_ms;
|
||||
#endif
|
||||
int spin = 0;
|
||||
libssh2_struct_stat_size got = 0;
|
||||
libssh2_struct_stat_size total = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&start, NULL);
|
||||
#endif
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
while((rc = libssh2_session_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
libssh2_trace(session, LIBSSH2_TRACE_CONN);
|
||||
#endif
|
||||
|
||||
/* Request a file via SCP */
|
||||
fprintf(stderr, "libssh2_scp_recv2().\n");
|
||||
do {
|
||||
channel = libssh2_scp_recv2(session, scppath, &fileinfo);
|
||||
|
||||
if(!channel) {
|
||||
if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
char *err_msg;
|
||||
|
||||
libssh2_session_last_error(session, &err_msg, NULL, 0);
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "libssh2_scp_recv2() spin\n");
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
}
|
||||
} while(!channel);
|
||||
fprintf(stderr, "libssh2_scp_recv2() is done, now receive data.\n");
|
||||
|
||||
while(got < fileinfo.st_size) {
|
||||
char mem[1024 * 24];
|
||||
ssize_t nread;
|
||||
|
||||
do {
|
||||
int amount = sizeof(mem);
|
||||
|
||||
if((fileinfo.st_size - got) < amount) {
|
||||
amount = (int)(fileinfo.st_size - got);
|
||||
}
|
||||
|
||||
/* loop until we block */
|
||||
nread = libssh2_channel_read(channel, mem, (size_t)amount);
|
||||
if(nread > 0) {
|
||||
write(1, mem, (size_t)nread);
|
||||
got += nread;
|
||||
total += nread;
|
||||
}
|
||||
} while(nread > 0);
|
||||
|
||||
if(nread == LIBSSH2_ERROR_EAGAIN && got < fileinfo.st_size) {
|
||||
/* this is due to blocking that would occur otherwise
|
||||
so we loop on this condition */
|
||||
|
||||
spin++;
|
||||
waitsocket(sock, session); /* now we wait */
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&end, NULL);
|
||||
|
||||
time_ms = tvdiff(end, start);
|
||||
fprintf(stderr, "Got %ld bytes in %ld ms = %.1f bytes/sec spin: %d\n",
|
||||
(long)total, time_ms,
|
||||
(double)total / ((double)time_ms / 1000.0), spin);
|
||||
#else
|
||||
fprintf(stderr, "Got %ld bytes spin: %d\n", (long)total, spin);
|
||||
#endif
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
228
vendor/libssh2/example/scp_write.c
vendored
Normal file
228
vendor/libssh2/example/scp_write.c
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do an SCP upload.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *loclfile = "scp_write.c";
|
||||
static const char *scppath = "/tmp/TEST";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
FILE *local;
|
||||
char mem[1024];
|
||||
size_t nread;
|
||||
char *ptr;
|
||||
struct stat fileinfo;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if(!local) {
|
||||
fprintf(stderr, "Cannot open local file %s\n", loclfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send a file via scp. The mode parameter must only have permissions! */
|
||||
channel = libssh2_scp_send(session, scppath, fileinfo.st_mode & 0777,
|
||||
(size_t)fileinfo.st_size);
|
||||
|
||||
if(!channel) {
|
||||
char *errmsg;
|
||||
int errlen;
|
||||
int err;
|
||||
err = libssh2_session_last_error(session, &errmsg, &errlen, 0);
|
||||
fprintf(stderr, "Unable to open a session: (%d) %s\n", err, errmsg);
|
||||
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 {
|
||||
ssize_t nwritten;
|
||||
/* write the same data over and over, until error or completion */
|
||||
nwritten = libssh2_channel_write(channel, ptr, nread);
|
||||
if(nwritten < 0) {
|
||||
fprintf(stderr, "ERROR %ld\n", (long)nwritten);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* nwritten indicates how many bytes were written this time */
|
||||
ptr += nwritten;
|
||||
nread -= (size_t)nwritten;
|
||||
}
|
||||
} while(nread);
|
||||
} 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);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
if(local)
|
||||
fclose(local);
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
297
vendor/libssh2/example/scp_write_nonblock.c
vendored
Normal file
297
vendor/libssh2/example/scp_write_nonblock.c
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do an SCP non-blocking upload transfer.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h> /* for time() */
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *loclfile = "scp_write.c";
|
||||
static const char *scppath = "/tmp/TEST";
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
FILE *local;
|
||||
char mem[1024 * 100];
|
||||
size_t nread;
|
||||
char *ptr;
|
||||
struct stat fileinfo;
|
||||
time_t start;
|
||||
libssh2_struct_stat_size total = 0;
|
||||
int duration;
|
||||
size_t prev;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if(!local) {
|
||||
fprintf(stderr, "Cannot open local file %s\n", loclfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send a file via scp. The mode parameter must only have permissions! */
|
||||
do {
|
||||
channel = libssh2_scp_send(session, scppath, fileinfo.st_mode & 0777,
|
||||
(size_t)fileinfo.st_size);
|
||||
|
||||
if(!channel &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
char *err_msg;
|
||||
|
||||
libssh2_session_last_error(session, &err_msg, NULL, 0);
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!channel);
|
||||
|
||||
fprintf(stderr, "SCP session waiting to send file\n");
|
||||
start = time(NULL);
|
||||
do {
|
||||
nread = fread(mem, 1, sizeof(mem), local);
|
||||
if(nread <= 0) {
|
||||
/* end of file */
|
||||
break;
|
||||
}
|
||||
ptr = mem;
|
||||
|
||||
total += (libssh2_struct_stat_size)nread;
|
||||
|
||||
prev = 0;
|
||||
do {
|
||||
ssize_t nwritten;
|
||||
while((nwritten = libssh2_channel_write(channel, ptr, nread)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
prev = 0;
|
||||
}
|
||||
if(nwritten < 0) {
|
||||
fprintf(stderr, "ERROR %ld total %ld / %lu prev %lu\n",
|
||||
(long)nwritten, (long)total,
|
||||
(unsigned long)nread, (unsigned long)prev);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
prev = nread;
|
||||
|
||||
/* nwritten indicates how many bytes were written this time */
|
||||
ptr += nwritten;
|
||||
nread -= (size_t)nwritten;
|
||||
}
|
||||
} while(nread);
|
||||
} while(!nread); /* only continue if nread was drained */
|
||||
|
||||
duration = (int)(time(NULL) - start);
|
||||
|
||||
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
(long)total, duration, (double)total / duration);
|
||||
|
||||
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);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
while(libssh2_session_disconnect(session, "Normal Shutdown") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
309
vendor/libssh2/example/sftp.c
vendored
Normal file
309
vendor/libssh2/example/sftp.c
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP transfers.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp 192.168.0.1 user password /tmp/secrets -p|-i|-k
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define write(f, b, c) write((f), (b), (unsigned int)(c))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/TEST";
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
const char *instruction, int instruction_len,
|
||||
int num_prompts,
|
||||
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||
void **abstract)
|
||||
{
|
||||
int i;
|
||||
size_t n;
|
||||
char buf[1024];
|
||||
(void)abstract;
|
||||
|
||||
fprintf(stderr, "Performing keyboard-interactive authentication.\n");
|
||||
|
||||
fprintf(stderr, "Authentication name: '");
|
||||
fwrite(name, 1, (size_t)name_len, stderr);
|
||||
fprintf(stderr, "'\n");
|
||||
|
||||
fprintf(stderr, "Authentication instruction: '");
|
||||
fwrite(instruction, 1, (size_t)instruction_len, stderr);
|
||||
fprintf(stderr, "'\n");
|
||||
|
||||
fprintf(stderr, "Number of prompts: %d\n\n", num_prompts);
|
||||
|
||||
for(i = 0; i < num_prompts; i++) {
|
||||
fprintf(stderr, "Prompt %d from server: '", i);
|
||||
fwrite(prompts[i].text, 1, prompts[i].length, stderr);
|
||||
fprintf(stderr, "'\n");
|
||||
|
||||
fprintf(stderr, "Please type response: ");
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
n = strlen(buf);
|
||||
while(n > 0 && strchr("\r\n", buf[n - 1]))
|
||||
n--;
|
||||
buf[n] = 0;
|
||||
|
||||
responses[i].text = strdup(buf);
|
||||
responses[i].length = (unsigned int)n;
|
||||
|
||||
fprintf(stderr, "Response %d from user is '", i);
|
||||
fwrite(responses[i].text, 1, responses[i].length, stderr);
|
||||
fprintf(stderr, "'\n\n");
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"Done. Sending keyboard-interactive responses to server now.\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 0;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(strstr(userauthlist, "password")) {
|
||||
auth_pw |= 1;
|
||||
}
|
||||
if(strstr(userauthlist, "keyboard-interactive")) {
|
||||
auth_pw |= 2;
|
||||
}
|
||||
if(strstr(userauthlist, "publickey")) {
|
||||
auth_pw |= 4;
|
||||
}
|
||||
|
||||
/* check for options */
|
||||
if(argc > 5) {
|
||||
if((auth_pw & 1) && !strcmp(argv[5], "-p")) {
|
||||
auth_pw = 1;
|
||||
}
|
||||
if((auth_pw & 2) && !strcmp(argv[5], "-i")) {
|
||||
auth_pw = 2;
|
||||
}
|
||||
if((auth_pw & 4) && !strcmp(argv[5], "-k")) {
|
||||
auth_pw = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if(auth_pw & 1) {
|
||||
/* We could authenticate via password */
|
||||
if(libssh2_userauth_password(session, username, password)) {
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
else if(auth_pw & 2) {
|
||||
/* Or via keyboard-interactive */
|
||||
if(libssh2_userauth_keyboard_interactive(session, username,
|
||||
&kbd_callback) ) {
|
||||
fprintf(stderr,
|
||||
"Authentication by keyboard-interactive failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Authentication by keyboard-interactive succeeded.\n");
|
||||
}
|
||||
}
|
||||
else if(auth_pw & 4) {
|
||||
/* Or by public key */
|
||||
if(libssh2_userauth_publickey_fromfile(session, username,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "No supported authentication methods found.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open().\n");
|
||||
/* Request a file via SFTP */
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_READ, 0);
|
||||
if(!sftp_handle) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now receive data.\n");
|
||||
do {
|
||||
char mem[1024];
|
||||
ssize_t nread;
|
||||
|
||||
/* loop until we fail */
|
||||
fprintf(stderr, "libssh2_sftp_read().\n");
|
||||
nread = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
|
||||
if(nread > 0) {
|
||||
write(1, mem, (size_t)nread);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
384
vendor/libssh2/example/sftp_RW_nonblock.c
vendored
Normal file
384
vendor/libssh2/example/sftp_RW_nonblock.c
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
||||
*
|
||||
* It will first download a given source file, store it locally and then
|
||||
* upload the file again to a given destination file.
|
||||
*
|
||||
* Using the SFTP server running on 127.0.0.1
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define write(f, b, c) write((f), (b), (unsigned int)(c))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/TEST"; /* source path */
|
||||
static const char *dest = "/tmp/TEST2"; /* destination path */
|
||||
static const char *storage = "/tmp/sftp-storage"; /* local file name to store
|
||||
the downloaded file in */
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
FILE *tempstorage = NULL;
|
||||
char mem[1000];
|
||||
struct timeval timeout;
|
||||
fd_set fd;
|
||||
fd_set fd2;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 1) {
|
||||
username = argv[1];
|
||||
}
|
||||
if(argc > 2) {
|
||||
password = argv[2];
|
||||
}
|
||||
if(argc > 3) {
|
||||
sftppath = argv[3];
|
||||
}
|
||||
if(argc > 4) {
|
||||
dest = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(22);
|
||||
sin.sin_addr.s_addr = htonl(0x7F000001);
|
||||
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
tempstorage = fopen(storage, "wb");
|
||||
if(!tempstorage) {
|
||||
fprintf(stderr, "Cannot open temp storage file %s\n", storage);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "non-blocking init\n");
|
||||
waitsocket(sock, session); /* now we wait */
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
} while(!sftp_session);
|
||||
|
||||
/* Request a file via SFTP */
|
||||
do {
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_READ, 0);
|
||||
if(!sftp_handle) {
|
||||
if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "non-blocking open\n");
|
||||
waitsocket(sock, session); /* now we wait */
|
||||
}
|
||||
}
|
||||
} while(!sftp_handle);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now receive data.\n");
|
||||
do {
|
||||
ssize_t nread;
|
||||
do {
|
||||
/* read in a loop until we block */
|
||||
nread = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
|
||||
fprintf(stderr, "libssh2_sftp_read returned %ld\n",
|
||||
(long)nread);
|
||||
|
||||
if(nread > 0) {
|
||||
/* write to stderr */
|
||||
write(2, mem, (size_t)nread);
|
||||
/* write to temporary storage area */
|
||||
fwrite(mem, (size_t)nread, 1, tempstorage);
|
||||
}
|
||||
} while(nread > 0);
|
||||
|
||||
if(nread != LIBSSH2_ERROR_EAGAIN) {
|
||||
/* error or end of file */
|
||||
break;
|
||||
}
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
FD_ZERO(&fd2);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(sock, &fd);
|
||||
FD_SET(sock, &fd2);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* wait for readable or writeable */
|
||||
rc = select((int)(sock + 1), &fd, &fd2, NULL, &timeout);
|
||||
if(rc <= 0) {
|
||||
/* negative is error
|
||||
0 is timeout */
|
||||
fprintf(stderr, "SFTP download timed out: %d\n", rc);
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
fclose(tempstorage);
|
||||
|
||||
tempstorage = fopen(storage, "rb");
|
||||
if(!tempstorage) {
|
||||
/* weird, we cannot read the file we just wrote to... */
|
||||
fprintf(stderr, "Cannot open %s for reading\n", storage);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* we're done downloading, now reverse the process and upload the
|
||||
temporarily stored data to the destination path */
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, dest,
|
||||
LIBSSH2_FXF_WRITE |
|
||||
LIBSSH2_FXF_CREAT,
|
||||
LIBSSH2_SFTP_S_IRUSR |
|
||||
LIBSSH2_SFTP_S_IWUSR |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IROTH);
|
||||
if(sftp_handle) {
|
||||
size_t nread;
|
||||
char *ptr;
|
||||
do {
|
||||
ssize_t nwritten;
|
||||
nread = fread(mem, 1, sizeof(mem), tempstorage);
|
||||
if(nread <= 0) {
|
||||
/* end of file */
|
||||
break;
|
||||
}
|
||||
ptr = mem;
|
||||
|
||||
do {
|
||||
/* write data in a loop until we block */
|
||||
nwritten = libssh2_sftp_write(sftp_handle, ptr,
|
||||
nread);
|
||||
if(nwritten < 0)
|
||||
break;
|
||||
ptr += nwritten;
|
||||
nread -= (size_t)nwritten;
|
||||
} while(nwritten >= 0);
|
||||
|
||||
if(nwritten != LIBSSH2_ERROR_EAGAIN) {
|
||||
/* error or end of file */
|
||||
break;
|
||||
}
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
FD_ZERO(&fd2);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(sock, &fd);
|
||||
FD_SET(sock, &fd2);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* wait for readable or writeable */
|
||||
rc = select((int)(sock + 1), &fd, &fd2, NULL, &timeout);
|
||||
if(rc <= 0) {
|
||||
/* negative is error
|
||||
0 is timeout */
|
||||
fprintf(stderr, "SFTP upload timed out: %d\n", rc);
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
fprintf(stderr, "SFTP upload done.\n");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "SFTP failed to open destination path: %s\n",
|
||||
dest);
|
||||
}
|
||||
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
if(tempstorage)
|
||||
fclose(tempstorage);
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
248
vendor/libssh2/example/sftp_append.c
vendored
Normal file
248
vendor/libssh2/example/sftp_append.c
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP append of a local file onto a remote one.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_append 192.168.0.1 user password localfile /tmp/remotefile
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *loclfile = "sftp_write.c";
|
||||
static const char *sftppath = "/tmp/TEST";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
char mem[1024 * 100];
|
||||
FILE *local;
|
||||
size_t nread;
|
||||
ssize_t nwritten;
|
||||
char *ptr;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[5];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if(!local) {
|
||||
fprintf(stderr, "Cannot open local file %s\n", loclfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() for READ and WRITE.\n");
|
||||
/* Request a file via SFTP */
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_WRITE |
|
||||
LIBSSH2_FXF_READ,
|
||||
LIBSSH2_SFTP_S_IRUSR |
|
||||
LIBSSH2_SFTP_S_IWUSR |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IROTH);
|
||||
if(!sftp_handle) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
if(libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
|
||||
fprintf(stderr, "libssh2_sftp_fstat_ex failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else
|
||||
libssh2_sftp_seek64(sftp_handle, attrs.filesize);
|
||||
fprintf(stderr, "Did a seek to position %ld\n", (long) attrs.filesize);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() a handle for APPEND\n");
|
||||
if(!sftp_handle) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data.\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 */
|
||||
nwritten = libssh2_sftp_write(sftp_handle, ptr, nread);
|
||||
if(nwritten < 0)
|
||||
break;
|
||||
ptr += nwritten;
|
||||
nread -= (size_t)nwritten;
|
||||
} while(nread);
|
||||
} while(nwritten > 0);
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
if(local)
|
||||
fclose(local);
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
187
vendor/libssh2/example/sftp_mkdir.c
vendored
Normal file
187
vendor/libssh2/example/sftp_mkdir.c
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP mkdir
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_mkdir 192.168.0.1 user password /tmp/sftp_mkdir
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/sftp_mkdir";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||
libssh2_session_set_blocking(session, 1);
|
||||
|
||||
/* Make a directory via SFTP */
|
||||
rc = libssh2_sftp_mkdir(sftp_session, sftppath,
|
||||
LIBSSH2_SFTP_S_IRWXU |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IXGRP |
|
||||
LIBSSH2_SFTP_S_IROTH |
|
||||
LIBSSH2_SFTP_S_IXOTH);
|
||||
if(rc)
|
||||
fprintf(stderr, "libssh2_sftp_mkdir failed: %d\n", rc);
|
||||
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
186
vendor/libssh2/example/sftp_mkdir_nonblock.c
vendored
Normal file
186
vendor/libssh2/example/sftp_mkdir_nonblock.c
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking mkdir.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_mkdir_nonblock 192.168.0.1 user password /tmp/sftp_write_nonblock.c
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/sftp_mkdir_nonblock";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
/* Make a directory via SFTP */
|
||||
while(libssh2_sftp_mkdir(sftp_session, sftppath,
|
||||
LIBSSH2_SFTP_S_IRWXU |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IXGRP |
|
||||
LIBSSH2_SFTP_S_IROTH |
|
||||
LIBSSH2_SFTP_S_IXOTH) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
310
vendor/libssh2/example/sftp_nonblock.c
vendored
Normal file
310
vendor/libssh2/example/sftp_nonblock.c
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking transfers.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_nonblock 192.168.0.1 user password /tmp/secrets
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define write(f, b, c) write((f), (b), (unsigned int)(c))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/TEST";
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
/* diff in ms */
|
||||
static long tvdiff(struct timeval newer, struct timeval older)
|
||||
{
|
||||
return (newer.tv_sec - older.tv_sec) * 1000 +
|
||||
(newer.tv_usec - older.tv_usec) / 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval start;
|
||||
struct timeval end;
|
||||
long time_ms;
|
||||
#endif
|
||||
libssh2_struct_stat_size total = 0;
|
||||
int spin = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&start, NULL);
|
||||
#endif
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
while((rc = libssh2_session_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
libssh2_trace(session, LIBSSH2_TRACE_CONN);
|
||||
#endif
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
do {
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "non-blocking init\n");
|
||||
waitsocket(sock, session); /* now we wait */
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
} while(!sftp_session);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open().\n");
|
||||
/* Request a file via SFTP */
|
||||
do {
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_READ, 0);
|
||||
if(!sftp_handle) {
|
||||
if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "non-blocking open\n");
|
||||
waitsocket(sock, session); /* now we wait */
|
||||
}
|
||||
}
|
||||
} while(!sftp_handle);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now receive data.\n");
|
||||
do {
|
||||
char mem[1024 * 24];
|
||||
ssize_t nread;
|
||||
|
||||
/* loop until we fail */
|
||||
while((nread = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
spin++;
|
||||
waitsocket(sock, session); /* now we wait */
|
||||
}
|
||||
if(nread > 0) {
|
||||
total += nread;
|
||||
write(1, mem, (size_t)nread);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&end, NULL);
|
||||
time_ms = tvdiff(end, start);
|
||||
fprintf(stderr, "Got %ld bytes in %ld ms = %.1f bytes/sec spin: %d\n",
|
||||
(long)total, time_ms,
|
||||
(double)total / ((double)time_ms / 1000.0), spin);
|
||||
#else
|
||||
fprintf(stderr, "Got %ld bytes spin: %d\n", (long)total, spin);
|
||||
#endif
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
fprintf(stderr, "libssh2_session_disconnect\n");
|
||||
while(libssh2_session_disconnect(session, "Normal Shutdown") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
233
vendor/libssh2/example/sftp_write.c
vendored
Normal file
233
vendor/libssh2/example/sftp_write.c
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP write transfers.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_write 192.168.0.1 user password sftp_write.c /tmp/secrets
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *loclfile = "sftp_write.c";
|
||||
static const char *sftppath = "/tmp/TEST";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
FILE *local;
|
||||
char mem[1024 * 100];
|
||||
size_t nread;
|
||||
ssize_t nwritten;
|
||||
char *ptr;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[5];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if(!local) {
|
||||
fprintf(stderr, "Cannot open local file %s\n", loclfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open().\n");
|
||||
/* Request a file via SFTP */
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_WRITE |
|
||||
LIBSSH2_FXF_CREAT |
|
||||
LIBSSH2_FXF_TRUNC,
|
||||
LIBSSH2_SFTP_S_IRUSR |
|
||||
LIBSSH2_SFTP_S_IWUSR |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IROTH);
|
||||
if(!sftp_handle) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data.\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 */
|
||||
nwritten = libssh2_sftp_write(sftp_handle, ptr, nread);
|
||||
if(nwritten < 0)
|
||||
break;
|
||||
ptr += nwritten;
|
||||
nread -= (size_t)nwritten;
|
||||
} while(nread);
|
||||
} while(nwritten > 0);
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
if(local)
|
||||
fclose(local);
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
298
vendor/libssh2/example/sftp_write_nonblock.c
vendored
Normal file
298
vendor/libssh2/example/sftp_write_nonblock.c
vendored
Normal file
@@ -0,0 +1,298 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking write transfers.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_write_nonblock 192.168.0.1 user password thisfile /tmp/storehere
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h> /* for time() */
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *loclfile = "sftp_write_nonblock.c";
|
||||
static const char *sftppath = "/tmp/sftp_write_nonblock.c";
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
FILE *local;
|
||||
char mem[1024 * 100];
|
||||
size_t nread;
|
||||
ssize_t nwritten;
|
||||
char *ptr;
|
||||
time_t start;
|
||||
libssh2_struct_stat_size total = 0;
|
||||
int duration;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[5];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if(!local) {
|
||||
fprintf(stderr, "Cannot open local file %s\n", loclfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
do {
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!sftp_session);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open().\n");
|
||||
/* Request a file via SFTP */
|
||||
do {
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_WRITE |
|
||||
LIBSSH2_FXF_CREAT |
|
||||
LIBSSH2_FXF_TRUNC,
|
||||
LIBSSH2_SFTP_S_IRUSR |
|
||||
LIBSSH2_SFTP_S_IWUSR |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IROTH);
|
||||
if(!sftp_handle &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!sftp_handle);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data.\n");
|
||||
start = time(NULL);
|
||||
do {
|
||||
nread = fread(mem, 1, sizeof(mem), local);
|
||||
if(nread <= 0) {
|
||||
/* end of file */
|
||||
break;
|
||||
}
|
||||
ptr = mem;
|
||||
|
||||
total += (libssh2_struct_stat_size)nread;
|
||||
|
||||
do {
|
||||
/* write data in a loop until we block */
|
||||
while((nwritten = libssh2_sftp_write(sftp_handle, ptr, nread)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(nwritten < 0)
|
||||
break;
|
||||
ptr += nwritten;
|
||||
nread -= (size_t)nwritten;
|
||||
} while(nread);
|
||||
} while(nwritten > 0);
|
||||
|
||||
duration = (int)(time(NULL) - start);
|
||||
|
||||
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
(long)total, duration, (double)total / duration);
|
||||
|
||||
fclose(local);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
while(libssh2_session_disconnect(session, "Normal Shutdown") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
309
vendor/libssh2/example/sftp_write_sliding.c
vendored
Normal file
309
vendor/libssh2/example/sftp_write_sliding.c
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking write transfers.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftp_write_sliding 192.168.0.1 user password thisfile /tmp/storehere
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h> /* for time() */
|
||||
#include <string.h>
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *loclfile = "sftp_write_nonblock.c";
|
||||
static const char *sftppath = "/tmp/sftp_write_nonblock.c";
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
FILE *local;
|
||||
char mem[1024 * 1000];
|
||||
size_t nread;
|
||||
ssize_t nwritten;
|
||||
size_t memuse;
|
||||
time_t start;
|
||||
libssh2_struct_stat_size total = 0;
|
||||
int duration;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[5];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if(!local) {
|
||||
fprintf(stderr, "Cannot open local file %s\n", loclfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
do {
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!sftp_session);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open().\n");
|
||||
/* Request a file via SFTP */
|
||||
do {
|
||||
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
|
||||
LIBSSH2_FXF_WRITE |
|
||||
LIBSSH2_FXF_CREAT |
|
||||
LIBSSH2_FXF_TRUNC,
|
||||
LIBSSH2_SFTP_S_IRUSR |
|
||||
LIBSSH2_SFTP_S_IWUSR |
|
||||
LIBSSH2_SFTP_S_IRGRP |
|
||||
LIBSSH2_SFTP_S_IROTH);
|
||||
if(!sftp_handle &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to open file with SFTP: %ld\n",
|
||||
libssh2_sftp_last_error(sftp_session));
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!sftp_handle);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data.\n");
|
||||
start = time(NULL);
|
||||
memuse = 0; /* it starts blank */
|
||||
do {
|
||||
nread = fread(&mem[memuse], 1, sizeof(mem) - memuse, local);
|
||||
if(nread <= 0) {
|
||||
/* end of file */
|
||||
if(memuse > 0)
|
||||
/* the previous sending is not finished */
|
||||
nread = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
memuse += nread;
|
||||
total += (libssh2_struct_stat_size)nread;
|
||||
|
||||
/* write data in a loop until we block */
|
||||
while((nwritten = libssh2_sftp_write(sftp_handle, mem, memuse)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(nwritten < 0)
|
||||
break;
|
||||
|
||||
if(memuse - (size_t)nwritten) {
|
||||
/* make room for more data at the end of the buffer */
|
||||
memmove(&mem[0], &mem[nwritten], memuse - (size_t)nwritten);
|
||||
memuse -= (size_t)nwritten;
|
||||
}
|
||||
else
|
||||
/* 'mem' was consumed fully */
|
||||
memuse = 0;
|
||||
|
||||
} while(nwritten > 0);
|
||||
|
||||
duration = (int)(time(NULL) - start);
|
||||
|
||||
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
(long)total, duration, (double)total / duration);
|
||||
|
||||
fclose(local);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
while(libssh2_session_disconnect(session, "Normal Shutdown") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
310
vendor/libssh2/example/sftpdir.c
vendored
Normal file
310
vendor/libssh2/example/sftpdir.c
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample doing an SFTP directory listing.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password and
|
||||
* path, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftpdir 192.168.0.1 user password /tmp/secretdir
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define LIBSSH2_FILESIZE_MASK "I64u"
|
||||
#else
|
||||
#define LIBSSH2_FILESIZE_MASK "llu"
|
||||
#endif
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/secretdir";
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
const char *instruction, int instruction_len,
|
||||
int num_prompts,
|
||||
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||
void **abstract)
|
||||
{
|
||||
(void)name;
|
||||
(void)name_len;
|
||||
(void)instruction;
|
||||
(void)instruction_len;
|
||||
if(num_prompts == 1) {
|
||||
responses[0].text = strdup(password);
|
||||
responses[0].length = (unsigned int)strlen(password);
|
||||
}
|
||||
(void)prompts;
|
||||
(void)abstract;
|
||||
} /* kbd_callback */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 0;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(strstr(userauthlist, "password")) {
|
||||
auth_pw |= 1;
|
||||
}
|
||||
if(strstr(userauthlist, "keyboard-interactive")) {
|
||||
auth_pw |= 2;
|
||||
}
|
||||
if(strstr(userauthlist, "publickey")) {
|
||||
auth_pw |= 4;
|
||||
}
|
||||
|
||||
/* check for options */
|
||||
if(argc > 5) {
|
||||
if((auth_pw & 1) && !strcmp(argv[5], "-p")) {
|
||||
auth_pw = 1;
|
||||
}
|
||||
if((auth_pw & 2) && !strcmp(argv[5], "-i")) {
|
||||
auth_pw = 2;
|
||||
}
|
||||
if((auth_pw & 4) && !strcmp(argv[5], "-k")) {
|
||||
auth_pw = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if(auth_pw & 1) {
|
||||
/* We could authenticate via password */
|
||||
if(libssh2_userauth_password(session, username, password)) {
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
else if(auth_pw & 2) {
|
||||
/* Or via keyboard-interactive */
|
||||
if(libssh2_userauth_keyboard_interactive(session, username,
|
||||
&kbd_callback) ) {
|
||||
fprintf(stderr,
|
||||
"Authentication by keyboard-interactive failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Authentication by keyboard-interactive succeeded.\n");
|
||||
}
|
||||
}
|
||||
else if(auth_pw & 4) {
|
||||
/* Or by public key */
|
||||
if(libssh2_userauth_publickey_fromfile(session, username,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "No supported authentication methods found.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Since we have not set non-blocking, tell libssh2 we are blocking */
|
||||
libssh2_session_set_blocking(session, 1);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_opendir().\n");
|
||||
/* Request a dir listing via SFTP */
|
||||
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
|
||||
if(!sftp_handle) {
|
||||
fprintf(stderr, "Unable to open dir with SFTP\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing.\n");
|
||||
do {
|
||||
char mem[512];
|
||||
char longentry[512];
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
|
||||
/* loop until we fail */
|
||||
rc = libssh2_sftp_readdir_ex(sftp_handle, mem, sizeof(mem),
|
||||
longentry, sizeof(longentry), &attrs);
|
||||
if(rc > 0) {
|
||||
/* rc is the length of the file name in the mem
|
||||
buffer */
|
||||
|
||||
if(longentry[0] != '\0') {
|
||||
printf("%s\n", longentry);
|
||||
}
|
||||
else {
|
||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
|
||||
/* this should check what permissions it
|
||||
is and print the output accordingly */
|
||||
printf("--fix----- ");
|
||||
}
|
||||
else {
|
||||
printf("---------- ");
|
||||
}
|
||||
|
||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) {
|
||||
printf("%4d %4d ", (int) attrs.uid, (int) attrs.gid);
|
||||
}
|
||||
else {
|
||||
printf(" - - ");
|
||||
}
|
||||
|
||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
|
||||
printf("%8" LIBSSH2_FILESIZE_MASK " ", attrs.filesize);
|
||||
}
|
||||
|
||||
printf("%s\n", mem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
} while(1);
|
||||
|
||||
libssh2_sftp_closedir(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
250
vendor/libssh2/example/sftpdir_nonblock.c
vendored
Normal file
250
vendor/libssh2/example/sftpdir_nonblock.c
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample doing an SFTP directory listing.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password and
|
||||
* path, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./sftpdir_nonblock 192.168.0.1 user password /tmp/secretdir
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define LIBSSH2_FILESIZE_MASK "I64u"
|
||||
#else
|
||||
#define LIBSSH2_FILESIZE_MASK "llu"
|
||||
#endif
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
static const char *sftppath = "/tmp/secretdir";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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) {
|
||||
sftppath = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The application code is responsible for creating the socket
|
||||
* and establishing the connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* 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_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init().\n");
|
||||
do {
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if(!sftp_session &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!sftp_session);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_opendir().\n");
|
||||
/* Request a dir listing via SFTP */
|
||||
do {
|
||||
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
|
||||
|
||||
if(!sftp_handle &&
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "Unable to open dir with SFTP\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} while(!sftp_handle);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing.\n");
|
||||
do {
|
||||
char mem[512];
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
|
||||
/* loop until we fail */
|
||||
while((rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem),
|
||||
&attrs)) == LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc > 0) {
|
||||
/* rc is the length of the file name in the mem
|
||||
buffer */
|
||||
|
||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
|
||||
/* this should check what permissions it
|
||||
is and print the output accordingly */
|
||||
printf("--fix----- ");
|
||||
}
|
||||
else {
|
||||
printf("---------- ");
|
||||
}
|
||||
|
||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) {
|
||||
printf("%4d %4d ", (int) attrs.uid, (int) attrs.gid);
|
||||
}
|
||||
else {
|
||||
printf(" - - ");
|
||||
}
|
||||
|
||||
if(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
|
||||
printf("%8" LIBSSH2_FILESIZE_MASK " ", attrs.filesize);
|
||||
}
|
||||
|
||||
printf("%s\n", mem);
|
||||
}
|
||||
else if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
/* blocking */
|
||||
fprintf(stderr, "Blocking\n");
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
} while(1);
|
||||
|
||||
libssh2_sftp_closedir(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
364
vendor/libssh2/example/ssh2.c
vendored
Normal file
364
vendor/libssh2/example/ssh2.c
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SSH2 connect.
|
||||
*
|
||||
* The sample code has default values for host name, user name, password
|
||||
* and path to copy, but you can specify them on the command line like:
|
||||
*
|
||||
* $ ./ssh2 hostip user password [[-p|-i|-k] [command]]
|
||||
*
|
||||
* -p authenticate using password
|
||||
* -i authenticate using keyboard-interactive
|
||||
* -k authenticate using public key (password argument decrypts keyfile)
|
||||
* command executes on the remote machine
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *pubkey = ".ssh/id_rsa.pub";
|
||||
static const char *privkey = ".ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "password";
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
const char *instruction, int instruction_len,
|
||||
int num_prompts,
|
||||
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||
void **abstract)
|
||||
{
|
||||
(void)name;
|
||||
(void)name_len;
|
||||
(void)instruction;
|
||||
(void)instruction_len;
|
||||
if(num_prompts == 1) {
|
||||
responses[0].text = strdup(password);
|
||||
responses[0].length = (unsigned int)strlen(password);
|
||||
}
|
||||
(void)prompts;
|
||||
(void)abstract;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i, auth_pw = 0;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#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];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(22);
|
||||
sin.sin_addr.s_addr = hostaddr;
|
||||
|
||||
fprintf(stderr, "Connecting to %s:%d as user %s\n",
|
||||
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), username);
|
||||
|
||||
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance and start it up. This will trade welcome
|
||||
* banners, exchange keys, and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Enable all debugging when libssh2 was built with debugging enabled */
|
||||
libssh2_trace(session, ~0);
|
||||
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(strstr(userauthlist, "password")) {
|
||||
auth_pw |= 1;
|
||||
}
|
||||
if(strstr(userauthlist, "keyboard-interactive")) {
|
||||
auth_pw |= 2;
|
||||
}
|
||||
if(strstr(userauthlist, "publickey")) {
|
||||
auth_pw |= 4;
|
||||
}
|
||||
|
||||
/* check for options */
|
||||
if(argc > 4) {
|
||||
if((auth_pw & 1) && !strcmp(argv[4], "-p")) {
|
||||
auth_pw = 1;
|
||||
}
|
||||
if((auth_pw & 2) && !strcmp(argv[4], "-i")) {
|
||||
auth_pw = 2;
|
||||
}
|
||||
if((auth_pw & 4) && !strcmp(argv[4], "-k")) {
|
||||
auth_pw = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if(auth_pw & 1) {
|
||||
/* We could authenticate via password */
|
||||
if(libssh2_userauth_password(session, username, password)) {
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by password succeeded.\n");
|
||||
}
|
||||
}
|
||||
else if(auth_pw & 2) {
|
||||
/* Or via keyboard-interactive */
|
||||
if(libssh2_userauth_keyboard_interactive(session, username,
|
||||
&kbd_callback) ) {
|
||||
fprintf(stderr,
|
||||
"Authentication by keyboard-interactive failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Authentication by keyboard-interactive succeeded.\n");
|
||||
}
|
||||
}
|
||||
else if(auth_pw & 4) {
|
||||
/* Or by public key */
|
||||
size_t fn1sz, fn2sz;
|
||||
char *fn1, *fn2;
|
||||
char const *h = getenv("HOME");
|
||||
if(!h || !*h)
|
||||
h = ".";
|
||||
fn1sz = strlen(h) + strlen(pubkey) + 2;
|
||||
fn2sz = strlen(h) + strlen(privkey) + 2;
|
||||
fn1 = malloc(fn1sz);
|
||||
fn2 = malloc(fn2sz);
|
||||
if(!fn1 || !fn2) {
|
||||
free(fn2);
|
||||
free(fn1);
|
||||
fprintf(stderr, "out of memory\n");
|
||||
goto shutdown;
|
||||
}
|
||||
/* Avoid false positives */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic warning "-Wformat-truncation=1"
|
||||
#endif
|
||||
/* Using asprintf() here would be much cleaner,
|
||||
but less portable */
|
||||
snprintf(fn1, fn1sz, "%s/%s", h, pubkey);
|
||||
snprintf(fn2, fn2sz, "%s/%s", h, privkey);
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
if(libssh2_userauth_publickey_fromfile(session, username,
|
||||
fn1, fn2,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
free(fn2);
|
||||
free(fn1);
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
}
|
||||
free(fn2);
|
||||
free(fn1);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "No supported authentication methods found.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* Request a session channel on which to run a shell */
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Unable to open a session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Some environment variables may be set,
|
||||
* It's up to the server which ones it'll allow though
|
||||
*/
|
||||
libssh2_channel_setenv(channel, "FOO", "bar");
|
||||
|
||||
/* Request a terminal with 'vanilla' terminal emulation
|
||||
* See /etc/termcap for more options. This is useful when opening
|
||||
* an interactive shell.
|
||||
*/
|
||||
#if 0
|
||||
if(libssh2_channel_request_pty(channel, "vanilla")) {
|
||||
fprintf(stderr, "Failed requesting pty\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 5) {
|
||||
if(libssh2_channel_exec(channel, argv[5])) {
|
||||
fprintf(stderr, "Unable to request command on channel\n");
|
||||
goto shutdown;
|
||||
}
|
||||
/* Instead of just running a single command with libssh2_channel_exec,
|
||||
* a shell can be opened on the channel instead, for interactive use.
|
||||
* You usually want a pty allocated first in that case (see above). */
|
||||
#if 0
|
||||
if(libssh2_channel_shell(channel)) {
|
||||
fprintf(stderr, "Unable to request shell on allocated pty\n");
|
||||
goto shutdown;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* At this point the shell can be interacted with using
|
||||
* libssh2_channel_read()
|
||||
* libssh2_channel_read_stderr()
|
||||
* libssh2_channel_write()
|
||||
* libssh2_channel_write_stderr()
|
||||
*
|
||||
* Blocking mode may be (en|dis)abled with:
|
||||
* libssh2_channel_set_blocking()
|
||||
* If the server send EOF, libssh2_channel_eof() will return non-0
|
||||
* To send EOF to the server use: libssh2_channel_send_eof()
|
||||
* A channel can be closed with: libssh2_channel_close()
|
||||
* A channel can be freed with: libssh2_channel_free()
|
||||
*/
|
||||
|
||||
/* Read and display all the data received on stdout (ignoring stderr)
|
||||
* until the channel closes. This will eventually block if the command
|
||||
* produces too much data on stderr; the loop must be rewritten to use
|
||||
* non-blocking mode and include interspersed calls to
|
||||
* libssh2_channel_read_stderr() to avoid this. See ssh2_echo.c for
|
||||
* an idea of how such a loop might look.
|
||||
*/
|
||||
while(!libssh2_channel_eof(channel)) {
|
||||
char buf[1024];
|
||||
ssize_t err = libssh2_channel_read(channel, buf, sizeof(buf));
|
||||
if(err < 0)
|
||||
fprintf(stderr, "Unable to read response: %ld\n", (long)err);
|
||||
else {
|
||||
fwrite(buf, 1, (size_t)err, stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = libssh2_channel_get_exit_status(channel);
|
||||
|
||||
if(libssh2_channel_close(channel))
|
||||
fprintf(stderr, "Unable to close channel\n");
|
||||
|
||||
if(channel) {
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
/* Other channel types are supported via:
|
||||
* libssh2_scp_send()
|
||||
* libssh2_scp_recv2()
|
||||
* libssh2_channel_direct_tcpip()
|
||||
*/
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
253
vendor/libssh2/example/ssh2_agent.c
vendored
Normal file
253
vendor/libssh2/example/ssh2_agent.c
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to do SSH2 connect using ssh-agent.
|
||||
*
|
||||
* The sample code has default values for host name, user name:
|
||||
*
|
||||
* $ ./ssh2_agent host user
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *username = "username";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
int i;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_AGENT *agent = NULL;
|
||||
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 1) {
|
||||
hostaddr = inet_addr(argv[1]);
|
||||
}
|
||||
else {
|
||||
hostaddr = htonl(0x7F000001);
|
||||
}
|
||||
if(argc > 2) {
|
||||
username = argv[2];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(!strstr(userauthlist, "publickey")) {
|
||||
fprintf(stderr, "'publickey' authentication is not supported\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Connect to the ssh-agent */
|
||||
agent = libssh2_agent_init(session);
|
||||
if(!agent) {
|
||||
fprintf(stderr, "Failure initializing ssh-agent support\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_connect(agent)) {
|
||||
fprintf(stderr, "Failure connecting to ssh-agent\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_list_identities(agent)) {
|
||||
fprintf(stderr, "Failure requesting identities to ssh-agent\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
for(;;) {
|
||||
rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
|
||||
if(rc == 1)
|
||||
break;
|
||||
if(rc < 0) {
|
||||
fprintf(stderr,
|
||||
"Failure obtaining identity from ssh-agent support\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_userauth(agent, username, identity)) {
|
||||
fprintf(stderr, "Authentication with username %s and "
|
||||
"public key %s failed.\n",
|
||||
username, identity->comment);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication with username %s and "
|
||||
"public key %s succeeded.\n",
|
||||
username, identity->comment);
|
||||
break;
|
||||
}
|
||||
prev_identity = identity;
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "Could not continue authentication\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* We're authenticated now. */
|
||||
|
||||
/* Request a shell */
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Unable to open a session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Some environment variables may be set,
|
||||
* It's up to the server which ones it'll allow though
|
||||
*/
|
||||
libssh2_channel_setenv(channel, "FOO", "bar");
|
||||
|
||||
/* Request a terminal with 'vanilla' terminal emulation
|
||||
* See /etc/termcap for more options. This is useful when opening
|
||||
* an interactive shell.
|
||||
*/
|
||||
if(libssh2_channel_request_pty(channel, "vanilla")) {
|
||||
fprintf(stderr, "Failed requesting pty\n");
|
||||
goto skip_shell;
|
||||
}
|
||||
|
||||
/* Open a SHELL on that pty */
|
||||
if(libssh2_channel_shell(channel)) {
|
||||
fprintf(stderr, "Unable to request shell on allocated pty\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point the shell can be interacted with using
|
||||
* libssh2_channel_read()
|
||||
* libssh2_channel_read_stderr()
|
||||
* libssh2_channel_write()
|
||||
* libssh2_channel_write_stderr()
|
||||
*
|
||||
* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
|
||||
* If the server send EOF, libssh2_channel_eof() will return non-0
|
||||
* To send EOF to the server use: libssh2_channel_send_eof()
|
||||
* A channel can be closed with: libssh2_channel_close()
|
||||
* A channel can be freed with: libssh2_channel_free()
|
||||
*/
|
||||
|
||||
skip_shell:
|
||||
|
||||
if(channel) {
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
/* Other channel types are supported via:
|
||||
* libssh2_scp_send()
|
||||
* libssh2_scp_recv2()
|
||||
* libssh2_channel_direct_tcpip()
|
||||
*/
|
||||
|
||||
shutdown:
|
||||
|
||||
if(agent) {
|
||||
libssh2_agent_disconnect(agent);
|
||||
libssh2_agent_free(agent);
|
||||
}
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
306
vendor/libssh2/example/ssh2_agent_forwarding.c
vendored
Normal file
306
vendor/libssh2/example/ssh2_agent_forwarding.c
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to use libssh2 to request agent forwarding
|
||||
* on the remote host. The command executed will run with agent forwarded
|
||||
* so you should be able to do things like clone out protected git
|
||||
* repos and such.
|
||||
*
|
||||
* The example uses agent authentication to ensure an agent to forward
|
||||
* is running.
|
||||
*
|
||||
* $ ./ssh2_agent_forwarding 127.0.0.1 user "uptime"
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const char *hostname = "127.0.0.1";
|
||||
static const char *commandline = "uptime";
|
||||
static const char *username;
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
struct sockaddr_in sin;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_AGENT *agent = NULL;
|
||||
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
||||
int exitcode;
|
||||
char *exitsignal = (char *)"none";
|
||||
ssize_t bytecount = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc < 2) {
|
||||
fprintf(stderr, "At least IP and username arguments are required.\n");
|
||||
return 1;
|
||||
}
|
||||
/* must be ip address only */
|
||||
hostname = argv[1];
|
||||
username = argv[2];
|
||||
|
||||
if(argc > 3) {
|
||||
commandline = argv[3];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hostaddr = inet_addr(hostname);
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
if(libssh2_session_handshake(session, sock) != 0) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Connect to the ssh-agent */
|
||||
agent = libssh2_agent_init(session);
|
||||
if(!agent) {
|
||||
fprintf(stderr, "Failure initializing ssh-agent support\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_connect(agent)) {
|
||||
fprintf(stderr, "Failure connecting to ssh-agent\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_list_identities(agent)) {
|
||||
fprintf(stderr, "Failure requesting identities to ssh-agent\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
for(;;) {
|
||||
rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
|
||||
if(rc == 1)
|
||||
break;
|
||||
if(rc < 0) {
|
||||
fprintf(stderr,
|
||||
"Failure obtaining identity from ssh-agent support\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_userauth(agent, username, identity)) {
|
||||
fprintf(stderr, "Authentication with username %s and "
|
||||
"public key %s failed.\n",
|
||||
username, identity->comment);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication with username %s and "
|
||||
"public key %s succeeded.\n",
|
||||
username, identity->comment);
|
||||
break;
|
||||
}
|
||||
prev_identity = identity;
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "Could not continue authentication\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
#if 0
|
||||
libssh2_trace(session, ~0);
|
||||
#endif
|
||||
|
||||
/* Set session to non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
/* Exec non-blocking on the remote host */
|
||||
do {
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(channel ||
|
||||
libssh2_session_last_error(session, NULL, NULL, 0) !=
|
||||
LIBSSH2_ERROR_EAGAIN)
|
||||
break;
|
||||
waitsocket(sock, session);
|
||||
} while(1);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Error\n");
|
||||
exit(1);
|
||||
}
|
||||
while((rc = libssh2_channel_request_auth_agent(channel)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "Error, could not request auth agent, "
|
||||
"error code %d.\n", rc);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, "Agent forwarding request succeeded.\n");
|
||||
}
|
||||
while((rc = libssh2_channel_exec(channel, commandline)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "Error\n");
|
||||
exit(1);
|
||||
}
|
||||
for(;;) {
|
||||
ssize_t nread;
|
||||
/* loop until we block */
|
||||
do {
|
||||
char buffer[0x4000];
|
||||
nread = libssh2_channel_read(channel, buffer, sizeof(buffer) );
|
||||
if(nread > 0) {
|
||||
ssize_t i;
|
||||
bytecount += nread;
|
||||
fprintf(stderr, "We read:\n");
|
||||
for(i = 0; i < nread; ++i)
|
||||
fputc(buffer[i], stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
else {
|
||||
if(nread != LIBSSH2_ERROR_EAGAIN)
|
||||
/* no need to output this for the EAGAIN case */
|
||||
fprintf(stderr, "libssh2_channel_read returned %ld\n",
|
||||
(long)nread);
|
||||
}
|
||||
} while(nread > 0);
|
||||
|
||||
/* this is due to blocking that would occur otherwise so we loop on
|
||||
this condition */
|
||||
if(nread == LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
exitcode = 127;
|
||||
while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc == 0) {
|
||||
exitcode = libssh2_channel_get_exit_status(channel);
|
||||
libssh2_channel_get_exit_signal(channel, &exitsignal,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if(exitsignal) {
|
||||
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\nEXIT: %d bytecount: %ld\n",
|
||||
exitcode, (long)bytecount);
|
||||
}
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
380
vendor/libssh2/example/ssh2_echo.c
vendored
Normal file
380
vendor/libssh2/example/ssh2_echo.c
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* The code sends a 'cat' command, and then writes a lot of data to it only to
|
||||
* check that reading the returned data sums up to the same amount.
|
||||
*
|
||||
* $ ./ssh2_echo 127.0.0.1 user password
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *hostname = "127.0.0.1";
|
||||
static const char *commandline = "cat";
|
||||
static const char *username = "user";
|
||||
static const char *password = "password";
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define BUFSIZE 32000
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
int exitcode = 0;
|
||||
char *exitsignal = (char *)"none";
|
||||
size_t len;
|
||||
LIBSSH2_KNOWNHOSTS *nh;
|
||||
int type;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 1) {
|
||||
hostname = argv[1]; /* must be ip address only */
|
||||
}
|
||||
if(argc > 2) {
|
||||
username = argv[2];
|
||||
}
|
||||
if(argc > 3) {
|
||||
password = argv[3];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hostaddr = inet_addr(hostname);
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* tell libssh2 we want it all done 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_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
nh = libssh2_knownhost_init(session);
|
||||
if(!nh) {
|
||||
/* eeek, do cleanup here */
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* read all hosts from here */
|
||||
libssh2_knownhost_readfile(nh, "known_hosts",
|
||||
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
|
||||
|
||||
/* store all known hosts to here */
|
||||
libssh2_knownhost_writefile(nh, "dumpfile",
|
||||
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
|
||||
|
||||
fingerprint = libssh2_session_hostkey(session, &len, &type);
|
||||
if(fingerprint) {
|
||||
struct libssh2_knownhost *host;
|
||||
int check = libssh2_knownhost_checkp(nh, hostname, 22,
|
||||
fingerprint, len,
|
||||
LIBSSH2_KNOWNHOST_TYPE_PLAIN|
|
||||
LIBSSH2_KNOWNHOST_KEYENC_RAW,
|
||||
&host);
|
||||
|
||||
fprintf(stderr, "Host check: %d, key: %s\n", check,
|
||||
(check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ?
|
||||
host->key : "<none>");
|
||||
|
||||
/*****
|
||||
* At this point, we could verify that 'check' tells us the key is
|
||||
* fine or bail out.
|
||||
*****/
|
||||
}
|
||||
else {
|
||||
/* eeek, do cleanup here */
|
||||
return 3;
|
||||
}
|
||||
libssh2_knownhost_free(nh);
|
||||
|
||||
if(strlen(password) != 0) {
|
||||
/* 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");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
libssh2_trace(session, LIBSSH2_TRACE_SOCKET);
|
||||
|
||||
/* Exec non-blocking on the remote host */
|
||||
do {
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(channel ||
|
||||
libssh2_session_last_error(session, NULL, NULL, 0) !=
|
||||
LIBSSH2_ERROR_EAGAIN)
|
||||
break;
|
||||
waitsocket(sock, session);
|
||||
} while(1);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Error\n");
|
||||
exit(1);
|
||||
}
|
||||
while((rc = libssh2_channel_exec(channel, commandline)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "exec error\n");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
LIBSSH2_POLLFD *fds = NULL;
|
||||
int running = 1;
|
||||
size_t bufsize = BUFSIZE;
|
||||
char buffer[BUFSIZE];
|
||||
size_t totsize = 1500000;
|
||||
size_t totwritten = 0;
|
||||
size_t totread = 0;
|
||||
int rereads = 0;
|
||||
int rewrites = 0;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < BUFSIZE; i++)
|
||||
buffer[i] = 'A';
|
||||
|
||||
fds = malloc(sizeof(LIBSSH2_POLLFD));
|
||||
if(!fds) {
|
||||
fprintf(stderr, "malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
|
||||
fds[0].fd.channel = channel;
|
||||
fds[0].events = LIBSSH2_POLLFD_POLLIN | LIBSSH2_POLLFD_POLLOUT;
|
||||
|
||||
do {
|
||||
int act = 0;
|
||||
rc = libssh2_poll(fds, 1, 10);
|
||||
|
||||
if(rc < 1)
|
||||
continue;
|
||||
|
||||
if(fds[0].revents & LIBSSH2_POLLFD_POLLIN) {
|
||||
ssize_t n = libssh2_channel_read(channel,
|
||||
buffer, sizeof(buffer));
|
||||
act++;
|
||||
|
||||
if(n == LIBSSH2_ERROR_EAGAIN) {
|
||||
rereads++;
|
||||
fprintf(stderr, "will read again\n");
|
||||
}
|
||||
else if(n < 0) {
|
||||
fprintf(stderr, "read failed\n");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
totread += (size_t)n;
|
||||
fprintf(stderr, "read %ld bytes (%lu in total)\n",
|
||||
(long)n, (unsigned long)totread);
|
||||
}
|
||||
}
|
||||
|
||||
if(fds[0].revents & LIBSSH2_POLLFD_POLLOUT) {
|
||||
act++;
|
||||
|
||||
if(totwritten < totsize) {
|
||||
/* we have not written all data yet */
|
||||
size_t left = totsize - totwritten;
|
||||
size_t size = (left < bufsize) ? left : bufsize;
|
||||
ssize_t n = libssh2_channel_write_ex(channel, 0,
|
||||
buffer, size);
|
||||
|
||||
if(n == LIBSSH2_ERROR_EAGAIN) {
|
||||
rewrites++;
|
||||
fprintf(stderr, "will write again\n");
|
||||
}
|
||||
else if(n < 0) {
|
||||
fprintf(stderr, "write failed\n");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
totwritten += (size_t)n;
|
||||
fprintf(stderr, "wrote %ld bytes (%lu in total)",
|
||||
(long)n, (unsigned long)totwritten);
|
||||
if(left >= bufsize && (size_t)n != bufsize) {
|
||||
fprintf(stderr, " PARTIAL");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* all data written, send EOF */
|
||||
rc = libssh2_channel_send_eof(channel);
|
||||
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
fprintf(stderr, "will send eof again\n");
|
||||
}
|
||||
else if(rc < 0) {
|
||||
fprintf(stderr, "send eof failed\n");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "sent eof\n");
|
||||
/* we're done writing, stop listening for OUT events */
|
||||
fds[0].events &=
|
||||
~(unsigned long)LIBSSH2_POLLFD_POLLOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(fds[0].revents & LIBSSH2_POLLFD_CHANNEL_CLOSED) {
|
||||
if(!act) /* don't leave loop until we have read all data */
|
||||
running = 0;
|
||||
}
|
||||
} while(running);
|
||||
|
||||
exitcode = 127;
|
||||
while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN)
|
||||
waitsocket(sock, session);
|
||||
|
||||
if(rc == 0) {
|
||||
exitcode = libssh2_channel_get_exit_status(channel);
|
||||
libssh2_channel_get_exit_signal(channel, &exitsignal,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if(exitsignal)
|
||||
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
fprintf(stderr, "\nrereads: %d rewrites: %d totwritten %lu\n",
|
||||
rereads, rewrites, (unsigned long)totwritten);
|
||||
|
||||
if(totwritten != totread) {
|
||||
fprintf(stderr, "\n*** FAIL bytes written: "
|
||||
"%lu bytes read: %lu ***\n",
|
||||
(unsigned long)totwritten, (unsigned long)totread);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return exitcode;
|
||||
}
|
||||
315
vendor/libssh2/example/ssh2_exec.c
vendored
Normal file
315
vendor/libssh2/example/ssh2_exec.c
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to use libssh2 to execute a command remotely.
|
||||
*
|
||||
* The sample code has fixed values for host name, user name, password
|
||||
* and command to run.
|
||||
*
|
||||
* $ ./ssh2_exec 127.0.0.1 user password "uptime"
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *hostname = "127.0.0.1";
|
||||
static const char *commandline = "uptime";
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "user";
|
||||
static const char *password = "password";
|
||||
|
||||
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(socket_fd, &fd);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr;
|
||||
libssh2_socket_t sock;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
int exitcode;
|
||||
char *exitsignal = (char *)"none";
|
||||
ssize_t bytecount = 0;
|
||||
size_t len;
|
||||
LIBSSH2_KNOWNHOSTS *nh;
|
||||
int type;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 1) {
|
||||
hostname = argv[1]; /* must be ip address only */
|
||||
}
|
||||
if(argc > 2) {
|
||||
username = argv[2];
|
||||
}
|
||||
if(argc > 3) {
|
||||
password = argv[3];
|
||||
}
|
||||
if(argc > 4) {
|
||||
commandline = argv[4];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hostaddr = inet_addr(hostname);
|
||||
|
||||
/* 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);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to create socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "failed to connect.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* tell libssh2 we want it all done 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_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
nh = libssh2_knownhost_init(session);
|
||||
if(!nh) {
|
||||
/* eeek, do cleanup here */
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* read all hosts from here */
|
||||
libssh2_knownhost_readfile(nh, "known_hosts",
|
||||
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
|
||||
|
||||
/* store all known hosts to here */
|
||||
libssh2_knownhost_writefile(nh, "dumpfile",
|
||||
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
|
||||
|
||||
fingerprint = libssh2_session_hostkey(session, &len, &type);
|
||||
if(fingerprint) {
|
||||
struct libssh2_knownhost *host;
|
||||
int check = libssh2_knownhost_checkp(nh, hostname, 22,
|
||||
fingerprint, len,
|
||||
LIBSSH2_KNOWNHOST_TYPE_PLAIN|
|
||||
LIBSSH2_KNOWNHOST_KEYENC_RAW,
|
||||
&host);
|
||||
|
||||
fprintf(stderr, "Host check: %d, key: %s\n", check,
|
||||
(check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ?
|
||||
host->key : "<none>");
|
||||
|
||||
/*****
|
||||
* At this point, we could verify that 'check' tells us the key is
|
||||
* fine or bail out.
|
||||
*****/
|
||||
}
|
||||
else {
|
||||
/* eeek, do cleanup here */
|
||||
return 3;
|
||||
}
|
||||
libssh2_knownhost_free(nh);
|
||||
|
||||
if(strlen(password) != 0) {
|
||||
/* 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,
|
||||
pubkey, privkey,
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
libssh2_trace(session, ~0);
|
||||
#endif
|
||||
|
||||
/* Exec non-blocking on the remote host */
|
||||
do {
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(channel ||
|
||||
libssh2_session_last_error(session, NULL, NULL, 0) !=
|
||||
LIBSSH2_ERROR_EAGAIN)
|
||||
break;
|
||||
waitsocket(sock, session);
|
||||
} while(1);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Error\n");
|
||||
exit(1);
|
||||
}
|
||||
while((rc = libssh2_channel_exec(channel, commandline)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "exec error\n");
|
||||
exit(1);
|
||||
}
|
||||
for(;;) {
|
||||
ssize_t nread;
|
||||
/* loop until we block */
|
||||
do {
|
||||
char buffer[0x4000];
|
||||
nread = libssh2_channel_read(channel, buffer, sizeof(buffer));
|
||||
if(nread > 0) {
|
||||
ssize_t i;
|
||||
bytecount += nread;
|
||||
fprintf(stderr, "We read:\n");
|
||||
for(i = 0; i < nread; ++i)
|
||||
fputc(buffer[i], stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
else {
|
||||
if(nread != LIBSSH2_ERROR_EAGAIN)
|
||||
/* no need to output this for the EAGAIN case */
|
||||
fprintf(stderr, "libssh2_channel_read returned %ld\n",
|
||||
(long)nread);
|
||||
}
|
||||
} while(nread > 0);
|
||||
|
||||
/* this is due to blocking that would occur otherwise so we loop on
|
||||
this condition */
|
||||
if(nread == LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
exitcode = 127;
|
||||
while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN)
|
||||
waitsocket(sock, session);
|
||||
|
||||
if(rc == 0) {
|
||||
exitcode = libssh2_channel_get_exit_status(channel);
|
||||
libssh2_channel_get_exit_signal(channel, &exitsignal,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if(exitsignal)
|
||||
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||
else
|
||||
fprintf(stderr, "\nEXIT: %d bytecount: %ld\n",
|
||||
exitcode, (long)bytecount);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
308
vendor/libssh2/example/subsystem_netconf.c
vendored
Normal file
308
vendor/libssh2/example/subsystem_netconf.c
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (in_addr_t)~0
|
||||
#endif
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "";
|
||||
|
||||
static const char *server_ip = "127.0.0.1";
|
||||
|
||||
enum {
|
||||
AUTH_NONE = 0,
|
||||
AUTH_PASSWORD = 1,
|
||||
AUTH_PUBLICKEY = 2
|
||||
};
|
||||
|
||||
static int netconf_write(LIBSSH2_CHANNEL *channel, const char *buf, size_t len)
|
||||
{
|
||||
ssize_t i;
|
||||
ssize_t wr = 0;
|
||||
|
||||
do {
|
||||
i = libssh2_channel_write(channel, buf, len);
|
||||
if(i < 0) {
|
||||
fprintf(stderr, "libssh2_channel_write: %ld\n", (long)i);
|
||||
return -1;
|
||||
}
|
||||
wr += i;
|
||||
} while(i > 0 && wr < (ssize_t)len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t netconf_read_until(LIBSSH2_CHANNEL *channel, const char *endtag,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
ssize_t len;
|
||||
size_t rd = 0;
|
||||
char *endreply = NULL, *specialsequence = NULL;
|
||||
|
||||
memset(buf, 0, buflen);
|
||||
|
||||
do {
|
||||
len = libssh2_channel_read(channel, buf + rd, buflen - rd);
|
||||
if(LIBSSH2_ERROR_EAGAIN == len)
|
||||
continue;
|
||||
else if(len < 0) {
|
||||
fprintf(stderr, "libssh2_channel_read: %ld\n", (long)len);
|
||||
return -1;
|
||||
}
|
||||
rd += (size_t)len;
|
||||
|
||||
/* read more data until we see a rpc-reply closing tag followed by
|
||||
* the special sequence ]]>]]> */
|
||||
|
||||
/* really, this MUST be replaced with proper XML parsing. */
|
||||
|
||||
endreply = strstr(buf, endtag);
|
||||
if(endreply)
|
||||
specialsequence = strstr(endreply, "]]>]]>");
|
||||
|
||||
} while(!specialsequence && rd < buflen);
|
||||
|
||||
if(!specialsequence) {
|
||||
fprintf(stderr, "netconf_read_until(): ]]>]]> not found."
|
||||
" Read buffer too small?\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* discard the special sequence so that only XML is returned */
|
||||
rd = (size_t)(specialsequence - buf);
|
||||
buf[rd] = 0;
|
||||
|
||||
return (ssize_t)rd;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, auth = AUTH_NONE;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
char buf[1048576]; /* avoid any buffer reallocation for simplicity */
|
||||
ssize_t len;
|
||||
libssh2_socket_t sock;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 1)
|
||||
server_ip = argv[1];
|
||||
if(argc > 2)
|
||||
username = argv[2];
|
||||
if(argc > 3)
|
||||
password = argv[3];
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = inet_addr(server_ip);
|
||||
if(INADDR_NONE == sin.sin_addr.s_addr) {
|
||||
fprintf(stderr, "inet_addr: Invalid IP address '%s'\n", server_ip);
|
||||
goto shutdown;
|
||||
}
|
||||
sin.sin_port = htons(830);
|
||||
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
|
||||
fprintf(stderr, "Failed to connect to %s.\n", inet_ntoa(sin.sin_addr));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Error when starting up SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++)
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(strstr(userauthlist, "password"))
|
||||
auth |= AUTH_PASSWORD;
|
||||
if(strstr(userauthlist, "publickey"))
|
||||
auth |= AUTH_PUBLICKEY;
|
||||
|
||||
/* check for options */
|
||||
if(argc > 4) {
|
||||
if((auth & AUTH_PASSWORD) && !strcmp(argv[4], "-p"))
|
||||
auth = AUTH_PASSWORD;
|
||||
if((auth & AUTH_PUBLICKEY) && !strcmp(argv[4], "-k"))
|
||||
auth = AUTH_PUBLICKEY;
|
||||
}
|
||||
|
||||
if(auth & AUTH_PASSWORD) {
|
||||
if(libssh2_userauth_password(session, username, password)) {
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
else if(auth & AUTH_PUBLICKEY) {
|
||||
if(libssh2_userauth_publickey_fromfile(session, username,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "No supported authentication methods found.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* open a channel */
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Could not open the channel.\n"
|
||||
"(Note that this can be a problem at the server."
|
||||
" Please review the server logs.)\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* execute the subsystem on our channel */
|
||||
if(libssh2_channel_subsystem(channel, "netconf")) {
|
||||
fprintf(stderr, "Could not execute the 'netconf' subsystem.\n"
|
||||
"(Note that this can be a problem at the server."
|
||||
" Please review the server logs.)\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* NETCONF: https://tools.ietf.org/html/draft-ietf-netconf-ssh-06 */
|
||||
|
||||
fprintf(stderr, "Sending NETCONF client <hello>\n");
|
||||
len = snprintf(buf, sizeof(buf),
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<hello>"
|
||||
"<capabilities>"
|
||||
"<capability>urn:ietf:params:xml:ns:netconf:base:1.0</capability>"
|
||||
"</capabilities>"
|
||||
"</hello>\n"
|
||||
"]]>]]>\n");
|
||||
if(len < 0)
|
||||
goto shutdown;
|
||||
if(-1 == netconf_write(channel, buf, (size_t)len))
|
||||
goto shutdown;
|
||||
|
||||
fprintf(stderr, "Reading NETCONF server <hello>\n");
|
||||
len = netconf_read_until(channel, "</hello>", buf, sizeof(buf));
|
||||
if(-1 == len)
|
||||
goto shutdown;
|
||||
|
||||
fprintf(stderr, "Got %ld bytes:\n----------------------\n%s",
|
||||
(long)len, buf);
|
||||
|
||||
fprintf(stderr, "Sending NETCONF <rpc>\n");
|
||||
len = snprintf(buf, sizeof(buf),
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
|
||||
"<get-interface-information><terse/></get-interface-information>"
|
||||
"</rpc>\n"
|
||||
"]]>]]>\n");
|
||||
if(len < 0)
|
||||
goto shutdown;
|
||||
if(-1 == netconf_write(channel, buf, (size_t)len))
|
||||
goto shutdown;
|
||||
|
||||
fprintf(stderr, "Reading NETCONF <rpc-reply>\n");
|
||||
len = netconf_read_until(channel, "</rpc-reply>", buf, sizeof(buf));
|
||||
if(-1 == len)
|
||||
goto shutdown;
|
||||
|
||||
fprintf(stderr, "Got %ld bytes:\n----------------------\n%s",
|
||||
(long)len, buf);
|
||||
|
||||
shutdown:
|
||||
|
||||
if(channel)
|
||||
libssh2_channel_free(channel);
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
351
vendor/libssh2/example/tcpip-forward.c
vendored
Normal file
351
vendor/libssh2/example/tcpip-forward.c
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h> /* for socklen_t */
|
||||
#define recv(s, b, l, f) recv((s), (b), (int)(l), (f))
|
||||
#define send(s, b, l, f) send((s), (b), (int)(l), (f))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (in_addr_t)~0
|
||||
#endif
|
||||
|
||||
static const char *pubkey = "/home/username/.ssh/id_rsa.pub";
|
||||
static const char *privkey = "/home/username/.ssh/id_rsa";
|
||||
static const char *username = "username";
|
||||
static const char *password = "";
|
||||
|
||||
static const char *server_ip = "127.0.0.1";
|
||||
|
||||
/* resolved by the server */
|
||||
static const char *remote_listenhost = "localhost";
|
||||
|
||||
static int remote_wantport = 2222;
|
||||
static int remote_listenport;
|
||||
|
||||
static const char *local_destip = "127.0.0.1";
|
||||
static int local_destport = 22;
|
||||
|
||||
enum {
|
||||
AUTH_NONE = 0,
|
||||
AUTH_PASSWORD = 1,
|
||||
AUTH_PUBLICKEY = 2
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, auth = AUTH_NONE;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen = sizeof(sin);
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_LISTENER *listener = NULL;
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
struct timeval tv;
|
||||
ssize_t len, wr;
|
||||
char buf[16384];
|
||||
libssh2_socket_t sock;
|
||||
libssh2_socket_t forwardsock = LIBSSH2_INVALID_SOCKET;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
if(rc) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(argc > 1)
|
||||
server_ip = argv[1];
|
||||
if(argc > 2)
|
||||
username = argv[2];
|
||||
if(argc > 3)
|
||||
password = argv[3];
|
||||
if(argc > 4)
|
||||
remote_listenhost = argv[4];
|
||||
if(argc > 5)
|
||||
remote_wantport = atoi(argv[5]);
|
||||
if(argc > 6)
|
||||
local_destip = argv[6];
|
||||
if(argc > 7)
|
||||
local_destport = atoi(argv[7]);
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = inet_addr(server_ip);
|
||||
if(INADDR_NONE == sin.sin_addr.s_addr) {
|
||||
fprintf(stderr, "inet_addr: Invalid IP address '%s'\n", server_ip);
|
||||
goto shutdown;
|
||||
}
|
||||
sin.sin_port = htons(22);
|
||||
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
|
||||
fprintf(stderr, "Failed to connect to %s.\n", inet_ntoa(sin.sin_addr));
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session) {
|
||||
fprintf(stderr, "Could not initialize SSH session.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Error when starting up SSH session: %d\n", rc);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point we have not 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_SHA1);
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++)
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username,
|
||||
(unsigned int)strlen(username));
|
||||
if(userauthlist) {
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if(strstr(userauthlist, "password"))
|
||||
auth |= AUTH_PASSWORD;
|
||||
if(strstr(userauthlist, "publickey"))
|
||||
auth |= AUTH_PUBLICKEY;
|
||||
|
||||
/* check for options */
|
||||
if(argc > 8) {
|
||||
if((auth & AUTH_PASSWORD) && !strcmp(argv[8], "-p"))
|
||||
auth = AUTH_PASSWORD;
|
||||
if((auth & AUTH_PUBLICKEY) && !strcmp(argv[8], "-k"))
|
||||
auth = AUTH_PUBLICKEY;
|
||||
}
|
||||
|
||||
if(auth & AUTH_PASSWORD) {
|
||||
if(libssh2_userauth_password(session, username, password)) {
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
else if(auth & AUTH_PUBLICKEY) {
|
||||
if(libssh2_userauth_publickey_fromfile(session, username,
|
||||
pubkey, privkey,
|
||||
password)) {
|
||||
fprintf(stderr, "Authentication by public key failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "No supported authentication methods found.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Asking server to listen on remote %s:%d\n",
|
||||
remote_listenhost, remote_wantport);
|
||||
|
||||
listener = libssh2_channel_forward_listen_ex(session, remote_listenhost,
|
||||
remote_wantport,
|
||||
&remote_listenport, 1);
|
||||
if(!listener) {
|
||||
fprintf(stderr, "Could not start the tcpip-forward listener.\n"
|
||||
"(Note that this can be a problem at the server."
|
||||
" Please review the server logs.)\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Server is listening on %s:%d\n", remote_listenhost,
|
||||
remote_listenport);
|
||||
|
||||
fprintf(stderr, "Waiting for remote connection\n");
|
||||
channel = libssh2_channel_forward_accept(listener);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Could not accept connection.\n"
|
||||
"(Note that this can be a problem at the server."
|
||||
" Please review the server logs.)\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"Accepted remote connection. Connecting to local server %s:%d\n",
|
||||
local_destip, local_destport);
|
||||
forwardsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(forwardsock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open forward socket.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons((unsigned short)local_destport);
|
||||
sin.sin_addr.s_addr = inet_addr(local_destip);
|
||||
if(INADDR_NONE == sin.sin_addr.s_addr) {
|
||||
fprintf(stderr, "failed in inet_addr().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
if(-1 == connect(forwardsock, (struct sockaddr *)&sin, sinlen)) {
|
||||
fprintf(stderr, "failed to connect().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Forwarding connection from remote %s:%d to local %s:%d\n",
|
||||
remote_listenhost, remote_listenport,
|
||||
local_destip, local_destport);
|
||||
|
||||
/* Must use non-blocking IO hereafter due to the current libssh2 API */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
for(;;) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(forwardsock, &fds);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000;
|
||||
rc = select((int)(forwardsock + 1), &fds, NULL, NULL, &tv);
|
||||
if(-1 == rc) {
|
||||
fprintf(stderr, "failed to select().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
if(rc && FD_ISSET(forwardsock, &fds)) {
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
ssize_t nwritten;
|
||||
len = recv(forwardsock, buf, sizeof(buf), 0);
|
||||
if(len < 0) {
|
||||
fprintf(stderr, "failed to recv().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else if(len == 0) {
|
||||
fprintf(stderr, "The local server at %s:%d disconnected.\n",
|
||||
local_destip, local_destport);
|
||||
goto shutdown;
|
||||
}
|
||||
wr = 0;
|
||||
do {
|
||||
nwritten = libssh2_channel_write(channel, buf, (size_t)len);
|
||||
if(nwritten < 0) {
|
||||
fprintf(stderr, "libssh2_channel_write: %ld\n",
|
||||
(long)nwritten);
|
||||
goto shutdown;
|
||||
}
|
||||
wr += nwritten;
|
||||
} while(nwritten > 0 && wr < len);
|
||||
}
|
||||
for(;;) {
|
||||
ssize_t nsent;
|
||||
len = libssh2_channel_read(channel, buf, sizeof(buf));
|
||||
if(LIBSSH2_ERROR_EAGAIN == len)
|
||||
break;
|
||||
else if(len < 0) {
|
||||
fprintf(stderr, "libssh2_channel_read: %ld",
|
||||
(long)len);
|
||||
goto shutdown;
|
||||
}
|
||||
wr = 0;
|
||||
while(wr < len) {
|
||||
nsent = send(forwardsock, buf + wr, (size_t)(len - wr), 0);
|
||||
if(nsent <= 0) {
|
||||
fprintf(stderr, "failed to send().\n");
|
||||
goto shutdown;
|
||||
}
|
||||
wr += nsent;
|
||||
}
|
||||
if(libssh2_channel_eof(channel)) {
|
||||
fprintf(stderr, "The remote client at %s:%d disconnected.\n",
|
||||
remote_listenhost, remote_listenport);
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shutdown:
|
||||
|
||||
if(forwardsock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(forwardsock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(forwardsock);
|
||||
}
|
||||
|
||||
if(channel)
|
||||
libssh2_channel_free(channel);
|
||||
|
||||
if(listener)
|
||||
libssh2_channel_forward_cancel(listener);
|
||||
|
||||
if(session) {
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
if(sock != LIBSSH2_INVALID_SOCKET) {
|
||||
shutdown(sock, 2);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
517
vendor/libssh2/example/x11.c
vendored
Normal file
517
vendor/libssh2/example/x11.c
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
/* Copyright (C) The libssh2 project and its contributors.
|
||||
*
|
||||
* Sample showing how to makes SSH2 with X11 Forwarding works.
|
||||
*
|
||||
* $ ./x11 host user password [DEBUG]
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "libssh2_setup.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.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_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#define _PATH_UNIX_X "/tmp/.X11-unix/X%d"
|
||||
|
||||
/*
|
||||
* Chained list that contains channels and associated X11 socket for each X11
|
||||
* connections
|
||||
*/
|
||||
struct chan_X11_list {
|
||||
LIBSSH2_CHANNEL *chan;
|
||||
libssh2_socket_t sock;
|
||||
struct chan_X11_list *next;
|
||||
};
|
||||
|
||||
static struct chan_X11_list * gp_x11_chan = NULL;
|
||||
static struct termios _saved_tio;
|
||||
|
||||
/*
|
||||
* Utility function to remove a Node of the chained list
|
||||
*/
|
||||
static void remove_node(struct chan_X11_list *elem)
|
||||
{
|
||||
struct chan_X11_list *current_node = NULL;
|
||||
|
||||
current_node = gp_x11_chan;
|
||||
|
||||
if(gp_x11_chan == elem) {
|
||||
gp_x11_chan = gp_x11_chan->next;
|
||||
free(current_node);
|
||||
return;
|
||||
}
|
||||
|
||||
while(current_node->next) {
|
||||
if(current_node->next == elem) {
|
||||
current_node->next = current_node->next->next;
|
||||
current_node = current_node->next;
|
||||
free(current_node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void session_shutdown(LIBSSH2_SESSION *session)
|
||||
{
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
static int _raw_mode(void)
|
||||
{
|
||||
int rc;
|
||||
struct termios tio;
|
||||
|
||||
rc = tcgetattr(fileno(stdin), &tio);
|
||||
if(rc != -1) {
|
||||
_saved_tio = tio;
|
||||
/* do the equivalent of cfmakeraw() manually, to build on Solaris */
|
||||
tio.c_iflag &= ~(tcflag_t)(IGNBRK|BRKINT|PARMRK|ISTRIP|
|
||||
INLCR|IGNCR|ICRNL|IXON);
|
||||
tio.c_oflag &= ~(tcflag_t)OPOST;
|
||||
tio.c_lflag &= ~(tcflag_t)(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||
tio.c_cflag &= ~(tcflag_t)(CSIZE|PARENB);
|
||||
tio.c_cflag |= CS8;
|
||||
rc = tcsetattr(fileno(stdin), TCSADRAIN, &tio);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _normal_mode(void)
|
||||
{
|
||||
int rc;
|
||||
rc = tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* CallBack to initialize the forwarding.
|
||||
* Save the channel to loop on it, save the X11 forwarded socket to send
|
||||
* and receive info from our X server.
|
||||
*/
|
||||
static void x11_callback(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel,
|
||||
char *shost, int sport, void **abstract)
|
||||
{
|
||||
const char *display;
|
||||
char *ptr;
|
||||
char *temp_buff;
|
||||
int display_port;
|
||||
int rc;
|
||||
libssh2_socket_t sock = LIBSSH2_INVALID_SOCKET;
|
||||
struct sockaddr_un addr;
|
||||
struct chan_X11_list *new;
|
||||
struct chan_X11_list *chan_iter;
|
||||
(void)session;
|
||||
(void)shost;
|
||||
(void)sport;
|
||||
(void)abstract;
|
||||
/*
|
||||
* Connect to the display
|
||||
* Inspired by x11_connect_display in openssh
|
||||
*/
|
||||
display = getenv("DISPLAY");
|
||||
if(display) {
|
||||
if(strncmp(display, "unix:", 5) == 0 ||
|
||||
display[0] == ':') {
|
||||
/* Connect to the local unix domain */
|
||||
ptr = strrchr(display, ':');
|
||||
temp_buff = (char *)calloc(strlen(ptr + 1) + 1, sizeof(char));
|
||||
if(!temp_buff) {
|
||||
fprintf(stderr, "failed to calloc().\n");
|
||||
return;
|
||||
}
|
||||
memcpy(temp_buff, ptr + 1, strlen(ptr + 1));
|
||||
display_port = atoi(temp_buff);
|
||||
free(temp_buff);
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET)
|
||||
return;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path),
|
||||
_PATH_UNIX_X, display_port);
|
||||
rc = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
if(rc != -1) {
|
||||
/* Connection Successful */
|
||||
if(!gp_x11_chan) {
|
||||
/* Calloc ensure that gp_X11_chan is full of 0 */
|
||||
gp_x11_chan = (struct chan_X11_list *)
|
||||
calloc(1, sizeof(struct chan_X11_list));
|
||||
gp_x11_chan->sock = sock;
|
||||
gp_x11_chan->chan = channel;
|
||||
gp_x11_chan->next = NULL;
|
||||
}
|
||||
else {
|
||||
chan_iter = gp_x11_chan;
|
||||
while(chan_iter->next)
|
||||
chan_iter = chan_iter->next;
|
||||
/* Create the new Node */
|
||||
new = (struct chan_X11_list *)
|
||||
malloc(sizeof(struct chan_X11_list));
|
||||
new->sock = sock;
|
||||
new->chan = channel;
|
||||
new->next = NULL;
|
||||
chan_iter->next = new;
|
||||
}
|
||||
}
|
||||
else {
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send and receive Data for the X11 channel.
|
||||
* If the connection is closed, returns -1, 0 either.
|
||||
*/
|
||||
static int x11_send_receive(LIBSSH2_CHANNEL *channel, libssh2_socket_t sock)
|
||||
{
|
||||
char *buf;
|
||||
unsigned int bufsize = 8192;
|
||||
int rc;
|
||||
unsigned int nfds = 1;
|
||||
LIBSSH2_POLLFD *fds = NULL;
|
||||
fd_set set;
|
||||
struct timeval timeval_out;
|
||||
timeval_out.tv_sec = 0;
|
||||
timeval_out.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&set);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(sock, &set);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
buf = calloc(bufsize, sizeof(char));
|
||||
if(!buf)
|
||||
return 0;
|
||||
|
||||
fds = malloc(sizeof(LIBSSH2_POLLFD));
|
||||
if(!fds) {
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
|
||||
fds[0].fd.channel = channel;
|
||||
fds[0].events = LIBSSH2_POLLFD_POLLIN;
|
||||
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
|
||||
|
||||
rc = libssh2_poll(fds, nfds, 0);
|
||||
if(rc > 0) {
|
||||
ssize_t nread;
|
||||
nread = libssh2_channel_read(channel, buf, bufsize);
|
||||
if(nread > 0)
|
||||
write(sock, buf, (size_t)nread);
|
||||
}
|
||||
|
||||
rc = select((int)(sock + 1), &set, NULL, NULL, &timeval_out);
|
||||
if(rc > 0) {
|
||||
ssize_t nread;
|
||||
|
||||
memset(buf, 0, bufsize);
|
||||
|
||||
/* Data in sock */
|
||||
nread = read(sock, buf, bufsize);
|
||||
if(nread > 0) {
|
||||
libssh2_channel_write(channel, buf, (size_t)nread);
|
||||
}
|
||||
else {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(fds);
|
||||
free(buf);
|
||||
if(libssh2_channel_eof(channel) == 1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main, more than inspired by ssh2.c by Bagder
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t hostaddr = 0;
|
||||
int rc;
|
||||
libssh2_socket_t sock = LIBSSH2_INVALID_SOCKET;
|
||||
struct sockaddr_in sin;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username = NULL;
|
||||
char *password = NULL;
|
||||
size_t bufsiz = 8193;
|
||||
char *buf = NULL;
|
||||
int set_debug_on = 0;
|
||||
unsigned int nfds = 1;
|
||||
LIBSSH2_POLLFD *fds = NULL;
|
||||
|
||||
/* Chan List struct */
|
||||
struct chan_X11_list *current_node = NULL;
|
||||
|
||||
/* Struct winsize for term size */
|
||||
struct winsize w_size;
|
||||
struct winsize w_size_bck;
|
||||
|
||||
/* For select on stdin */
|
||||
fd_set set;
|
||||
struct timeval timeval_out;
|
||||
timeval_out.tv_sec = 0;
|
||||
timeval_out.tv_usec = 10;
|
||||
|
||||
if(argc > 3) {
|
||||
hostaddr = inet_addr(argv[1]);
|
||||
username = argv[2];
|
||||
password = argv[3];
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Usage: %s destination username password",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(argc > 4) {
|
||||
set_debug_on = 1;
|
||||
fprintf(stderr, "DEBUG is ON: %d\n", set_debug_on);
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sock == LIBSSH2_INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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))) {
|
||||
fprintf(stderr, "Failed to established connection.\n");
|
||||
return -1;
|
||||
}
|
||||
/* Open a session */
|
||||
session = libssh2_session_init();
|
||||
rc = libssh2_session_handshake(session, sock);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failed Start the SSH session\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(set_debug_on == 1)
|
||||
libssh2_trace(session, LIBSSH2_TRACE_CONN);
|
||||
|
||||
/* Set X11 Callback */
|
||||
libssh2_session_callback_set2(session, LIBSSH2_CALLBACK_X11,
|
||||
(libssh2_cb_generic *)x11_callback);
|
||||
|
||||
/* Authenticate via password */
|
||||
rc = libssh2_userauth_password(session, username, password);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failed to authenticate\n");
|
||||
session_shutdown(session);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open a channel */
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if(!channel) {
|
||||
fprintf(stderr, "Failed to open a new channel\n");
|
||||
session_shutdown(session);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Request a PTY */
|
||||
rc = libssh2_channel_request_pty(channel, "xterm");
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failed to request a pty\n");
|
||||
session_shutdown(session);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Request X11 */
|
||||
rc = libssh2_channel_x11_req(channel, 0);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failed to request X11 forwarding\n");
|
||||
session_shutdown(session);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Request a shell */
|
||||
rc = libssh2_channel_shell(channel);
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failed to open a shell\n");
|
||||
session_shutdown(session);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = _raw_mode();
|
||||
if(rc) {
|
||||
fprintf(stderr, "Failed to entered in raw mode\n");
|
||||
session_shutdown(session);
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&w_size, 0, sizeof(struct winsize));
|
||||
memset(&w_size_bck, 0, sizeof(struct winsize));
|
||||
|
||||
for(;;) {
|
||||
|
||||
FD_ZERO(&set);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
FD_SET(fileno(stdin), &set);
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* Search if a resize pty has to be send */
|
||||
ioctl(fileno(stdin), TIOCGWINSZ, &w_size);
|
||||
if((w_size.ws_row != w_size_bck.ws_row) ||
|
||||
(w_size.ws_col != w_size_bck.ws_col)) {
|
||||
w_size_bck = w_size;
|
||||
|
||||
libssh2_channel_request_pty_size(channel,
|
||||
w_size.ws_col,
|
||||
w_size.ws_row);
|
||||
}
|
||||
|
||||
buf = calloc(bufsiz, sizeof(char));
|
||||
if(!buf)
|
||||
break;
|
||||
|
||||
fds = malloc(sizeof(LIBSSH2_POLLFD));
|
||||
if(!fds) {
|
||||
free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
|
||||
fds[0].fd.channel = channel;
|
||||
fds[0].events = LIBSSH2_POLLFD_POLLIN;
|
||||
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
|
||||
|
||||
rc = libssh2_poll(fds, nfds, 0);
|
||||
if(rc > 0) {
|
||||
libssh2_channel_read(channel, buf, sizeof(buf));
|
||||
fprintf(stdout, "%s", buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Looping on X clients */
|
||||
if(gp_x11_chan) {
|
||||
current_node = gp_x11_chan;
|
||||
}
|
||||
else
|
||||
current_node = NULL;
|
||||
|
||||
while(current_node) {
|
||||
struct chan_X11_list *next_node;
|
||||
rc = x11_send_receive(current_node->chan, current_node->sock);
|
||||
next_node = current_node->next;
|
||||
if(rc == -1) {
|
||||
shutdown(current_node->sock, SHUT_RDWR);
|
||||
LIBSSH2_SOCKET_CLOSE(current_node->sock);
|
||||
remove_node(current_node);
|
||||
}
|
||||
|
||||
current_node = next_node;
|
||||
}
|
||||
|
||||
rc = select((int)(fileno(stdin) + 1), &set, NULL, NULL, &timeval_out);
|
||||
if(rc > 0) {
|
||||
ssize_t nread;
|
||||
|
||||
/* Data in stdin */
|
||||
nread = read(fileno(stdin), buf, 1);
|
||||
if(nread > 0)
|
||||
libssh2_channel_write(channel, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
free(fds);
|
||||
free(buf);
|
||||
|
||||
if(libssh2_channel_eof(channel) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(channel) {
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
}
|
||||
_normal_mode();
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(void)
|
||||
{
|
||||
fprintf(stderr, "Sorry, this platform is not supported.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SYS_UN_H */
|
||||
Reference in New Issue
Block a user