435 lines
14 KiB
C++
435 lines
14 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2009 Intel Corporation
|
|
//
|
|
// File: MPSSoapServer.cpp
|
|
//
|
|
// Contents: This class implements a SOAP server.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "global.h"
|
|
#include "TunnelManager.h"
|
|
#include "MPSNotificationSoapBinding.nsmap"
|
|
#include "TypeValidationsExtraction.h"
|
|
#include "MPSSoapServer.h"
|
|
#include "soapStub.h"
|
|
#include "SoapBinding.h"
|
|
#include "OptionsUtils.h"
|
|
#include "ConnectedSystems.h"
|
|
#include "ListParser.h"
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
|
|
string chomp(const string &strToChomp);
|
|
|
|
//*****************************************************************************
|
|
// Name : MPSoapServer
|
|
// Description : Constructor - initializes soap structures
|
|
//*****************************************************************************
|
|
MPSSoapServer::MPSSoapServer()
|
|
{
|
|
// Initialize soap.
|
|
m_soap = soap_new1(SOAP_XML_STRICT);
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Name : MPSSoapServer
|
|
// Description : Destructor - kill soap.
|
|
//*****************************************************************************
|
|
MPSSoapServer::~MPSSoapServer(void)
|
|
{
|
|
if (m_soap != NULL)
|
|
{
|
|
soap_destroy(m_soap);
|
|
soap_end(m_soap);
|
|
soap_done(m_soap);
|
|
soap_del(m_soap);
|
|
}
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// Name : MPSSoapServer::RunServer
|
|
// Description : Listen on socket for one time interval.
|
|
//*****************************************************************************
|
|
bool MPSSoapServer::RunServer (SOAP_SOCKET handle)
|
|
{
|
|
bool ret = true;
|
|
m_soap->socket = handle;
|
|
|
|
if (soap_serve(m_soap) != SOAP_OK)
|
|
{
|
|
ACE_DEBUG((MY_DEBUG ACE_TEXT("Failed to process request")));
|
|
ret = false;
|
|
}
|
|
soap_destroy(m_soap); // clean up class instances
|
|
soap_end(m_soap); // clean up everything and close socket
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Service operations:
|
|
//*****************************************************************************
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
// This function generated together with server operation but this is the client function
|
|
//*****************************************************************************
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mps__MPSAlert(struct soap* , _mps__EventNotificationRequest *, _mps__MPSAlertResponse *)
|
|
{
|
|
return 501; // not implemented
|
|
}
|
|
|
|
|
|
// return 0 in case of not number string
|
|
int string_to_integer(const string& str)
|
|
{
|
|
stringstream ss(str);
|
|
int i;
|
|
ss >> i;
|
|
if (ss.fail())
|
|
i = 0;
|
|
return i;
|
|
}
|
|
|
|
// Checks if string is in URI format
|
|
bool is_URI(string str)
|
|
{
|
|
ACE_TString astr = str.c_str();
|
|
URL_Wrapper mc_data;
|
|
if (validateAndGetElement(astr, mc_data) != STATUS_SUCCESS)
|
|
{
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Invalid URI: %s.\n"),
|
|
str.c_str()));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// Name : Authenticate
|
|
// Description : Authenicate the user using _soap_auth_func
|
|
//*****************************************************************************
|
|
|
|
bool Authenticate(struct soap* soap)
|
|
{
|
|
#ifdef ACE_WIN32
|
|
if (_soap_auth_func != NULL) // Need credentials for service connection
|
|
{
|
|
char error[MAX_DLL_ERR_LEN];
|
|
|
|
|
|
if (!soap->userid ||!soap->passwd ||
|
|
(_soap_auth_func (soap->userid,
|
|
soap->passwd,
|
|
getSOAPDllParameters()->c_str(),
|
|
error, MAX_DLL_ERR_LEN ) == 0) )
|
|
{
|
|
ACE_DEBUG((MY_INFO ACE_TEXT("Failed to authenticate soap client\n")));
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Name : __mpi__IsMachineConnected
|
|
// Description : Checks if machine appears in Tunnel_Manager map
|
|
//*****************************************************************************
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mpi__IsMachineConnected(struct soap* soap, _mpi__IsMachineConnected *mpi__IsMachineConnected, _mpi__IsMachineConnectedResponse *mpi__IsMachineConnectedResponse)
|
|
{
|
|
ACE_TRACE(ACE_TEXT("__mpi__IsMachineConnected"));
|
|
if (!Authenticate(soap))
|
|
return soap_receiver_fault_subcode(soap, "101", "User not authorized", "Wrong user name or permission denied.");
|
|
|
|
|
|
string system = mpi__IsMachineConnected->Machine->SystemName;
|
|
if (Tunnel_Manager::instance().fqdn_exists(ACE_CString(system.c_str())))
|
|
mpi__IsMachineConnectedResponse->IsConnected = true;
|
|
else
|
|
mpi__IsMachineConnectedResponse->IsConnected = false;
|
|
|
|
|
|
return SOAP_OK;
|
|
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// Name : __mpi__EnumerateConnectedMachines
|
|
// Description : Enumerates connected machines, save in Connected_Systems map
|
|
// and return the context
|
|
//*****************************************************************************
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mpi__EnumerateConnectedMachines(struct soap* soap, _mpi__EnumerateConnectedMachines *mpi__EnumerateConnectedMachines, _mpi__EnumerateConnectedMachinesResponse *mpi__EnumerateConnectedMachinesResponse)
|
|
{
|
|
ACE_TRACE(ACE_TEXT("__mpi__EnumerateConnectedMachines"));
|
|
if (!Authenticate(soap))
|
|
return soap_receiver_fault_subcode(soap, "101", "User not authorized", "Wrong user name or permission denied.");
|
|
|
|
|
|
if (Connected_Systems::instance().max_concurrent_enums_exceeded())
|
|
{
|
|
ACE_DEBUG((MY_DEBUG
|
|
ACE_TEXT("Max concurrent enumeration exceeeded (%d)\n"), *getMaxConcurrentEnums()));
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
}
|
|
|
|
try{
|
|
// create new enumeration using current connected list
|
|
ConnectedSystemsEnumerationDataPtr cs(new Connected_Systems_Enumeration_Data());
|
|
|
|
ACE_UINT32 context;
|
|
if (!Connected_Systems::instance().add_new_enumeration(context , cs))
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
|
|
time_t expires = cs->get_expires();
|
|
|
|
|
|
stringstream ss;
|
|
ss << context;
|
|
string* str = soap_new_std__string(soap, -1);
|
|
*str = ss.str();
|
|
|
|
mpi__EnumerateConnectedMachinesResponse->EnumerationContext = soap_new_xsd__anyType(soap, -1);
|
|
mpi__EnumerateConnectedMachinesResponse->EnumerationContext->__item = (char *) str->c_str();
|
|
mpi__EnumerateConnectedMachinesResponse->Expires = soap_new_std__string(soap, -1);
|
|
mpi__EnumerateConnectedMachinesResponse->Expires->assign(ctime(&expires));
|
|
|
|
return SOAP_OK;
|
|
|
|
}
|
|
catch(...)
|
|
{
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
}
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Name : __mpi__Pull
|
|
// Description : Retrieves a list of names of machines corresponding to the
|
|
// enumeration specified by the enumeration context.
|
|
//*****************************************************************************
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mpi__Pull(struct soap* soap, _mpi__Pull *mpi__Pull, _mpi__PullResponse *mpi__PullResponse)
|
|
{
|
|
ACE_TRACE(ACE_TEXT("__mpi__Pull"));
|
|
|
|
if (!Authenticate(soap))
|
|
return soap_receiver_fault_subcode(soap, "101", "User not authorized", "Wrong user name or permission denied.");
|
|
|
|
ACE_UINT32 context = string_to_integer(mpi__Pull->EnumerationContext->__item);
|
|
|
|
unsigned int num_items_to_pull = 1;
|
|
if (mpi__Pull->MaxElements != NULL && mpi__Pull->MaxElements->length() > 0)
|
|
num_items_to_pull = string_to_integer(mpi__Pull->MaxElements->c_str());
|
|
if (num_items_to_pull == 0) // MaxElements does not include numbers
|
|
num_items_to_pull = 1;
|
|
|
|
// takes the minimum of MaxEnumElements config data and MaxElements parametere
|
|
num_items_to_pull = min (num_items_to_pull, *(getMaxEnumElements()) );
|
|
|
|
// get the enumeration for this context
|
|
ConnectedSystemsEnumerationDataPtr* cs = Connected_Systems::instance().get_connected_system_enumeration_data_ptr(context);
|
|
if (cs == NULL)
|
|
return soap_receiver_fault_subcode(soap, "102", "Invalid Enumeration context", "An invalid enumeration context has been passed as parameter");
|
|
|
|
unsigned int num=0;
|
|
for( ;
|
|
(*cs)->get_systems_set_iterator() != (*cs)->get_systems_set_end() && num < num_items_to_pull;
|
|
(*cs)->get_systems_set_iterator()++)
|
|
{
|
|
mpi__SystemType* system = soap_new_mpi__SystemType(soap, 1);
|
|
system->SystemName = (*cs)->get_systems_set_iterator()->c_str();
|
|
mpi__PullResponse->Items.push_back(system);
|
|
num++;
|
|
}
|
|
|
|
// in case this is the last element - create the EndOfSequence parameter, and release the context
|
|
if ((*cs)->get_systems_set_iterator() == (*cs)->get_systems_set_end())
|
|
{
|
|
mpi__PullResponse->EndOfSequence = soap_new_xsd__anyType(soap,1);
|
|
Connected_Systems::instance().release_context(context);
|
|
}
|
|
|
|
return SOAP_OK;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Name : __mpi__Release
|
|
// Description : Release a enumeration context.
|
|
//*****************************************************************************
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mpi__Release(struct soap* soap, _mpi__Release *mpi__Release, struct __mpi__ReleaseResponse &_param_1)
|
|
{
|
|
ACE_TRACE(ACE_TEXT("__mpi__Release"));
|
|
if (!Authenticate(soap))
|
|
return soap_receiver_fault_subcode(soap, "101", "User not authorized", "Wrong user name or permission denied.");
|
|
|
|
ACE_UINT32 context = string_to_integer(mpi__Release->EnumerationContext->__item);
|
|
if (!Connected_Systems::instance().context_exists(context))
|
|
return soap_receiver_fault_subcode(soap, "102", "Invalid Enumeration context", "An invalid enumeration context has been passed as parameter");
|
|
|
|
if (Connected_Systems::instance().release_context(context))
|
|
return SOAP_OK;
|
|
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// Name : __mpi__SubscribeForNotifications
|
|
// Description : Enables subscribing a system to receive MpsNotification events
|
|
// whenever a machine connects to or disconnects from the MPS.
|
|
//*****************************************************************************
|
|
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mpi__SubscribeForNotifications(struct soap* soap, _mpi__SubscribeForNotifications *mpi__SubscribeForNotifications, _mpi__SubscribeForNotificationsResponse *mpi__SubscribeForNotificationsResponse)
|
|
{
|
|
ACE_TRACE(ACE_TEXT("__mpi__SubscribeForNotifications"));
|
|
if (!Authenticate(soap))
|
|
return soap_receiver_fault_subcode(soap, "101", "User not authorized", "Wrong user name or permission denied.");
|
|
|
|
string delivery = mpi__SubscribeForNotifications->Delivery;
|
|
if (!is_URI(delivery))
|
|
return soap_sender_fault(soap, "Validation constraint violation: data type mismatch in element Delivery", NULL);
|
|
|
|
List_Parser parser;
|
|
vector<ACE_TString> vec;
|
|
if (parser.parseItemList(NOTIFICATION_LIST_DEFAULT, vec) != PARSER_STATUS_SUCCESS)
|
|
{
|
|
ACE_DEBUG((MY_DEBUG
|
|
ACE_TEXT("Error parsing notificationList.config file \n")));
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
}
|
|
if (vec.size() >= *getMaxSubsribers())
|
|
{
|
|
ACE_DEBUG((MY_DEBUG
|
|
ACE_TEXT("Subsribers number excedded MaxSubscribers (%d) \n"),
|
|
*getMaxSubsribers()));
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
}
|
|
|
|
ofstream fileStream;
|
|
fileStream.open(NOTIFICATION_LIST_DEFAULT, ios::app);
|
|
if(!fileStream.fail())
|
|
{
|
|
fileStream << "\n" << delivery;
|
|
}
|
|
fileStream.close();
|
|
|
|
return SOAP_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// Name : __mpi__Unsubscribe
|
|
// Description : function removes a system from the subscribers list for
|
|
// receiving MpsNotification events whenever a machine connects
|
|
// to or disconnects from the MPS.
|
|
//*****************************************************************************
|
|
SOAP_FMAC5 int SOAP_FMAC6 __mpi__Unsubscribe(struct soap* soap, _mpi__Unsubscribe *mpi__Unsubscribe, struct __mpi__UnsubscribeResponse &_param_2)
|
|
{
|
|
ACE_TRACE(ACE_TEXT("__mpi__Unsubscribe"));
|
|
if (!Authenticate(soap))
|
|
return soap_receiver_fault_subcode(soap, "101", "User not authorized", "Wrong user name or permission denied.");
|
|
|
|
string delivery = mpi__Unsubscribe->Delivery;
|
|
if (!is_URI(delivery))
|
|
return soap_sender_fault(soap, "Validation constraint violation: data type mismatch in element Delivery", NULL);
|
|
|
|
|
|
|
|
ifstream fileStream;
|
|
ofstream outfileStream;
|
|
string str;
|
|
bool found = false;
|
|
|
|
|
|
try{
|
|
fileStream.open(NOTIFICATION_LIST_DEFAULT, ios::in);
|
|
outfileStream.open(TEMP_NOTIFICATION_LIST_DEFAULT, ios::out|ios::trunc);
|
|
if(!fileStream.fail())
|
|
{
|
|
|
|
while (!fileStream.eof())
|
|
{
|
|
getline(fileStream, str);
|
|
|
|
if(!fileStream.fail())
|
|
{
|
|
// first chomp the line from '\n' or "\n\r" (in Linux)
|
|
str = chomp(str);
|
|
|
|
if (str.compare(delivery) == 0)
|
|
{
|
|
ACE_DEBUG((MY_DEBUG
|
|
ACE_TEXT("%s found in notification.config file and deleted\n"),
|
|
delivery.c_str()));
|
|
found = true;
|
|
}
|
|
else
|
|
outfileStream << str << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
fileStream.clear(); // if getline failed the failbit internal flag is set
|
|
fileStream.close();
|
|
outfileStream.close();
|
|
|
|
if (!found)
|
|
{
|
|
remove(TEMP_NOTIFICATION_LIST_DEFAULT);
|
|
return soap_receiver_fault_subcode(soap, "103", "URI not found", "No such URI in notification.config file");
|
|
}
|
|
|
|
|
|
|
|
// copy TEMP_NOTIFICATION_LIST_DEFAULT to NOTIFICATION_LIST_DEFAULT
|
|
// make sure to not add newline at the end of the file
|
|
fileStream.open(TEMP_NOTIFICATION_LIST_DEFAULT, ios::in);
|
|
if(fileStream.fail())
|
|
{
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
}
|
|
else
|
|
{
|
|
outfileStream.open(NOTIFICATION_LIST_DEFAULT, ios::out|ios::trunc);
|
|
if(outfileStream.fail())
|
|
return soap_receiver_fault_subcode(soap, "100", "Unexpected exeption", "Internal error.");
|
|
|
|
// read first line and don't add newline
|
|
getline(fileStream, str);
|
|
if(!fileStream.fail())
|
|
outfileStream << str ;
|
|
while (!fileStream.eof())
|
|
{
|
|
getline(fileStream, str);
|
|
outfileStream << "\n" << str;
|
|
}
|
|
}
|
|
|
|
outfileStream.close();
|
|
fileStream.close();
|
|
}
|
|
catch(...)
|
|
{
|
|
ACE_DEBUG((MY_DEBUG
|
|
ACE_TEXT("__mpi__Unsubscribe: got exception\n")));
|
|
}
|
|
|
|
remove(TEMP_NOTIFICATION_LIST_DEFAULT);
|
|
|
|
return SOAP_OK;
|
|
}
|