1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-01 05:47:01 +03:00

F #2150: Log IP/TCP port from client

(cherry picked from commit 565a3e69bbe612630d0a9fea75626287520341bd)
(cherry picked from commit 7d0c4f08dcfd9141e456717a1bbf24a99e4dbcb5)
(cherry picked from commit 4e04e37ef7a0fa519f9507a7013aefdd5c7a6474)
(cherry picked from commit 568202d82e7aeb1a590ff5c99f7e9e0413b784a8)
This commit is contained in:
juanmont 2018-07-31 10:51:16 +02:00 committed by Ruben S. Montero
parent e9fd0d56cb
commit a76f55d8e0
3 changed files with 76 additions and 7 deletions

View File

@ -133,7 +133,7 @@ public:
* The Request Class represents the basic abstraction for the OpenNebula
* XML-RPC API. This interface must be implemented by any XML-RPC API call
*/
class Request: public xmlrpc_c::method
class Request: public xmlrpc_c::method2
{
public:
/**
@ -171,6 +171,8 @@ public:
* %g -- group id
* %G -- group name
* %a -- auth token
* %A -- client IP address (only IPv4)
* %a -- client port (only IPv4)
* %% -- %
*/
static void set_call_log_format(const string& log_format)
@ -226,7 +228,7 @@ protected:
* @param _retval value to be returned to the client
*/
virtual void execute(xmlrpc_c::paramList const& _paramList,
xmlrpc_c::value * const _retval);
const xmlrpc_c::callInfo * _callInfoP, xmlrpc_c::value * const _retval);
/**
* Actual Execution method for the request. Must be implemented by the
@ -434,10 +436,12 @@ private:
* @param paramList list of XML parameters
* @param format_str for the log
* @param hidden_params params not to be shown
* @param callInfoP information of client
*/
static void log_method_invoked(const RequestAttributes& att,
const xmlrpc_c::paramList& paramList, const string& format_str,
const std::string& method_name, const std::set<int>& hidden_params);
const std::string& method_name, const std::set<int>& hidden_params,
const xmlrpc_c::callInfo * callInfoP);
/**
* Logs the method result, including the output data or error message
@ -453,8 +457,10 @@ private:
*
* @param v value to format
* @param oss stream to write v
* @param limit of characters to wirte
*/
static void log_xmlrpc_value(const xmlrpc_c::value& v, std::ostringstream& oss, const int limit);
static void log_xmlrpc_value(const xmlrpc_c::value& v,
std::ostringstream& oss, const int limit);
// Default number of character to show in the log. Option %l<number>
const static int DEFAULT_LOG_LIMIT = 20;

View File

@ -236,6 +236,8 @@ DEFAULT_COST = [
# %g -- group id
# %G -- group name
# %a -- auth token
# %A -- Request IP address
# %P -- Request PORT
# %% -- %
#*******************************************************************************

View File

@ -20,6 +20,11 @@
#include "PoolObjectAuth.h"
#include <xmlrpc-c/abyss.h>
#include <sys/socket.h>
#include <netdb.h>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* RequestLog Methods */
@ -74,16 +79,53 @@ string Request::object_name(PoolObjectSQL::ObjectType ob)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static void get_client_ip(const xmlrpc_c::callInfo * call_info, char * const
ip, char * const port)
{
struct abyss_unix_chaninfo * unix_ci;
const xmlrpc_c::callInfo_serverAbyss * abyss_ci =
static_cast<const xmlrpc_c::callInfo_serverAbyss *>(call_info);
SessionGetChannelInfo(abyss_ci->abyssSessionP, (void **) &unix_ci);
// -------------------------------------------------------------------------
// NOTE: This only works for IPv4 as abyss_unix_chaninfo is not IPv6 ready
// it should use sockaddr_storage for peerAddr, and set peerAddrLen properly
// This could be bypassed with getpeername if library exposes access to
// channel implementation, i.e. socket fd
// -------------------------------------------------------------------------
int rc = getnameinfo(&(unix_ci->peerAddr), unix_ci->peerAddrLen, ip,
NI_MAXHOST, port, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV);
if ( rc != 0 )
{
ip[0] = '-';
ip[1] = '\0';
port[0] = '-';
port[1] = '\0';
}
}
void Request::log_method_invoked(const RequestAttributes& att,
const xmlrpc_c::paramList& paramList, const string& format_str,
const std::string& method_name, const std::set<int>& hidden_params)
const std::string& method_name, const std::set<int>& hidden_params,
const xmlrpc_c::callInfo * call_info)
{
std::ostringstream oss;
std::ostringstream oss_limit;
int limit = DEFAULT_LOG_LIMIT;
char mod;
char ip[NI_MAXHOST];
char port[NI_MAXSERV];
ip[0] = '\0';
port[0] = '\0';
for (unsigned int j = 0 ;j < format_str.length() - 1; j++ )
{
if (format_str[j] != '%')
@ -164,6 +206,24 @@ void Request::log_method_invoked(const RequestAttributes& att,
}
break;
case 'A':
if ( ip[0] == '\0' )
{
get_client_ip(call_info, ip, port);
}
oss << ip;
break;
case 'P':
if ( port[0] == '\0' )
{
get_client_ip(call_info, ip, port);
}
oss << port;
break;
default:
oss << format_str[j] << format_str[j+1];
break;
@ -288,6 +348,7 @@ const long long Request::xmlrpc_timeout = 10000;
void Request::execute(
xmlrpc_c::paramList const& _paramList,
const xmlrpc_c::callInfo * _callInfoP,
xmlrpc_c::value * const _retval)
{
RequestAttributes att;
@ -308,7 +369,7 @@ void Request::execute(
if ( log_method_call )
{
log_method_invoked(att, _paramList, format_str, method_name,
hidden_params);
hidden_params, _callInfoP);
}
if ( authenticated == false )