-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathssh_stuff.h
159 lines (149 loc) · 4 KB
/
ssh_stuff.h
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
#ifndef SSH_STUFF_H
#define SSH_STUFF_H
#include <string>
#include <string.h>
#include "send.h"
using namespace std;
extern pthread_mutex_t *mx;
int verify_knownhost(ssh_session session){
enum ssh_known_hosts_e state;
unsigned char *hash = NULL;
ssh_key srv_pubkey = NULL;
size_t hlen;
char buf[10];
char *hexa;
char *p;
int cmp;
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_SHA1, &hash, &hlen);
ssh_key_free(srv_pubkey);
if (rc < 0) {
return -1;
}
state = ssh_session_is_known_server(session);
string response;
switch (state) {
case SSH_KNOWN_HOSTS_OK:
/* OK */
break;
case SSH_KNOWN_HOSTS_CHANGED:
response.clear();
response += "\nHost key for server changed: it is now:\n";
response += "For security reasons, connection will be stopped";
send(response);
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
ssh_clean_pubkey_hash(&hash);
return -1;
case SSH_KNOWN_HOSTS_OTHER:
response.clear();
response += "\nThe host key for this server was not found but an other type of key exists.\n";
response += "An attacker might change the default server key to confuse your client into thinking the key does not exist";
send(response);
ssh_clean_pubkey_hash(&hash);
return -1;
case SSH_KNOWN_HOSTS_NOT_FOUND:
response.clear();
response += "\nCould not find known host file.\n";
response += "If you accept the host key here, the file will be automatically created.";
send(response);
/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
case SSH_KNOWN_HOSTS_UNKNOWN:
hexa = ssh_get_hexa(hash, hlen);
response.clear();
response += "\nThe server is unknown. Adding to the list of trusted host keys.";
response += "Public key hash: ";
response += hexa;
send(response);
ssh_string_free_char(hexa);
ssh_clean_pubkey_hash(&hash);
rc = ssh_session_update_known_hosts(session);
if (rc < 0) {
response.clear();
response += "\nError ";
response += strerror(errno);
send(response);
return -1;
}
break;
case SSH_KNOWN_HOSTS_ERROR:
response.clear();
response += "\nError: ";
response += ssh_get_error(session);
send(response);
ssh_clean_pubkey_hash(&hash);
return -1;
}
ssh_clean_pubkey_hash(&hash);
return 0;
}
void connectSession(ssh_session session, string ip){
ssh_options_set(session, SSH_OPTIONS_HOST, ip.c_str());
if(ssh_connect(session) != SSH_OK){
string response;
response += '\n';
response += ip;
response += ": error connecting";
send(response);
return;
}
if(verify_knownhost(session) < 0){
ssh_disconnect(session);
return;
}
if(ssh_userauth_password(session, "admin", "adminpass") != SSH_AUTH_SUCCESS){
string response;
response += "\nauth error\n";
response += ip;
response += ": ";
response += ssh_get_error(session);
send(response);
ssh_disconnect(session);
}
}
int sshCommand(ssh_session session, const char * command){
ssh_channel channel = ssh_channel_new(session);
int rc;
if(channel == NULL)
return SSH_ERROR;
if((rc = ssh_channel_open_session(channel)) != SSH_OK){
ssh_channel_free(channel);
return rc;
}
if((rc = ssh_channel_request_exec(channel, command)) != SSH_OK){
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
char buffer[256];
int nBytes;
pthread_mutex_lock(mx);
for(int i = 0; i < 2; i++){
nBytes = 1;
write(1, &nBytes, sizeof(int));
write(1, "\n", sizeof(char));
while((nBytes = ssh_channel_read(channel, buffer, 256 * sizeof(char), i)) > 0){
write(1, &nBytes, sizeof(int));
if(write(1, buffer, nBytes * sizeof(char)) != nBytes){
ssh_channel_close(channel);
ssh_channel_free(channel);
pthread_mutex_unlock(mx);
return SSH_ERROR;
}
}
}
pthread_mutex_unlock(mx);
if(nBytes < 0){
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_OK;
}
#endif