Archeus 0.0.0
A C library and game engine that focuses on documentation
Loading...
Searching...
No Matches
ssh.c File Reference
#include "arc/networking/ssh.h"
#include "arc/std/errno.h"
#include "arc/std/string.h"
#include <stdint.h>
#include <stdlib.h>
#include <libssh/libssh.h>

Go to the source code of this file.

Data Structures

struct  ARC_Ssh
 

Functions

int verify_knownhost (ssh_session session)
 
void ARC_Ssh_Create (ARC_Ssh **ssh, char *host, char *user, char *password)
 creates ARC_Ssh type
 
void ARC_Ssh_Destroy (ARC_Ssh *ssh)
 destroyes ARC_Ssh type
 
void ARC_Ssh_RunInSession (ARC_Ssh *ssh, ARC_Ssh_SessionFn sessionFn)
 runs a callback function within a ssh session
 
void ARC_Ssh_ExecStrInNewSession (ARC_Ssh *ssh, char *command)
 
ARC_StringARC_Ssh_ExecStrInNewSessionAndGetResponse (ARC_Ssh *ssh, char *command)
 

Function Documentation

◆ ARC_Ssh_Create()

void ARC_Ssh_Create ( ARC_Ssh ** ssh,
char * host,
char * user,
char * password )

creates ARC_Ssh type

Parameters
sshARC_Ssh to create

Definition at line 94 of file ssh.c.

94 {
95 *ssh = (ARC_Ssh *)malloc(sizeof(ARC_Ssh));
96
97 (*ssh)->session = ssh_new();
98 if((*ssh)->session == NULL){
100 ARC_DEBUG_ERR("ARC_Ssh_Create(ssh), ssh session could not be created\n");
101 free(*ssh);
102 *ssh = NULL;
103 return;
104 }
105
106 if(host != NULL){
107 ssh_options_set((*ssh)->session, SSH_OPTIONS_HOST, host);
108 }
109
110 if(user != NULL){
111 ssh_options_set((*ssh)->session, SSH_OPTIONS_USER, user);
112 }
113
114 int32_t returnCode = ssh_connect((*ssh)->session);
115 if(returnCode != SSH_OK){
117 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_Create(ssh), ssh failed to connect to localhost: %s\n", ssh_get_error((*ssh)->session));
118 ssh_free((*ssh)->session);
119 free(*ssh);
120 *ssh = NULL;
121 return;
122 }
123
124 if(verify_knownhost((*ssh)->session) < 0){
126 ARC_DEBUG_ERR("ARC_Ssh_Create(ssh), ssh failed to verify knownhost\n");
127 ssh_disconnect((*ssh)->session);
128 ssh_free((*ssh)->session);
129 free(*ssh);
130 *ssh = NULL;
131 }
132
133 //if no password is provided try to connect with a public key
134 if(password == NULL){
135 returnCode = ssh_userauth_publickey_auto((*ssh)->session, NULL, NULL);
136 if(returnCode != SSH_AUTH_SUCCESS){
138 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_Create(ssh), ssh failed to authenticate with password: %s\n", ssh_get_error((*ssh)->session));
139 ssh_disconnect((*ssh)->session);
140 ssh_free((*ssh)->session);
141 free(*ssh);
142 *ssh = NULL;
143 }
144
145 ssh_send_ignore((*ssh)->session, "mpv https://youtu.be/1P5BSm_oFJg --input-ipc-server=/tmp/mpvsocket --no-terminal & disown");
146
147 return;
148 }
149
150 //try connecting with password
151 returnCode = ssh_userauth_password((*ssh)->session, NULL, password);
152 if(returnCode != SSH_AUTH_SUCCESS){
154 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_Create(ssh), ssh failed to authenticate with password: %s\n", ssh_get_error((*ssh)->session));
155 ssh_disconnect((*ssh)->session);
156 ssh_free((*ssh)->session);
157 free(*ssh);
158 *ssh = NULL;
159 }
160}
#define ARC_ERRNO_CONNECTION
Definition errno.h:12
int32_t arc_errno
Definition errno.c:5
#define ARC_ERRNO_NULL
Definition errno.h:6
int verify_knownhost(ssh_session session)
Definition ssh.c:15
Definition ssh.c:11
ssh_session session
Definition ssh.c:12

References arc_errno, ARC_ERRNO_CONNECTION, ARC_ERRNO_NULL, ARC_Ssh::session, and verify_knownhost().

◆ ARC_Ssh_Destroy()

void ARC_Ssh_Destroy ( ARC_Ssh * ssh)

destroyes ARC_Ssh type

Parameters
sshARC_Ssh to destroy

Definition at line 162 of file ssh.c.

162 {
163 if(ssh == NULL){
164 return;
165 }
166
167 ssh_disconnect(ssh->session);
168 ssh_free(ssh->session);
169 free(ssh);
170}

References ARC_Ssh::session.

◆ ARC_Ssh_ExecStrInNewSession()

void ARC_Ssh_ExecStrInNewSession ( ARC_Ssh * ssh,
char * command )

Definition at line 199 of file ssh.c.

199 {
200 ssh_channel channel;
201 channel = ssh_channel_new(ssh->session);
202 if(channel == NULL){
204 ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to create channel\n");
205 return;
206 }
207
208 int32_t returnCode = ssh_channel_open_session(channel);
209 if(returnCode != SSH_OK){
210 ssh_channel_free(channel);
212 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to open session with return code: %d\n", returnCode);
213 return;
214 }
215
216 returnCode = ssh_channel_request_exec(channel, command);
217 if(returnCode != SSH_OK){
219 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed when executing command with error code: %d\n", returnCode);
220 }
221
222 ssh_channel_send_eof(channel);
223 ssh_channel_close(channel);
224 ssh_channel_free(channel);
225}
#define ARC_ERRNO_DATA
Definition errno.h:7

References arc_errno, ARC_ERRNO_CONNECTION, ARC_ERRNO_DATA, ARC_ERRNO_NULL, and ARC_Ssh::session.

◆ ARC_Ssh_ExecStrInNewSessionAndGetResponse()

ARC_String * ARC_Ssh_ExecStrInNewSessionAndGetResponse ( ARC_Ssh * ssh,
char * command )

Definition at line 227 of file ssh.c.

227 {
228 ssh_channel channel;
229 channel = ssh_channel_new(ssh->session);
230 if(channel == NULL){
232 ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to create channel\n");
233 return NULL;
234 }
235
236 int32_t returnCode = ssh_channel_open_session(channel);
237 if(returnCode != SSH_OK){
238 ssh_channel_free(channel);
240 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to open session with return code: %d\n", returnCode);
241 return NULL;
242 }
243
244 returnCode = ssh_channel_request_exec(channel, command);
245 if(returnCode != SSH_OK){
246 ssh_channel_close(channel);
247 ssh_channel_free(channel);
249 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed when executing command with error code: %d\n", returnCode);
250 return NULL;
251 }
252
253 //this is taken from https://api.libssh.org/master/libssh_tutor_command.html
254 char buffer[256];
255 int32_t bytesSize;
256
257 ARC_String *returnString = NULL;
258
259 bytesSize = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
260 while(bytesSize > 0){
261 if(returnString == NULL){
262 ARC_String_Create(&returnString, buffer, bytesSize);
263
264 bytesSize = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
265 continue;
266 }
267
268 ARC_String_AppendCString(&returnString, (const char *)buffer, bytesSize);
269
270 bytesSize = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
271 }
272
273 if(bytesSize < 0){
274 ssh_channel_close(channel);
275 ssh_channel_free(channel);
277 ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed when reading bytes from channel\n");
278
279 if(returnString != NULL){
280 ARC_String_Destroy(returnString);
281 }
282
283 return NULL;
284 }
285
286 ssh_channel_send_eof(channel);
287 ssh_channel_close(channel);
288 ssh_channel_free(channel);
289
290 return returnString;
291}
void ARC_String_AppendCString(ARC_String **string, const char *cstring, uint64_t length)
appends to an ARC_String with an ARC_String
Definition string.c:130
void ARC_String_Create(ARC_String **string, char *data, uint64_t length)
creates ARC_String type
Definition string.c:9
void ARC_String_Destroy(ARC_String *string)
destroys ARC_String type
Definition string.c:52
substring position within a string
Definition string.h:14

References arc_errno, ARC_ERRNO_CONNECTION, ARC_ERRNO_DATA, ARC_ERRNO_NULL, ARC_String_AppendCString(), ARC_String_Create(), ARC_String_Destroy(), and ARC_Ssh::session.

◆ ARC_Ssh_RunInSession()

void ARC_Ssh_RunInSession ( ARC_Ssh * ssh,
ARC_Ssh_SessionFn sessionFn )

runs a callback function within a ssh session

Parameters
sshARC_Ssh to create and run function in ssh session
sessionFNcallback to run in a ssh session

Definition at line 172 of file ssh.c.

172 {
173 ssh_channel channel;
174
175 channel = ssh_channel_new(ssh->session);
176 if(channel == NULL){
178 ARC_DEBUG_ERR("ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to create channel\n");
179 return;
180 }
181
182 int32_t returnCode = ssh_channel_open_session(channel);
183 if(returnCode != SSH_OK){
184 ssh_channel_free(channel);
186 ARC_DEBUG_LOG(arc_errno, "ARC_Ssh_RunInSession(ssh, sessionFn), ssh failed to open session with return code: %d\n", returnCode);
187 return;
188 }
189
190 // sessionFn(ssh, );
191 returnCode = ssh_channel_request_exec(channel, "export DISPLAY=:0 ; volume --inc");
192 printf("return code: %d\n", returnCode);
193
194 ssh_channel_send_eof(channel);
195 ssh_channel_close(channel);
196 ssh_channel_free(channel);
197}

References arc_errno, ARC_ERRNO_CONNECTION, ARC_ERRNO_NULL, and ARC_Ssh::session.

◆ verify_knownhost()

int verify_knownhost ( ssh_session session)

Definition at line 15 of file ssh.c.

15 {
16 enum ssh_known_hosts_e state;
17 unsigned char *hash = NULL;
18 ssh_key srv_pubkey = NULL;
19 size_t hlen;
20 char buf[10];
21 char *hexa;
22 char *p;
23 int cmp;
24 int rc;
25
26 rc = ssh_get_server_publickey(session, &srv_pubkey);
27 if(rc < 0){
28 return -1;
29 }
30
31 rc = ssh_get_publickey_hash(srv_pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen);
32 ssh_key_free(srv_pubkey);
33 if(rc < 0){
34 return -1;
35 }
36
37 state = ssh_session_is_known_server(session);
38 switch(state){
39 case SSH_KNOWN_HOSTS_OK:
40 /* OK */
41 break;
42
43 case SSH_KNOWN_HOSTS_CHANGED:
44 fprintf(stderr, "Host key for server changed: it is now:\n");
45 //ssh_print_hexa("Public key hash", hash, hlen);
46 fprintf(stderr, "For security reasons, connection will be stopped\n");
47 ssh_clean_pubkey_hash(&hash);
48 return -1;
49
50 case SSH_KNOWN_HOSTS_OTHER:
51 fprintf(stderr, "The host key for this server was not found but an other type of key exists.\n");
52 fprintf(stderr, "An attacker might change the default server key to confuse your client into thinking the key does not exist\n");
53 ssh_clean_pubkey_hash(&hash);
54 return -1;
55
56 case SSH_KNOWN_HOSTS_NOT_FOUND:
57 fprintf(stderr, "Could not find known host file.\n");
58 fprintf(stderr, "If you accept the host key here, the file will be automatically created.\n");
59 /* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
60
61 case SSH_KNOWN_HOSTS_UNKNOWN:
62 hexa = ssh_get_hexa(hash, hlen);
63 fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
64 fprintf(stderr, "Public key hash: %s\n", hexa);
65 ssh_string_free_char(hexa);
66 ssh_clean_pubkey_hash(&hash);
67 p = fgets(buf, sizeof(buf), stdin);
68 if(p == NULL){
69 return -1;
70 }
71
72 cmp = strncasecmp(buf, "yes", 3);
73 if(cmp != 0){
74 return -1;
75 }
76
77 rc = ssh_session_update_known_hosts(session);
78 if(rc < 0){
79 fprintf(stderr, "Error %s\n", strerror(errno));
80 return -1;
81 }
82 break;
83
84 case SSH_KNOWN_HOSTS_ERROR:
85 fprintf(stderr, "Error %s", ssh_get_error(session));
86 ssh_clean_pubkey_hash(&hash);
87 return -1;
88 }
89
90 ssh_clean_pubkey_hash(&hash);
91 return 0;
92}

Referenced by ARC_Ssh_Create().