Changeset c6a974c in nscp


Ignore:
Timestamp:
06/17/12 22:15:11 (11 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.1, 0.4.2
Children:
6090c98
Parents:
49187ce
Message:
  • Initial (rather crude) NRDP support.
Files:
10 added
7 edited

Legend:

Unmodified
Added
Removed
  • CMakeLists.txt

    rc3f233d rc6a974c  
    101101  MESSAGE(STATUS "Found python (lib) in: ${PYTHON_LIBRARY}") 
    102102ENDIF (PYTHONLIBSEX_FOUND) 
     103 
     104FIND_PACKAGE(TINYXML2) 
     105IF (TINYXML2_FOUND) 
     106  MESSAGE(STATUS "Found tinyxml2 in: ${TINYXML2_INCLUDE_DIR}") 
     107ENDIF (TINYXML2_FOUND) 
    103108 
    104109 
     
    186191elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) 
    187192  # Update if necessary 
    188   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic") 
     193  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-long-long -pedantic -Wno-unused-parameter") 
    189194endif() 
    190195 
  • build.cmake

    r84cdb9b rc6a974c  
    77  SET(INC_PSDK_61 "C:/Program Files/Microsoft SDKs/Windows/v6.1/") 
    88  SET(INC_PSDK_2003 "C:/Program Files/Microsoft Platform SDK/") 
     9  SET(TINYXML2_DIR "D:/source/libraries/tinyxml2") 
    910 
    1011  if(CMAKE_CL_64) 
  • changelog

    ra48fd4c rc6a974c  
    44 * Fix dependonservice LanManWorkStation (old win) 
    55 * Fix RtlStringFromGUID problem on NT4 
     6 
     72012-06-16 MickeM 
     8 * Initial (rather crude) NRDP support. 
    69 
    7102012-06-16 MickeM 
  • include/http/client.hpp

    rb7d17f8 rc6a974c  
    55#include <ostream> 
    66#include <string> 
     7 
    78#include <boost/asio.hpp> 
     9#include <boost/tuple/tuple.hpp> 
    810 
    911#include <strEx.h> 
     12#include <socket/socket_helpers.hpp> 
    1013 
    1114using boost::asio::ip::tcp; 
     
    1316namespace http { 
    1417  class client { 
     18 
     19    boost::asio::io_service io_service; 
     20    tcp::socket socket; 
     21 
     22 
     23    static std::string charToHex(char c) { 
     24      std::string result; 
     25      char first, second; 
     26 
     27      first = (c & 0xF0) / 16; 
     28      first += first > 9 ? 'A' - 10 : '0'; 
     29      second = c & 0x0F; 
     30      second += second > 9 ? 'A' - 10 : '0'; 
     31 
     32      result.append(1, first); 
     33      result.append(1, second); 
     34 
     35      return result; 
     36    } 
     37 
     38    static std::string uri_encode(const std::string& src) 
     39    { 
     40      std::string result; 
     41      std::string::const_iterator iter; 
     42 
     43      for(iter = src.begin(); iter != src.end(); ++iter) { 
     44        switch(*iter) { 
     45  case ' ': 
     46    result.append(1, '+'); 
     47    break; 
     48    // alnum 
     49  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 
     50  case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 
     51  case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 
     52  case 'V': case 'W': case 'X': case 'Y': case 'Z': 
     53  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 
     54  case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 
     55  case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 
     56  case 'v': case 'w': case 'x': case 'y': case 'z': 
     57  case '0': case '1': case '2': case '3': case '4': case '5': case '6': 
     58  case '7': case '8': case '9': 
     59    // mark 
     60  case '-': case '_': case '.': case '!': case '~': case '*': case '\'':  
     61  case '(': case ')': 
     62    result.append(1, *iter); 
     63    break; 
     64    // escape 
     65  default: 
     66    result.append(1, '%'); 
     67    result.append(charToHex(*iter)); 
     68    break; 
     69        } 
     70      } 
     71 
     72      return result; 
     73    } 
     74 
     75 
    1576  public: 
     77    client() 
     78      : io_service() 
     79      , socket(io_service) 
     80    { 
     81    } 
     82 
     83    void connect() { 
     84 
     85    } 
     86    struct response_type { 
     87      unsigned int code; 
     88      std::list<std::string> headers; 
     89      std::string payload; 
     90      std::string version; 
     91      std::string message; 
     92 
     93      void add_header(const std::string &header)  
     94      { 
     95        headers.push_back(header); 
     96      } 
     97 
     98 
     99    }; 
     100    struct request_type { 
     101      typedef std::map<std::string,std::string> post_map_type; 
     102      std::string verb; 
     103      std::list<std::string> headers; 
     104      std::string payload; 
     105      void add_default_headers() { 
     106        add_header("Accept:", "*/*"); 
     107        add_header("Connection:", "close"); 
     108      } 
     109      void add_header(std::string key, std::string value) { 
     110        headers.push_back(key + ": " + value); 
     111      } 
     112      void add_header(std::string value) { 
     113        headers.push_back(value); 
     114      } 
     115      void build_request(std::string verb, std::string server, std::string path, std::ostream &os) const { 
     116        const char* crlf = "\r\n"; 
     117        os << verb << " " << path << " HTTP/1.0" << crlf; 
     118        os << "Host: " << server << crlf; 
     119        BOOST_FOREACH(const std::string &s, headers) { 
     120          os << s << crlf; 
     121        } 
     122        os << crlf; 
     123        if (!payload.empty())  
     124          os << payload; 
     125        os << crlf; 
     126        os << crlf; 
     127      } 
     128      void add_post_payload(const post_map_type &payload_map) { 
     129        std::string data; 
     130        BOOST_FOREACH(const post_map_type::value_type &v, payload_map) { 
     131          if (!data.empty()) 
     132            data += "&"; 
     133          data += uri_encode(v.first); 
     134          data += "="; 
     135          data += uri_encode(v.second); 
     136        } 
     137        add_header("Content-Length", strEx::s::xtos(data.size())); 
     138        add_header("Content-Type", "application/x-www-form-urlencoded"); 
     139        verb = "POST"; 
     140        payload = data; 
     141      } 
     142    }; 
     143 
     144    void connect(std::string server, std::string port) { 
     145      tcp::resolver resolver(io_service); 
     146      tcp::resolver::query query(server, port); 
     147      tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); 
     148      tcp::resolver::iterator end; 
     149 
     150      boost::system::error_code error = boost::asio::error::host_not_found; 
     151      while (error && endpoint_iterator != end) { 
     152        socket.close(); 
     153        socket.connect(*endpoint_iterator++, error); 
     154      } 
     155      if (error) 
     156        throw boost::system::system_error(error); 
     157    } 
     158    void send_request(std::string server, std::string path, request_type &request) { 
     159      boost::asio::streambuf requestbuf; 
     160      std::ostream request_stream(&requestbuf); 
     161      request.build_request(request.verb, server, path, request_stream); 
     162      boost::asio::write(socket, requestbuf); 
     163    } 
     164    boost::tuple<std::string,unsigned int,std::string> read_result() { 
     165      const char* crlf = "\r\n"; 
     166      boost::asio::streambuf response; 
     167      std::string http_version, status_message; 
     168      unsigned int status_code; 
     169      boost::asio::read_until(socket, response, crlf); 
     170 
     171      std::istream response_stream(&response); 
     172      if (response_stream) 
     173        throw socket_helpers::socket_exception("Invalid response"); 
     174      response_stream >> http_version; 
     175      response_stream >> status_code; 
     176      std::getline(response_stream, status_message); 
     177      return boost::make_tuple(http_version, status_code, status_message); 
     178    } 
     179 
     180 
     181    response_type execute(std::string server, std::string port, std::string path, request_type &request) { 
     182      response_type response; 
     183      connect(server, port); 
     184      send_request(server, path, request); 
     185 
     186      boost::tie(response.version, response.code, response.message) = read_result(); 
     187 
     188      if (response.version.substr(0, 5) != "HTTP/") 
     189        throw socket_helpers::socket_exception("Invalid response: " + response.version); 
     190      if (response.code != 200) 
     191        throw socket_helpers::socket_exception("Response returned with status code " + strEx::s::xtos(response.code)); 
     192 
     193      boost::asio::streambuf responsebuffer; 
     194      std::istream response_stream(&responsebuffer); 
     195      boost::asio::read_until(socket, responsebuffer, "\r\n\r\n"); 
     196 
     197      std::string header; 
     198      while (std::getline(response_stream, header) && header != "\r") 
     199        response.add_header(header); 
     200 
     201      std::ostringstream os; 
     202      if (responsebuffer.size() > 0) 
     203        os << &responsebuffer; 
     204 
     205      boost::system::error_code error; 
     206      while (boost::asio::read(socket, responsebuffer, boost::asio::transfer_at_least(1), error)) 
     207        os << &responsebuffer; 
     208      if (error != boost::asio::error::eof) 
     209        throw boost::system::system_error(error); 
     210      response.payload = os.str(); 
     211      return response; 
     212    } 
     213 
    16214    static bool download(std::string protocol, std::string server, std::string path, std::ostream &os, std::string &error_msg) { 
    17215      try { 
    18  
    19         boost::asio::io_service io_service; 
    20  
    21         // Get a list of endpoints corresponding to the server name. 
    22         tcp::resolver resolver(io_service); 
    23         tcp::resolver::query query(server, protocol); 
    24         tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); 
    25         tcp::resolver::iterator end; 
    26  
    27         // Try each endpoint until we successfully establish a connection. 
    28         tcp::socket socket(io_service); 
    29         boost::system::error_code error = boost::asio::error::host_not_found; 
    30         while (error && endpoint_iterator != end) { 
    31           socket.close(); 
    32           socket.connect(*endpoint_iterator++, error); 
    33         } 
    34         if (error) 
    35           throw boost::system::system_error(error); 
    36  
    37         // Form the request. We specify the "Connection: close" header so that the 
    38         // server will close the socket after transmitting the response. This will 
    39         // allow us to treat all data up until the EOF as the content. 
    40         boost::asio::streambuf request; 
    41         std::ostream request_stream(&request); 
    42         request_stream << "GET " << path << " HTTP/1.0\r\n"; 
    43         request_stream << "Host: " << server << "\r\n"; 
    44         request_stream << "Accept: */*\r\n"; 
    45         request_stream << "Connection: close\r\n\r\n"; 
    46  
    47         // Send the request. 
    48         boost::asio::write(socket, request); 
    49  
    50         // Read the response status line. 
    51         boost::asio::streambuf response; 
    52         boost::asio::read_until(socket, response, "\r\n"); 
    53  
    54         // Check that response is OK. 
    55         std::istream response_stream(&response); 
    56         std::string http_version; 
    57         response_stream >> http_version; 
    58         unsigned int status_code; 
    59         response_stream >> status_code; 
    60         std::string status_message; 
    61         std::getline(response_stream, status_message); 
    62         if (!response_stream || http_version.substr(0, 5) != "HTTP/") { 
    63           error_msg = "Invalid response"; 
    64           return false; 
    65         } 
    66         if (status_code != 200) { 
    67           error_msg = "Response returned with status code " + strEx::wstring_to_string(strEx::itos(status_code)); 
    68           return false; 
    69         } 
    70  
    71         // Read the response headers, which are terminated by a blank line. 
    72         boost::asio::read_until(socket, response, "\r\n\r\n"); 
    73  
    74         // Process the response headers. 
    75         std::string header; 
    76         while (std::getline(response_stream, header) && header != "\r") 
    77           ; 
    78           //std::cout << "HDR: " << header << "\n"; 
    79  
    80         // Write whatever content we already have to output. 
    81         if (response.size() > 0) 
    82           os << &response; 
    83  
    84         // Read until EOF, writing data to output as we go. 
    85         while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)) 
    86           os << &response; 
    87         if (error != boost::asio::error::eof) 
    88           throw boost::system::system_error(error); 
     216        request_type rq; 
     217        rq.verb = "GET"; 
     218        rq.add_default_headers(); 
     219        client c; 
     220        response_type rs = c.execute(server, protocol, path, rq); 
     221        os << rs.payload; 
     222        return true; 
    89223      } catch (std::exception& e) { 
    90224        error_msg = std::string("Exception: ") + e.what(); 
    91225        return false; 
    92226      } 
    93       return true; 
    94227    } 
    95228  }; 
  • modules/NSCAClient/NSCAClient.cpp

    ra48fd4c rc6a974c  
    422422    } 
    423423    client.shutdown(); 
    424 /* 
    425     boost::asio::io_service io_service; 
    426     nsca::socket socket(io_service); 
    427     socket.connect(data.host, data.port); 
    428     if (!socket.recv_iv(data.password, data.get_encryption(), boost::posix_time::seconds(data.timeout<5?30:data.timeout))) { 
    429       NSC_LOG_ERROR_STD(_T("Failed to read iv")); 
    430       return NSCAPI::hasFailed; 
    431     } 
    432     NSC_DEBUG_MSG_STD(_T("Got IV sending packets: ") + strEx::itos(packets.size())); 
    433     BOOST_FOREACH(const nsca::packet &packet, packets) { 
    434       NSC_DEBUG_MSG_STD(_T("Sending (data): ") + utf8::cvt<std::wstring>(packet.to_string())); 
    435       socket.send_nsca(packet, boost::posix_time::seconds(data.timeout)); 
    436     } 
    437     socket.shutdown(); 
    438     */ 
    439424    return boost::make_tuple(NSCAPI::returnUNKNOWN, _T("")); 
    440425  } catch (const nsca::nsca_encrypt::encryption_exception &e) { 
  • modules/NSCAClient/NSCAClient.h

    ra48fd4c rc6a974c  
    8686    std::string password; 
    8787    std::string encryption; 
    88     std::string host, port; 
     88    std::string host; 
     89    std::string port; 
    8990    std::string sender_hostname; 
    9091    int timeout; 
     
    9293    int time_delta; 
    9394 
    94     connection_data(nscapi::protobuf::types::destination_container recipient, nscapi::protobuf::types::destination_container target, nscapi::protobuf::types::destination_container sender) { 
    95       recipient.import(target); 
    96       timeout = recipient.get_int_data("timeout", 30); 
    97       buffer_length = recipient.get_int_data("payload length", 512); 
    98       password = recipient.get_string_data("password"); 
    99       encryption = recipient.get_string_data("encryption"); 
    100       std::string tmp = recipient.get_string_data("time offset"); 
     95    connection_data(nscapi::protobuf::types::destination_container arguments, nscapi::protobuf::types::destination_container target, nscapi::protobuf::types::destination_container sender) { 
     96      arguments.import(target); 
     97      timeout = arguments.get_int_data("timeout", 30); 
     98      buffer_length = arguments.get_int_data("payload length", 512); 
     99      password = arguments.get_string_data("password"); 
     100      encryption = arguments.get_string_data("encryption"); 
     101      std::string tmp = arguments.get_string_data("time offset"); 
    101102      if (!tmp.empty()) 
    102         time_delta = strEx::stol_as_time_sec(recipient.get_string_data("time offset")); 
     103        time_delta = strEx::stol_as_time_sec(arguments.get_string_data("time offset")); 
    103104      else 
    104105        time_delta = 0; 
    105       host = recipient.address.get_host(); 
    106       port = strEx::s::xtos(recipient.address.get_port(5667)); 
     106      host = arguments.address.get_host(); 
     107      port = strEx::s::xtos(arguments.address.get_port(5667)); 
    107108      sender_hostname = sender.address.host; 
    108109      if (sender.has_data("host")) 
     
    113114    } 
    114115 
    115     std::wstring to_wstring() { 
    116       std::wstringstream ss; 
    117       ss << _T("host: ") << utf8::cvt<std::wstring>(host); 
    118       ss << _T(", port: ") << utf8::cvt<std::wstring>(port); 
    119       ss << _T(", timeout: ") << timeout; 
    120       ss << _T(", buffer_length: ") << buffer_length; 
    121       ss << _T(", time_delta: ") << time_delta; 
    122       ss << _T(", password: ") << utf8::cvt<std::wstring>(password); 
    123       ss << _T(", encryption: ") << utf8::cvt<std::wstring>(encryption); 
     116    std::wstring to_wstring() const { 
     117      return utf8::cvt<std::wstring>(to_string()); 
     118    } 
     119 
     120    std::string to_string() const { 
     121      std::stringstream ss; 
     122      ss << "host: " << host; 
     123      ss << ", port: " << port; 
     124      ss << ", timeout: " << timeout; 
     125      ss << ", buffer_length: " << buffer_length; 
     126      ss << ", time_delta: " << time_delta; 
     127      ss << ", password: " << password; 
     128      ss << ", encryption: " << encryption; 
    124129      return ss.str(); 
    125130    } 
     
    158163  */ 
    159164  static std::wstring getModuleName() { 
    160 #ifdef HAVE_LIBCRYPTOPP 
    161165    return _T("NSCAClient"); 
    162 #else 
    163     return _T("NSCAClient (without encryption support)"); 
    164 #endif 
    165166  } 
    166167  /** 
     
    173174  } 
    174175  static std::wstring getModuleDescription() { 
    175     return std::wstring(_T("Passive check support (needs NSCA on nagios server).\nAvalible crypto are: ")) + getCryptos(); 
     176    return std::wstring(_T("Passive check support over NSCA.\nAvalible crypto are: ")) + getCryptos(); 
    176177  } 
    177178 
  • modules/NSCPServer/CMakeLists.txt

    r465866c rc6a974c  
    5151 
    5252INCLUDE(${BUILD_CMAKE_FOLDER}/module.cmake) 
     53SOURCE_GROUP("Socket" REGULAR_EXPRESSION .*include/socket/.*) 
    5354SOURCE_GROUP("Server" REGULAR_EXPRESSION .*include/nscp/.*) 
Note: See TracChangeset for help on using the changeset viewer.