Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsHTTPSOAPTransport.cpp File Reference
#include "nsXPIDLString.h"
#include "nsHTTPSOAPTransport.h"
#include "nsIComponentManager.h"
#include "nsIDOMDocument.h"
#include "nsIDOMText.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "nsIVariant.h"
#include "nsString.h"
#include "nsSOAPUtils.h"
#include "nsSOAPCall.h"
#include "nsSOAPException.h"
#include "nsSOAPResponse.h"
#include "nsISOAPCallCompletion.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMSerializer.h"
#include "nsIWebScriptsAccessService.h"
#include "nsMemory.h"
#include "nsIDocument.h"

Go to the source code of this file.

Defines

#define DEBUG_DUMP_DOCUMENT(message, doc)

Functions

static nsresult ChangePrincipal (nsIDOMDocument *aDocument)
 This method will replace the target document's codebase principal with the subject codebase to override cross-domain checks.
static nsresult GetTransportURI (nsISOAPCall *aCall, nsAString &aURI)
 Get and check the transport URI for accessibility.
 NS_IMPL_ISUPPORTS2_CI (nsHTTPSOAPTransportCompletion, nsIDOMEventListener, nsISOAPCallCompletion) nsHTTPSOAPTransportCompletion

Define Documentation

#define DEBUG_DUMP_DOCUMENT (   message,
  doc 
)

Definition at line 86 of file nsHTTPSOAPTransport.cpp.


Function Documentation

static nsresult ChangePrincipal ( nsIDOMDocument aDocument) [static]

This method will replace the target document's codebase principal with the subject codebase to override cross-domain checks.

So use caution because this might lead to a serious security breach if misused.

Parameters:
aDocument- The target/response document.

Definition at line 98 of file nsHTTPSOAPTransport.cpp.

{
  if (!aDocument)
    return NS_OK;

  nsresult rv;
  nsCOMPtr<nsIScriptSecurityManager> secMgr = 
    do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  
  nsCOMPtr<nsIDocument> targetDoc(do_QueryInterface(aDocument, &rv));
  NS_ENSURE_SUCCESS(rv, rv);
  
  rv = secMgr->CheckSameOrigin(nsnull, targetDoc->GetDocumentURI());
  // change the principal only if the script security 
  // manager has denied access.
  if (NS_FAILED(rv)) {
    nsCOMPtr<nsIPrincipal> subjectPrincipal;
    rv = secMgr->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
    if (NS_SUCCEEDED(rv))
      targetDoc->SetPrincipal(subjectPrincipal);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsresult GetTransportURI ( nsISOAPCall aCall,
nsAString &  aURI 
) [static]

Get and check the transport URI for accessibility.

In the future, this might also attempt to automatically add a mustUnderstand header to messages for untrusted sources and send them anyway.

Definition at line 128 of file nsHTTPSOAPTransport.cpp.

{
  nsresult rc = aCall->GetTransportURI(aURI);
  if (NS_FAILED(rc))
    return rc;
  
  // Create a new URI
  nsCOMPtr<nsIURI> uri;
  rc = NS_NewURI(getter_AddRefs(uri), aURI, nsnull);
  if (NS_FAILED(rc)) 
    return rc;

  nsCOMPtr<nsIWebScriptsAccessService> wsa_service = 
      do_GetService(NS_WEBSCRIPTSACCESSSERVICE_CONTRACTID, &rc);
  if (NS_FAILED(rc)) 
    return rc;
 
  PRBool safe = PR_FALSE;
  rc = aCall->GetVerifySourceHeader(&safe);
  if (NS_FAILED(rc)) 
    return rc;

  nsCOMPtr<nsIScriptSecurityManager> secMan;
  PRBool accessGranted;
  if (!safe) {
    rc = wsa_service->CanAccess(uri, NS_LITERAL_STRING("soap"), &accessGranted);
    if (NS_FAILED(rc))
      return rc;
    if (!accessGranted) {
      // Get security manager, check to see if we're allowed to call this URI.
      secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rc);
      if (NS_FAILED(rc)) 
        return rc;
      if (NS_FAILED(secMan->CheckConnect(nsnull, uri, "SOAPCall", "invoke")))
        return SOAP_EXCEPTION(NS_ERROR_FAILURE,
                              "SOAP_INVOKE_DISABLED", 
                              "SOAPCall.invoke not enabled by client");
    }
  }
  else {
    // Get security manager, check to see if we're allowed to call this URI.
    secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rc);
    if (NS_FAILED(rc))
      return rc;
    rc = wsa_service->CanAccess(uri, NS_LITERAL_STRING("soapv"), &accessGranted);
    if (NS_FAILED(rc))
      return rc;
    if (!accessGranted) {
      if (NS_FAILED(secMan->CheckConnect(nsnull, uri, "SOAPCall", "invokeVerifySourceHeader")))
        return SOAP_EXCEPTION(NS_ERROR_FAILURE,
                              "SOAP_INVOKE_VERIFY_DISABLED", 
                              "SOAPCall.invokeVerifySourceHeader not enabled by client");
    }

    nsAutoString sourceURI;

    {

      nsCOMPtr<nsIPrincipal> principal;
      rc = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
      if (NS_FAILED(rc)) 
        return rc;
      if (!principal) {
        return SOAP_EXCEPTION(NS_ERROR_FAILURE,
                              "SOAP_INVOKE_VERIFY_PRINCIPAL", 
                              "Source-verified message cannot be sent without principal.");
      }

      nsCOMPtr<nsIURI> uri;
      principal->GetURI(getter_AddRefs(uri));
      if (!uri) {
        return SOAP_EXCEPTION(NS_ERROR_FAILURE,
                              "SOAP_INVOKE_VERIFY_URI", 
                              "Source-verified message cannot be sent without URI.");
      }

      nsCAutoString spec;
      rc = uri->GetSpec(spec);
      if (NS_FAILED(rc)) 
        return rc;
      CopyASCIItoUCS2(spec, sourceURI);
    }

//  Adding a header to tell the server that it must understand and verify the source of the call

    nsCOMPtr<nsIDOMElement> element;
    rc = aCall->GetHeader(getter_AddRefs(element));
    if (NS_FAILED(rc)) 
      return rc;
    if (!element)
      return SOAP_EXCEPTION(NS_ERROR_FAILURE,"SOAP_INVOKE_VERIFY_HEADER", "Source-verified message cannot be sent without a header.");
    //  Node ignored on remove / append calls
    nsCOMPtr<nsIDOMNode> ignore;
    //  Remove any existing elements that may conflict with this verifySource identification
    nsCOMPtr<nsIDOMElement> verifySource;
    for (;;) {
      nsSOAPUtils::GetSpecificChildElement(nsnull, element, gSOAPStrings->kVerifySourceNamespaceURI, 
        gSOAPStrings->kVerifySourceHeader, getter_AddRefs(verifySource));
      if (verifySource) {
        rc = element->RemoveChild(verifySource, getter_AddRefs(ignore));
        if (NS_FAILED(rc))
          return rc;
      }
      else
       break;
    }
    //  Document as factory
    nsCOMPtr<nsIDOMDocument> document;
    rc = element->GetOwnerDocument(getter_AddRefs(document));
    if (NS_FAILED(rc)) 
      return rc;
    //  Proper version to use of SOAP
    PRUint16 version;
    rc = aCall->GetVersion(&version);
    if (NS_FAILED(rc)) 
      return rc;
    //  Proper schema to use for types
    nsAutoString XSURI;
    nsAutoString XSIURI;
    nsAutoString SOAPEncURI;
    if (version == nsISOAPMessage::VERSION_1_1) {
      XSURI.Assign(gSOAPStrings->kXSURI1999);
      XSIURI.Assign(gSOAPStrings->kXSIURI1999);
      SOAPEncURI.Assign(gSOAPStrings->kSOAPEncURI11);
    }
    else {
      XSURI.Assign(gSOAPStrings->kXSURI);
      XSIURI.Assign(gSOAPStrings->kXSIURI);
      SOAPEncURI.Assign(gSOAPStrings->kSOAPEncURI);
    }
    //  Create the header and append it with mustUnderstand and normal encoding.
    rc = document->CreateElementNS(gSOAPStrings->kVerifySourceNamespaceURI, 
      gSOAPStrings->kVerifySourceHeader, 
      getter_AddRefs(verifySource));
    if (NS_FAILED(rc)) 
      return rc;
    rc = element->AppendChild(verifySource, getter_AddRefs(ignore));
    if (NS_FAILED(rc)) 
      return rc;
    rc = verifySource->SetAttributeNS(*gSOAPStrings->kSOAPEnvURI[version],
      gSOAPStrings->kMustUnderstandAttribute,gSOAPStrings->kTrueA);// mustUnderstand
    if (NS_FAILED(rc)) 
      return rc;
    rc = verifySource->SetAttributeNS(*gSOAPStrings->kSOAPEnvURI[version], 
      gSOAPStrings->kEncodingStyleAttribute, SOAPEncURI);// 1.2 encoding
    if (NS_FAILED(rc)) 
      return rc;

    //  Prefixed string for xsi:string
    nsAutoString stringType;
    {
      nsAutoString prefix;
      rc = nsSOAPUtils::MakeNamespacePrefix(nsnull, verifySource, XSURI, stringType);
      if (NS_FAILED(rc)) 
        return rc;
      stringType.Append(gSOAPStrings->kQualifiedSeparator);
      stringType.AppendLiteral("anyURI");
    }

    //  If it is available, add the sourceURI 
    if (!sourceURI.IsEmpty()) {
      rc = document->CreateElementNS(gSOAPStrings->kVerifySourceNamespaceURI,
        gSOAPStrings->kVerifySourceURI,getter_AddRefs(element));
      if (NS_FAILED(rc)) 
        return rc;
      rc = verifySource->AppendChild(element, getter_AddRefs(ignore));
      if (NS_FAILED(rc)) 
        return rc;
      rc = element->SetAttributeNS(XSIURI,
        gSOAPStrings->kXSITypeAttribute,stringType);
      if (NS_FAILED(rc)) 
        return rc;
      nsCOMPtr<nsIDOMText> text;
      rc = document->CreateTextNode(sourceURI, getter_AddRefs(text));
      if (NS_FAILED(rc)) 
        return rc;
      rc = element->AppendChild(text, getter_AddRefs(ignore));
      if (NS_FAILED(rc)) 
        return rc;
    }
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 433 of file nsHTTPSOAPTransport.cpp.

{
}