Changeset e3da181c


Ignore:
Timestamp:
Mar 20, 2012 6:38:28 PM (8 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
ca57b712
Parents:
3da6ccfb
Message:
  • NetDB:
    • Don't reread RI if netdb date is recent
    • Prevent LS/RI overwrites
    • Disallow hash mismatches in RI files
    • Reseed won't fetch our own RI
    • Reseed won't overwrite recent RIs
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • history.txt

    r3da6ccfb re3da181c  
     12012-03-20 zzz
     2  * i2psnark: Message area tweaks and clear link
     3  * NetDB:
     4    - Don't reread RI if netdb date is recent
     5    - Prevent LS/RI overwrites
     6    - Disallow hash mismatches in RI files
     7    - Reseed won't fetch our own RI
     8    - Reseed won't overwrite recent RIs
     9  * Router: Make runRouter() public
     10
    1112012-03-19 sponge
    212  * Plugins: Less confusing message, fix CNFE by catch and ignore on delete.
    313             Order and reverse order plugin names for start/stop all cases.
     14
     152012-03-18 zzz
     16  * Jetty: Fix check alias override
    417
    5182012-03-17 zzz
  • router/java/src/net/i2p/router/RouterVersion.java

    r3da6ccfb re3da181c  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 18;
     21    public final static long BUILD = 19;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    r3da6ccfb re3da181c  
    685685                return rv;
    686686            }
    687         } catch (ClassCastException cce) {}
     687        } catch (ClassCastException cce) {
     688            throw new IllegalArgumentException("Attempt to replace RI with " + leaseSet);
     689        }
    688690       
    689691        String err = validate(key, leaseSet);
     
    812814    }
    813815
    814     public RouterInfo store(Hash key, RouterInfo routerInfo, boolean persist) throws IllegalArgumentException {
     816    RouterInfo store(Hash key, RouterInfo routerInfo, boolean persist) throws IllegalArgumentException {
    815817        if (!_initialized) return null;
    816818       
     
    822824                return rv;
    823825            }
    824         } catch (ClassCastException cce) {}
     826        } catch (ClassCastException cce) {
     827            throw new IllegalArgumentException("Attempt to replace LS with " + routerInfo);
     828        }
    825829       
    826830        String err = validate(key, routerInfo);
  • router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java

    r3da6ccfb re3da181c  
    393393        private final File _routerFile;
    394394        private final Hash _key;
    395 
     395        private long _knownDate;
     396
     397        /**
     398         *  @param key must match the RI hash in the file
     399         */
    396400        public ReadRouterJob(File routerFile, Hash key) {
    397401            super(PersistentDataStore.this._context);
     
    399403            _key = key;
    400404        }
     405
    401406        public String getName() { return "Read RouterInfo"; }
    402407       
     
    406411            if (data == null) return true;
    407412            if (data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
    408                 long knownDate = ((RouterInfo)data).getPublished();
     413                _knownDate = ((RouterInfo)data).getPublished();
    409414                long fileDate = _routerFile.lastModified();
    410                 if (fileDate > knownDate)
    411                     return true;
    412                 else
    413                     return false;
     415                // don't overwrite recent netdb RIs with reseed data
     416                return fileDate > _knownDate + (60*60*1000);
    414417            } else {
    415                 // wtf
    416                 return true;
    417             }
    418         }
     418                // wtf - prevent injection from reseeding
     419                _log.error("Prevented LS overwrite by RI " + _key + " from " + _routerFile);
     420                return false;
     421            }
     422        }
     423
    419424        public void runJob() {
    420425            if (!shouldRead()) return;
     426            if (_log.shouldLog(Log.DEBUG))
     427                _log.debug("Reading " + _routerFile);
    421428            try {
    422429                InputStream fis = null;
     
    433440                                       + ri.getIdentity().calculateHash().toBase64()
    434441                                       + " is from a different network");
     442                    } else if (!ri.getIdentity().calculateHash().equals(_key)) {
     443                        // prevent injection from reseeding
     444                        // this is checked in KNDF.validate() but catch it sooner and log as error.
     445                        corrupt = true;
     446                        _log.error(ri.getIdentity().calculateHash() + " does not match " + _key + " from " + _routerFile);
     447                    } else if (ri.getPublished() <= _knownDate) {
     448                        // Don't store but don't delete
     449                        if (_log.shouldLog(Log.WARN))
     450                            _log.warn("Skipping since netdb newer than " + _routerFile);
    435451                    } else {
    436452                        try {
     
    442458                            getContext().profileManager().heardAbout(ri.getIdentity().getHash(), ri.getPublished());
    443459                        } catch (IllegalArgumentException iae) {
    444                             _log.info("Refused locally loaded routerInfo - deleting");
     460                            _log.info("Refused locally loaded routerInfo - deleting", iae);
    445461                            corrupt = true;
    446462                        }
  • router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java

    r3da6ccfb re3da181c  
    335335                // but they may include % encoding
    336336                Set<String> urls = new HashSet(1024);
     337                Hash ourHash = _context.routerHash();
     338                String ourB64 = ourHash != null ? ourHash.toBase64() : null;
    337339                int cur = 0;
    338340                int total = 0;
     
    353355                    }
    354356                    String name = content.substring(start + ("href=\"" + ROUTERINFO_PREFIX).length(), end);
    355                     urls.add(name);
     357                    // never load our own RI
     358                    if (ourB64 == null || !name.contains(ourB64)) {
     359                        urls.add(name);
     360                    } else {
     361                        if (_log.shouldLog(Log.INFO))
     362                            _log.info("Skipping our own RI");
     363                    }
    356364                    cur = end + 1;
    357365                }
     
    373381                            _("Reseeding: fetching router info from seed URL ({0} successful, {1} errors).", fetched, errors));
    374382
    375                         fetchSeed(seedURL, iter.next());
     383                        if (!fetchSeed(seedURL, iter.next()))
     384                            continue;
    376385                        fetched++;
    377386                        if (echoStatus) {
     
    409418         *
    410419         *  @param peer The Base64 hash, may include % encoding. It is decoded and validated here.
     420         *  @return true on success, false if skipped
    411421         */
    412         private void fetchSeed(String seedURL, String peer) throws IOException, URISyntaxException {
     422        private boolean fetchSeed(String seedURL, String peer) throws IOException, URISyntaxException {
    413423            // Use URI to do % decoding of the B64 hash (some servers escape ~ and =)
    414424            // Also do basic hash validation. This prevents stuff like
     
    421431            if (hash == null || hash.length != Hash.HASH_LENGTH)
    422432                throw new IOException("bad hash " + peer);
     433            Hash ourHash = _context.routerHash();
     434            if (ourHash != null && DataHelper.eq(hash, ourHash.getData()))
     435                return false;
    423436
    424437            URL url = new URL(seedURL + (seedURL.endsWith("/") ? "" : "/") + ROUTERINFO_PREFIX + peer + ROUTERINFO_SUFFIX);
     
    427440            if (data == null || data.length <= 0)
    428441                throw new IOException("Failed fetch of " + url);
    429             writeSeed(b64, data);
     442            return writeSeed(b64, data);
    430443        }
    431444
     
    469482        /**
    470483         *  @param name valid Base64 hash
     484         *  @return true on success, false if skipped
    471485         */
    472         private void writeSeed(String name, byte data[]) throws IOException {
     486        private boolean writeSeed(String name, byte data[]) throws IOException {
    473487            String dirName = "netDb"; // _context.getProperty("router.networkDatabase.dbDir", "netDb");
    474488            File netDbDir = new SecureDirectory(_context.getRouterDir(), dirName);
    475489            if (!netDbDir.exists()) {
    476                 boolean ok = netDbDir.mkdirs();
     490                netDbDir.mkdirs();
     491            }
     492            File file = new File(netDbDir, ROUTERINFO_PREFIX + name + ROUTERINFO_SUFFIX);
     493            // don't overwrite recent file
     494            // TODO: even better would be to compare to last-mod date from eepget
     495            if (file.exists() && file.lastModified() > _context.clock().now() - 60*60*1000) {
     496                if (_log.shouldLog(Log.INFO))
     497                    _log.info("Skipping RI, ours is recent: " + file);
     498                return false;
    477499            }
    478500            FileOutputStream fos = null;
    479501            try {
    480                 File file = new File(netDbDir, ROUTERINFO_PREFIX + name + ROUTERINFO_SUFFIX);
    481502                fos = new SecureFileOutputStream(file);
    482503                fos.write(data);
     
    488509                } catch (IOException ioe) {}
    489510            }
     511            return true;
    490512        }
    491513
Note: See TracChangeset for help on using the changeset viewer.