Mixe for Privacy and Anonymity in the Internet
CAAccountingBIInterface.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #ifdef PAYMENT
00030 #include "CAAccountingBIInterface.hpp"
00031 #include "CACmdLnOptions.hpp"
00032 #include "CAMsg.hpp"
00033 #include "CASocketAddrINet.hpp"
00034 #include "CASocket.hpp"
00035 #include "CAHttpClient.hpp"
00036 
00037 //CAMutex* CAAccountingBIInterface::m_pPiInterfaceMutex = new CAMutex();
00038 //CAAccountingBIInterface *CAAccountingBIInterface::m_pPiInterfaceSingleton = NULL;
00039 
00044 CAAccountingBIInterface::CAAccountingBIInterface()
00045   {
00046     //m_pSocket =NULL;
00047     //m_pPiInterfaceMutex = new CAMutex();
00048     m_pSocket = new CATLSClientSocket();
00049     m_pPiServerAddress = new CASocketAddrINet();
00050     m_phttpClient = new CAHttpClient();
00051   }
00052 
00056 CAAccountingBIInterface::~CAAccountingBIInterface()
00057   {
00058     terminateBIConnection();
00059     if(m_pSocket!=NULL)
00060     {
00061       delete m_pSocket;
00062       m_pSocket = NULL;
00063     }
00064     if(m_pPiServerAddress!=NULL)
00065     {
00066       delete m_pPiServerAddress;
00067       m_pPiServerAddress = NULL;
00068     }
00069     if(m_phttpClient!=NULL)
00070     {
00071       delete m_phttpClient;
00072       m_phttpClient = NULL;
00073     }
00074     /*if(m_pPiInterfaceMutex!=NULL)
00075     {
00076       delete m_pPiInterfaceMutex;
00077       m_pPiInterfaceMutex = NULL;
00078     }*/
00079   }
00080 
00081 
00082 SINT32 CAAccountingBIInterface::setPIServerConfiguration(CAXMLBI* pPiServerConfig)
00083 {
00084   UINT8 *pPiName = NULL;
00085   UINT16 piPort = 0;
00086   CACertificate *pPiCert = NULL;
00087 
00088   //m_pPiInterfaceMutex->lock();
00089 
00090   if(pPiServerConfig==NULL)
00091   {
00092     CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface: could not configure PI interface: no proper configuration given.\n");
00093     //m_pPiInterfaceMutex->unlock();
00094     return E_UNKNOWN;
00095   }
00096 
00097   pPiName = pPiServerConfig->getHostName();
00098   pPiCert = pPiServerConfig->getCertificate();
00099   piPort = (UINT16)pPiServerConfig->getPortNumber();
00100 
00101   if(pPiName==NULL)
00102   {
00103     CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface: could not configure PI interface: no PI name specified.\n");
00104     //m_pPiInterfaceMutex->unlock();
00105     return E_UNKNOWN;
00106   }
00107   if(pPiCert==NULL)
00108   {
00109     CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface: could not configure PI interface: no PI certificate specified.\n");
00110     //m_pPiInterfaceMutex->unlock();
00111     return E_UNKNOWN;
00112   }
00113 
00114   if(m_pPiServerAddress == NULL)
00115   {
00116     //Should never happen
00117     #ifdef DEBUG
00118     CAMsg::printMsg(LOG_ERR,"CAAccountingBIInterface: no server address initialized while trying to configure PI interface.\n");
00119     #endif
00120     m_pPiServerAddress = new CASocketAddrINet();
00121   }
00122   m_pPiServerAddress->setAddr(pPiName, piPort);
00123   m_pPiServerCertificate = pPiCert;
00124   //m_pPiInterfaceMutex->unlock();
00125   return E_SUCCESS;
00126 }
00127 
00131 SINT32 CAAccountingBIInterface::initBIConnection()
00132 {
00133   SINT32 rc;
00134   UINT8 buf[64];
00135 
00136   memset(buf,0,64);
00137 
00138   //m_pPiInterfaceMutex->lock();
00139   if(m_pPiServerAddress == NULL)
00140   {
00141     //Should never happen
00142     #ifdef DEBUG
00143     CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface: no address initialized while trying to connect. Connect aborted.\n");
00144     #endif
00145     //m_pPiInterfaceMutex->unlock();
00146     return E_UNKNOWN;
00147   }
00148 
00149   if(m_pSocket == NULL)
00150   {
00151     //Should never happen
00152     #ifdef DEBUG
00153     CAMsg::printMsg(LOG_ERR,"CAAccountingBIInterface: no socket initialized while trying to connect. Creating new one.\n");
00154     #endif
00155     m_pSocket = new CATLSClientSocket();
00156   }
00157 
00158   if(m_pPiServerCertificate == NULL)
00159   {
00160     CAMsg::printMsg(LOG_ERR,"CAAccountingBIInterface: no PI server certificate specified. Connect aborted.\n");
00161     //m_pPiInterfaceMutex->unlock();
00162     return E_UNKNOWN;
00163   }
00164   // connect
00165   m_pSocket->setServerCertificate(m_pPiServerCertificate);
00166   rc=m_pSocket->connect(*m_pPiServerAddress, PI_CONNECT_TIMEOUT);
00167   if(rc!=E_SUCCESS)
00168   {
00169     m_pPiServerAddress->getHostName(buf, 64);
00170     CAMsg::printMsg(
00171         LOG_ERR,
00172         "CAAccountingBIInterface: Could not connect to BI at %s:%i. Reason: %i\n",
00173         buf, m_pPiServerAddress->getPort(), rc
00174         //pBI->getHostName(), pBI->getPortNumber(), rc
00175       );
00176     m_pSocket->close();
00177     //m_pPiInterfaceMutex->unlock();
00178     return E_UNKNOWN;
00179   }
00180   m_pPiServerAddress->getHostName(buf, 64);
00181   CAMsg::printMsg(LOG_DEBUG,"CAAccountingBIInterface: BI connection to %s:%i established!\n", buf,m_pPiServerAddress->getPort());
00182   m_phttpClient->setSocket(m_pSocket);
00183   //m_pPiInterfaceMutex->unlock();
00184   return E_SUCCESS;
00185 }
00186 
00187 
00188 
00192 SINT32 CAAccountingBIInterface::terminateBIConnection()
00193 {
00194   //m_pPiInterfaceMutex->lock();
00195   if(m_pSocket == NULL)
00196   {
00197     //Should never happen
00198     #ifdef DEBUG
00199     CAMsg::printMsg(LOG_ERR,"CAAccountingBIInterface: no socket initialized while trying to close connection.\n");
00200     #endif
00201     //m_pPiInterfaceMutex->unlock();
00202     return E_UNKNOWN;
00203   }
00204   m_pSocket->close();
00205   //m_pPiInterfaceMutex->unlock();
00206   return E_SUCCESS;
00207 }
00208 
00209 //TODO: not finished yet
00210 CAXMLErrorMessage **CAAccountingBIInterface::settleAll(CAXMLCostConfirmation **ccs, UINT32 nrOfCCs,
00211     CAXMLErrorMessage **settleException)
00212 {
00213   XERCES_CPP_NAMESPACE::DOMDocument *allCCsEnvelopeDoc = createDOMDocument();
00214   DOMElement *allCCsEnvelope = createDOMElement(allCCsEnvelopeDoc, XML_ELEMENT_CCS);
00215   CAXMLErrorMessage **resultMessages = NULL;
00216   DOMNodeList *errorMsgList = NULL;
00217   UINT8 *allCCsAsString = NULL, *response = NULL;
00218   UINT32 contentLength = 0, nrOfErrorMessages = 0, i = 0;
00219   UINT32 status = 0;
00220   SINT32 transmitStatus = 0, domStatus;
00221   bool settleSuccessful = false;
00222 
00223 
00224   if(nrOfCCs <= 0)
00225   {
00226     return NULL;
00227   }
00228 
00229   allCCsEnvelopeDoc->appendChild(allCCsEnvelope);
00230 
00231   for (i = 0; i < nrOfCCs; i++)
00232   {
00233     allCCsEnvelope->appendChild(allCCsEnvelopeDoc->importNode(
00234       ccs[i]->getXMLDocument()->getDocumentElement(), true));
00235   }
00236 
00237   allCCsAsString = DOM_Output::dumpToMem(allCCsEnvelopeDoc, &contentLength);
00238   transmitStatus = (allCCsAsString != NULL) ?
00239     m_phttpClient->sendPostRequest((UINT8*) POST_CMD_SETTLEALL,
00240       allCCsAsString, contentLength) : E_UNKNOWN;
00241 
00242   allCCsEnvelopeDoc->release();
00243   allCCsEnvelopeDoc = NULL;
00244   allCCsEnvelope = NULL;
00245 
00246   delete [] allCCsAsString;
00247   allCCsAsString = NULL;
00248 
00249   if( transmitStatus != E_SUCCESS )
00250   {
00251     return NULL;
00252   }
00253 
00254   m_pSocket->setNonBlocking(true);
00255   transmitStatus = m_phttpClient->parseHTTPHeader(&contentLength, &status, 20000);
00256   if( (transmitStatus != E_SUCCESS) || (status != 200) || (contentLength == 0))
00257   {
00258     if(transmitStatus == E_TIMEDOUT)
00259     {
00260       CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface::settle: timeout while receiving response!\n");
00261     }
00262     else
00263     {
00264       CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface::settle: received bad response from PI: %u!\n", status);
00265     }
00266     return NULL;
00267   }
00268 #ifdef DEBUG
00269   CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::settle: got response header [Status,content-Length]=[%i,%i]!\n",
00270       status, contentLength);
00271 #endif
00272   response = new UINT8[contentLength+1];
00273 
00274   transmitStatus = m_pSocket->receiveFullyT(response, contentLength, 3000);
00275   if(transmitStatus !=E_SUCCESS)
00276   {
00277     if(transmitStatus == E_TIMEDOUT)
00278     {
00279       CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface::settle: timeout while receiving settle message!\n");
00280     }
00281     else
00282     {
00283       CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::settle: error\n");
00284     }
00285     delete [] response;
00286     response = NULL;
00287     return NULL;
00288   }
00289 
00290 
00291 
00292   response[contentLength]='\0';
00293 #ifdef DEBUG
00294   CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::settle: response body received: %s\n", response);
00295 #endif
00296 
00297   allCCsEnvelopeDoc = parseDOMDocument(response, contentLength);
00298   if(allCCsEnvelopeDoc != NULL)
00299   {
00300     errorMsgList = getElementsByTagName(allCCsEnvelopeDoc->getDocumentElement(),
00301         XML_ELEMENT_ERROR_MSG);
00302     domStatus =
00303       getDOMElementAttribute(allCCsEnvelopeDoc->getDocumentElement(), XML_ATTR_SETTLE_SUCCESSFUL, settleSuccessful);
00304     if(domStatus != E_SUCCESS)
00305     {
00306       settleSuccessful = false;
00307     }
00308 
00309     nrOfErrorMessages = errorMsgList->getLength();
00310     if(settleSuccessful)
00311     {
00312       if(nrOfErrorMessages == nrOfCCs)
00313       {
00314         resultMessages = new CAXMLErrorMessage *[nrOfCCs];
00315         for (i = 0; i < nrOfErrorMessages; i++)
00316         {
00317           resultMessages[i] = new CAXMLErrorMessage((DOMElement *) errorMsgList->item(i));
00318         }
00319       }
00320       else
00321       {
00322         CAMsg::printMsg(LOG_WARNING, "CAAccountingBIInterface::settle: BUG: number of messages != number of cost confirmations!\n");
00323         //This would be a bug.
00324         *settleException =
00325           new CAXMLErrorMessage(CAXMLErrorMessage::ERR_INTERNAL_SERVER_ERROR);
00326 
00327 
00328       }
00329     }
00330     else
00331     {
00332       CAMsg::printMsg(LOG_WARNING, "CAAccountingBIInterface::settle: PI exception raised.\n");
00333       *settleException = (nrOfErrorMessages > 0) ?
00334         new CAXMLErrorMessage((DOMElement *) errorMsgList->item(0)) :
00335         new CAXMLErrorMessage(CAXMLErrorMessage::ERR_INTERNAL_SERVER_ERROR);
00336     }
00337   }
00338 
00339   delete [] response;
00340   response = NULL;
00341 
00342   if(allCCsEnvelopeDoc != NULL)
00343   {
00344     allCCsEnvelopeDoc->release();
00345     allCCsEnvelopeDoc = NULL;
00346   }
00347 
00348   return (settleException != NULL) ? resultMessages : NULL;
00349 }
00354 CAXMLErrorMessage * CAAccountingBIInterface::settle(CAXMLCostConfirmation &cc)
00355 {
00356   UINT8 * pStrCC=NULL;
00357   UINT8* response=NULL;
00358   UINT32 contentLen=0, status=0;
00359   SINT32 ret = 0;
00360   CAXMLErrorMessage *pErrMsg;
00361 
00362   //m_pPiInterfaceMutex->lock();
00363   pStrCC = cc.dumpToMem(&contentLen);
00364   if( pStrCC==NULL || m_phttpClient->sendPostRequest((UINT8*)"/settle", pStrCC,contentLen)!= E_SUCCESS)
00365   {
00366     delete[] pStrCC;
00367     pStrCC = NULL;
00368     //m_pPiInterfaceMutex->unlock();
00369     return NULL;
00370   }
00371   delete[] pStrCC;
00372   pStrCC = NULL;
00373   contentLen=0;
00374   status=0;
00375 
00376   m_pSocket->setNonBlocking(true);
00377   ret = m_phttpClient->parseHTTPHeader(&contentLen, &status, 20000);
00378   if( ret !=E_SUCCESS || (status!=200) || (contentLen==0))
00379   {
00380     if(ret == E_TIMEDOUT)
00381     {
00382       CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface::settle: timeout while receiving response!\n");
00383     }
00384     else
00385     {
00386       CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface::settle: received bad response from PI!\n");
00387     }
00388     //m_pPiInterfaceMutex->unlock();
00389     return NULL;
00390   }
00391 #ifdef DEBUG
00392   CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::settle: got response header [Status,content-Lenght]=[%i,%i]!\n",status,contentLen);
00393 #endif
00394   response = new UINT8[contentLen+1];
00395 
00396   ret = m_pSocket->receiveFullyT(response, contentLen, 3000);
00397   if(ret !=E_SUCCESS)
00398     {
00399       if(ret == E_TIMEDOUT)
00400       {
00401         CAMsg::printMsg(LOG_ERR, "CAAccountingBIInterface::settle: timeout while receiving settle message!\n");
00402       }
00403       else
00404       {
00405         CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::settle: error\n");
00406       }
00407       delete[] response;
00408       response = NULL;
00409       //m_pPiInterfaceMutex->unlock();
00410       return NULL;
00411     }
00412 #ifdef DEBUG
00413   CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::settle: response body received!\n");
00414 #endif
00415   response[contentLen]='\0';
00416   pErrMsg = new CAXMLErrorMessage(response);
00417   delete[] response;
00418   response = NULL;
00419   //m_pPiInterfaceMutex->unlock();
00420   return pErrMsg;
00421 }
00422 
00423 /*CAAccountingBIInterface *CAAccountingBIInterface::getInstance(CAXMLBI* pPiServerConfig)
00424 {
00425   SINT32 ret;
00426   m_pPiInterfaceMutex->lock();
00427   if(m_pPiInterfaceSingleton == NULL)
00428   {
00429     if(pPiServerConfig == NULL)
00430     {
00431       CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::could not create PI interface: no proper configuration specified!\n");
00432       m_pPiInterfaceMutex->unlock();
00433       return NULL;
00434     }
00435     m_pPiInterfaceSingleton = new CAAccountingBIInterface();
00436     ret = m_pPiInterfaceSingleton->setPIServerConfiguration(pPiServerConfig);
00437     if(ret != E_SUCCESS)
00438     {
00439       CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface::could not create PI interface: no proper configuration specified!\n");
00440       m_pPiInterfaceMutex->unlock();
00441       return NULL;
00442     }
00443   }
00444   else
00445   {
00446     CAMsg::printMsg(LOG_DEBUG, "CAAccountingBIInterface:: PI Interface already running!\n");
00447   }
00448   m_pPiInterfaceMutex->unlock();
00449   return m_pPiInterfaceSingleton;
00450 
00451 }*/
00452 
00453 /*
00454 
00455 **
00456  * Request a new Balance certificate from the JPI
00457  * TODO: Error handling
00458  *
00459  * @param balanceCert an old balance certificate that the AI wishes to update
00460  * @param response a buffer to receive the new balanceCert
00461  * @param responseLen the maximum size of the buffer
00462  *
00463 SINT32 CAAccountingBIInterface::update(UINT8 *balanceCert, UINT8 * response, UINT32 *responseLen)
00464 {
00465   UINT8 requestF[] = "<?xml version=\"1.0\">\n<Balances>\n%s</Balances>\n";
00466   UINT32 sendbuflen = strlen((char *)balanceCert) + strlen((char *)requestF) + 10;
00467   UINT8* sendbuf=new UINT8[sendbuflen];
00468   UINT32 status;
00469   sprintf((char *)sendbuf, (char *)requestF, (char *)balanceCert);
00470   m_httpClient.sendPostRequest((UINT8 *)"/update", sendbuf, strlen((char *)sendbuf));
00471   delete sendbuf;
00472   receiveResponse(&status, response, responseLen);
00473   return E_SUCCESS;
00474 }
00475 */
00476 
00477 #endif