source: osm/applications/editors/josm/plugins/native-password-manager/netbeans-keyring-patches.diff@ 34795

Last change on this file since 34795 was 26361, checked in by bastik, 13 years ago

make it work for windows

File size: 15.2 KB
  • src/org/netbeans/modules/keyring/fallback/FallbackProvider.java

    old new  
    4242
    4343package org.netbeans.modules.keyring.fallback;
    4444
    45 import java.util.Arrays;
    46 import java.util.HashMap;
    47 import java.util.Map;
    4845import java.util.UUID;
    49 import java.util.concurrent.Callable;
    5046import java.util.logging.Level;
    5147import java.util.logging.Logger;
    52 import java.util.prefs.BackingStoreException;
    53 import java.util.prefs.Preferences;
    54 import org.netbeans.api.keyring.Keyring;
    5548import org.netbeans.modules.keyring.impl.Utils;
    5649import org.netbeans.modules.keyring.spi.EncryptionProvider;
    5750import org.netbeans.spi.keyring.KeyringProvider;
    58 import org.openide.DialogDisplayer;
    59 import org.openide.NotifyDescriptor;
    60 import org.openide.util.Lookup;
    61 import org.openide.util.NbBundle;
    62 import org.openide.util.NbPreferences;
    63 import org.openide.util.lookup.ServiceProvider;
    6451
    6552/**
    6653 * Platform-independent keyring provider using a master password and the user directory.
    6754 */
    68 @ServiceProvider(service=KeyringProvider.class, position=1000)
    69 public class FallbackProvider implements KeyringProvider, Callable<Void> {
     55public class FallbackProvider implements KeyringProvider {
    7056
    7157    private static final Logger LOG = Logger.getLogger(FallbackProvider.class.getName());
    7258    private static final String DESCRIPTION = ".description";
    7359    private static final String SAMPLE_KEY = "__sample__";
    7460
    7561    private EncryptionProvider encryption;
    76  
     62    private IPreferences prefs;
     63
     64    // simple interface for a generic preferences store
     65    public interface IPreferences {
     66        byte[] getByteArray(String key, byte[] def);
     67        void putByteArray(String key, byte[] val);
     68        void remove(String key);
     69    }
     70
     71    public FallbackProvider(EncryptionProvider encryption, IPreferences prefs) {
     72        this.encryption = encryption;
     73        this.prefs = prefs;
     74    }
     75
    7776    public boolean enabled() {
    78         for (EncryptionProvider p : Lookup.getDefault().lookupAll(EncryptionProvider.class)) {
    79             if (p.enabled()) {
    80                 encryption = p;
    81                 Preferences prefs = prefs();
    82                 Utils.goMinusR(prefs);
    83                 p.encryptionChangingCallback(this);
    84                 if (!testSampleKey(prefs)) {
    85                     continue;
    86                 }
    87                 LOG.log(Level.FINE, "Using provider: {0}", p);
     77        if (encryption.enabled()) {
     78            if (testSampleKey()) {
     79                LOG.log(Level.FINE, "Using provider: {0}", encryption);
    8880                return true;
    8981            }
    9082        }
     
    9284        return false;
    9385    }
    9486   
    95     private boolean testSampleKey(Preferences prefs) {
    96         byte[] ciphertext = prefs.getByteArray(SAMPLE_KEY, null);
    97         if (ciphertext == null) {
    98             encryption.freshKeyring(true);
    99             if (_save(SAMPLE_KEY, (SAMPLE_KEY + UUID.randomUUID()).toCharArray(),
    100                     NbBundle.getMessage(FallbackProvider.class, "FallbackProvider.sample_key.description"))) {
    101                 LOG.fine("saved sample key");
    102                 return true;
    103             } else {
    104                 LOG.fine("could not save sample key");
    105                 return false;
    106             }
    107         } else {
    108             encryption.freshKeyring(false);
    109             while (true) {
    110                 try {
    111                     if (new String(encryption.decrypt(ciphertext)).startsWith(SAMPLE_KEY)) {
    112                         LOG.fine("succeeded in decrypting sample key");
    113                         return true;
    114                     } else {
    115                         LOG.fine("wrong result decrypting sample key");
    116                     }
    117                 } catch (Exception x) {
    118                     LOG.log(Level.FINE, "failed to decrypt sample key", x);
    119                 }
    120                 if (!encryption.decryptionFailed()) {
    121                     LOG.fine("sample key decryption failed");
    122                     return promptToDelete(prefs);
    123                 }
    124                 LOG.fine("will retry decryption of sample key");
    125             }
    126         }
    127     }
    128 
    129     private boolean promptToDelete(Preferences prefs) {
    130         Object result = DialogDisplayer.getDefault().notify(new NotifyDescriptor.Confirmation(
    131                 NbBundle.getMessage(FallbackProvider.class, "FallbackProvider.msg_clear_keys"),
    132                 NbBundle.getMessage(FallbackProvider.class, "FallbackProvider.title_clear_keys"),
    133                 NotifyDescriptor.OK_CANCEL_OPTION));
    134         if (result == NotifyDescriptor.OK_OPTION) {
    135             try {
    136                 LOG.log(Level.FINE, "agreed to delete stored passwords: {0}", Arrays.asList(prefs.keys()));
    137                 prefs.clear();
    138                 return testSampleKey(prefs);
    139             } catch (BackingStoreException x) {
    140                 LOG.log(Level.INFO, null, x);
    141             }
     87    private boolean testSampleKey() {
     88        encryption.freshKeyring(true);
     89        if (_save(SAMPLE_KEY, (SAMPLE_KEY + UUID.randomUUID()).toCharArray(),
     90                "Sample value ensuring that decryption is working.")) {
     91            LOG.fine("saved sample key");
     92            return true;
    14293        } else {
    143             LOG.fine("refused to delete stored passwords");
     94            LOG.fine("could not save sample key");
     95            return false;
    14496        }
    145         return false;
    146     }
    147 
    148     private Preferences prefs() {
    149         return NbPreferences.forModule(Keyring.class).node(encryption.id());
    15097    }
    15198
    15299    public char[] read(String key) {
    153         byte[] ciphertext = prefs().getByteArray(key, null);
     100        byte[] ciphertext = prefs.getByteArray(key, null);
    154101        if (ciphertext == null) {
    155102            return null;
    156103        }
     
    166113        _save(key, password, description);
    167114    }
    168115    private boolean _save(String key, char[] password, String description) {
    169         Preferences prefs = prefs();
    170116        try {
    171117            prefs.putByteArray(key, encryption.encrypt(password));
    172118        } catch (Exception x) {
    173119            LOG.log(Level.FINE, "failed to encrypt password for " + key, x);
    174120            return false;
    175121        }
    176         if (description != null) {
    177             // Preferences interface gives no access to *.properties comments, so:
    178             prefs.put(key + DESCRIPTION, description);
    179         }
    180122        return true;
    181123    }
    182124
    183125    public void delete(String key) {
    184         Preferences prefs = prefs();
    185126        prefs.remove(key);
    186127        prefs.remove(key + DESCRIPTION);
    187128    }
    188129
    189     public Void call() throws Exception { // encryption changing
    190         LOG.fine("encryption changing");
    191         Map<String,char[]> saved = new HashMap<String,char[]>();
    192         Preferences prefs = prefs();
    193         for (String k : prefs.keys()) {
    194             if (k.endsWith(DESCRIPTION)) {
    195                 continue;
    196             }
    197             byte[] ciphertext = prefs.getByteArray(k, null);
    198             if (ciphertext == null) {
    199                 continue;
    200             }
    201             saved.put(k, encryption.decrypt(ciphertext));
    202         }
    203         LOG.log(Level.FINE, "reencrypting keys: {0}", saved.keySet());
    204         encryption.encryptionChanged();
    205         for (Map.Entry<String,char[]> entry : saved.entrySet()) {
    206             prefs.putByteArray(entry.getKey(), encryption.encrypt(entry.getValue()));
    207         }
    208         LOG.fine("encryption changing finished");
    209         return null;
    210     }
    211 
    212130}
  • src/org/netbeans/modules/keyring/gnome/GnomeProvider.java

    old new  
    4343package org.netbeans.modules.keyring.gnome;
    4444
    4545import com.sun.jna.Pointer;
    46 import java.text.MessageFormat;
    47 import java.util.MissingResourceException;
    4846import java.util.logging.Level;
    4947import java.util.logging.Logger;
    5048import static org.netbeans.modules.keyring.gnome.GnomeKeyringLibrary.*;
    5149import org.netbeans.spi.keyring.KeyringProvider;
    52 import org.openide.util.NbBundle;
    53 import org.openide.util.lookup.ServiceProvider;
    5450
    55 @ServiceProvider(service=KeyringProvider.class, position=100)
    5651public class GnomeProvider implements KeyringProvider {
    5752
    5853    private static final Logger LOG = Logger.getLogger(GnomeProvider.class.getName());
     
    7469            LOG.fine("no GNOME_KEYRING_* environment variable set");
    7570            return false;
    7671        }
    77         String appName;
    78         try {
    79             appName = MessageFormat.format(
    80                     NbBundle.getBundle("org.netbeans.core.windows.view.ui.Bundle").getString("CTL_MainWindow_Title_No_Project"),
    81                     /*System.getProperty("netbeans.buildnumber")*/"…");
    82         } catch (MissingResourceException x) {
    83             appName = "NetBeans"; // NOI18N
    84         }
     72        String appName = "JOSM";
    8573        try {
    8674            // Need to do this somewhere, or we get warnings on console.
    8775            // Also used by confirmation dialogs to give the app access to the login keyring.
  • src/org/netbeans/modules/keyring/kde/KWalletProvider.java

    old new  
    4545import java.io.BufferedReader;
    4646import java.io.IOException;
    4747import java.io.InputStreamReader;
    48 import java.text.MessageFormat;
    4948import java.util.Arrays;
    50 import java.util.MissingResourceException;
    5149import java.util.logging.Level;
    5250import java.util.logging.Logger;
    5351import org.netbeans.spi.keyring.KeyringProvider;
    54 import org.openide.util.NbBundle;
    55 import org.openide.util.lookup.ServiceProvider;
    5652
    5753/**
    5854 *
    5955 * @author psychollek, ynov
    6056 */
    61 @ServiceProvider(service=KeyringProvider.class, position=99)
    6257public class KWalletProvider implements KeyringProvider{
    6358
    6459    private static final Logger logger = Logger.getLogger(KWalletProvider.class.getName());
     
    221216    }
    222217
    223218    private char[] getApplicationName(boolean version){
    224         String appName;
    225         try {
    226             appName = MessageFormat.format(NbBundle.getBundle("org.netbeans.core.windows.view.ui.Bundle").getString("CTL_MainWindow_Title_No_Project"),version ? System.getProperty("netbeans.buildnumber"):"");
    227         } catch (MissingResourceException x) {
    228             appName = "NetBeans"+(version? " "+System.getProperty("netbeans.buildnumber"):"");
    229         }
    230         return appName.toCharArray();
     219        return "JOSM".toCharArray();
    231220    }
    232221
    233222    private void warning(String descr) {
  • src/org/netbeans/modules/keyring/mac/MacProvider.java

    old new  
    4747import java.util.logging.Level;
    4848import java.util.logging.Logger;
    4949import org.netbeans.spi.keyring.KeyringProvider;
    50 import org.openide.util.Utilities;
    51 import org.openide.util.lookup.ServiceProvider;
    5250
    53 @ServiceProvider(service=KeyringProvider.class, position=200)
    5451public class MacProvider implements KeyringProvider {
    5552
    5653    private static final Logger LOG = Logger.getLogger(MacProvider.class.getName());
    5754
    5855    public boolean enabled() {
    59         if (Boolean.getBoolean("netbeans.keyring.no.native")) {
    60             LOG.fine("native keyring integration disabled");
    61             return false;
    62         }
    63         return Utilities.isMac();
     56        return true; // test elsewhere if we are on a mac
    6457    }
    6558
    6659    public char[] read(String key) {
    6760        try {
    6861            byte[] serviceName = key.getBytes("UTF-8");
    69             byte[] accountName = "NetBeans".getBytes("UTF-8");
     62            byte[] accountName = "JOSM".getBytes("UTF-8");
    7063            int[] dataLength = new int[1];
    7164            Pointer[] data = new Pointer[1];
    7265            error("find", SecurityLibrary.LIBRARY.SecKeychainFindGenericPassword(null, serviceName.length, serviceName,
     
    8679        delete(key); // XXX supposed to use SecKeychainItemModifyContent instead, but this seems like too much work
    8780        try {
    8881            byte[] serviceName = key.getBytes("UTF-8");
    89             byte[] accountName = "NetBeans".getBytes("UTF-8");
     82            byte[] accountName = "JOSM".getBytes("UTF-8");
    9083            // Keychain Access seems to expect UTF-8, so do not use Utils.chars2Bytes:
    9184            byte[] data = new String(password).getBytes("UTF-8");
    9285            error("save", SecurityLibrary.LIBRARY.SecKeychainAddGenericPassword(null, serviceName.length, serviceName,
     
    10093    public void delete(String key) {
    10194        try {
    10295            byte[] serviceName = key.getBytes("UTF-8");
    103             byte[] accountName = "NetBeans".getBytes("UTF-8");
     96            byte[] accountName = "JOSM".getBytes("UTF-8");
    10497            Pointer[] itemRef = new Pointer[1];
    10598            error("find (for delete)", SecurityLibrary.LIBRARY.SecKeychainFindGenericPassword(null, serviceName.length, serviceName,
    10699                    accountName.length, accountName, null, null, itemRef));
  • src/org/netbeans/modules/keyring/win32/Win32Protect.java

    old new  
    5454import java.util.logging.Logger;
    5555import org.netbeans.modules.keyring.impl.Utils;
    5656import org.netbeans.modules.keyring.spi.EncryptionProvider;
    57 import org.openide.util.Utilities;
    58 import org.openide.util.lookup.ServiceProvider;
    5957
    6058/**
    6159 * Data protection utility for Microsoft Windows.
    6260 * XXX org.tmatesoft.svn.core.internal.util.jna.SVNWinCrypt is a possibly more robust implementation
    6361 * (though it seems to set CRYPTPROTECT_UI_FORBIDDEN which we do not necessarily want).
    6462 */
    65 @ServiceProvider(service=EncryptionProvider.class, position=100)
    6663public class Win32Protect implements EncryptionProvider {
    6764
    6865    private static final Logger LOG = Logger.getLogger(Win32Protect.class.getName());
    6966   
    7067    public @Override boolean enabled() {
    71         if (!Utilities.isWindows()) {
    72             LOG.fine("not running on Windows");
    73             return false;
    74         }
    75         if (Boolean.getBoolean("netbeans.keyring.no.native")) {
    76             LOG.fine("native keyring integration disabled");
    77             return false;
    78         }
     68        // asssume, we have windows os
    7969        try {
    8070            if (CryptLib.INSTANCE == null) {
    8171                LOG.fine("loadLibrary -> null");
Note: See TracBrowser for help on using the repository browser.