public String toString(boolean prefix, boolean pureAscii) {
    if (keyType == null) {
      // Not activated or something...
      if (logMINOR)
        Logger.minor(this, "Not activated?? in toString(" + prefix + "," + pureAscii + ")");
      return null;
    }
    StringBuilder b;
    if (prefix) b = new StringBuilder("freenet:");
    else b = new StringBuilder();

    b.append(keyType).append('@');

    if (!"KSK".equals(keyType)) {
      if (routingKey != null) b.append(Base64.encode(routingKey));
      if (cryptoKey != null) b.append(',').append(Base64.encode(cryptoKey));
      if (extra != null) b.append(',').append(Base64.encode(extra));
      if (docName != null) b.append('/');
    }

    if (docName != null) b.append(URLEncoder.encode(docName, "/", pureAscii));
    if (keyType.equals("USK")) {
      b.append('/');
      b.append(suggestedEdition);
    }
    if (metaStr != null)
      for (int i = 0; i < metaStr.length; i++) {
        b.append('/').append(URLEncoder.encode(metaStr[i], "/", pureAscii));
      }
    return b.toString();
  }
 public String getPreferredFilename() {
   if (logMINOR) Logger.minor(this, "Getting preferred filename for " + this);
   ArrayList<String> names = new ArrayList<String>();
   if (keyType != null
       && (keyType.equals("KSK") || keyType.equals("SSK") || keyType.equals("USK"))) {
     if (logMINOR) Logger.minor(this, "Adding docName: " + docName);
     names.add(docName);
     if (keyType.equals("USK")) names.add(Long.toString(suggestedEdition));
   }
   if (metaStr != null)
     for (int i = 0; i < metaStr.length; i++) {
       if (logMINOR) Logger.minor(this, "Adding metaString " + i + ": " + metaStr[i]);
       names.add(metaStr[i]);
     }
   StringBuilder out = new StringBuilder();
   for (int i = 0; i < names.size(); i++) {
     String s = names.get(i);
     if (logMINOR) Logger.minor(this, "name " + i + " = " + s);
     s = FileUtil.sanitize(s);
     if (logMINOR) Logger.minor(this, "Sanitized name " + i + " = " + s);
     if (s.length() > 0) {
       if (out.length() > 0) out.append('-');
       out.append(s);
     }
   }
   if (logMINOR) Logger.minor(this, "out = " + out.toString());
   if (out.length() == 0) {
     if (routingKey != null) {
       if (logMINOR) Logger.minor(this, "Returning base64 encoded routing key");
       return Base64.encode(routingKey);
     }
     return "unknown";
   }
   return out.toString();
 }
 public String getDomain() {
   try {
     return Base32.encode(Base64.decode(identity)).toLowerCase(Locale.ROOT) + ".freemail";
   } catch (IllegalBase64Exception e) {
     // This would mean that WoT has changed the encoding of the identity string
     throw new AssertionError("Got IllegalBase64Exception when decoding " + identity);
   }
 }
  public void exportIntroductionPuzzle(IntroductionPuzzle puzzle, OutputStream os)
      throws TransformerException, ParserConfigurationException {

    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 puzzleElement = xmlDoc.createElement("IntroductionPuzzle");
    puzzleElement.setAttribute(
        "Version",
        Integer.toString(INTRODUCTION_XML_FORMAT_VERSION)); /* Version of the XML format */

    // This lock is actually not necessary because all values which are taken from the puzzle are
    // final. We leave it here just to make sure that it does
    // not get lost if it becomes necessary someday.
    synchronized (puzzle) {
      puzzleElement.setAttribute("ID", puzzle.getID());
      puzzleElement.setAttribute("Type", puzzle.getType().toString());
      puzzleElement.setAttribute("MimeType", puzzle.getMimeType());
      synchronized (mDateFormat) {
        puzzleElement.setAttribute("ValidUntil", mDateFormat.format(puzzle.getValidUntilDate()));
      }

      Element dataElement = xmlDoc.createElement("Data");
      dataElement.setAttribute("Value", Base64.encodeStandard(puzzle.getData()));
      puzzleElement.appendChild(dataElement);
    }

    rootElement.appendChild(puzzleElement);

    DOMSource domSource = new DOMSource(xmlDoc);
    StreamResult resultStream = new StreamResult(os);
    synchronized (mSerializer) {
      mSerializer.transform(domSource, resultStream);
    }
  }
  public IntroductionPuzzle getIntroductionPuzzle(String id) throws Exception {
    SimpleFieldSet params = new SimpleFieldSet(true);
    params.putOverwrite("Message", "GetIntroductionPuzzle");
    params.putOverwrite("Puzzle", id);

    try {
      SimpleFieldSet result = sendFCPMessageBlocking(params, null, "IntroductionPuzzle").params;

      try {
        return new IntroductionPuzzle(
            id, result.get("MimeType"), Base64.decodeStandard(result.get("Data")));
      } catch (RuntimeException e) {
        Logger.error(this, "Parsing puzzle failed", e);
      } catch (IllegalBase64Exception e) {
        Logger.error(this, "Parsing puzzle failed", e);
      }

      return null;
    } catch (PluginNotFoundException e) {
      Logger.error(this, "Getting puzzles failed", e);

      return null;
    }
  }
  FreemailAccount(String identity, File _accdir, PropsFile _accprops, Freemail freemail) {
    if (!FreenetURI.checkSSKHash(identity)) {
      throw new IllegalArgumentException("Expected valid identity string, but got " + identity);
    }
    try {
      Base64.decode(identity);
    } catch (IllegalBase64Exception e) {
      throw new IllegalArgumentException("Couldn't decode identity string: " + identity, e);
    }

    this.identity = identity;
    accdir = _accdir;
    accprops = _accprops;
    mb = new MessageBank(this);

    File channelDir = new File(accdir, "channel");
    messageHandler =
        new MessageHandler(
            new File(accdir, "outbox"),
            freemail,
            channelDir,
            this,
            new HighLevelFCPClientFactory());
  }
 // TODO: Replace with IdentityID.constructFromURI
 public static String getIDFromURI(FreenetURI uri) {
   /* WARNING: This is a copy of the code of plugins.WoT.Identity. Freetalk is not allowed to have its own custom IDs, you cannot change
    * this code here. */
   return Base64.encode(uri.getRoutingKey());
 }
  public FreenetURI(String URI) throws MalformedURLException {
    //		this.uniqueHashCode = super.hashCode();
    if (URI == null) throw new MalformedURLException("No URI specified");

    URI = URI.trim();
    if (URI.indexOf('@') < 0 || URI.indexOf('/') < 0)
      // Encoded URL?
      try {
        URI = URLDecoder.decode(URI, false);
      } catch (URLEncodedFormatException e) {
        throw new MalformedURLException(
            "Invalid URI: no @ or /, or @ or / is escaped but there are invalid escapes");
      }

    URI = URI_PREFIX.matcher(URI).replaceFirst("");

    // decode keyType
    int atchar = URI.indexOf('@');
    if (atchar == -1) throw new MalformedURLException("There is no @ in that URI! (" + URI + ')');

    String _keyType = URI.substring(0, atchar).toUpperCase();
    URI = URI.substring(atchar + 1);

    boolean validKeyType = false;
    for (int i = 0; i < VALID_KEY_TYPES.length; i++) {
      if (_keyType.equals(VALID_KEY_TYPES[i])) {
        validKeyType = true;
        _keyType = VALID_KEY_TYPES[i];
        break;
      }
    }
    keyType = _keyType;
    if (!validKeyType) throw new MalformedURLException("Invalid key type: " + keyType);

    boolean isSSK = "SSK".equals(keyType);
    boolean isUSK = "USK".equals(keyType);
    boolean isKSK = "KSK".equals(keyType);

    // decode metaString
    ArrayList<String> sv = null;
    int slash2;
    sv = new ArrayList<String>();
    if (isKSK) URI = "/" + URI; // ensure that KSK docNames are decoded
    while ((slash2 = URI.lastIndexOf('/')) != -1) {
      String s;
      try {
        s = URLDecoder.decode(URI.substring(slash2 + 1 /* "/".length() */), true);
      } catch (URLEncodedFormatException e) {
        MalformedURLException ue = new MalformedURLException(e.toString());
        ue.initCause(e);
        throw ue;
      }
      if (s != null) sv.add(s);
      URI = URI.substring(0, slash2);
    }

    // sv is *backwards*
    // this makes for more efficient handling

    if (isSSK || isUSK || isKSK) {

      if (sv.isEmpty()) throw new MalformedURLException("No docname for " + keyType);
      docName = sv.remove(sv.size() - 1);
      if (isUSK) {
        if (sv.isEmpty()) throw new MalformedURLException("No suggested edition number for USK");
        try {
          suggestedEdition = Long.parseLong(sv.remove(sv.size() - 1));
        } catch (NumberFormatException e) {
          MalformedURLException e1 = new MalformedURLException("Invalid suggested edition: " + e);
          e1.initCause(e);
          throw e1;
        }
      } else suggestedEdition = -1;
    } else {
      // docName not necessary, nor is it supported, for CHKs.
      docName = null;
      suggestedEdition = -1;
    }

    if (!sv.isEmpty()) {
      metaStr = new String[sv.size()];
      for (int i = 0; i < metaStr.length; i++) {
        metaStr[i] = sv.get(metaStr.length - 1 - i).intern();
        if (metaStr[i] == null) throw new NullPointerException();
      }
    } else metaStr = null;

    if (isKSK) {
      routingKey = extra = cryptoKey = null;
      return;
    }

    // strip 'file extensions' from CHKs
    // added by aum ([email protected])
    if ("CHK".equals(keyType)) URI = URI.split("[.]")[0];

    // URI now contains: routingKey[,cryptoKey][,metaInfo]
    StringTokenizer st = new StringTokenizer(URI, ",");
    try {
      if (st.hasMoreTokens()) routingKey = Base64.decode(st.nextToken());
      else {
        routingKey = cryptoKey = extra = null;
        return;
      }
      if (!st.hasMoreTokens()) {
        cryptoKey = extra = null;
        return;
      }

      // Can be cryptokey or name-value pair.
      String t = st.nextToken();
      cryptoKey = Base64.decode(t);
      if (!st.hasMoreTokens()) {
        extra = null;
        return;
      }
      extra = Base64.decode(st.nextToken());

    } catch (IllegalBase64Exception e) {
      throw new MalformedURLException("Invalid Base64 quantity: " + e);
    }
    if (logDEBUG)
      Logger.minor(
          this, "Created from parse: " + toString() + " from " + URI, new Exception("debug"));
  }
  /**
   * @param xmlInputStream An InputStream which must not return more than {@link
   *     MAX_INTRODUCTIONPUZZLE_BYTE_SIZE} bytes.
   */
  public IntroductionPuzzle importIntroductionPuzzle(
      FreenetURI puzzleURI, InputStream xmlInputStream)
      throws SAXException, IOException, InvalidParameterException, UnknownIdentityException,
          IllegalBase64Exception, ParseException {

    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_INTRODUCTIONPUZZLE_BYTE_SIZE)
      throw new IllegalArgumentException(
          "XML contains too many bytes: " + xmlInputStream.available());

    String puzzleID;
    IntroductionPuzzle.PuzzleType puzzleType;
    String puzzleMimeType;
    Date puzzleValidUntilDate;
    byte[] puzzleData;

    Document xmlDoc;
    synchronized (
        mDocumentBuilder) { // TODO: Figure out whether the DocumentBuilder is maybe synchronized
                            // anyway
      xmlDoc = mDocumentBuilder.parse(xmlInputStream);
    }
    Element puzzleElement = (Element) xmlDoc.getElementsByTagName("IntroductionPuzzle").item(0);

    if (Integer.parseInt(puzzleElement.getAttribute("Version")) > INTRODUCTION_XML_FORMAT_VERSION)
      throw new InvalidParameterException(
          "Version "
              + puzzleElement.getAttribute("Version")
              + " > "
              + INTRODUCTION_XML_FORMAT_VERSION);

    puzzleID = puzzleElement.getAttribute("ID");
    puzzleType = IntroductionPuzzle.PuzzleType.valueOf(puzzleElement.getAttribute("Type"));
    puzzleMimeType = puzzleElement.getAttribute("MimeType");
    synchronized (mDateFormat) {
      puzzleValidUntilDate = mDateFormat.parse(puzzleElement.getAttribute("ValidUntil"));
    }

    Element dataElement = (Element) puzzleElement.getElementsByTagName("Data").item(0);
    puzzleData = Base64.decodeStandard(dataElement.getAttribute("Value"));

    IntroductionPuzzle puzzle;

    synchronized (mWoT) {
      Identity puzzleInserter = mWoT.getIdentityByURI(puzzleURI);
      puzzle =
          new IntroductionPuzzle(
              mWoT,
              puzzleInserter,
              puzzleID,
              puzzleType,
              puzzleMimeType,
              puzzleData,
              IntroductionPuzzle.getDateFromRequestURI(puzzleURI),
              puzzleValidUntilDate,
              IntroductionPuzzle.getIndexFromRequestURI(puzzleURI));

      mWoT.getIntroductionPuzzleStore().storeAndCommit(puzzle);
    }

    return puzzle;
  }
Exemple #10
0
 @Override
 public String toString() {
   return super.toString() + '@' + Base64.encode(routingKey) + ':' + Integer.toHexString(hash);
 }