-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathconnect_ssh.c
More file actions
168 lines (145 loc) · 4.64 KB
/
Copy pathconnect_ssh.c
File metadata and controls
168 lines (145 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* connect_ssh.c
* This file contains an example of how to connect to a
* SSH server using libssh
*/
/*
Copyright 2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include <libssh/libssh.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#ifdef _WIN32
#define strncasecmp _strnicmp
#endif
int verify_knownhost(ssh_session session)
{
enum ssh_known_hosts_e state;
char buf[10];
unsigned char *hash = NULL;
size_t hlen;
ssh_key srv_pubkey;
int rc;
rc = ssh_get_server_publickey(session, &srv_pubkey);
if (rc < 0) {
return -1;
}
rc = ssh_get_publickey_hash(srv_pubkey,
SSH_PUBLICKEY_HASH_SHA256,
&hash,
&hlen);
ssh_key_free(srv_pubkey);
if (rc < 0) {
return -1;
}
state = ssh_session_is_known_server(session);
switch(state) {
case SSH_KNOWN_HOSTS_CHANGED:
fprintf(stderr,"[CLIENT] error: Host key for server changed : server's one is now :\n");
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
// ssh_clean_pubkey_hash(&hash);
// fprintf(stderr,"For security reason, connection will be stopped\n");
printf("[CLIENT] Auto Trust.\n");
rc = ssh_session_update_known_hosts(session);
if (rc != SSH_OK)
{
ssh_clean_pubkey_hash(&hash);
fprintf(stderr, "[CLIENT] error: %s\n", strerror(errno));
return -1;
}
break;
case SSH_KNOWN_HOSTS_OTHER:
fprintf(stderr,"[CLIENT] error: The host key for this server was not found but an other type of key exists.\n");
fprintf(stderr,"[CLIENT] error: An attacker might change the default server key to confuse your client"
"into thinking the key does not exist\n"
"We advise you to rerun the client with -d or -r for more safety.\n");
printf("[CLIENT] Auto Trust.\n");
rc = ssh_session_update_known_hosts(session);
if (rc != SSH_OK)
{
ssh_clean_pubkey_hash(&hash);
fprintf(stderr, "[CLIENT] error: %s\n", strerror(errno));
return -1;
}
break;
case SSH_KNOWN_HOSTS_NOT_FOUND:
fprintf(stderr,"[CLIENT] error: Could not find known host file. If you accept the host key here,\n");
fprintf(stderr,"[CLIENT] error: the file will be automatically created.\n");
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
return -1;
case SSH_SERVER_NOT_KNOWN:
// fprintf(stderr,
// "The server is unknown. Do you trust the host key (yes/no)?\n");
fprintf(stderr, "[CLIENT] error: The server is unknown.\n");
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
printf("[CLIENT] Auto Trust.\n");
rc = ssh_session_update_known_hosts(session);
if (rc != SSH_OK)
{
ssh_clean_pubkey_hash(&hash);
fprintf(stderr, "[CLIENT] error: %s\n", strerror(errno));
return -1;
}
break;
case SSH_KNOWN_HOSTS_ERROR:
ssh_clean_pubkey_hash(&hash);
fprintf(stderr,"[CLIENT] error: %s",ssh_get_error(session));
return -1;
case SSH_KNOWN_HOSTS_OK:
break; /* ok */
}
ssh_clean_pubkey_hash(&hash);
return 0;
}
ssh_session connect_ssh(const char *host, const char *user, int port, int verbosity)
{
ssh_session session;
session = ssh_new();
if (session == NULL)
{
return NULL;
}
if(user != NULL)
{
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0)
{
ssh_free(session);
return NULL;
}
}
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0)
{
ssh_free(session);
return NULL;
}
if (ssh_options_set(session, SSH_OPTIONS_PORT, &port) < 0)
{
ssh_free(session);
return NULL;
}
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
if(ssh_connect(session))
{
fprintf(stderr,"[CLIENT] error: Connection failed : %s\n",ssh_get_error(session));
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
if(verify_knownhost(session)<0)
{
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
return session;
}