10 #include "SimpleSSHClient.h"
22 int SimpleSSHClient::libssh2_init_rc = -1;
25 static int qmutex_mutex_init(
void **priv)
27 QMutex *lock =
new QMutex();
34 static int qmutex_mutex_destroy(
void **lock)
36 delete reinterpret_cast<QMutex*
>(*lock);
40 static int qmutex_mutex_lock(
void **lock)
42 reinterpret_cast<QMutex*
>(*lock)->lock();
46 static int qmutex_mutex_unlock(
void **lock)
48 reinterpret_cast<QMutex*
>(*lock)->unlock();
52 static struct gcry_thread_cbs gcry_threads_qmutex =
53 { GCRY_THREAD_OPTION_USER, NULL,
54 qmutex_mutex_init, qmutex_mutex_destroy,
55 qmutex_mutex_lock, qmutex_mutex_unlock };
61 gcry_control( GCRYCTL_SET_THREAD_CBS, &gcry_threads_qmutex );
63 SimpleSSHClient::libssh2_init_rc = libssh2_init (0);
64 return libssh2_init_rc;
73 const char *password_,
75 const char *sftp_path_)
77 this->username = username_;
78 this->password = password_;
79 this->hostip = hostip_;
80 this->sftp_path = sftp_path_;
88 LIBSSH2_KNOWNHOSTS *nh;
89 unsigned long hostaddr = inet_addr(hostip.c_str());
90 struct sockaddr_in sin;
91 const char *fingerprint;
98 WSAStartup(MAKEWORD(2,0), &wsadata);
101 if (libssh2_init_rc != 0)
103 fprintf (stderr,
"libssh2 initialization failed (%d)\n", libssh2_init_rc);
111 sock = socket(AF_INET, SOCK_STREAM, 0);
113 sin.sin_family = AF_INET;
114 sin.sin_port = htons(22);
115 sin.sin_addr.s_addr = hostaddr;
116 if (connect(sock, (
struct sockaddr*)(&sin),
sizeof(
struct sockaddr_in)) != 0)
118 fprintf(stderr,
"failed to connect!\n");
123 session = libssh2_session_init();
124 if (!session)
return -1;
129 while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
132 fprintf(stderr,
"Failure establishing SSH session: %d\n", rc);
136 nh = libssh2_knownhost_init(session);
145 libssh2_knownhost_readfile(nh,
"known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
148 libssh2_knownhost_writefile(nh,
"dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
149 fingerprint = libssh2_session_hostkey(session, &len, &type);
153 struct libssh2_knownhost *host;
154 #if LIBSSH2_VERSION_NUM >= 0x010206
156 int check = libssh2_knownhost_checkp(nh, hostip.c_str(), 22,
158 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
159 LIBSSH2_KNOWNHOST_KEYENC_RAW,
163 int check = libssh2_knownhost_check(nh, hostip.c_str(),
165 LIBSSH2_KNOWNHOST_TYPE_PLAIN|
166 LIBSSH2_KNOWNHOST_KEYENC_RAW,
169 fprintf(stderr,
"Host check: %d, key: %s\n", check,
170 (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
183 libssh2_knownhost_free(nh);
185 if ( strlen(password.c_str()) != 0 )
188 while ((rc = libssh2_userauth_password(session, username.c_str(),
190 == LIBSSH2_ERROR_EAGAIN);
192 fprintf(stderr,
"Authentication by password failed.\n");
201 while ((rc = libssh2_userauth_publickey_fromfile(session, username.c_str(),
206 password.c_str())) ==
207 LIBSSH2_ERROR_EAGAIN);
210 fprintf(stderr,
"\tAuthentication by public key failed\n");
217 fprintf(stderr,
"Before sftp_init session.\n");
218 sftp_session = libssh2_sftp_init(session);
221 fprintf(stderr,
"Unable to init sftp session.\n");
225 fprintf(stderr,
"sftp_init session ok.\n");
228 libssh2_trace(session, ~0 );
238 libssh2_sftp_shutdown(sftp_session);
243 libssh2_session_disconnect(session,
244 "Normal Shutdown, Thank you for playing");
246 libssh2_session_free(session);
260 struct stat fileinfo;
261 char mem[1024 * 100];
267 LIBSSH2_CHANNEL *channel;
268 LIBSSH2_SFTP_HANDLE *sftp_handle;
269 LIBSSH2_SFTP_ATTRIBUTES attrs;
270 bool isModified =
true;
273 string temp = localncl;
274 found = temp.find_last_of(
"/\\");
275 string nclfile = temp.substr(found+1);
277 sftp_file = destpath + string(
"/") + nclfile;
282 WSAStartup(MAKEWORD(2,0), &wsadata);
291 local = fopen(localncl,
"rb");
294 fprintf(stderr,
"Can't open local file %s\n", localncl);
299 stat(localncl, &fileinfo);
301 libssh2_session_set_blocking(session, 1);
303 rc = libssh2_sftp_stat(sftp_session, sftp_file.c_str(), &attrs);
307 if(attrs.mtime < fileinfo.st_mtime)
359 channel = libssh2_scp_send(session, sftp_file.c_str(), fileinfo.st_mode & 0777,
360 (
unsigned long)fileinfo.st_size);
365 int err = libssh2_session_last_error(session, &errmsg, &errlen, 0);
367 fprintf(stderr,
"Unable to open a session: (%d) %s\n", err, errmsg);
371 fprintf(stderr,
"SCP session waiting to send file\n");
373 nread = fread(mem, 1,
sizeof(mem), local);
382 rc = libssh2_channel_write(channel, ptr, nread);
385 fprintf(stderr,
"ERROR %d\n", rc);
397 fprintf(stderr,
"Sending EOF\n");
398 libssh2_channel_send_eof(channel);
401 fprintf(stderr,
"Waiting for EOF\n");
402 libssh2_channel_wait_eof(channel);
405 fprintf(stderr,
"Waiting for channel to close\n");
406 libssh2_channel_wait_closed(channel);
409 libssh2_channel_free(channel);
414 rc = libssh2_sftp_stat(sftp_session, sftp_file.c_str(), &attrs);
417 fprintf(stderr,
"I could not check if the file was copied correctly.\n");
421 fprintf(stderr,
"Modification time is: %s.\n", ctime((
const time_t*)&attrs.mtime));
424 attrs.mtime = fileinfo.st_mtime;
425 rc = libssh2_sftp_setstat(sftp_session, sftp_file.c_str(), &attrs);
428 rc = libssh2_sftp_stat(sftp_session, sftp_file.c_str(), &attrs);
431 fprintf(stderr,
"I could not check if the mtime file was copied correctly.\n");
435 fprintf(stderr,
"Updated modification time is: %s", ctime((
const time_t*)&attrs.mtime));
440 fprintf(stderr,
"I will not copy the file %s, because it was not modified.\n", sftp_file.c_str());
453 LIBSSH2_CHANNEL *channel;
456 char *exitsignal=(
char *)
"none";
462 channel = libssh2_channel_open_session(session);
464 if( channel == NULL )
466 fprintf(stderr,
"Error 1\n");
471 libssh2_channel_set_blocking(channel, 1);
473 while( (rc = libssh2_channel_exec(channel, command)) == LIBSSH2_ERROR_EAGAIN )
475 waitsocket(sock, session);
480 fprintf(stderr,
"Error 2\n");
491 rc = libssh2_channel_read( channel, buffer,
sizeof(buffer) );
497 fprintf(stderr,
"We read:\n");
498 for( i=0; i < rc; ++i )
499 fputc( buffer[i], stderr);
500 fprintf(stderr,
"\n");
503 fprintf(stderr,
"libssh2_channel_read returned %d\n", rc);
510 if( rc == LIBSSH2_ERROR_EAGAIN )
512 waitsocket(sock, session);
520 while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
521 waitsocket(sock, session);
525 exitcode = libssh2_channel_get_exit_status( channel );
533 printf(
"\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
535 printf(
"\nExit channel was ok!\n");
540 int SimpleSSHClient::waitsocket(
int socket_fd, LIBSSH2_SESSION *session)
542 struct timeval timeout;
545 fd_set *writefd = NULL;
546 fd_set *readfd = NULL;
554 FD_SET(socket_fd, &fd);
557 dir = libssh2_session_block_directions(session);
559 if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
562 if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
565 rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);