Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <libssh/libssh.h>
- #include <stdlib.h>
- #include <string>
- #include <stdio.h>
- #include <list>
- enum ReturnValues
- {
- no = 0,
- yes = 1,
- na = -1,
- fail = na,
- success = 0,
- done = success
- };
- enum Errors
- {
- errFirst = -100,
- errNotConnected,
- nErrors
- };
- //-----------------------------------------------------------------
- // class SshClient
- //-----------------------------------------------------------------
- struct Buffer
- {
- Buffer() { buffer = 0; bufferLen = 0; resize(1024); memset(buffer, 0, bufferLen); }
- virtual ~Buffer() { free((void*)buffer); }
- int resize(int newSize);
- char* buffer;
- int bufferLen;
- };
- struct ServerResponse
- {
- ServerResponse() { code = 0; }
- int code;
- std::string error;
- Buffer stdout;
- Buffer stderr;
- };
- int connect(const char* host, const char* user, const char* password = 0, int port = 22, int aVerbosity = SSH_LOG_NOLOG);
- struct ServerResponse* execute(const char* command);
- int writeBytes(const char* bytes, int len);
- int readBytes(Buffer* aBuffer, int fromStderr, const char* until = 0);
- int checkResponse(ServerResponse* response);
- ssh_session session;
- ssh_channel channel;
- const char* commandSeparator = "9903373aee394f16a077720cc5f58e80";
- const char* commandSeparatorWithLF = "9903373aee394f16a077720cc5f58e80\n";
- const char* commandSeparatorWithEchoStatus = "echo \"$? 9903373aee394f16a077720cc5f58e80\"";
- int verbosity = SSH_LOG_NOLOG;
- int main(int argc, const char* argv[])
- {
- int res = success;
- res = connect("some-host", "some-user");
- if (res)
- return res;
- checkResponse(execute("bash -l"));
- checkResponse(execute("date"));
- checkResponse(execute("pwd -P"));
- checkResponse(execute("pwd -P"));
- checkResponse(execute("pwd -P"));
- checkResponse(execute("cat /etc/passwd"));
- checkResponse(execute("pwd -P"));
- checkResponse(execute("pwd -P"));
- checkResponse(execute("cd /some/dir/with/nodejs/script"));
- checkResponse(execute("npm install"));
- checkResponse(execute("pwd -P")); // channel broken here
- return 0;
- }
- int checkResponse(ServerResponse* response)
- {
- if (!response)
- return fail;
- printf("------\nServer response: Code (%d)\n", response->code);
- printf("Server output: [%s]\n", response->stdout.buffer);
- printf("Server error: [%s]\n", response->stderr.buffer);
- return success;
- }
- //-----------------------------------------------------------------
- // connect
- //-----------------------------------------------------------------
- int connect(const char* host, const char* user, const char* password,
- int port, int aVerbosity)
- {
- int res = SSH_OK;
- // verbosity = SSH_LOG_FUNCTIONS; // aVerbosity
- session = ssh_new();
- if (session == NULL)
- return fail;
- ssh_options_set(session, SSH_OPTIONS_USER, user);
- ssh_options_set(session, SSH_OPTIONS_HOST, host);
- ssh_options_set(session, SSH_OPTIONS_PORT, &port);
- ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
- res = ssh_connect(session);
- if (res != SSH_OK) return fail;
- if (password)
- res= ssh_userauth_password(session, NULL, password);
- else
- res= ssh_userauth_publickey_auto(session, NULL, NULL);
- if (res != SSH_OK) return fail;
- Buffer tmpBuf;
- channel = ssh_channel_new(session);
- if (channel == NULL) return fail;
- res = ssh_channel_open_session(channel);
- if (res != SSH_OK) return fail;
- res = ssh_channel_request_shell(channel);
- if (res != SSH_OK) return fail;
- writeBytes("bash -l", strlen("bash -l"));
- writeBytes("\n", 1);
- writeBytes(commandSeparatorWithEchoStatus, strlen(commandSeparatorWithEchoStatus));
- writeBytes("\n", 1);
- readBytes(&tmpBuf, 0, commandSeparatorWithLF);
- if (verbosity != SSH_LOG_NOLOG) printf("Connected to %s@%s:%d\n", user, host, port);
- return success;
- }
- //-----------------------------------------------------------------
- // Buffer::resize
- //-----------------------------------------------------------------
- int Buffer::resize(int newSize)
- {
- if (bufferLen == newSize)
- return 0;
- bufferLen = newSize;
- if (buffer)
- buffer = (char*)realloc(buffer, bufferLen);
- else
- buffer = (char*)malloc(bufferLen);
- buffer[bufferLen-1] = 0;
- return 0;
- }
- //-----------------------------------------------------------------
- // Execute Command
- //-----------------------------------------------------------------
- struct ServerResponse* execute(const char* command)
- {
- int rc = success;
- char statusBuffer[20]; *statusBuffer = 0;
- ServerResponse* res = 0;
- printf("Execute [%s]\n", command);
- if (!command)
- return 0;
- // (1) write command + separator echo which will include the return value
- rc = writeBytes(command, strlen(command));
- if (!rc) rc= writeBytes("\n", 1);
- if (!rc) rc= writeBytes(commandSeparatorWithEchoStatus, strlen(commandSeparatorWithEchoStatus));
- if (!rc) rc= writeBytes("\n", 1);
- res = new ServerResponse;
- if (rc) return 0;
- // (2) read STDOUT until the separator marker + LF
- rc = readBytes(&res->stdout, 0, commandSeparatorWithLF);
- if (rc) return 0;
- // (4) read STDERR *nonblocking*
- rc = readBytes(&res->stderr, 1);
- if (rc) return 0;
- return res;
- }
- //-----------------------------------------------------------------
- // Write Bytes
- //-----------------------------------------------------------------
- int writeBytes(const char* buffer, int len)
- {
- if (!buffer)
- return fail;
- if (!ssh_channel_is_open(channel))
- {
- printf("ERROR: CHANNEL IS CLOSED, trying to REOPEN....\n");
- return errNotConnected;
- }
- int nwritten = ssh_channel_write(channel, buffer, len);
- if (nwritten != len)
- {
- const char* err = ssh_get_error(session);
- if (verbosity != SSH_LOG_NOLOG) fprintf(stderr, "[SshClient] Error: Sending bytes to server failed: '%s'\n", err ? err : "");
- return fail;
- }
- return success;
- }
- //-----------------------------------------------------------------
- // Read Bytes
- //-----------------------------------------------------------------
- int readBytes(Buffer* aBuffer, int fromStderr, const char* until)
- {
- int nbytes = 0;
- if (!aBuffer)
- return fail;
- if (!ssh_channel_is_open(channel))
- {
- printf("ERROR: CHANNEL IS CLOSED, trying to REOPEN....\n");
- return errNotConnected;
- }
- while (ssh_channel_is_open(channel) && !ssh_channel_is_eof(channel))
- {
- if (!fromStderr)
- nbytes = ssh_channel_read(channel, aBuffer->buffer+nbytes, aBuffer->bufferLen-nbytes, fromStderr);
- else
- nbytes = ssh_channel_read_nonblocking(channel, aBuffer->buffer+nbytes, aBuffer->bufferLen-nbytes, fromStderr);
- if (nbytes < 0) return fail;
- // printf("read bytes: [%s]\n", aBuffer->buffer);
- if (!until && nbytes == 0) break;
- if (until && strstr(aBuffer->buffer, until)) break;
- if (aBuffer->bufferLen-nbytes < 10)
- aBuffer->resize(aBuffer->bufferLen*2);
- }
- return success;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement