public synchronized void addTorrentEntry(URN urn) { String torrentDirPath = SharingSettings.INCOMPLETE_DIRECTORY.get().getAbsolutePath() + File.separator + Base32.encode(urn.getBytes()); File torrentDir = new File(torrentDirPath); hashes.put(urn, torrentDir); }
public static PublicKey loadPublicKey(String base32) throws IOException, SignatureException, InvalidKeyException { ByteArrayInputStream bais = new ByteArrayInputStream(Base32.decode(base32)); GZIPInputStream gz = null; try { gz = new GZIPInputStream(bais); return loadPublicKey(gz); } finally { if (gz != null) { gz.close(); } } }
public XMLTorrent(LimeXMLDocument xmlDocument) throws InvalidDataException { this.name = parseTorrentName(xmlDocument); this.torrentFileEntries = parsePathEntries(xmlDocument); this.size = computeTotalSize(this.torrentFileEntries); this.trackers = parseTrackers(xmlDocument.getValue(LimeXMLNames.TORRENT_TRACKERS)); this.trackerUris = getTrackerUris(this.trackers); String privateValue = xmlDocument.getValue(LimeXMLNames.TORRENT_PRIVATE); this.isPrivate = privateValue != null && Boolean.parseBoolean(privateValue); String hash = xmlDocument.getValue(LimeXMLNames.TORRENT_INFO_HASH); if (!StringUtils.isEmpty(hash)) { byte[] bytes = Base32.decode(hash); if (bytes.length != SHA1.HASH_LENGTH) { throw new InvalidDataException("torrent xml with invalid hash: " + xmlDocument); } sha1 = StringUtils.toHexString(bytes); } else { throw new InvalidDataException("torrent xml without info hash: " + xmlDocument); } }
private void doHTTPRequestTest(boolean settingOn, boolean expectTLS) throws Exception { if(settingOn) networkManagerStub.setIncomingTLSEnabled(true); setAccepted(true); BlockingConnectionUtils.drain(testUP[0]); // some setup byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "boalt.org"); // the testUP[0] should get it Message m; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // set up a server socket ServerSocket ss = new ServerSocket(7000); try { ss.setReuseAddress(true); ss.setSoTimeout(25 * TIMEOUT); // send a reply with some PushProxy info Set<IpPort> proxies = new TreeSet<IpPort>(IpPort.COMPARATOR); proxies.add(new IpPortImpl("127.0.0.1", 7000)); Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "boalt.org", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply(m.getGUID(), (byte) 1, 6355, myIP(), 0, res, clientGUID, new byte[0], true, false, true, true, false, false, proxies); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to download the file, should result in push proxy // request Downloader download = downloadServices.download((new RemoteFileDesc[] { callback.getRFD() }), true, new GUID(m.getGUID())); // wait for the incoming HTTP request Socket httpSock = ss.accept(); try { assertNotNull(httpSock); // start reading and confirming the HTTP request String currLine; BufferedReader reader = new BufferedReader(new InputStreamReader(httpSock.getInputStream())); // confirm a GET/HEAD pushproxy request currLine = reader.readLine(); assertTrue(currLine.startsWith("GET /gnutella/push-proxy") || currLine.startsWith("HEAD /gnutella/push-proxy")); if(expectTLS) { assertTrue(currLine.contains("tls=true")); } else { assertFalse(currLine.contains("tls")); } // make sure it sends the correct client GUID int beginIndex = currLine.indexOf("ID=") + 3; String guidString = currLine.substring(beginIndex, beginIndex+26); GUID guidFromBackend = new GUID(clientGUID); GUID guidFromNetwork = new GUID(Base32.decode(guidString)); assertEquals(guidFromNetwork, guidFromBackend); // make sure the node sends the correct X-Node currLine = reader.readLine(); assertTrue(currLine.startsWith("X-Node:")); StringTokenizer st = new StringTokenizer(currLine, ":"); assertEquals(st.nextToken(), "X-Node"); InetAddress addr = InetAddress.getByName(st.nextToken().trim()); Arrays.equals(addr.getAddress(), networkManagerStub.getAddress()); assertEquals(PORT, Integer.parseInt(st.nextToken())); // send back a 202 and make sure no PushRequest is sent via the normal // way BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpSock.getOutputStream())); writer.write("HTTP/1.1 202 gobbledygook"); writer.flush(); } finally { httpSock.close(); } try { do { m = testUP[0].receive(TIMEOUT); assertTrue(!(m instanceof PushRequest)); } while (true) ; } catch (InterruptedIOException ignore) {} // now make a connection to the leaf to confirm that it will send a // correct download request Socket push = new Socket(InetAddress.getLocalHost(), PORT); try { BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(push.getOutputStream())); writer.write("GIV "); writer.flush(); NIOTestUtils.waitForNIO(); // the PUSH request is not matched in PushList.getBestHost() if // this is set to false: the RemoteFileDesc contains the IP // 192.168.0.1 but since we are connecting from a different IP // it is not matched but it'll accept it this is set to true and // both IPs are private ConnectionSettings.LOCAL_IS_PRIVATE.setValue(true); writer.write("0:" + new GUID(clientGUID).toHexString() + "/\r\n"); writer.write("\r\n"); writer.flush(); BufferedReader reader = new BufferedReader(new InputStreamReader(push.getInputStream())); String currLine = reader.readLine(); assertEquals(MessageFormat.format("GET /uri-res/N2R?{0} HTTP/1.1", UrnHelper.SHA1), currLine); } finally { push.close(); } download.stop(); } finally { ss.close(); } }
public void testPushProxyRequest() throws Exception { // wait for connections to process any messages Thread.sleep(6000); BlockingConnectionUtils.drain(testUP[0]); // some setup final byte[] clientGUID = GUID.makeGuid(); // construct and send a query byte[] guid = GUID.makeGuid(); searchServices.query(guid, "nyu.edu"); // the testUP[0] should get it Message m = null; do { m = testUP[0].receive(TIMEOUT); } while (!(m instanceof QueryRequest)); // set up a server socket to wait for proxy request ServerSocket ss = new ServerSocket(7000); try { ss.setReuseAddress(true); ss.setSoTimeout(TIMEOUT * 4); // send a reply with some PushProxy info final IpPortSet proxies = new IpPortSet(); proxies.add(new IpPortImpl("127.0.0.1", 7000)); Response[] res = new Response[1]; res[0] = responseFactory.createResponse(10, 10, "nyu.edu", UrnHelper.SHA1); m = queryReplyFactory.createQueryReply( m.getGUID(), (byte) 1, 6999, InetAddress.getLocalHost().getAddress(), 0, res, clientGUID, new byte[0], true, false, true, true, false, false, proxies); testUP[0].send(m); testUP[0].flush(); // wait a while for Leaf to process result assertNotNull(callback.getRFD()); // tell the leaf to browse host the file, should result in PushProxy // request searchServices.doAsynchronousBrowseHost( new MockFriendPresence( new MockFriend(), null, new AddressFeature(callback.getRFD().getAddress())), new GUID(), new BrowseListener() { public void handleBrowseResult(SearchResult searchResult) { // To change body of implemented methods use File | Settings | File Templates. } public void browseFinished(boolean success) { // To change body of implemented methods use File | Settings | File Templates. } }); // wait for the incoming PushProxy request // increase the timeout since we send udp pushes first ss.setSoTimeout(7000); Socket httpSock = ss.accept(); try { BufferedWriter sockWriter = new BufferedWriter( new OutputStreamWriter(httpSock.getOutputStream(), HTTP.DEFAULT_PROTOCOL_CHARSET)); sockWriter.write("HTTP/1.1 202 OK\r\n"); sockWriter.flush(); // start reading and confirming the HTTP request String currLine = null; BufferedReader reader = new BufferedReader( new InputStreamReader(httpSock.getInputStream(), HTTP.DEFAULT_PROTOCOL_CHARSET)); // confirm a GET/HEAD pushproxy request currLine = reader.readLine(); assertTrue( currLine.startsWith("GET /gnutella/push-proxy") || currLine.startsWith("HEAD /gnutella/push-proxy")); // make sure it sends the correct client GUID int beginIndex = currLine.indexOf("ID=") + 3; String guidString = currLine.substring(beginIndex, beginIndex + 26); GUID guidFromBackend = new GUID(clientGUID); GUID guidFromNetwork = new GUID(Base32.decode(guidString)); assertEquals(guidFromNetwork, guidFromBackend); // make sure the node sends the correct X-Node currLine = reader.readLine(); assertTrue(currLine.startsWith("X-Node:")); StringTokenizer st = new StringTokenizer(currLine, ":"); assertEquals(st.nextToken(), "X-Node"); InetAddress addr = InetAddress.getByName(st.nextToken().trim()); Arrays.equals(addr.getAddress(), networkManagerStub.getAddress()); assertEquals(SERVER_PORT, Integer.parseInt(st.nextToken())); // now we need to GIV Socket push = new Socket(InetAddress.getLocalHost(), SERVER_PORT); try { BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(push.getOutputStream(), HTTP.DEFAULT_PROTOCOL_CHARSET)); writer.write("GIV 0:" + new GUID(clientGUID).toHexString() + "/\r\n"); writer.write("\r\n"); writer.flush(); assertIsBrowse(push, push.getLocalPort()); } finally { push.close(); } } finally { httpSock.close(); } try { do { m = testUP[0].receive(TIMEOUT); assertNotInstanceof(m.toString(), PushRequest.class, m); } while (true); } catch (InterruptedIOException expected) { } } finally { ss.close(); } }
/** * Constructs the file system using the given BTData & hash information. If any of the information * is malformed, throws a ValueException. * * @param data contains all the data about a .torrent file * @param numHashes number of pieces the torrent was divided into * @param pieceLength size of divided up torrent file * @param infoHash a string of alphanumeric characters in the .torrent file that the client uses * to verify the data that is being transferred * @throws ValueException */ TorrentFileSystem(BTData data, int numHashes, long pieceLength, byte[] infoHash) throws IOException { // name of the torrent, also specifying the directory under which to save the torrents. _name = CommonUtils.convertFileName(data.getName()); // we need to check the name of the torrent, security risk! if (_name.length() == 0) throw new ValueException("bad torrent name"); _incompleteFile = new File( SharingSettings.INCOMPLETE_DIRECTORY.get(), Base32.encode(infoHash) + File.separator + _name); _completeFile = new File(SharingSettings.getSaveDirectory(_name), _name); if (!FileUtils.isReallyParent(SharingSettings.getSaveDirectory(_name), _completeFile)) { throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, _completeFile); } if (data.getFiles() != null) { List<BTData.BTFileData> files = data.getFiles(); List<TorrentFile> torrents = new ArrayList<TorrentFile>(files.size()); long position = 0; for (BTData.BTFileData file : files) { String torrentPath = _name + file.getPath(); TorrentFile f = new TorrentFile( file.getLength(), new File(_completeFile, file.getPath()).getAbsolutePath(), torrentPath); f.setBeginPiece((int) (position / pieceLength)); f.setStartByte(position); position += f.length(); f.setEndPiece((int) (position / pieceLength)); f.setEndByte(position - 1); if (!FileUtils.isReallyInParentPath(_completeFile, f)) throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, f); torrents.add(f); } if (files.size() == 0) throw new ValueException("bad metainfo, no files!"); _files = torrents; // add folders, for easier conflict checking later on for (String folderPath : data.getFolders()) _folders.add(new File(_completeFile, folderPath)); _folders.add(_completeFile); } else { String torrentPath = data.getName(); TorrentFile f = new TorrentFile(data.getLength(), _completeFile.getAbsolutePath(), torrentPath); f.setBeginPiece(0); f.setStartByte(0); f.setEndPiece(numHashes - 1); f.setEndByte(f.length()); _files = new ArrayList<TorrentFile>(1); _files.add(f); } _unmodFiles = Collections.unmodifiableList(_files); _totalSize = calculateTotalSize(_files); if (_totalSize <= 0) throw new ValueException("invalid size " + _totalSize); }
private QueryReply createLimeReply() { byte[] reply = Base32.decode(SearchSettings.LIME_SIGNED_RESPONSE.get()); return createReply(new ByteArrayInputStream(reply)); }
public byte[] getOldUpdateResponse() { return Base32.decode( "I5AVOQKFIZCE4Q2RKFATKVBWKBKVEWSOJRFU6WS2JVIUCR2QGRJESNBVIE3UESKDINIUCSSWIZKE2WCHGZKFMMS2GJAVSTKCGQ2TINSLIRFEQWCRG5KEITL4PQ6HK4DEMF2GKIDJMQ6SEMRRGQ3TIOBTGY2DOIRAORUW2ZLTORQW24B5EIYSEPQKEAQCAPDNONTSAZTSN5WT2IRXGYXDONZOG42SEIDGN5ZD2IRYGYXDQOBOHA2SEIDUN46SEOBWFY4DSLRYGURCA5LSNQ6SE2DUORYDULZPO53XOLTMNFWWK53JOJSS4Y3PNUXXK4DEMF2GKIRAON2HS3DFHURDAIRAN5ZT2ISXNFXGI33XOMRCA5LSNY6SE5LSNY5GE2LUOBZGS3TUHJIEYUCSKRIEET2BKJBE6U2BJNIECTKHKZJTEU2MGU3VGM2HIRGFCLRXIZIEGR2NG43VGSCPKFGVAUSQJU2UGNKMJ5NEKT2EG43EGRK2IQ2E2USBIVGESIRAOVRW63LNMFXGIPJHEISCKIRAF5JSOIDVNZQW2ZJ5EJGGS3LFK5UXEZKXNFXDILRRGYXDMLTFPBSSEIDTNF5GKPJCGQ2TANRSGU3CEPQKEAQCAIBAEA6GYYLOM4QGSZB5E5SW4JZ6BIQCAIBAEAQCAIB4EFNUGRCBKRAVWNBOGE3C4NRAKVJE4XK5HYFCAIBAEAQCAPBPNRQW4ZZ6BIQCAIB4F5WXGZZ6BIQCAIBAEAQDY3LTM4QGM4TPNU6SENBOHAXDCIRAMZXXEPJCGQXDCNROGYRCA5LSNQ6SE2DUORYDULZPO53XOLTMNFWWK53JOJSS4Y3PNUXXK4DEMF2GKIRAMZZGKZJ5EJ2HE5LFEIQG64Z5EJLWS3TEN53XGIRAON2HS3DFHURDIIRAOVZG4PJCOVZG4OTCNF2HA4TJNZ2DUUCMKBJFIUCCJ5AVEQSPKNAUWUCBJVDVMUZSKNGDKN2TGNDUITCRFY3UMUCDI5GTON2TJBHVCTKQKJIE2NKDGVGE6WSFJ5CDONSDIVNEINCNKJAUKTCJEIQHKY3PNVWWC3TEHUTSEJBFEIQC6UZHEB2W4YLNMU6SETDJNVSVO2LSMVLWS3RUFYYTMLRWFZSXQZJCEBZWS6TFHURDINJQGYZDKNRCHYFCAIBAEAQCAPDMMFXGOIDJMQ6SOZLOE47AUIBAEAQCAIB4EFNUGRCBKRAVWCRAEAQCAIBAHR2GCYTMMUQGC3DJM5XD2Y3FNZ2GK4RAOZQWY2LHNY6WGZLOORSXEPR4ORZD4PDUMQ7AUPDDMVXHIZLSHY6GEPSVOJTWK3TUEBGGS3LFK5UXEZJAKNSWG5LSNF2HSICVOBSGC5DFEBAXMYLJNRQWE3DFFY6GE4R6BJIGYZLBONSSAVLQMRQXIZJAJFWW2ZLENFQXIZLMPEXDYYTSHY6GE4R6HQXWEPQKJFTCA5DIMUQHK4DEMF2GKIDEN5SXGIDON52CA53POJVSYIDWNFZWS5B4MJZD4CTIOR2HAORPF53XO5ZONRUW2ZLXNFZGKLTDN5WS6ZDPO5XGY33BMQ6GE4R6EBTG64RAORUGKIDMMF2GK43UEB3GK4TTNFXW4IDPMYQEY2LNMVLWS4TFFY6C6YR6HQXWGZLOORSXEPR4F52GIPR4F52HEPR4F52GCYTMMU7AUIBAEAQCAIC5LU7AUIBAEAQCAIB4F5WGC3THHYFCAIBAEAQCAPBPNVZWOPQKEAQCAIBAEAFCAIBAEAQCAPDNONTSAZTSN5WT2IRUFY4C4MJCEBTG64R5EI2C4MJWFY3CEIDVOJWD2ITIOR2HAORPF53XO5ZONRUW2ZLXNFZGKLTDN5WS65LQMRQXIZJCEBZXI6LMMU6SENBCHYFCAIBAEAQCAPDMMFXGOIDJMQ6SOZLOE47AUIBAEAQCAIB4EFNUGRCBKRAVWCRAEAQCAIBAHR2GCYTMMUQGC3DJM5XD2Y3FNZ2GK4RAOZQWY2LHNY6WGZLOORSXEPR4ORZD4PDUMQ7AUPDDMVXHIZLSHY6GEPSVOJTWK3TUEBGGS3LFK5UXEZJAKNSWG5LSNF2HSICVOBSGC5DFEBAXMYLJNRQWE3DFFY6GE4R6BJIGYZLBONSSAVLQMRQXIZJAJFWW2ZLENFQXIZLMPEXDYYTSHY6GE4R6HQXWEPQKJFTCA5DIMUQHK4DEMF2GKIDEN5SXGIDON52CA53POJVSYIDWNFZWS5B4MJZD4CTIOR2HAORPF53XO5ZONRUW2ZLXNFZGKLTDN5WS6ZDPO5XGY33BMQ6GE4R6EBTG64RAORUGKIDMMF2GK43UEB3GK4TTNFXW4IDPMYQEY2LNMVLWS4TFFY6C6YR6HQXWGZLOORSXEPR4F52GIPR4F52HEPR4F52GCYTMMU7AUIBAEAQCAIC5LU7AUIBAEAQCAIB4F5WGC3THHYFCAIBAEAQCAPBPNVZWOPQKHQXXK4DEMF2GKPQK"); }