Changeset 6b578df


Ignore:
Timestamp:
May 8, 2016 7:49:14 PM (4 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
ab3dbd5
Parents:
8bb6922
Message:

Console: Fix UTF-8 passwords
Partial fix for UTF-8 usernames
Better input checking and help messages

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java

    r8bb6922 r6b578df  
    464464            (isDigest ? ", nonce=\"" + getNonce() + "\"," +
    465465                        " algorithm=MD5," +
     466                        " charset=UTF-8," +     // RFC 7616/7617
    466467                        " qop=\"auth\"" +
    467468                        (isStale ? ", stale=true" : "")
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHandler.java

    r8bb6922 r6b578df  
    55import java.util.List;
    66import java.util.Map;
     7
     8import net.i2p.data.DataHelper;
    79
    810/** set the theme */
     
    8183            return;
    8284        }
     85        // XSS filters # and ; but not =
     86        // We store the username as the part of an option key, so we can't handle '='
     87        if (name.contains("=")) {
     88            addFormError("User name may not contain '='");
     89            return;
     90        }
     91        byte[] b1 = DataHelper.getUTF8(name);
     92        byte[] b2 = DataHelper.getASCII(name);
     93        if (!DataHelper.eq(b1, b2))
     94            addFormError(_t("Warning: User names outside the ISO-8859-1 character set are not recommended. Support is not standardized and varies by browser."));
    8395        String pw = getJettyString("nofilter_pw");
    8496        if (pw == null || pw.length() <= 0) {
     
    92104                _context.router().saveConfig(RouterConsoleRunner.PROP_PW_ENABLE, "true");
    93105            addFormNotice(_t("Added user {0}", name));
     106            addFormNotice(_t("To recover from a forgotten or non-working password, stop I2P, edit the file {0}, delete the line {1}, and restart I2P.",
     107                             _context.router().getConfigFilename(), RouterConsoleRunner.PROP_PW_ENABLE + "=true"));
    94108            addFormError(_t("Restart required to take effect"));
    95109        } else {
  • apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java

    r8bb6922 r6b578df  
    66import java.io.IOException;
    77import java.io.Serializable;
     8import java.io.UnsupportedEncodingException;
    89import java.net.InetAddress;
    910import java.net.Inet4Address;
     
    839840                sec.setLoginService(realm);
    840841                sec.setAuthenticator(authenticator);
     842                String[] role = new String[] {JETTY_ROLE};
    841843                for (Map.Entry<String, String> e : userpw.entrySet()) {
    842844                    String user = e.getKey();
    843845                    String pw = e.getValue();
    844                     realm.putUser(user, Credential.getCredential(MD5.__TYPE + pw), new String[] {JETTY_ROLE});
     846                    Credential cred = Credential.getCredential(MD5.__TYPE + pw);
     847                    realm.putUser(user, cred, role);
    845848                    Constraint constraint = new Constraint(user, JETTY_ROLE);
    846849                    constraint.setAuthenticate(true);
     
    849852                    cm.setPathSpec("/");
    850853                    constraints.add(cm);
     854                    // Jetty does auth checking only with ISO-8859-1,
     855                    // so register a 2nd and 3rd user with different encodings if necessary.
     856                    // Might work, might not...
     857                    // There's no standard and browser behavior varies.
     858                    // Chrome sends UTF-8. Firefox doesn't send anything.
     859                    // https://bugzilla.mozilla.org/show_bug.cgi?id=41489
     860                    // see also RFC 7616/7617 (late 2015) and PasswordManager.md5Hex()
     861                    byte[] b1 = DataHelper.getUTF8(user);
     862                    byte[] b2 = DataHelper.getASCII(user);
     863                    if (!DataHelper.eq(b1, b2)) {
     864                        try {
     865                            // each char truncated to 8 bytes
     866                            String user2 = new String(b2, "ISO-8859-1");
     867                            realm.putUser(user2, cred, role);
     868                            constraint = new Constraint(user2, JETTY_ROLE);
     869                            constraint.setAuthenticate(true);
     870                            cm = new ConstraintMapping();
     871                            cm.setConstraint(constraint);
     872                            cm.setPathSpec("/");
     873                            constraints.add(cm);
     874
     875                            // each UTF-8 byte as a char
     876                            // this is what chrome does
     877                            String user3 = new String(b1, "ISO-8859-1");
     878                            realm.putUser(user3, cred, role);
     879                            constraint = new Constraint(user3, JETTY_ROLE);
     880                            constraint.setAuthenticate(true);
     881                            cm = new ConstraintMapping();
     882                            cm.setConstraint(constraint);
     883                            cm.setPathSpec("/");
     884                            constraints.add(cm);
     885                        } catch (UnsupportedEncodingException uee) {}
     886                    }
    851887                }
    852888            }
  • core/java/src/net/i2p/data/DataHelper.java

    r8bb6922 r6b578df  
    18741874     *  will not throw an exception.
    18751875     *
    1876      *  @param orig non-null, must be 7-bit chars
     1876     *  Warning - misnamed, converts to ISO-8859-1.
     1877     *
     1878     *  @param orig non-null, truncates to 8-bit chars
    18771879     *  @since 0.9.5
    18781880     */
  • core/java/src/net/i2p/util/PasswordManager.java

    r8bb6922 r6b578df  
    3131    /** stored obfuscated as b64 of the UTF-8 bytes */
    3232    protected static final String PROP_B64 = ".b64";
    33     /** stored as the hex of the MD5 hash of the ISO-8859-1 bytes. Compatible with Jetty. */
     33    /** stored as the hex of the MD5 hash of the UTF-8 bytes. Compatible with Jetty. */
    3434    protected static final String PROP_MD5 = ".md5";
    3535    /** stored as a Unix crypt string */
     
    186186     *  and RFC 2617.
    187187     *
     188     *  Updated in 0.9.26 to use UTF-8, as implied in RFC 7616/7617
     189     *  See also http://stackoverflow.com/questions/7242316/what-encoding-should-i-use-for-http-basic-authentication
     190     *  http://stackoverflow.com/questions/702629/utf-8-characters-mangled-in-http-basic-auth-username
     191     *
    188192     *  @param subrealm to be used in creating the checksum
    189193     *  @param user non-null, non-empty, already trimmed
     
    201205     *  and RFC 2617.
    202206     *
     207     *  Updated in 0.9.26 to use UTF-8, as implied in RFC 7616/7617
     208     *  See also http://stackoverflow.com/questions/7242316/what-encoding-should-i-use-for-http-basic-authentication
     209     *
    203210     *  @param fullpw non-null, plain text, already trimmed
    204211     *  @return lower-case hex with leading zeros, 32 chars, or null on error
    205212     */
    206213    public static String md5Hex(String fullpw) {
    207         try {
    208             byte[] data = fullpw.getBytes("ISO-8859-1");
    209             byte[] sum = md5Sum(data);
    210             if (sum != null)
    211                 // adds leading zeros if necessary
    212                 return DataHelper.toString(sum);
    213         } catch (UnsupportedEncodingException uee) {}
     214        byte[] data = DataHelper.getUTF8(fullpw);
     215        byte[] sum = md5Sum(data);
     216        if (sum != null)
     217            // adds leading zeros if necessary
     218            return DataHelper.toString(sum);
    214219        return null;
    215220    }
Note: See TracChangeset for help on using the changeset viewer.