Advertisement
pfid12

Untitled

May 8th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.01 KB | None | 0 0
  1.     #include <libssh/libssh.h>
  2.     #include <stdlib.h>
  3.     #include <string>
  4.     #include <stdio.h>
  5.     #include <list>
  6.  
  7.     enum ReturnValues
  8.     {
  9.         no = 0,
  10.         yes = 1,
  11.         na = -1,
  12.         fail = na,
  13.         success = 0,
  14.         done = success
  15.     };
  16.  
  17.     enum Errors
  18.     {
  19.         errFirst = -100,
  20.  
  21.         errNotConnected,
  22.  
  23.         nErrors
  24.     };
  25.  
  26.     //-----------------------------------------------------------------
  27.     // class SshClient
  28.     //-----------------------------------------------------------------
  29.  
  30.     struct Buffer
  31.     {
  32.         Buffer() { buffer = 0; bufferLen = 0; resize(1024); memset(buffer, 0, bufferLen); }
  33.         virtual ~Buffer() { free((void*)buffer); }
  34.         int resize(int newSize);
  35.  
  36.         char* buffer;
  37.         int bufferLen;
  38.     };
  39.  
  40.     struct ServerResponse
  41.     {
  42.         ServerResponse() { code = 0; }
  43.         int code;
  44.         std::string error;
  45.         Buffer stdout;
  46.         Buffer stderr;
  47.     };
  48.  
  49.     int connect(const char* host, const char* user, const char* password = 0, int port = 22, int aVerbosity = SSH_LOG_NOLOG);
  50.     struct ServerResponse* execute(const char* command);
  51.     int writeBytes(const char* bytes, int len);
  52.     int readBytes(Buffer* aBuffer, int fromStderr, const char* until = 0);
  53.     int checkResponse(ServerResponse* response);
  54.  
  55.     ssh_session session;
  56.     ssh_channel channel;
  57.            
  58.     const char* commandSeparator = "9903373aee394f16a077720cc5f58e80";
  59.     const char* commandSeparatorWithLF = "9903373aee394f16a077720cc5f58e80\n";
  60.     const char* commandSeparatorWithEchoStatus = "echo \"$? 9903373aee394f16a077720cc5f58e80\"";
  61.     int verbosity = SSH_LOG_NOLOG;
  62.  
  63.     int main(int argc, const char* argv[])
  64.     {
  65.         int res = success;
  66.  
  67.         res = connect("some-host", "some-user");
  68.  
  69.         if (res)
  70.             return res;
  71.  
  72.         checkResponse(execute("bash -l")); 
  73.         checkResponse(execute("date"));
  74.         checkResponse(execute("pwd -P"));  
  75.         checkResponse(execute("pwd -P"));  
  76.         checkResponse(execute("pwd -P"));  
  77.         checkResponse(execute("cat /etc/passwd")); 
  78.         checkResponse(execute("pwd -P"));  
  79.         checkResponse(execute("pwd -P"));  
  80.         checkResponse(execute("cd /some/dir/with/nodejs/script")); 
  81.         checkResponse(execute("npm install")); 
  82.         checkResponse(execute("pwd -P"));     // channel broken here
  83.        
  84.         return 0;
  85.     }
  86.  
  87.     int checkResponse(ServerResponse* response)
  88.     {
  89.         if (!response)
  90.             return fail;
  91.  
  92.         printf("------\nServer response: Code (%d)\n",  response->code);
  93.         printf("Server output: [%s]\n", response->stdout.buffer);
  94.         printf("Server error: [%s]\n",  response->stderr.buffer);
  95.  
  96.         return success;
  97.     }
  98.  
  99.     //-----------------------------------------------------------------
  100.     // connect
  101.     //-----------------------------------------------------------------
  102.  
  103.     int connect(const char* host, const char* user, const char* password,
  104.                     int port, int aVerbosity)
  105.     {
  106.         int res = SSH_OK;
  107.        
  108.         // verbosity = SSH_LOG_FUNCTIONS; // aVerbosity
  109.  
  110.         session = ssh_new();
  111.        
  112.         if (session == NULL)
  113.             return fail;
  114.  
  115.         ssh_options_set(session, SSH_OPTIONS_USER, user);
  116.         ssh_options_set(session, SSH_OPTIONS_HOST, host);
  117.         ssh_options_set(session, SSH_OPTIONS_PORT, &port);
  118.         ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
  119.  
  120.         res = ssh_connect(session);
  121.  
  122.         if (res != SSH_OK) return fail;
  123.  
  124.         if (password)
  125.             res= ssh_userauth_password(session, NULL, password);
  126.         else
  127.             res= ssh_userauth_publickey_auto(session, NULL, NULL);
  128.  
  129.         if (res != SSH_OK) return fail;
  130.  
  131.         Buffer tmpBuf;
  132.  
  133.         channel = ssh_channel_new(session);
  134.  
  135.         if (channel == NULL) return fail;
  136.  
  137.         res = ssh_channel_open_session(channel);
  138.  
  139.         if (res != SSH_OK) return fail;
  140.  
  141.         res = ssh_channel_request_shell(channel);
  142.  
  143.         if (res != SSH_OK) return fail;
  144.  
  145.         writeBytes("bash -l", strlen("bash -l"));
  146.         writeBytes("\n", 1);
  147.  
  148.         writeBytes(commandSeparatorWithEchoStatus, strlen(commandSeparatorWithEchoStatus));
  149.         writeBytes("\n", 1);
  150.  
  151.         readBytes(&tmpBuf, 0, commandSeparatorWithLF);
  152.  
  153.         if (verbosity != SSH_LOG_NOLOG) printf("Connected to %s@%s:%d\n", user, host, port);
  154.  
  155.         return success;
  156.     }
  157.  
  158.     //-----------------------------------------------------------------
  159.     // Buffer::resize
  160.     //-----------------------------------------------------------------
  161.  
  162.     int Buffer::resize(int newSize)
  163.     {
  164.         if (bufferLen == newSize)
  165.             return 0;
  166.  
  167.         bufferLen = newSize;
  168.  
  169.         if (buffer)
  170.             buffer = (char*)realloc(buffer, bufferLen);
  171.         else
  172.             buffer = (char*)malloc(bufferLen);
  173.  
  174.         buffer[bufferLen-1] = 0;
  175.  
  176.         return 0;
  177.     }
  178.  
  179.     //-----------------------------------------------------------------
  180.     // Execute Command
  181.     //-----------------------------------------------------------------
  182.  
  183.     struct ServerResponse* execute(const char* command)
  184.     {
  185.         int rc = success;
  186.         char statusBuffer[20]; *statusBuffer = 0;
  187.         ServerResponse* res = 0;
  188.  
  189.         printf("Execute [%s]\n", command);
  190.  
  191.         if (!command)
  192.             return 0;
  193.  
  194.         // (1) write command + separator echo which will include the return value
  195.  
  196.         rc = writeBytes(command, strlen(command));
  197.  
  198.         if (!rc) rc= writeBytes("\n", 1);
  199.         if (!rc) rc= writeBytes(commandSeparatorWithEchoStatus, strlen(commandSeparatorWithEchoStatus));
  200.         if (!rc) rc= writeBytes("\n", 1);
  201.  
  202.         res = new ServerResponse;
  203.  
  204.         if (rc) return 0;
  205.  
  206.         // (2) read STDOUT until the separator marker + LF
  207.  
  208.         rc = readBytes(&res->stdout, 0, commandSeparatorWithLF);
  209.  
  210.         if (rc) return 0;
  211.  
  212.         // (4) read STDERR *nonblocking*
  213.  
  214.         rc = readBytes(&res->stderr, 1);
  215.  
  216.         if (rc) return 0;
  217.  
  218.         return res;
  219.     }
  220.  
  221.     //-----------------------------------------------------------------
  222.     // Write Bytes
  223.     //-----------------------------------------------------------------
  224.  
  225.     int writeBytes(const char* buffer, int len)
  226.     {
  227.         if (!buffer)
  228.             return fail;
  229.  
  230.         if (!ssh_channel_is_open(channel))
  231.         {
  232.             printf("ERROR: CHANNEL IS CLOSED, trying to REOPEN....\n");
  233.             return errNotConnected;
  234.         }
  235.  
  236.         int nwritten = ssh_channel_write(channel, buffer, len);
  237.  
  238.         if (nwritten != len)
  239.         {
  240.             const char* err = ssh_get_error(session);
  241.  
  242.             if (verbosity != SSH_LOG_NOLOG) fprintf(stderr, "[SshClient] Error: Sending bytes to server failed: '%s'\n", err ? err : "");
  243.             return fail;
  244.         }
  245.  
  246.         return success;
  247.     }
  248.  
  249.     //-----------------------------------------------------------------
  250.     // Read Bytes
  251.     //-----------------------------------------------------------------
  252.  
  253.     int readBytes(Buffer* aBuffer, int fromStderr, const char* until)
  254.     {
  255.         int nbytes = 0;
  256.  
  257.         if (!aBuffer)
  258.             return fail;
  259.  
  260.         if (!ssh_channel_is_open(channel))
  261.         {
  262.             printf("ERROR: CHANNEL IS CLOSED, trying to REOPEN....\n");
  263.             return errNotConnected;
  264.         }      
  265.  
  266.         while (ssh_channel_is_open(channel) &&  !ssh_channel_is_eof(channel))
  267.         {
  268.             if (!fromStderr)
  269.                 nbytes = ssh_channel_read(channel, aBuffer->buffer+nbytes, aBuffer->bufferLen-nbytes, fromStderr);
  270.             else
  271.                 nbytes = ssh_channel_read_nonblocking(channel, aBuffer->buffer+nbytes, aBuffer->bufferLen-nbytes, fromStderr);
  272.  
  273.             if (nbytes < 0) return fail;
  274.             // printf("read bytes: [%s]\n", aBuffer->buffer);
  275.            
  276.             if (!until && nbytes == 0) break;
  277.             if (until && strstr(aBuffer->buffer, until)) break;
  278.  
  279.             if (aBuffer->bufferLen-nbytes < 10)
  280.                 aBuffer->resize(aBuffer->bufferLen*2);
  281.         }  
  282.  
  283.         return success;
  284.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement