예제 #1
0
  public void exportIntroduction(OwnIdentity identity, OutputStream os)
      throws TransformerException {
    Document xmlDoc;
    synchronized (
        mDocumentBuilder) { // TODO: Figure out whether the DocumentBuilder is maybe synchronized
                            // anyway
      xmlDoc = mDOM.createDocument(null, WebOfTrust.WOT_NAME, null);
    }

    // 1.0 does not support all Unicode characters which the String class supports. To prevent us
    // from having to filter all Strings, we use 1.1
    xmlDoc.setXmlVersion("1.1");

    Element rootElement = xmlDoc.getDocumentElement();

    // We include the WoT version to have an easy way of handling bogus XML which might be created
    // by bugged versions.
    rootElement.setAttribute("Version", Long.toString(Version.getRealVersion()));

    Element introElement = xmlDoc.createElement("IdentityIntroduction");
    introElement.setAttribute(
        "Version", Integer.toString(XML_FORMAT_VERSION)); /* Version of the XML format */

    Element identityElement = xmlDoc.createElement("Identity");
    // synchronized(mWoT) { // Not necessary according to JavaDoc of identity.getRequestURI()
    identityElement.setAttribute("URI", identity.getRequestURI().toString());
    // }
    introElement.appendChild(identityElement);

    rootElement.appendChild(introElement);

    DOMSource domSource = new DOMSource(xmlDoc);
    StreamResult resultStream = new StreamResult(os);
    synchronized (
        mSerializer) { // TODO: Figure out whether the Serializer is maybe synchronized anyway
      mSerializer.transform(domSource, resultStream);
    }
  }
예제 #2
0
  /**
   * Creates an identity from an identity introduction, stores it in the database and returns the
   * new identity. If the identity already exists, the existing identity is returned.
   *
   * <p>You have to synchronize on the WebOfTrust object when using this function! TODO: Remove this
   * requirement and re-query the parameter OwnIdentity puzzleOwner from the database after we are
   * synchronized.
   *
   * @param xmlInputStream An InputStream which must not return more than {@link
   *     MAX_INTRODUCTION_BYTE_SIZE} bytes.
   * @throws InvalidParameterException If the XML format is unknown or if the puzzle owner does not
   *     allow introduction anymore.
   * @throws IOException
   * @throws SAXException
   */
  public Identity importIntroduction(OwnIdentity puzzleOwner, InputStream xmlInputStream)
      throws InvalidParameterException, SAXException, IOException {
    xmlInputStream =
        new OneBytePerReadInputStream(
            xmlInputStream); // Workaround for Java bug, see the stream class for explanation

    // May not be accurate by definition of available(). So the JavaDoc requires the callers to obey
    // the size limit, this is a double-check.
    if (xmlInputStream.available() > MAX_INTRODUCTION_BYTE_SIZE)
      throw new IllegalArgumentException(
          "XML contains too many bytes: " + xmlInputStream.available());

    FreenetURI identityURI;
    Identity newIdentity;

    Document xmlDoc;
    synchronized (
        mDocumentBuilder) { // TODO: Figure out whether the DocumentBuilder is maybe synchronized
                            // anyway
      xmlDoc = mDocumentBuilder.parse(xmlInputStream);
    }

    Element introductionElement =
        (Element) xmlDoc.getElementsByTagName("IdentityIntroduction").item(0);

    if (Integer.parseInt(introductionElement.getAttribute("Version")) > XML_FORMAT_VERSION)
      throw new InvalidParameterException(
          "Version " + introductionElement.getAttribute("Version") + " > " + XML_FORMAT_VERSION);

    Element identityElement =
        (Element) introductionElement.getElementsByTagName("Identity").item(0);

    identityURI = new FreenetURI(identityElement.getAttribute("URI"));

    final IdentityFetcher identityFetcher = mWoT.getIdentityFetcher();

    synchronized (mWoT) {
      synchronized (identityFetcher) {
        if (!puzzleOwner.hasContext(IntroductionPuzzle.INTRODUCTION_CONTEXT))
          throw new InvalidParameterException(
              "Trying to import an identity identroduction for an own identity which does not allow introduction.");

        synchronized (Persistent.transactionLock(mDB)) {
          try {
            try {
              newIdentity = mWoT.getIdentityByURI(identityURI);
              if (logMINOR)
                Logger.minor(
                    this, "Imported introduction for an already existing identity: " + newIdentity);
            } catch (UnknownIdentityException e) {
              newIdentity = new Identity(mWoT, identityURI, null, false);
              // We do NOT call setEdition(): An attacker might solve puzzles pretending to be
              // someone else and publish bogus edition numbers for
              // that identity by that. The identity constructor only takes the edition number as
              // edition hint, this is the proper behavior.
              // TODO: As soon as we have code for signing XML with an identity SSK we could sign
              // the introduction XML and therefore prevent that
              // attack.
              // newIdentity.setEdition(identityURI.getEdition());
              newIdentity.storeWithoutCommit();
              if (logMINOR)
                Logger.minor(this, "Imported introduction for an unknown identity: " + newIdentity);
            }

            try {
              mWoT.getTrust(puzzleOwner, newIdentity); /* Double check ... */
              if (logMINOR) Logger.minor(this, "The identity is already trusted.");
            } catch (NotTrustedException ex) {
              // 0 trust will not allow the import of other new identities for the new identity
              // because the trust list import code will only create
              // new identities if the score of an identity is > 0, not if it is equal to 0.
              mWoT.setTrustWithoutCommit(
                  puzzleOwner, newIdentity, (byte) 0, "Trust received by solving a captcha.");
            }

            // setTrustWithoutCommit() does this for us.
            // identityFetcher.storeStartFetchCommandWithoutCommit(newIdentity.getID());

            newIdentity.checkedCommit(this);
          } catch (RuntimeException error) {
            Persistent.checkedRollbackAndThrow(mDB, this, error);
            // Satisfy the compiler - without this the return at the end of the function would
            // complain about the uninitialized newIdentity variable
            throw error;
          }
        }
      }
    }

    return newIdentity;
  }
예제 #3
0
  public void exportOwnIdentity(OwnIdentity identity, OutputStream os) throws TransformerException {
    Document xmlDoc;
    synchronized (
        mDocumentBuilder) { // TODO: Figure out whether the DocumentBuilder is maybe synchronized
                            // anyway
      xmlDoc = mDOM.createDocument(null, WebOfTrust.WOT_NAME, null);
    }

    // 1.0 does not support all Unicode characters which the String class supports. To prevent us
    // from having to filter all Strings, we use 1.1
    xmlDoc.setXmlVersion("1.1");

    Element rootElement = xmlDoc.getDocumentElement();

    // We include the WoT version to have an easy way of handling bogus XML which might be created
    // by bugged versions.
    rootElement.setAttribute("Version", Long.toString(Version.getRealVersion()));

    /* Create the identity Element */

    Element identityElement = xmlDoc.createElement("Identity");
    identityElement.setAttribute(
        "Version", Integer.toString(XML_FORMAT_VERSION)); /* Version of the XML format */

    synchronized (mWoT) {
      identityElement.setAttribute("Name", identity.getNickname());
      identityElement.setAttribute(
          "PublishesTrustList", Boolean.toString(identity.doesPublishTrustList()));

      /* Create the context Elements */

      for (String context : identity.getContexts()) {
        Element contextElement = xmlDoc.createElement("Context");
        contextElement.setAttribute("Name", context);
        identityElement.appendChild(contextElement);
      }

      /* Create the property Elements */

      for (Entry<String, String> property : identity.getProperties().entrySet()) {
        Element propertyElement = xmlDoc.createElement("Property");
        propertyElement.setAttribute("Name", property.getKey());
        propertyElement.setAttribute("Value", property.getValue());
        identityElement.appendChild(propertyElement);
      }

      /* Create the trust list Element and its trust Elements */

      if (identity.doesPublishTrustList()) {
        Element trustListElement = xmlDoc.createElement("TrustList");

        int trustCount = 0;
        for (Trust trust : mWoT.getGivenTrustsSortedDescendingByLastSeen(identity)) {
          if (++trustCount > MAX_IDENTITY_XML_TRUSTEE_AMOUNT) {
            Logger.normal(
                this,
                "Amount of trustees exceeded "
                    + MAX_IDENTITY_XML_TRUSTEE_AMOUNT
                    + ", not adding any more to trust list of "
                    + identity);
            break;
          }

          /* We should make very sure that we do not reveal the other own identity's */
          if (trust.getTruster() != identity)
            throw new RuntimeException(
                "Error in WoT: It is trying to export trust values of someone else in the trust list "
                    + "of "
                    + identity
                    + ": Trust value from "
                    + trust.getTruster()
                    + "");

          Element trustElement = xmlDoc.createElement("Trust");
          trustElement.setAttribute("Identity", trust.getTrustee().getRequestURI().toString());
          trustElement.setAttribute("Value", Byte.toString(trust.getValue()));
          trustElement.setAttribute("Comment", trust.getComment());
          trustListElement.appendChild(trustElement);
        }
        identityElement.appendChild(trustListElement);
      }
    }

    rootElement.appendChild(identityElement);

    DOMSource domSource = new DOMSource(xmlDoc);
    StreamResult resultStream = new StreamResult(os);
    synchronized (
        mSerializer) { // TODO: Figure out whether the Serializer is maybe synchronized anyway
      mSerializer.transform(domSource, resultStream);
    }
  }