1
/* Copyright (C) The libssh2 project and its contributors.
3
* Sample showing how to do SSH2 connect using ssh-agent.
5
* The sample code has default values for host name, user name:
7
* $ ./ssh2_agent host user
9
* SPDX-License-Identifier: BSD-3-Clause
12
#include "libssh2_setup.h"
15
#ifdef HAVE_SYS_SOCKET_H
16
#include <sys/socket.h>
21
#ifdef HAVE_NETINET_IN_H
22
#include <netinet/in.h>
24
#ifdef HAVE_ARPA_INET_H
31
static const char *username = "username";
33
int main(int argc, char *argv[])
36
libssh2_socket_t sock;
38
struct sockaddr_in sin;
39
const char *fingerprint;
42
LIBSSH2_SESSION *session = NULL;
43
LIBSSH2_CHANNEL *channel;
44
LIBSSH2_AGENT *agent = NULL;
45
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
50
rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
52
fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
58
hostaddr = inet_addr(argv[1]);
61
hostaddr = htonl(0x7F000001);
69
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
73
/* Ultra basic "connect to port 22 on localhost". Your code is
74
* responsible for creating the socket establishing the connection
76
sock = socket(AF_INET, SOCK_STREAM, 0);
77
if(sock == LIBSSH2_INVALID_SOCKET) {
78
fprintf(stderr, "failed to create socket.\n");
83
sin.sin_family = AF_INET;
84
sin.sin_port = htons(22);
85
sin.sin_addr.s_addr = hostaddr;
86
if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
87
fprintf(stderr, "failed to connect.\n");
91
/* Create a session instance */
92
session = libssh2_session_init();
94
fprintf(stderr, "Could not initialize SSH session.\n");
98
rc = libssh2_session_handshake(session, sock);
100
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
104
/* At this point we have not yet authenticated. The first thing to do
105
* is check the hostkey's fingerprint against our known hosts Your app
106
* may have it hard coded, may go to a file, may present it to the
107
* user, that's your call
109
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
110
fprintf(stderr, "Fingerprint: ");
111
for(i = 0; i < 20; i++) {
112
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
114
fprintf(stderr, "\n");
116
/* check what authentication methods are available */
117
userauthlist = libssh2_userauth_list(session, username,
118
(unsigned int)strlen(username));
120
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
121
if(!strstr(userauthlist, "publickey")) {
122
fprintf(stderr, "'publickey' authentication is not supported\n");
126
/* Connect to the ssh-agent */
127
agent = libssh2_agent_init(session);
129
fprintf(stderr, "Failure initializing ssh-agent support\n");
133
if(libssh2_agent_connect(agent)) {
134
fprintf(stderr, "Failure connecting to ssh-agent\n");
138
if(libssh2_agent_list_identities(agent)) {
139
fprintf(stderr, "Failure requesting identities to ssh-agent\n");
144
rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
149
"Failure obtaining identity from ssh-agent support\n");
153
if(libssh2_agent_userauth(agent, username, identity)) {
154
fprintf(stderr, "Authentication with username %s and "
155
"public key %s failed.\n",
156
username, identity->comment);
159
fprintf(stderr, "Authentication with username %s and "
160
"public key %s succeeded.\n",
161
username, identity->comment);
164
prev_identity = identity;
167
fprintf(stderr, "Could not continue authentication\n");
172
/* We're authenticated now. */
174
/* Request a shell */
175
channel = libssh2_channel_open_session(session);
177
fprintf(stderr, "Unable to open a session\n");
181
/* Some environment variables may be set,
182
* It's up to the server which ones it'll allow though
184
libssh2_channel_setenv(channel, "FOO", "bar");
186
/* Request a terminal with 'vanilla' terminal emulation
187
* See /etc/termcap for more options. This is useful when opening
188
* an interactive shell.
190
if(libssh2_channel_request_pty(channel, "vanilla")) {
191
fprintf(stderr, "Failed requesting pty\n");
195
/* Open a SHELL on that pty */
196
if(libssh2_channel_shell(channel)) {
197
fprintf(stderr, "Unable to request shell on allocated pty\n");
201
/* At this point the shell can be interacted with using
202
* libssh2_channel_read()
203
* libssh2_channel_read_stderr()
204
* libssh2_channel_write()
205
* libssh2_channel_write_stderr()
207
* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
208
* If the server send EOF, libssh2_channel_eof() will return non-0
209
* To send EOF to the server use: libssh2_channel_send_eof()
210
* A channel can be closed with: libssh2_channel_close()
211
* A channel can be freed with: libssh2_channel_free()
217
libssh2_channel_free(channel);
221
/* Other channel types are supported via:
223
* libssh2_scp_recv2()
224
* libssh2_channel_direct_tcpip()
230
libssh2_agent_disconnect(agent);
231
libssh2_agent_free(agent);
235
libssh2_session_disconnect(session, "Normal Shutdown");
236
libssh2_session_free(session);
239
if(sock != LIBSSH2_INVALID_SOCKET) {
241
LIBSSH2_SOCKET_CLOSE(sock);
244
fprintf(stderr, "all done\n");