Mixe for Privacy and Anonymity in the Internet
Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions
CAMix Class Reference

#include <CAMix.hpp>

Inheritance diagram for CAMix:
[legend]
Collaboration diagram for CAMix:
[legend]

List of all members.

Public Types

enum  tMixType { FIRST_MIX, MIDDLE_MIX, LAST_MIX, JAP }

Public Member Functions

 CAMix ()
virtual ~CAMix ()
SINT32 start ()
virtual SINT32 reconfigure ()
virtual tMixType getType () const =0
virtual void shutDown ()
virtual bool isShutDown ()
SINT32 getMixCascadeInfo (XERCES_CPP_NAMESPACE::DOMDocument *&docMixCascadeInfo)
 Returns the Mix-Cascade info which should be send to the InfoService.
bool acceptsReconfiguration ()
CAControlChannelDispatchergetDownstreamControlChannelDispatcher () const
CAControlChannelDispatchergetUpstreamControlChannelDispatcher () const
UINT32 getLastConnectionTime ()
bool isConnected ()

Static Public Attributes

static const UINT32 TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT = 60000

Protected Member Functions

virtual SINT32 clean ()=0
virtual SINT32 initOnce ()
virtual SINT32 init ()=0
virtual SINT32 loop ()=0
SINT32 checkCompatibility (DOMNode *a_parent, const char *a_mixPosition)
SINT32 appendCompatibilityInfo (DOMNode *a_parent)
SINT32 addMixInfo (DOMNode *a_element, bool a_bForceFirstNode)
DOMNode * appendTermsAndConditionsExtension (XERCES_CPP_NAMESPACE::DOMDocument *doc, DOMElement *root)
 convenience function: returns an already prepared and signed TermsAndCondition node which can be appended as a KeyInfoExtension.
DOMNode * termsAndConditionsInfoNode (XERCES_CPP_NAMESPACE::DOMDocument *ownerDoc)
 convenience function: creates a node for the KeyInfo structure for indicating the clients which Terms And Conditions are valid.
virtual SINT32 processKeyExchange ()=0
virtual SINT32 initMixCascadeInfo (DOMElement *elemMixes)
 This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo()
SINT32 signXML (DOMNode *a_element)

Protected Attributes

bool m_bReconfiguring
volatile bool m_bShutDown
CAMultiSignaturem_pMultiSignature
CAInfoServicem_pInfoService
UINT32 m_u32KeepAliveRecvInterval
UINT32 m_u32KeepAliveSendInterval
bool m_acceptReconfiguration
volatile bool m_bConnected
volatile UINT32 m_lLastConnectionTime
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
CAControlChannelDispatcherm_pMuxOutControlChannelDispatcher
CAControlChannelDispatcherm_pMuxInControlChannelDispatcher

Private Member Functions

bool needAutoConfig ()
 This method checks if target interfaces (network adress and port of next mix) have been specified in the config file.

Detailed Description

Definition at line 48 of file CAMix.hpp.


Member Enumeration Documentation

Enumerator:
FIRST_MIX 
MIDDLE_MIX 
LAST_MIX 
JAP 

Definition at line 51 of file CAMix.hpp.


Constructor & Destructor Documentation

Definition at line 39 of file CAMix.cpp.

References CACmdLnOptions::acceptReconfiguration(), CALibProxytest::getOptions(), m_acceptReconfiguration, m_bConnected, m_bReconfiguring, m_bShutDown, m_docMixCascadeInfo, m_lLastConnectionTime, m_pInfoService, m_pMultiSignature, m_pMuxInControlChannelDispatcher, m_pMuxOutControlChannelDispatcher, m_u32KeepAliveRecvInterval, and m_u32KeepAliveSendInterval.

{
    m_acceptReconfiguration = CALibProxytest::getOptions()->acceptReconfiguration();
    //m_pSignature=NULL;
    m_pMultiSignature=NULL;
    m_pInfoService=NULL;
    m_pMuxOutControlChannelDispatcher=NULL;
    m_pMuxInControlChannelDispatcher=NULL;
    m_u32KeepAliveSendInterval=0;//zero means --> do not use
    m_u32KeepAliveRecvInterval=0;//zero means --> do not use
    m_bShutDown = false;
    m_docMixCascadeInfo=NULL;
    m_bConnected = false;
    m_lLastConnectionTime = 0;
#ifdef DYNAMIC_MIX
    /* LERNGRUPPE: Run by default */
    m_bLoop = true;
    m_bReconfiguring = false;
    m_bCascadeEstablished = false;
    m_bReconfigured = false;
#endif
#ifdef DATA_RETENTION_LOG
    m_pDataRetentionLog=NULL;
#endif
  }

Here is the call graph for this function:

CAMix::~CAMix ( ) [virtual]

Definition at line 65 of file CAMix.cpp.

  {
#ifdef DATA_RETENTION_LOG
    if(m_pDataRetentionLog!=NULL)
      {
        delete m_pDataRetentionLog;
        m_pDataRetentionLog=NULL;
      }
#endif

  }

Member Function Documentation

bool CAMix::acceptsReconfiguration ( ) [inline]

Definition at line 109 of file CAMix.hpp.

References m_acceptReconfiguration.

SINT32 CAMix::addMixInfo ( DOMNode *  a_element,
bool  a_bForceFirstNode 
) [protected]

Definition at line 432 of file CAMix.cpp.

References E_SUCCESS, E_UNKNOWN, and CALibProxytest::getOptions().

Referenced by initMixCascadeInfo(), CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), and CAFirstMix::processKeyExchange().

{
  // this is a complete mixinfo node to be sent to the InfoService
  XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo=NULL;
  if(CALibProxytest::getOptions()->getMixXml(docMixInfo)!=E_SUCCESS)
  {
    return E_UNKNOWN;
  }
  DOMNode* nodeMixInfo = a_element->getOwnerDocument()->importNode(
    docMixInfo->getDocumentElement(), true);
  if (a_bForceFirstNode && a_element->hasChildNodes())
  {
    a_element->insertBefore(nodeMixInfo, a_element->getFirstChild());
  }
  else
  {
    a_element->appendChild(nodeMixInfo);
  }
  return E_SUCCESS;
}

Here is the call graph for this function:

SINT32 CAMix::appendCompatibilityInfo ( DOMNode *  a_parent) [protected]

EDIT HERE FOR INTRODUCING NEW FLAGS!

Definition at line 630 of file CAMix.cpp.

References createDOMElement(), E_SUCCESS, MIX_VERSION, NEW_CHANNEL_ENCRYPTION_COMPATIBILITY, NEW_FLOW_CONTROL_COMPATIBILITY, PAYMENT_COMPATIBILITY, setDOMElementAttribute(), and WITH_INTEGRITY_CHECK_COMPATIBILITY.

Referenced by CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), and CAFirstMix::processKeyExchange().

{
  DOMElement* elemCompatibility=createDOMElement(a_parent->getOwnerDocument(),"Compatibility");
  setDOMElementAttribute(elemCompatibility,"version",(UINT8*)MIX_VERSION);
  a_parent->appendChild(elemCompatibility);

  DOMElement* elemFlags=NULL;
  DOMElement* elemFlag=NULL;

  elemFlags = createDOMElement(a_parent->getOwnerDocument(), "Flags");
  elemCompatibility->appendChild(elemFlags);

#ifdef PAYMENT
  elemFlag = createDOMElement(a_parent->getOwnerDocument(), PAYMENT_COMPATIBILITY);
  //setDOMElementValue(elemFlag,(UINT8*)"true"); // you might add a version number here for a protocol etc.
  elemFlags->appendChild(elemFlag);
#endif

  elemFlag = createDOMElement(a_parent->getOwnerDocument(), NEW_FLOW_CONTROL_COMPATIBILITY);
  //setDOMElementValue(elemFlag,(UINT8*)"true");
  elemFlags->appendChild(elemFlag);

  elemFlag = createDOMElement(a_parent->getOwnerDocument(), NEW_CHANNEL_ENCRYPTION_COMPATIBILITY);
  //setDOMElementValue(elemFlag,(UINT8*)"true");
  elemFlags->appendChild(elemFlag);

#ifdef WITH_INTEGRITY_CHECK
  elemFlag = createDOMElement(a_parent->getOwnerDocument(), WITH_INTEGRITY_CHECK_COMPATIBILITY);
  //setDOMElementValue(elemFlag,(UINT8*)"true");
  elemFlags->appendChild(elemFlag);
#endif

  return E_SUCCESS;
}

Here is the call graph for this function:

DOMNode * CAMix::appendTermsAndConditionsExtension ( XERCES_CPP_NAMESPACE::DOMDocument *  doc,
DOMElement *  root 
) [protected]

convenience function: returns an already prepared and signed TermsAndCondition node which can be appended as a KeyInfoExtension.

if elemTnCExtensions is null it will be created by this function. returns the TNCExtension root element.

Definition at line 453 of file CAMix.cpp.

References createDOMElement(), CACmdLnOptions::getAllTermsAndConditionsTemplates(), getDOMChildByName(), getElementsByTagName(), CACmdLnOptions::getNumberOfTermsAndConditionsTemplates(), CACmdLnOptions::getOperatorSubjectKeyIdentifier(), CALibProxytest::getOptions(), getTermsAndConditionsTemplateRefId(), KEYINFO_NODE_EXTENSIONS, KEYINFO_NODE_TNC_EXTENSION, m_pMultiSignature, OPTIONS_ATTRIBUTE_TNC_ID, OPTIONS_NODE_TNCS_TEMPLATES, OPTIONS_NODE_TNCS_TRANSLATION, CAMsg::printMsg(), setDOMElementAttribute(), CAMultiSignature::signXML(), TEMPLATE_REFID_MAXLEN, and TMP_BUFF_SIZE.

Referenced by CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), and CAFirstMix::processKeyExchange().

{
  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
  {
    if( (root == NULL) || (ownerDoc == NULL) )
    {
      return NULL;
    }

    DOMElement *elemTnCExtension = NULL, *elemExtensions = NULL,
          *elemTemplates = NULL;
    /* Tag for Nodes that can be removed without destroying the signature.
     * To be appended to the "mixes"-node so older mix versions won't get confused.
     */
    getDOMChildByName(root, KEYINFO_NODE_EXTENSIONS, elemExtensions);
    if(elemExtensions == NULL)
    {
      elemExtensions = createDOMElement(ownerDoc, KEYINFO_NODE_EXTENSIONS);
      root->appendChild(elemExtensions);
    }
    else
    {
      getDOMChildByName(elemExtensions, KEYINFO_NODE_TNC_EXTENSION, elemTnCExtension);
    }

    if(elemTnCExtension == NULL)
    {
      elemTnCExtension = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_EXTENSION);
      elemExtensions->appendChild(elemTnCExtension);
    }

    //First add templates if there are any
    UINT32 nrOfTemplates = CALibProxytest::getOptions()->getNumberOfTermsAndConditionsTemplates();

    if(nrOfTemplates > 0)
    {
      UINT32 nrOfSentTemplates = 0;
      UINT8 **sentTemplatesRefIds = NULL;
      getDOMChildByName(elemTnCExtension, OPTIONS_NODE_TNCS_TEMPLATES, elemTemplates);
      if(elemTemplates == NULL)
      {
        elemTemplates = createDOMElement(ownerDoc, OPTIONS_NODE_TNCS_TEMPLATES);
        elemTnCExtension->appendChild(elemTemplates);
      }
      else
      {
        DOMNodeList *nl = getElementsByTagName(elemTemplates, "TermsAndConditionsTemplate");
        nrOfSentTemplates = nl->getLength();
        if(nrOfSentTemplates > 0)
        {
          sentTemplatesRefIds = new UINT8*[nrOfSentTemplates];
          for (UINT32 i = 0; i < nrOfSentTemplates; i++)
          {
            sentTemplatesRefIds[i] = getTermsAndConditionsTemplateRefId(nl->item(i));
          }
        }
      }

      XERCES_CPP_NAMESPACE::DOMDocument **allTemplates = CALibProxytest::getOptions()->getAllTermsAndConditionsTemplates();
      UINT8 *currentTemplateRefId = NULL;
      bool duplicate = false;
      for(UINT32 i = 0; i < nrOfTemplates; i++)
      {
        currentTemplateRefId =
          getTermsAndConditionsTemplateRefId(allTemplates[i]->getDocumentElement());
        duplicate = false;
        if(currentTemplateRefId != NULL)
        {
          for(UINT32 j=0; j < nrOfSentTemplates; j++)
          {
            if(strncmp((char *)currentTemplateRefId, (char *)sentTemplatesRefIds[j], TEMPLATE_REFID_MAXLEN) == 0)
            {
              duplicate = true;
              break;
            }
          }
          if(!duplicate)
          {
            //TODO: avoid duplicates.
            elemTemplates->appendChild(ownerDoc->importNode(
                allTemplates[i]->getDocumentElement(), true));
            CAMsg::printMsg(LOG_DEBUG,"appended a tc template node!\n");
          }
          else
          {
            CAMsg::printMsg(LOG_DEBUG,"template '%s' already sent.\n", currentTemplateRefId);
          }
          delete [] currentTemplateRefId;
          currentTemplateRefId = NULL;
        }
      }

      for(UINT32 i = 0; i < nrOfSentTemplates; i++)
      {
        delete [] sentTemplatesRefIds[i];
        sentTemplatesRefIds[i] = NULL;
      }
      delete [] sentTemplatesRefIds;
      sentTemplatesRefIds = NULL;
    }

    DOMNode* elemTnCs = ownerDoc->importNode(CALibProxytest::getOptions()->getTermsAndConditions(), true);
    UINT8 tmpOpSKIBuff[TMP_BUFF_SIZE];
    UINT32 tmpOpSKILen = TMP_BUFF_SIZE;
    memset(tmpOpSKIBuff, 0, tmpOpSKILen);
    CALibProxytest::getOptions()->getOperatorSubjectKeyIdentifier(tmpOpSKIBuff, &tmpOpSKILen);
    setDOMElementAttribute(elemTnCs, OPTIONS_ATTRIBUTE_TNC_ID, tmpOpSKIBuff);

    DOMNodeList *tncDefEntryList = getElementsByTagName((DOMElement *)elemTnCs, OPTIONS_NODE_TNCS_TRANSLATION);
    for (XMLSize_t i = 0; i < tncDefEntryList->getLength(); i++)
    {
      //TODO don't know if to include certs here
      m_pMultiSignature->signXML((DOMElement *)tncDefEntryList->item(i), false);
    }
    elemTnCExtension->appendChild(elemTnCs);
    return elemTnCExtension;
  }
  else
  {
    return NULL;
  }
}

Here is the call graph for this function:

SINT32 CAMix::checkCompatibility ( DOMNode *  a_parent,
const char *  a_mixPosition 
) [protected]

EDIT HERE FOR ADDING INCOMPATIBLE VERSIONS!

EDIT HERE FOR INTRODUCING NEW FLAGS!

EDIT HERE FOR INTRODUCING NEW FLAGS!

Definition at line 666 of file CAMix.cpp.

References E_SUCCESS, E_UNKNOWN, flags, getDOMChildByName(), getDOMElementAttribute(), getNodeName(), len, MIX_VERSION, MIX_VERSION_COMPATIBILITY, NEW_CHANNEL_ENCRYPTION_COMPATIBILITY, NEW_FLOW_CONTROL_COMPATIBILITY, PAYMENT_COMPATIBILITY, CAMsg::printMsg(), and WITH_INTEGRITY_CHECK_COMPATIBILITY.

Referenced by CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), and CAFirstMix::processKeyExchange().

{
  // get compatibility info
  DOMElement* elemCompatibility=NULL;
  DOMElement* elemFlags=NULL;
  DOMElement* elemDummy=NULL;
  UINT8 strAllFlags[500];
  UINT32 lenAllFlags;
  UINT8 strNodeName[50];
  UINT32 lenNodeName=50;
  UINT8 strVersion[50];
  UINT32 len=50;
  SINT32 iCompare;
  UINT8* strComment;
  UINT32 iCountFlags = 0;
  UINT32 iLogLevel = LOG_INFO;
  bool bCompatible = true;
  bool bCompatibleFlags = true;

  if (getDOMChildByName(a_parent,"Compatibility",elemCompatibility,false) != E_SUCCESS ||
    getDOMElementAttribute(elemCompatibility, "version", strVersion, &len) != E_SUCCESS)
  {
    CAMsg::printMsg(LOG_WARNING,"Could not get any compatibility information from the %s mix. It may or may not be compatible. If the connection fails for an unknown reason, the %s mix should be updated.\n", a_mixPosition, a_mixPosition);
    return E_SUCCESS;
  }

  iCompare = strncmp (MIX_VERSION, (char*)strVersion, len);

  if (iCompare == 0)
  {
    strComment = (UINT8*)" We have the same version.";
  }
  else if (iCompare < 0)
  {
    strComment = (UINT8*)" Our version (" MIX_VERSION ") might be too old. If the connection fails for an unknown reason, you should think about an update.";
    iLogLevel = LOG_WARNING;
  }
  else
  {
    if (strncmp ("00.08.71", (char*)strVersion, len) > 0)
    {
      strComment = (UINT8*)" This version is NOT COMPATIBLE with our version (" MIX_VERSION ")! The mixes will not work together in a cascade.";
      bCompatible = false;
      iLogLevel = LOG_CRIT;
    }
    else
    {
      strComment = (UINT8*)" We have a newer version (" MIX_VERSION "), but both are known to work fine together.";
    }
  }

  CAMsg::printMsg(iLogLevel,"The software version of the %s mix is %s.%s\n", a_mixPosition, strVersion, strComment);

#ifdef PAYMENT
  iCountFlags++;
#endif

  iCountFlags++;

  iCountFlags++;

#ifdef WITH_INTEGRITY_CHECK
  iCountFlags++;
#endif

  if (getDOMChildByName(elemCompatibility, "Flags", elemFlags, false) == E_SUCCESS)
  {
    DOMNodeList* flags = elemFlags->getChildNodes();
    if (flags->getLength() != iCountFlags)
    {
      bCompatibleFlags = false;
    }

    // Hint: We might also check for a version of the compile flags if available; it should be set in the content of each tag instead of 'true'.
#ifdef PAYMENT
    if (getDOMChildByName(elemFlags, PAYMENT_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
    {
      bCompatibleFlags = false;
    }
#endif
    if (getDOMChildByName(elemFlags, NEW_FLOW_CONTROL_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
    {
      bCompatibleFlags = false;
    }
    if (getDOMChildByName(elemFlags, NEW_CHANNEL_ENCRYPTION_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
    {
      bCompatibleFlags = false;
    }
#ifdef WITH_INTEGRITY_CHECK
    if (getDOMChildByName(elemFlags, WITH_INTEGRITY_CHECK_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
    {
      bCompatibleFlags = false;
    }
#endif

    if (!bCompatibleFlags)
    {
      // get the flags of the other mix
      strAllFlags[0] = 0;
      lenAllFlags = 1;
      for (UINT32 i = 0; i < flags->getLength(); i++)
      {
        if (getNodeName(flags->item(i), strNodeName, &lenNodeName) == E_SUCCESS)
        {

          lenAllFlags += strlen((char*)strNodeName) + 1;
          if (lenAllFlags > 500)
          {
            break;
          }
          strcat((char*)strAllFlags, " ");
          strcat((char*)strAllFlags, (char*)strNodeName);
        }

        lenNodeName = 50;
      }

      CAMsg::printMsg(LOG_CRIT, "The compile flags of the %s mix are NOT COMPATIBLE with our flags. We have: %s They have: %s  --> The mixes won't run together.\n", a_mixPosition, MIX_VERSION_COMPATIBILITY, strAllFlags);
      return E_UNKNOWN;

    }
  }


  if (!bCompatible)
  {
    return E_UNKNOWN;
  }

  return E_SUCCESS;
}

Here is the call graph for this function:

virtual SINT32 CAMix::clean ( ) [protected, pure virtual]

Implemented in CAFirstMix, CALastMix, and CAMiddleMix.

Referenced by start().

Definition at line 124 of file CAMix.hpp.

References m_lLastConnectionTime.

Referenced by CAInfoService::InfoLoop().

      {
        return m_lLastConnectionTime;
      }
SINT32 CAMix::getMixCascadeInfo ( XERCES_CPP_NAMESPACE::DOMDocument *&  docMixCascadeInfo) [inline]

Returns the Mix-Cascade info which should be send to the InfoService.

This is NOT a copy!

Parameters:
docMixCascadeInfowhere the XML struct would be stored
Return values:
E_SUCCESS

Definition at line 95 of file CAMix.hpp.

References E_SUCCESS, E_UNKNOWN, and m_docMixCascadeInfo.

Referenced by CAInfoService::getCascadeHeloXMLAsString(), and CAAccountingInstance::prepareCCRequest().

      {
        if (m_docMixCascadeInfo != NULL)
          {
            docMixCascadeInfo = m_docMixCascadeInfo;
            return E_SUCCESS;
          }
        else
          {
            return E_UNKNOWN;
          }
      }
virtual tMixType CAMix::getType ( ) const [pure virtual]
virtual SINT32 CAMix::init ( ) [protected, pure virtual]

Implemented in CAFirstMix, CALastMix, and CAMiddleMix.

Referenced by start().

SINT32 CAMix::initMixCascadeInfo ( DOMElement *  mixes) [protected, virtual]

This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo()

Parameters:
mixesthe <Mixes> element of the XML struct we received from the succeeding mix.
Return values:
E_UNKNOWNif processing produces an error
E_SUCCESSotherwise

Reimplemented in CALastMix.

Definition at line 297 of file CAMix.cpp.

References addMixInfo(), createDOMDocument(), createDOMElement(), E_SUCCESS, equals(), getDOMChildByName(), getLastDOMChildByName(), CACmdLnOptions::getListenerInterface(), CACmdLnOptions::getListenerInterfaceCount(), CACmdLnOptions::getMaxNrOfUsers(), CACmdLnOptions::getMixId(), CALibProxytest::getOptions(), CAListenerInterface::getType(), CAListenerInterface::isHidden(), m_docMixCascadeInfo, PAYMENT_VERSION, CAMsg::printMsg(), RAW_TCP, setDOMElementAttribute(), setDOMElementValue(), signXML(), and CAListenerInterface::toDOMElement().

Referenced by CAFirstMix::processKeyExchange().

{
    UINT32 count;
    m_docMixCascadeInfo=createDOMDocument();
    DOMElement* elemRoot=createDOMElement(m_docMixCascadeInfo,"MixCascade");
#ifdef LOG_DIALOG
    setDOMElementAttribute(elemRoot,"study",(UINT8*)"true");
#endif
    if(CALibProxytest::getOptions()->isFirstMix())
    {
      UINT32 maxUsers = CALibProxytest::getOptions()->getMaxNrOfUsers();
      if(maxUsers > 0)
      {
        setDOMElementAttribute(elemRoot,"maxUsers", maxUsers);
      }
#ifdef MANIOQ
      setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym.business");
#else

#ifdef PAYMENT
      setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym.premium");
#else
      setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym");
#endif
#endif
    }

    UINT8 id[50];
    UINT8* cascadeID=NULL;
    CALibProxytest::getOptions()->getMixId(id,50);

    UINT8 name[255];
    m_docMixCascadeInfo->appendChild(elemRoot);
    DOMElement* elem = NULL;

    if(CALibProxytest::getOptions()->getCascadeName(name,255) == E_SUCCESS)
    {
      elem = createDOMElement(m_docMixCascadeInfo,"Name");
      setDOMElementValue(elem,name);
      elemRoot->appendChild(elem);
  }
    else
    {
      CAMsg::printMsg(LOG_ERR,"No cascade name given!\n");
    }

    elem=createDOMElement(m_docMixCascadeInfo,"Network");
    elemRoot->appendChild(elem);
    DOMElement* elemListenerInterfaces=createDOMElement(m_docMixCascadeInfo,"ListenerInterfaces");
    elem->appendChild(elemListenerInterfaces);


    for(UINT32 i=1;i<=CALibProxytest::getOptions()->getListenerInterfaceCount();i++)
    {
        CAListenerInterface* pListener=CALibProxytest::getOptions()->getListenerInterface(i);
        if(pListener->isHidden())
        {//do nothing
        }
        else if(pListener->getType()==RAW_TCP)
        {
            DOMElement* elemTmpLI=NULL;
            pListener->toDOMElement(elemTmpLI,m_docMixCascadeInfo);
            elemListenerInterfaces->appendChild(elemTmpLI);
        }
        delete pListener;
        pListener = NULL;
    }

    DOMNode* elemMixesDocCascade=createDOMElement(m_docMixCascadeInfo,"Mixes");
    DOMElement* elemMix=NULL;
    count=1;
    if(CALibProxytest::getOptions()->isFirstMix())
    {
      addMixInfo(elemMixesDocCascade, false);
    getDOMChildByName(elemMixesDocCascade, "Mix", elemMix, false);
      // create signature
    if (signXML(elemMix) != E_SUCCESS)
    {
      CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
    }
      //if(m_pSignature->signXML(docMixInfo,m_pcertstoreOwnCerts)!=E_SUCCESS)
    //m_pSignature, CALibProxytest::getOptions()->getOwnCertificate()
    /*
        elemMixesDocCascade.appendChild(elemThisMix);*/
    }
    elemRoot->appendChild(elemMixesDocCascade);

//    UINT8 cascadeId[255];
//    UINT32 cascadeIdLen=255;

    DOMNode* node=mixes->getFirstChild();
    while(node!=NULL)
    {
        if(node->getNodeType()==DOMNode::ELEMENT_NODE&&equals(node->getNodeName(),"Mix"))
        {
            elemMixesDocCascade->appendChild(m_docMixCascadeInfo->importNode(node,true));
            count++;
 //           cascadeId = static_cast<const DOM_Element&>(node).getAttribute("id").transcode();
        }
        node=node->getNextSibling();
    }

    if(CALibProxytest::getOptions()->isLastMix())
    {
      addMixInfo(elemMixesDocCascade, false);
      getLastDOMChildByName(elemMixesDocCascade, "Mix", elemMix);
      // create signature
    if (signXML(elemMix) != E_SUCCESS)
    {
      CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
    }
        cascadeID = id;
    }
    else if(CALibProxytest::getOptions()->isFirstMix())
    {
        cascadeID = id;
    }

    if(cascadeID != NULL)
        setDOMElementAttribute(elemRoot,"id",cascadeID);
    setDOMElementAttribute(elemMixesDocCascade,"count",count);

  DOMNode* elemPayment=createDOMElement(m_docMixCascadeInfo,"Payment");
  elemRoot->appendChild(elemPayment);
#ifdef PAYMENT
  setDOMElementAttribute(elemPayment,"required",(UINT8*)"true");
  setDOMElementAttribute(elemPayment,"version",(UINT8*)PAYMENT_VERSION);
  setDOMElementAttribute(elemPayment,"prepaidInterval", CALibProxytest::getOptions()->getPrepaidInterval());
  setDOMElementAttribute(elemPayment,"piid", CALibProxytest::getOptions()->getBI()->getID());
#else
  setDOMElementAttribute(elemPayment,"required",(UINT8*)"false");
#endif
    return E_SUCCESS;
}

Here is the call graph for this function:

SINT32 CAMix::initOnce ( ) [protected, virtual]

Reimplemented in CAFirstMix, CALastMix, and CAMiddleMix.

Definition at line 77 of file CAMix.cpp.

References E_SUCCESS, E_UNKNOWN, CALibProxytest::getOptions(), and CAMsg::printMsg().

Referenced by start().

  {
#ifdef DATA_RETENTION_LOG
    m_pDataRetentionLog=new CADataRetentionLog();
    CAASymCipher* pKey=NULL;
    CALibProxytest::getOptions()->getDataRetentionPublicEncryptionKey(&pKey);
    if(m_pDataRetentionLog->setPublicEncryptionKey(pKey)!=E_SUCCESS)
      return E_UNKNOWN;
    UINT8 strDir[4096];
    strDir[0]=0;
    if(CALibProxytest::getOptions()->getDataRetentionLogDir(strDir,4096)!=E_SUCCESS ||
       m_pDataRetentionLog->setLogDir(strDir)!=E_SUCCESS)
      {
        CAMsg::printMsg(LOG_ERR,"Data Retention Error: Could not set log dir to %s!\n",strDir);
        return E_UNKNOWN;
      }
    else
      {
        CAMsg::printMsg(LOG_INFO,"Data Retention: Set log dir to: %s\n",strDir);
        CAMsg::printMsg(LOG_INFO,"Data Retention: tQueueEntry size is: %u\n",sizeof(tQueueEntry));
      }

#endif
    return E_SUCCESS;
  }

Here is the call graph for this function:

bool CAMix::isConnected ( ) [inline]

Definition at line 129 of file CAMix.hpp.

References m_bConnected.

Referenced by CAInfoService::InfoLoop(), CAInfoService::sendCascadeHelo(), and CAInfoService::sendStatus().

      {
        return m_bConnected;
      }
virtual bool CAMix::isShutDown ( ) [inline, virtual]

Definition at line 76 of file CAMix.hpp.

References m_bShutDown.

Referenced by my_terminate().

      {
        return m_bShutDown;
      }
virtual SINT32 CAMix::loop ( ) [protected, pure virtual]
bool CAMix::needAutoConfig ( ) [private]

This method checks if target interfaces (network adress and port of next mix) have been specified in the config file.

A return value of true means that necessary information to bring the cascade online is missing and must be downloaded from the InfoService (if available).

Return values:
falseif the target interfaces are configured one way or another
trueif config file contains no target interface info and InfoService is unavailable

Definition at line 261 of file CAMix.cpp.

References CATargetInterface::cleanAddr(), CALibProxytest::getOptions(), CACmdLnOptions::getTargetInterface(), CACmdLnOptions::getTargetInterfaceCount(), CATargetInterface::getTargetType(), and TARGET_MIX.

Referenced by start().

{
    bool ret = false;

    if(!CALibProxytest::getOptions()->isLastMix())
    {
        ret = true;

        // look for usable target interfaces
        for(UINT32 i=0;i<CALibProxytest::getOptions()->getTargetInterfaceCount();i++)
        {
            CATargetInterface oNextMix;
            CALibProxytest::getOptions()->getTargetInterface(oNextMix,i+1);
            if(oNextMix.getTargetType()==TARGET_MIX)
            {
                ret = false;
            }
            oNextMix.cleanAddr();
        }

        if(!CALibProxytest::getOptions()->hasNextMixTestCertificate())
            ret = true;
    }

    if(!CALibProxytest::getOptions()->isFirstMix() && !CALibProxytest::getOptions()->hasPrevMixTestCertificate())
        ret = true;

    return ret;
}

Here is the call graph for this function:

virtual SINT32 CAMix::processKeyExchange ( ) [protected, pure virtual]

Implemented in CAFirstMix, CALastMix, and CAMiddleMix.

virtual SINT32 CAMix::reconfigure ( ) [inline, virtual]

Reimplemented in CAFirstMix, and CALastMix.

Definition at line 65 of file CAMix.hpp.

References E_SUCCESS.

Referenced by threadReConfigure().

      {
        return E_SUCCESS;
      }
virtual void CAMix::shutDown ( ) [inline, virtual]

Reimplemented in CAFirstMixA.

Definition at line 71 of file CAMix.hpp.

References m_bShutDown.

Referenced by my_terminate().

      {
        m_bShutDown = true;
      }
SINT32 CAMix::signXML ( DOMNode *  a_element) [protected]

Definition at line 802 of file CAMix.cpp.

References m_pMultiSignature, and CAMultiSignature::signXML().

Referenced by initMixCascadeInfo(), CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), and CAFirstMix::processKeyExchange().

  {
    return m_pMultiSignature->signXML(a_element, true);
    /*CACertStore* tmpCertStore=new CACertStore();

    CACertificate* ownCert=CALibProxytest::getOptions()->getOwnCertificate();
    if(ownCert==NULL)
      {
        CAMsg::printMsg(LOG_DEBUG,"Own Test Cert is NULL!\n");
      }

    // Operator Certificates
    CACertificate* opCert = CALibProxytest::getOptions()->getOpCertificate();
    if(opCert==NULL)
  {
        CAMsg::printMsg(LOG_DEBUG,"Op Test Cert is NULL!\n");
  }
  else
  {
    // Own  Mix Certificates first, then Operator Certificates
    tmpCertStore->add(opCert);
  }
    tmpCertStore->add(ownCert);

    if(m_pSignature->signXML(a_element, tmpCertStore)!=E_SUCCESS)
  {
    return E_UNKNOWN;
  }

  CASignature* test = new CASignature();
  test->setVerifyKey(ownCert);

  if(test->verifyXML(a_element) != E_SUCCESS)
  {
    CAMsg::printMsg(LOG_DEBUG, "Error verifying own Signature!!\n");
    m_pSignature->signXML(a_element, tmpCertStore);
  }
  else
  {
    CAMsg::printMsg(LOG_DEBUG, "Own Signature looks ok!\n");
  }


    delete ownCert;
    ownCert = NULL;

  delete opCert;
  opCert = NULL;

    delete tmpCertStore;
    tmpCertStore = NULL;

    return E_SUCCESS;*/
}

Here is the call graph for this function:

Definition at line 103 of file CAMix.cpp.

References CACmdLnOptions::acceptReconfiguration(), clean(), E_SHUTDOWN, E_SUCCESS, E_UNKNOWN, ev_sys_enterMainLoop, ev_sys_leavingMainLoop, getcurrentTimeMillis(), CALibProxytest::getOptions(), init(), initOnce(), CAInfoService::isRunning(), loop(), m_bConnected, m_bReconfiguring, m_lLastConnectionTime, m_pInfoService, m_pMultiSignature, MONITORING_FIRE_SYS_EVENT, needAutoConfig(), CAMsg::printMsg(), CAInfoService::sendCascadeHelo(), CAInfoService::setConfiguring(), CAInfoService::setMultiSignature(), CAInfoService::setSerial(), CAInfoService::signal(), sSleep(), CAInfoService::start(), and CAInfoService::stop().

Referenced by main().

  {
    SINT32 initStatus;
    m_bConnected = false;
    m_lLastConnectionTime = 0;

    if(initOnce()!=E_SUCCESS)
      return E_UNKNOWN;
    if(m_pMultiSignature != NULL && CALibProxytest::getOptions()->isInfoServiceEnabled())
    {
      CAMsg::printMsg(LOG_DEBUG, "CAMix start: creating InfoService object\n");
      m_pInfoService=new CAInfoService(this);

      //UINT32 opCertLength;
      //CACertificate* opCert = CALibProxytest::getOptions()->getOpCertificate();
      //CACertificate* pOwnCert=CALibProxytest::getOptions()->getOwnCertificate();
      m_pInfoService->setMultiSignature(m_pMultiSignature);
      //delete pOwnCert;
      //pOwnCert = NULL;
      UINT64 currentMillis;
      if (getcurrentTimeMillis(currentMillis) != E_SUCCESS)
      {
        currentMillis = 0;
      }
      m_pInfoService->setSerial(currentMillis);

      //delete opCert;
      //opCert = NULL;

          bool allowReconf = CALibProxytest::getOptions()->acceptReconfiguration();
          bool needReconf = needAutoConfig();

          m_pInfoService->setConfiguring(allowReconf && needReconf);
      CAMsg::printMsg(LOG_DEBUG, "CAMix start: starting InfoService\n");
      m_pInfoService->start();
    }
    else
    {
      m_pInfoService = NULL;
    }
    bool allowReconf = CALibProxytest::getOptions()->acceptReconfiguration();
#ifdef DYNAMIC_MIX
    /* LERNGRUPPE: We might want to break out of this loop if the mix-type changes */
    while(m_bLoop)
#else
    for(;;)
#endif
      {
        if (m_pInfoService != NULL)
          m_pInfoService->setConfiguring(allowReconf && needAutoConfig());
      while(allowReconf && (needAutoConfig() || m_bReconfiguring))
      {
        CAMsg::printMsg(LOG_DEBUG, "Not configured -> sleeping\n");
              sSleep(20);
          }
#ifdef DYNAMIC_MIX
      // if we change the mix type, we must not enter init!
      if(!m_bLoop) goto SKIP;
#endif
      CAMsg::printMsg(LOG_DEBUG, "CAMix main: before init()\n");
      initStatus = init();
      if(initStatus == E_SUCCESS)
        {
          m_lLastConnectionTime = time(NULL);
          m_bConnected = true;
          CAMsg::printMsg(LOG_DEBUG, "CAMix main: init() returned success\n");
          if(m_pInfoService != NULL)
            {
              m_pInfoService->setConfiguring(false);
              if( ! m_pInfoService->isRunning())
                {
                  m_pInfoService->start();
                }
              m_pInfoService->signal();
            }

          CAMsg::printMsg(LOG_INFO, "The mix is now on-line.\n");
#ifdef DYNAMIC_MIX
          m_bReconfiguring = false;
          m_bCascadeEstablished = true;
          m_bReconfigured = false;
          if(CALibProxytest::getOptions()->isFirstMix() && CALibProxytest::getOptions()->isDynamic())
            m_pInfoService->sendCascadeHelo();
#endif
          MONITORING_FIRE_SYS_EVENT(ev_sys_enterMainLoop);
          loop();
          MONITORING_FIRE_SYS_EVENT(ev_sys_leavingMainLoop);
#ifdef DYNAMIC_MIX
          m_bCascadeEstablished = false;
          if(!m_bReconfiguring)
            m_pInfoService->dynamicCascadeConfiguration();
#endif
          CAMsg::printMsg(LOG_DEBUG, "CAMix main: loop() returned, maybe connection lost.\n");
        }
      else if (initStatus == E_SHUTDOWN)
        {
          CAMsg::printMsg(LOG_DEBUG, "Mix has been stopped. Waiting for shutdown...\n");
        //break;
        }
      else
        {
          CAMsg::printMsg(LOG_DEBUG, "init() failed, maybe no connection.\n");
        }
#ifdef DYNAMIC_MIX
SKIP:
#endif
        if(m_pInfoService != NULL)
          {
#ifndef DYNAMIC_MIX
              if(CALibProxytest::getOptions()->acceptReconfiguration())
#else
        // Only keep the InfoService alive if the Mix-Type doesn't change
        if(CALibProxytest::getOptions()->acceptReconfiguration() && m_bLoop)
#endif
                  m_pInfoService->setConfiguring(true);
              /*else
        {
          CAMsg::printMsg(LOG_DEBUG, "CAMix main: stopping InfoService\n");
                  m_pInfoService->stop();
        }*/
              // maybe Cascade information (e.g. certificate validity) will change on next connection
              UINT64 currentMillis;
              if (getcurrentTimeMillis(currentMillis) != E_SUCCESS)
              {
                currentMillis = 0;
              }
              m_pInfoService->setSerial(currentMillis);
          }
          m_bConnected = false;
      m_lLastConnectionTime = 0;
      CAMsg::printMsg(LOG_DEBUG, "CAMix main: before clean()\n");
      clean();
      CAMsg::printMsg(LOG_DEBUG, "CAMix main: after clean()\n");
#ifdef DYNAMIC_MIX
      if(m_bLoop)
#endif
      sSleep(10);
    }// Big loop....
    if(m_pInfoService != NULL)
    {
      m_pInfoService->stop();
      delete m_pInfoService;
      m_pInfoService = NULL;
    }
    m_pInfoService=NULL;
    return E_SUCCESS;
  }

Here is the call graph for this function:

DOMNode * CAMix::termsAndConditionsInfoNode ( XERCES_CPP_NAMESPACE::DOMDocument *  ownerDoc) [protected]

convenience function: creates a node for the KeyInfo structure for indicating the clients which Terms And Conditions are valid.

Definition at line 577 of file CAMix.cpp.

References createDOMElement(), getDOMElementAttribute(), getElementsByTagName(), CACmdLnOptions::getOperatorSubjectKeyIdentifier(), CALibProxytest::getOptions(), KEYINFO_NODE_TNC_INFO, KEYINFO_NODE_TNC_INFOS, OPTIONS_ATTRIBUTE_TNC_DATE, OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG, OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED, OPTIONS_ATTRIBUTE_TNC_ID, OPTIONS_ATTRIBUTE_TNC_LOCALE, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, OPTIONS_NODE_TNCS_TRANSLATION, setDOMElementAttribute(), and TMP_BUFF_SIZE.

Referenced by CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), and CAFirstMix::processKeyExchange().

{
  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
  {
    DOMElement *elemTnCInfos = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_INFOS);
    UINT8 tmpBuff[TMP_BUFF_SIZE];
    UINT32 tmpLen = TMP_BUFF_SIZE;
    memset(tmpBuff, 0, tmpLen);

    DOMNodeList *list = getElementsByTagName(CALibProxytest::getOptions()->getTermsAndConditions(), OPTIONS_NODE_TNCS_TRANSLATION);
    DOMElement *iterator = NULL;
    DOMElement *currentInfoNode = NULL;
    bool defaultLangDefined = false;
    for (XMLSize_t i = 0; i < list->getLength(); i++)
    {
      iterator = (DOMElement *) list->item(i);
      currentInfoNode = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_INFO);

      getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_LOCALE, tmpBuff, &tmpLen);
      setDOMElementAttribute(currentInfoNode, OPTIONS_ATTRIBUTE_TNC_LOCALE, tmpBuff);
      getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED, defaultLangDefined);
      if(defaultLangDefined)
      {
        setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG, tmpBuff);
      }
      defaultLangDefined = false;
      tmpLen = TMP_BUFF_SIZE;

      getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, tmpBuff, &tmpLen);
      setDOMElementAttribute(currentInfoNode, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, tmpBuff);
      tmpLen = TMP_BUFF_SIZE;

      elemTnCInfos->appendChild(currentInfoNode);
    }

    getDOMElementAttribute(CALibProxytest::getOptions()->getTermsAndConditions(), OPTIONS_ATTRIBUTE_TNC_DATE, tmpBuff, &tmpLen);
    setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_DATE, tmpBuff);

    tmpLen = TMP_BUFF_SIZE;
    //memset(tmpBuff, 0, tmpLen);

    CALibProxytest::getOptions()->getOperatorSubjectKeyIdentifier(tmpBuff, &tmpLen);
    setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_ID, tmpBuff);
    return elemTnCInfos;
  }
  else
  {
    return NULL;
  }

}

Here is the call graph for this function:


Member Data Documentation

Definition at line 184 of file CAMix.hpp.

Referenced by acceptsReconfiguration(), and CAMix().

volatile bool CAMix::m_bConnected [protected]

Definition at line 185 of file CAMix.hpp.

Referenced by CAMix(), isConnected(), and start().

bool CAMix::m_bReconfiguring [protected]

Definition at line 140 of file CAMix.hpp.

Referenced by CAMix(), and start().

volatile bool CAMix::m_bShutDown [protected]

Definition at line 141 of file CAMix.hpp.

Referenced by CAMix(), isShutDown(), and shutDown().

XERCES_CPP_NAMESPACE::DOMDocument* CAMix::m_docMixCascadeInfo [protected]

Reimplemented in CAFirstMix.

Definition at line 188 of file CAMix.hpp.

Referenced by CAMix(), getMixCascadeInfo(), CALastMix::initMixCascadeInfo(), and initMixCascadeInfo().

volatile UINT32 CAMix::m_lLastConnectionTime [protected]

Definition at line 186 of file CAMix.hpp.

Referenced by CAMix(), getLastConnectionTime(), and start().


The documentation for this class was generated from the following files: