Ignore:
Timestamp:
2009-12-16T18:58:04+01:00 (14 years ago)
Author:
Gubaer
Message:

new: supports system defined proxies if JOSM is started with -Djava.net.useSystemProxies=true
fixed #1641: JOSM doesn't allow for setting HTTP proxy user/password distrinct from OSM server user/password
fixed #2865: SOCKS Proxy Support
fixed #4182: Proxy Authentication

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/OsmConnection.java

    r2512 r2641  
    22package org.openstreetmap.josm.io;
    33
    4 import static org.openstreetmap.josm.tools.I18n.tr;
    5 
    6 import java.awt.Font;
    7 import java.awt.GridBagLayout;
    8 import java.net.Authenticator;
    94import java.net.HttpURLConnection;
    10 import java.net.PasswordAuthentication;
     5import java.net.Authenticator.RequestorType;
    116import java.nio.ByteBuffer;
    127import java.nio.CharBuffer;
     
    1611import java.util.logging.Logger;
    1712
    18 import javax.swing.JCheckBox;
    19 import javax.swing.JLabel;
    20 import javax.swing.JPanel;
    21 import javax.swing.JPasswordField;
    22 import javax.swing.JTextField;
    23 
    24 import org.openstreetmap.josm.Main;
    25 import org.openstreetmap.josm.gui.ExtendedDialog;
     13import org.openstreetmap.josm.io.auth.CredentialsManagerException;
     14import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
     15import org.openstreetmap.josm.io.auth.CredentialsManagerResponse;
    2616import org.openstreetmap.josm.tools.Base64;
    27 import org.openstreetmap.josm.tools.GBC;
    2817
    2918/**
     
    3827    protected boolean cancel = false;
    3928    protected HttpURLConnection activeConnection;
    40     /**
    41      * Handles password storage and some related gui-components.
    42      * It can be set by a plugin. This may happen at startup and
    43      * by changing the preferences.
    44      * Syncronize on this object to get or set a consistent
    45      * username/password pair.
    46      */
    47     public static CredentialsManager credentialsManager = new PlainCredentialsManager();
    48 
    49     private static OsmAuth authentication = new OsmAuth();
    5029
    5130    /**
     
    5332     */
    5433    static {
    55         // TODO: current authentication handling is sub-optimal in that it seems to use the same authenticator for
    56         // any kind of request. HTTP requests executed by plugins, e.g. to password-protected WMS servers,
    57         // will use the same username/password which is undesirable.
    5834        try {
    5935            HttpURLConnection.setFollowRedirects(true);
    60             Authenticator.setDefault(authentication);
    6136        } catch (SecurityException e) {
     37            e.printStackTrace();
    6238        }
    63     }
    64 
    65     /**
    66      * The authentication class handling the login requests.
    67      */
    68     public static class OsmAuth extends Authenticator {
    69         /**
    70          * Set to true, when the autenticator tried the password once.
    71          */
    72         public boolean passwordtried = false;
    73         /**
    74          * Whether the user cancelled the password dialog
    75          */
    76         public boolean authCancelled = false;
    77         @Override protected PasswordAuthentication getPasswordAuthentication() {
    78             return credentialsManager.getPasswordAuthentication(this);
    79         }
    80     }
    81 
    82     /**
    83      * Must be called before each connection attemp to initialize the authentication.
    84      */
    85     protected final void initAuthentication() {
    86         authentication.authCancelled = false;
    87         authentication.passwordtried = false;
    88     }
    89 
    90     /**
    91      * @return Whether the connection was cancelled.
    92      */
    93     protected final boolean isAuthCancelled() {
    94         return authentication.authCancelled;
    9539    }
    9640
     
    11559    }
    11660
    117     protected void addAuth(HttpURLConnection con) throws CharacterCodingException {
     61    protected void addAuth(HttpURLConnection con) throws OsmTransferException {
    11862        CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
    119         String auth;
     63        CredentialsManagerResponse response;
     64        String token;
    12065        try {
    121             synchronized (credentialsManager) {
    122                 auth = credentialsManager.lookup(CredentialsManager.Key.USERNAME) + ":" +
    123                 credentialsManager.lookup(CredentialsManager.Key.PASSWORD);
     66            synchronized (CredentialsManagerFactory.getCredentialManager()) {
     67                response = CredentialsManagerFactory.getCredentialManager().getCredentials(RequestorType.SERVER, false /* don't know yet whether the credentials will succeed */);
    12468            }
    125         } catch (CredentialsManager.CMException e) {
    126             auth = ":";
     69        } catch (CredentialsManagerException e) {
     70            throw new OsmTransferException(e);
    12771        }
    128         ByteBuffer bytes = encoder.encode(CharBuffer.wrap(auth));
    129         con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
     72        if (response == null) {
     73            token = ":";
     74        } else if (response.isCanceled()) {
     75            cancel = true;
     76            return;
     77        } else {
     78            String username= response.getUsername() == null ? "" : response.getUsername();
     79            String password = response.getPassword() == null ? "" : String.valueOf(response.getPassword());
     80            token = username + ":" + password;
     81            try {
     82                ByteBuffer bytes = encoder.encode(CharBuffer.wrap(token));
     83                con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
     84            } catch(CharacterCodingException e) {
     85                throw new OsmTransferException(e);
     86            }
     87        }
    13088    }
    13189
     
    13997        return cancel;
    14098    }
    141     /**
    142      * Default implementation of the CredentialsManager interface.
    143      * Saves passwords in plain text file.
    144      */
    145     public static class PlainCredentialsManager implements CredentialsManager {
    146         public String lookup(CredentialsManager.Key key) throws CMException {
    147             String secret = Main.pref.get("osm-server." + key.toString(), null);
    148             if (secret == null) throw new CredentialsManager.NoContentException();
    149             return secret;
    150         }
    151         public void store(CredentialsManager.Key key, String secret) {
    152             Main.pref.put("osm-server." + key.toString(), secret);
    153         }
    154         public PasswordAuthentication getPasswordAuthentication(OsmAuth caller) {
    155             String username, password;
    156             try {
    157                 username = lookup(Key.USERNAME);
    158             } catch (CMException e) {
    159                 username = "";
    160             }
    161             try {
    162                 password = lookup(Key.PASSWORD);
    163             } catch (CMException e) {
    164                 password = "";
    165             }
    166             if (caller.passwordtried || username.equals("") || password.equals("")) {
    167                 JPanel p = new JPanel(new GridBagLayout());
    168                 if (!username.equals("") && !password.equals("")) {
    169                     p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop());
    170                 }
    171                 p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0));
    172                 JTextField usernameField = new JTextField(username, 20);
    173                 p.add(usernameField, GBC.eol());
    174                 p.add(new JLabel(tr("Password")), GBC.std().insets(0,0,10,0));
    175                 JPasswordField passwordField = new JPasswordField(password, 20);
    176                 p.add(passwordField, GBC.eol());
    177                 JLabel warning = new JLabel(tr("Warning: The password is transferred unencrypted."));
    178                 warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
    179                 p.add(warning, GBC.eop());
    180 
    181                 JCheckBox savePassword = new JCheckBox(tr("Save user and password (unencrypted)"),
    182                         !username.equals("") && !password.equals(""));
    183                 p.add(savePassword, GBC.eop());
    184 
    185                 ExtendedDialog dialog = new ExtendedDialog(
    186                         Main.parent,
    187                         tr("Enter Password"),
    188                         new String[] {tr("Login"), tr("Cancel")}
    189                 );
    190                 dialog.setContent(p);
    191                 dialog.setButtonIcons( new String[] {"ok.png", "cancel.png"});
    192                 dialog.showDialog();
    193 
    194                 if (dialog.getValue() != 1) {
    195                     caller.authCancelled = true;
    196                     return null;
    197                 }
    198                 username = usernameField.getText();
    199                 password = String.valueOf(passwordField.getPassword());
    200                 if (savePassword.isSelected()) {
    201                     store(Key.USERNAME, username);
    202                     store(Key.PASSWORD, password);
    203                 }
    204                 if (username.equals(""))
    205                     return null;
    206             }
    207             caller.passwordtried = true;
    208             return new PasswordAuthentication(username, password.toCharArray());
    209         }
    210         public PreferenceAdditions newPreferenceAdditions() {
    211             return new PreferenceAdditions() {
    212                 /**
    213                  * Editfield for the Base url to the REST API from OSM.
    214                  */
    215                 final private JTextField osmDataServerURL = new JTextField(20);
    216                 /**
    217                  * Editfield for the username to the OSM account.
    218                  */
    219                 final private JTextField osmDataUsername = new JTextField(20);
    220                 /**
    221                  * Passwordfield for the userpassword of the REST API.
    222                  */
    223                 final private JPasswordField osmDataPassword = new JPasswordField(20);
    224 
    225                 private String oldServerURL = "";
    226                 private String oldUsername = "";
    227                 private String oldPassword = "";
    228 
    229                 public void addPreferenceOptions(JPanel panel) {
    230                     try {
    231                         oldServerURL = lookup(Key.OSM_SERVER_URL); // result is not null (see CredentialsManager)
    232                     } catch (CMException e) {
    233                         oldServerURL = "";
    234                     }
    235                     if (oldServerURL.equals("")) {
    236                         oldServerURL = "http://api.openstreetmap.org/api";
    237                     }
    238                     try {
    239                         oldUsername = lookup(Key.USERNAME);
    240                     } catch (CMException e) {
    241                         oldUsername = "";
    242                     }
    243                     try {
    244                         oldPassword = lookup(Key.PASSWORD);
    245                     } catch (CMException e) {
    246                         oldPassword = "";
    247                     }
    248                     osmDataServerURL.setText(oldServerURL);
    249                     osmDataUsername.setText(oldUsername);
    250                     osmDataPassword.setText(oldPassword);
    251                     osmDataServerURL.setToolTipText(tr("The base URL for the OSM server (REST API)"));
    252                     osmDataUsername.setToolTipText(tr("Login name (e-mail) to the OSM account."));
    253                     osmDataPassword.setToolTipText(tr("Login password to the OSM account. Leave blank to not store any password."));
    254                     panel.add(new JLabel(tr("Base Server URL")), GBC.std());
    255                     panel.add(osmDataServerURL, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
    256                     panel.add(new JLabel(tr("OSM username (e-mail)")), GBC.std());
    257                     panel.add(osmDataUsername, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
    258                     panel.add(new JLabel(tr("OSM password")), GBC.std());
    259                     panel.add(osmDataPassword, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,0));
    260                     JLabel warning = new JLabel(tr("<html>" +
    261                             "WARNING: The password is stored in plain text in the preferences file.<br>" +
    262                             "The password is transferred in plain text to the server, encoded in the URL.<br>" +
    263                     "<b>Do not use a valuable Password.</b></html>"));
    264                     warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
    265                     panel.add(warning, GBC.eop().fill(GBC.HORIZONTAL));
    266                 }
    267                 public void preferencesChanged() {
    268                     String newServerURL = osmDataServerURL.getText();
    269                     String newUsername = osmDataUsername.getText();
    270                     String newPassword = String.valueOf(osmDataPassword.getPassword());
    271                     if (!oldServerURL.equals(newServerURL)) {
    272                         store(Key.OSM_SERVER_URL, newServerURL);
    273                     }
    274                     if (!oldUsername.equals(newUsername)) {
    275                         store(Key.USERNAME, newUsername);
    276                     }
    277                     if (!oldPassword.equals(newPassword)) {
    278                         store(Key.PASSWORD, newPassword);
    279                     }
    280                 }
    281             };
    282         }
    283     }
    28499}
Note: See TracChangeset for help on using the changeset viewer.