Changeset 30822 in osm


Ignore:
Timestamp:
2014-11-29T16:30:52+01:00 (10 years ago)
Author:
donvip
Message:

[josm_native-password-manager] update Netbeans Keyring code + make plugin rely on JNA plugin

Location:
applications/editors/josm/plugins/native-password-manager
Files:
2 added
2 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/native-password-manager/.classpath

    r30442 r30822  
    22<classpath>
    33        <classpathentry kind="src" path="src"/>
    4         <classpathentry kind="lib" path="lib/jna.jar"/>
    54        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    65        <classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
     6        <classpathentry combineaccessrules="false" kind="src" path="/JOSM-jna"/>
    77        <classpathentry kind="output" path="build"/>
    88</classpath>
  • applications/editors/josm/plugins/native-password-manager/README

    r26335 r30822  
    1818
    1919Original code:
    20     http://hg.netbeans.org/main/file/524f40b94a30/keyring.impl  and
    21     http://hg.netbeans.org/main/file/524f40b94a30/keyring
     20    http://hg.netbeans.org/main/file/9413a02b6f0c/keyring.impl
     21    http://hg.netbeans.org/main/file/9413a02b6f0c/keyring
     22    http://hg.netbeans.org/main/file/9413a02b6f0c/keyring.fallback
    2223Patch:
    2324    netbeans-keyring-patches.diff
  • applications/editors/josm/plugins/native-password-manager/build.xml

    r30530 r30822  
    66    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    77    <property name="plugin.main.version" value="7001"/>
     8    <property name="plugin.author" value="Paul Hartmann"/>
     9    <property name="plugin.class" value="org.openstreetmap.josm.plugins.npm.NPMPlugin"/>
     10    <property name="plugin.description" value="Use your system''s password manager to store the API username and password. (KWallet and gnome-keyring are supported.)"/>
     11    <property name="plugin.icon" value="images/lock24x24.png"/>
     12    <property name="plugin.link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/Native_Password_Manager"/>
     13    <property name="plugin.requires" value="jna"/>
    814
    915    <!--
     
    1420    <import file="../build-common.xml"/>
    1521
    16     <!-- classpath -->
    17     <path id="classpath">
    18         <fileset dir="${plugin.lib.dir}" includes="**/*.jar"/>
    19         <pathelement path="${josm}"/>
    20     </path>
    21     <!--
    22     **********************************************************
    23     ** compile - complies the source tree
    24     ** Overrides the target from build-common.xml
    25     **********************************************************
    26     -->
    27     <target name="compile" depends="init">
    28         <echo message="compiling sources for ${plugin.jar} ..."/>
    29         <javac srcdir="src" classpathref="classpath" debug="true" destdir="${plugin.build.dir}" includeantruntime="false">
    30             <compilerarg value="-Xlint:deprecation"/>
    31             <compilerarg value="-Xlint:unchecked"/>
    32         </javac>
    33     </target>
    34 
    35     <!--
    36     **********************************************************
    37     ** dist - creates the plugin jar
    38     **********************************************************
    39     -->
    40     <target name="dist" depends="compile,revision">
    41         <echo message="creating ${ant.project.name}.jar ... "/>
    42         <copy todir="${plugin.build.dir}/images">
    43             <fileset dir="images"/>
    44         </copy>
    45         <copy todir="${plugin.build.dir}/data">
    46             <fileset dir="data"/>
    47         </copy>
    48         <copy todir="${plugin.build.dir}">
    49             <fileset dir=".">
    50                 <include name="README"/>
    51                 <include name="LICENSE"/>
    52                 <include name="gpl-2-cp.txt"/>
    53                 <include name="gpl-3.txt"/>
    54             </fileset>
    55         </copy>
    56         <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    57         <!--
    58         ************************************************
    59         ** configure these properties. Most of them will be copied to the plugins
    60         ** manifest file. Property values will also show up in the list available
    61         ** plugins: http://josm.openstreetmap.de/wiki/Plugins.
    62         **
    63         ************************************************
    64         -->
    65             <manifest>
    66                 <attribute name="Author" value="Paul Hartmann"/>
    67                 <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.npm.NPMPlugin"/>
    68                 <attribute name="Main-Class" value="org.openstreetmap.josm.plugins.npm.NPMPlugin"/>
    69                 <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
    70                 <attribute name="Plugin-Description" value="Use your system''s password manager to store the API username and password. (KWallet and gnome-keyring are supported.)"/>
    71                 <attribute name="Plugin-Icon" value="images/lock24x24.png"/>
    72                 <attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/Native_Password_Manager"/>
    73                 <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
    74                 <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    75             </manifest>
    76             <zipfileset src="${plugin.lib.dir}/jna.jar"/>
    77         </jar>
    78     </target>
     22    <fileset id="plugin.requires.jars" dir="${plugin.dist.dir}">
     23        <include name="jna.jar"/>
     24    </fileset>
     25   
    7926</project>
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/fallback/FallbackProvider.java

    r30737 r30822  
    4343package org.netbeans.modules.keyring.fallback;
    4444
    45 import java.util.UUID;
     45import java.security.SecureRandom;
    4646import java.util.logging.Level;
    4747import java.util.logging.Logger;
     48
    4849import org.netbeans.modules.keyring.spi.EncryptionProvider;
    4950import org.netbeans.spi.keyring.KeyringProvider;
     
    7374    }
    7475
     76    @Override
    7577    public boolean enabled() {
    7678        if (encryption.enabled()) {
     
    8688    private boolean testSampleKey() {
    8789        encryption.freshKeyring(true);
    88         if (_save(SAMPLE_KEY, (SAMPLE_KEY + UUID.randomUUID()).toCharArray(),
     90        byte[] randomArray = new byte[36];
     91        new SecureRandom().nextBytes(randomArray);
     92        if (_save(SAMPLE_KEY, (SAMPLE_KEY + new String(randomArray)).toCharArray(),
    8993                "Sample value ensuring that decryption is working.")) {
    9094            LOG.fine("saved sample key");
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/gnome/GnomeKeyringLibrary.java

    r26335 r30822  
    4343package org.netbeans.modules.keyring.gnome;
    4444
     45import com.sun.jna.DefaultTypeMapper;
     46import com.sun.jna.FromNativeContext;
    4547import com.sun.jna.Library;
    4648import com.sun.jna.Native;
    4749import com.sun.jna.Pointer;
    4850import com.sun.jna.Structure;
     51import com.sun.jna.ToNativeContext;
     52import com.sun.jna.TypeConverter;
     53import java.io.File;
     54import java.util.Arrays;
     55import java.util.Collections;
     56import java.util.List;
     57import java.util.Map;
    4958
    5059/**
     
    5564public interface GnomeKeyringLibrary extends Library {
    5665
    57     GnomeKeyringLibrary LIBRARY = (GnomeKeyringLibrary) Native.loadLibrary("gnome-keyring", GnomeKeyringLibrary.class);
     66    class LibFinder {
     67        private static final String GENERIC = "gnome-keyring";
     68        // http://packages.ubuntu.com/search?suite=precise&arch=any&mode=exactfilename&searchon=contents&keywords=libgnome-keyring.so.0
     69        private static final String EXPLICIT_ONEIRIC = "/usr/lib/libgnome-keyring.so.0";
     70        private static Object load(Map<?,?> options) {
     71            try {
     72                return Native.loadLibrary(GENERIC, GnomeKeyringLibrary.class, options);
     73            } catch (UnsatisfiedLinkError x) {
     74                // #203735: on Oneiric, may have trouble finding right lib.
     75                // Precise is using multiarch (#211401) which should work automatically using JNA 3.4+ (#211403).
     76                // Unclear if this workaround is still needed for Oneiric with 3.4, but seems harmless to leave it in for now.
     77                if (new File(EXPLICIT_ONEIRIC).isFile()) {
     78                    return Native.loadLibrary(EXPLICIT_ONEIRIC, GnomeKeyringLibrary.class, options);
     79                } else {
     80                    throw x;
     81                }
     82            }
     83        }
     84        private LibFinder() {}
     85    }
     86
     87    GnomeKeyringLibrary LIBRARY = (GnomeKeyringLibrary) LibFinder.load(Collections.singletonMap(OPTION_TYPE_MAPPER, new DefaultTypeMapper() {
     88        {
     89            addTypeConverter(Boolean.TYPE, new TypeConverter() { // #198921
     90                @Override public Object toNative(Object value, ToNativeContext context) {
     91                    return Boolean.TRUE.equals(value) ? 1 : 0;
     92                }
     93                @Override public Object fromNative(Object value, FromNativeContext context) {
     94                    return ((Integer) value).intValue() != 0;
     95                }
     96                @Override public Class<?> nativeType() {
     97                    // gint is 32-bit int
     98                    return Integer.class;
     99                }
     100            });
     101        }
     102    }));
    58103
    59104    boolean gnome_keyring_is_available();
     
    98143        public /*GnomeKeyringAttributeList*/Pointer attributes;
    99144        public String secret;
     145
     146        @Override
     147        protected List<String> getFieldOrder() {
     148            return Arrays.asList( new String[] {
     149                "keyring",
     150                "item_id",
     151                "attributes",
     152                "secret",
     153            } );
     154        }
    100155    }
    101156
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/gnome/GnomeProvider.java

    r26335 r30822  
    4343package org.netbeans.modules.keyring.gnome;
    4444
    45 import com.sun.jna.Pointer;
     45import static org.netbeans.modules.keyring.gnome.GnomeKeyringLibrary.GNOME_KEYRING_ITEM_GENERIC_SECRET;
     46import static org.netbeans.modules.keyring.gnome.GnomeKeyringLibrary.GnomeKeyringAttribute_SIZE;
     47import static org.netbeans.modules.keyring.gnome.GnomeKeyringLibrary.LIBRARY;
     48
    4649import java.util.logging.Level;
    4750import java.util.logging.Logger;
    48 import static org.netbeans.modules.keyring.gnome.GnomeKeyringLibrary.*;
     51
     52import org.netbeans.modules.keyring.gnome.GnomeKeyringLibrary.GnomeKeyringFound;
    4953import org.netbeans.spi.keyring.KeyringProvider;
     54
     55import com.sun.jna.Pointer;
    5056
    5157public class GnomeProvider implements KeyringProvider {
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/kde/KWalletProvider.java

    r30738 r30822  
    7070        }
    7171        CommandResult result = runCommand("isEnabled");
    72         if(new String(result.retVal).equals("true")) {
     72        if(new String(result.retVal).equals("true")) {       
    7373            return updateHandler();
    74         }
     74        }                   
    7575        return false;
    76     };
     76    }
    7777
    7878    @Override
    7979    public char[] read(String key){
    8080        if (updateHandler()){
    81             CommandResult result = runCommand("readPassword", handler, getApplicationName(), key.toCharArray(), getApplicationName(true));
     81            CommandResult result = runCommand("readPassword", handler, getApplicationName(), key.toCharArray(), getApplicationName());
    8282            if (result.exitCode != 0){
    8383                warning("read action returned not 0 exitCode");
     
    8787        return null;
    8888        //throw new KwalletException("read");
    89     };
     89    }
    9090
    9191    @Override
     
    9595        if (updateHandler()){
    9696            CommandResult result = runCommand("writePassword", handler , getApplicationName()
    97                     , key.toCharArray(), password , getApplicationName(true));
     97                    , key.toCharArray(), password , getApplicationName());
    9898            if (result.exitCode != 0 || (new String(result.retVal)).equals("-1")){
    9999                warning("save action failed");
     
    102102        }
    103103        //throw new KwalletException("save");
    104     };
     104    }
    105105
    106106    @Override
     
    108108        if (updateHandler()){
    109109            CommandResult result = runCommand("removeEntry" ,handler,
    110             getApplicationName() , key.toCharArray() , getApplicationName(true));
     110            getApplicationName() , key.toCharArray() , getApplicationName());
    111111             if (result.exitCode != 0  || (new String(result.retVal)).equals("-1")){
    112112                warning("delete action failed");
     
    115115        }
    116116        //throw new KwalletException("delete");
    117     };
     117    }
    118118
    119119    private boolean updateHandler(){
     
    122122        }
    123123        handler = new String(handler).equals("")? "0".toCharArray() : handler;
    124         CommandResult result = runCommand("isOpen",handler);
     124        CommandResult result = runCommand("isOpen",handler);         
    125125        if(new String(result.retVal).equals("true")){
    126126            return true;
    127127        }
    128128        char[] localWallet = defaultLocalWallet;
    129         result = runCommand("localWallet");
    130         if(result.exitCode == 0) {
     129        result = runCommand("localWallet");                     
     130        if(result.exitCode == 0) {                   
    131131            localWallet = result.retVal;
    132132        }
    133 
    134         if(new String(localWallet).contains(".service")) {
     133           
     134        if(new String(localWallet).contains(".service")) {           
    135135            //Temporary workaround for the bug in kdelibs/kdeui/util/kwallet.cpp
    136136            //The bug was fixed http://svn.reviewboard.kde.org/r/5885/diff/
     
    138138            return false;
    139139        }
    140         result = runCommand("open", localWallet , "0".toCharArray(), getApplicationName(true));
    141         if(result.exitCode == 2) {
     140        result = runCommand("open", localWallet , "0".toCharArray(), getApplicationName());
     141        if(result.exitCode == 2) { 
    142142            warning("time out happened while accessing KWallet");
    143143            //don't try to open KWallet anymore until bug https://bugs.kde.org/show_bug.cgi?id=259229 is fixed
    144144            timeoutHappened = true;
    145145            return false;
    146         }
     146        }     
    147147        if(result.exitCode != 0 || new String(result.retVal).equals("-1")) {
    148148            warning("failed to access KWallet");
    149149            return false;
    150         }
     150        }         
    151151        handler = result.retVal;
    152152        return true;
    153153    }
    154 
    155 
     154         
     155   
    156156
    157157    private CommandResult runCommand(String command,char[]... commandArgs) {
     
    175175            }
    176176            Process pr = rt.exec(argv);
    177             String line;
    178 
     177           
    179178            try (BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()))) {
     179
     180                String line;
    180181                while((line = input.readLine()) != null) {
    181182                    if (!retVal.equals("")){
     
    183184                    }
    184185                    retVal = retVal.concat(line);
    185                 }
    186             }
    187 
     186                }           
     187            }
    188188            try (BufferedReader input = new BufferedReader(new InputStreamReader(pr.getErrorStream()))) {
     189
     190                String line;
    189191                while((line = input.readLine()) != null) {
    190192                    if (!errVal.equals("")){
     
    199201                logger.log(Level.FINE, "application exit with code {0} for commandString: {1}; errVal: {2}",
    200202                            new Object[]{exitCode, Arrays.toString(argv), errVal});
    201             }
     203            }       
    202204        } catch (InterruptedException ex) {
    203205            logger.log(Level.FINE,
     
    210212        }
    211213        return new CommandResult(exitCode, retVal.trim().toCharArray(), errVal.trim());
    212     }
     214    }   
    213215
    214216    private char[] getApplicationName(){
    215         return getApplicationName(false);
    216     }
    217 
    218     private char[] getApplicationName(boolean version){
    219         return "JOSM".toCharArray();
     217        return "JOSM".toCharArray(); // NOI18N
    220218    }
    221219
    222220    private void warning(String descr) {
    223221        logger.log(Level.WARNING, "Something went wrong: {0}", descr);
    224     }
    225 
     222    }     
     223 
    226224    private class CommandResult {
    227225        private int exitCode;
     
    231229            this.exitCode = exitCode;
    232230            this.retVal = retVal;
    233         }
     231        }                       
    234232    }
    235233
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/mac/MacProvider.java

    r26335 r30822  
    7777
    7878    public void save(String key, char[] password, String description) {
    79         delete(key); // XXX supposed to use SecKeychainItemModifyContent instead, but this seems like too much work
    8079        try {
    8180            byte[] serviceName = key.getBytes("UTF-8");
     
    8382            // Keychain Access seems to expect UTF-8, so do not use Utils.chars2Bytes:
    8483            byte[] data = new String(password).getBytes("UTF-8");
    85             error("save", SecurityLibrary.LIBRARY.SecKeychainAddGenericPassword(null, serviceName.length, serviceName,
    86                     accountName.length, accountName, data.length, data, null));
     84            Pointer[] itemRef = new Pointer[1];
     85            error("find (for save)", SecurityLibrary.LIBRARY.SecKeychainFindGenericPassword(null, serviceName.length, serviceName,
     86                    accountName.length, accountName, null, null, itemRef));
     87            if (itemRef[0] != null) {
     88                error("save (update)", SecurityLibrary.LIBRARY.SecKeychainItemModifyContent(itemRef[0], null, data.length, data));
     89                SecurityLibrary.LIBRARY.CFRelease(itemRef[0]);
     90            } else {
     91                error("save (new)", SecurityLibrary.LIBRARY.SecKeychainAddGenericPassword(null, serviceName.length, serviceName,
     92                        accountName.length, accountName, data.length, data, null));
     93            }
    8794        } catch (UnsupportedEncodingException x) {
    8895            LOG.log(Level.WARNING, null, x);
     
    100107            if (itemRef[0] != null) {
    101108                error("delete", SecurityLibrary.LIBRARY.SecKeychainItemDelete(itemRef[0]));
     109                SecurityLibrary.LIBRARY.CFRelease(itemRef[0]);
    102110            }
    103111        } catch (UnsupportedEncodingException x) {
     
    108116    private static void error(String msg, int code) {
    109117        if (code != 0 && code != /* errSecItemNotFound, always returned from find it seems */-25300) {
    110             // XXX translate, but SecCopyErrorMessageString returns weird CFStringRef
    111             LOG.warning(msg + ": " + code);
     118            Pointer translated = SecurityLibrary.LIBRARY.SecCopyErrorMessageString(code, null);
     119            String str;
     120            if (translated == null) {
     121                str = String.valueOf(code);
     122            } else {
     123                char[] buf = new char[(int) SecurityLibrary.LIBRARY.CFStringGetLength(translated)];
     124                for (int i = 0; i < buf.length; i++) {
     125                    buf[i] = SecurityLibrary.LIBRARY.CFStringGetCharacterAtIndex(translated, i);
     126                }
     127                SecurityLibrary.LIBRARY.CFRelease(translated);
     128                str = new String(buf) + " (" + code + ")";
     129            }
     130            LOG.log(Level.WARNING, "{0}: {1}", new Object[] {msg, str});
    112131        }
    113132    }
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/mac/SecurityLibrary.java

    r26335 r30822  
    6565            );
    6666
     67    int SecKeychainItemModifyContent(
     68            Pointer/*SecKeychainItemRef*/ itemRef,
     69            Pointer/*SecKeychainAttributeList**/ attrList,
     70            int length,
     71            byte[] data
     72    );
     73
    6774    int SecKeychainFindGenericPassword(
    6875            Pointer keychainOrArray,
     
    7380            int[] passwordLength,
    7481            Pointer[] passwordData,
    75             Pointer[] itemRef
     82            Pointer/*SecKeychainItemRef*/[] itemRef
    7683            );
    7784
     
    8087            );
    8188
     89    Pointer/*CFString*/ SecCopyErrorMessageString(
     90            int status,
     91            Pointer reserved
     92            );
     93
     94    // http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html
     95
     96    long/*CFIndex*/ CFStringGetLength(
     97            Pointer/*CFStringRef*/ theString
     98    );
     99
     100    char/*UniChar*/ CFStringGetCharacterAtIndex(
     101            Pointer/*CFStringRef*/ theString,
     102            long/*CFIndex*/ idx
     103    );
     104
     105    void CFRelease(
     106            Pointer/*CFTypeRef*/ cf
     107    );
     108
    82109}
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/win32/Win32Protect.java

    r26335 r30822  
    4949import com.sun.jna.WString;
    5050import com.sun.jna.win32.StdCallLibrary;
     51
    5152import java.util.Arrays;
     53import java.util.List;
    5254import java.util.concurrent.Callable;
    5355import java.util.logging.Level;
    5456import java.util.logging.Logger;
    55 import org.netbeans.modules.keyring.impl.Utils;
     57
     58import org.netbeans.modules.keyring.utils.Utils;
    5659import org.netbeans.modules.keyring.spi.EncryptionProvider;
    5760
     
    161164            ((Memory) pbData).clear();
    162165        }
     166
     167        @Override
     168        protected List<String> getFieldOrder() {
     169            return Arrays.asList( new String[] {
     170                "cbData",
     171                "pbData",
     172            } );
     173        }
    163174    }
    164175
  • applications/editors/josm/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/InitializationWizard.java

    r30737 r30822  
    460460    }
    461461
     462    /**
     463     * Close the dialog and discard all changes.
     464     */
    462465    class CancelAction extends AbstractAction {
    463466        public CancelAction() {
     
    478481    }
    479482
     483    /**
     484     * Go to the previous page.
     485     */
    480486    class BackAction extends AbstractAction {
    481487        public BackAction() {
Note: See TracChangeset for help on using the changeset viewer.