Cyberduck Mountain Duck CLI

Changeset 43439


Ignore:
Timestamp:
Nov 22, 2017 12:44:24 PM (7 months ago)
Author:
dkocher
Message:

Merge pull request #1192 in ITERATE/cyberduck from bugfix/TRAC-10148 to master

  • commit '9505155f6ba4d18f9237080a3a2c5a0fc1003290': (27 commits) Remove check. Revert. Changes. Catch user cancel. Add different methods for looking up login and private key password. Fix compile. Only lookup password in keychain if not already set. Remove duplicated lookup of password in keychain. Prefetch password from keychain bevore validation of credentials. Add missing field. Read initial state for keychain checkbox from options. Enable keychain option for password prompt. Fix test. Read default setting from options. Read keychain setting from options. Try public key last for scenario with publickey auth with private key in agent + OTP. Remove duplicated validation. Review login options. Add client certificate option. Revert order. Fix #10148. ...
Files:
1 deleted
30 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property subgit:lock changed from commit:b1c3ae7caea5a89fa3451153bc324c1839182da2 timestamp:2017-11-22T11:17:43.272 to commit:46475a88684564f5066cd0c5ce2945a3ab6ac311 timestamp:2017-11-22T12:45:17.751
    • Property svn:mergeinfo changed
      /shelves/11.2017merged: 43412-43438
  • trunk/Changelog.txt

    r43398 r43439  
    446.3.1
    55- [Bugfix] Slow user interface performance (Mac) (#9970)
     6- [Bugfix] Prompt for credentials when using public key authentication with agent (SFTP) (#10148)
    67
    786.3
  • trunk/core/src/main/java/ch/cyberduck/core/AuthenticationProvider.java

    r43211 r43439  
    2626    R authenticate(Host bookmark, HostPasswordStore keychain, LoginCallback prompt, CancelCallback cancel)
    2727        throws BackgroundException;
     28
     29    String getMethod();
    2830}
  • trunk/core/src/main/java/ch/cyberduck/core/Credentials.java

    r43026 r43439  
    156156    }
    157157
     158    public boolean isPasswordAuthentication() {
     159        return StringUtils.isNotBlank(password);
     160    }
     161
    158162    /**
    159163     * SSH specific
  • trunk/core/src/main/java/ch/cyberduck/core/HostPasswordStore.java

    r43407 r43439  
    3131
    3232    /**
    33      * @param host Hostname
     33     * Find password for login
     34     *
     35     * @param bookmark Hostname
    3436     * @return the password fetched from the keychain or null if it was not found
    3537     */
    36     public String find(final Host host) {
    37         if(preferences.getBoolean("connection.login.keychain")) {
    38             log.warn("Keychain disabled in preferences");
    39             return null;
    40         }
    41         if(log.isInfoEnabled()) {
    42             log.info(String.format("Fetching password from keychain for %s", host));
    43         }
    44         if(StringUtils.isEmpty(host.getHostname())) {
     38    public String findLoginPassword(final Host bookmark) {
     39        if(StringUtils.isEmpty(bookmark.getHostname())) {
    4540            log.warn("No hostname given");
    4641            return null;
    4742        }
    48         final Credentials credentials = host.getCredentials();
     43        final Credentials credentials = bookmark.getCredentials();
    4944        if(StringUtils.isEmpty(credentials.getUsername())) {
    5045            log.warn("No username given");
    5146            return null;
    5247        }
    53         String p;
     48        if(log.isInfoEnabled()) {
     49            log.info(String.format("Fetching login password from keychain for %s", bookmark));
     50        }
     51        final String password = this.getPassword(bookmark.getProtocol().getScheme(), bookmark.getPort(),
     52            bookmark.getHostname(), credentials.getUsername());
     53        if(null == password) {
     54            if(log.isInfoEnabled()) {
     55                log.info(String.format("Password not found in keychain for %s", bookmark));
     56            }
     57        }
     58        return password;
     59    }
     60
     61    /**
     62     * Find passphrase for private key
     63     *
     64     * @param bookmark Hostname
     65     * @return the password fetched from the keychain or null if it was not found
     66     */
     67    public String findPrivateKeyPassphrase(final Host bookmark) {
     68        if(StringUtils.isEmpty(bookmark.getHostname())) {
     69            log.warn("No hostname given");
     70            return null;
     71        }
     72        final Credentials credentials = bookmark.getCredentials();
     73        if(StringUtils.isEmpty(credentials.getUsername())) {
     74            log.warn("No username given");
     75            return null;
     76        }
     77        if(log.isInfoEnabled()) {
     78            log.info(String.format("Fetching private key passphrase from keychain for %s", bookmark));
     79        }
    5480        if(credentials.isPublicKeyAuthentication()) {
    5581            final Local key = credentials.getIdentity();
    56             p = this.getPassword(host.getHostname(), key.getAbbreviatedPath());
    57             if(null == p) {
     82            String passphrase = this.getPassword(bookmark.getHostname(), key.getAbbreviatedPath());
     83            if(null == passphrase) {
    5884                // Interoperability with OpenSSH (ssh, ssh-agent, ssh-add)
    59                 p = this.getPassword("SSH", key.getAbsolute());
     85                passphrase = this.getPassword("SSH", key.getAbsolute());
    6086            }
    61             if(null == p) {
     87            if(null == passphrase) {
    6288                // Backward compatibility
    63                 p = this.getPassword("SSHKeychain", key.getAbbreviatedPath());
     89                passphrase = this.getPassword("SSHKeychain", key.getAbbreviatedPath());
    6490            }
     91            if(null == passphrase) {
     92                if(log.isInfoEnabled()) {
     93                    log.info(String.format("Passphrase not found in keychain for %s", key));
     94                }
     95            }
     96            return passphrase;
    6597        }
    6698        else {
    67             p = this.getPassword(host.getProtocol().getScheme(), host.getPort(),
    68                 host.getHostname(), credentials.getUsername());
     99            return null;
    69100        }
    70         if(null == p) {
    71             if(log.isInfoEnabled()) {
    72                 log.info(String.format("Password not found in keychain for %s", host));
    73             }
    74         }
    75         return p;
    76101    }
    77102
  • trunk/core/src/main/java/ch/cyberduck/core/KeychainLoginService.java

    r43407 r43439  
    9898            }
    9999        }
     100        String password = credentials.getPassword();
     101        if(StringUtils.isBlank(password) && options.keychain) {
     102            password = keychain.findLoginPassword(bookmark);
     103        }
     104        if(StringUtils.isNotBlank(password)) {
     105            if(log.isInfoEnabled()) {
     106                log.info(String.format("Fetched password from keychain for %s", bookmark));
     107            }
     108            // No need to reinsert found password to the keychain.
     109            credentials.setSaved(false);
     110        }
     111        credentials.setPassword(password);
    100112        if(!credentials.validate(bookmark.getProtocol(), options)) {
    101113            if(StringUtils.isNotBlank(credentials.getUsername())) {
    102                 final String password = keychain.find(bookmark);
    103                 if(StringUtils.isBlank(password)) {
     114                if(StringUtils.isBlank(credentials.getPassword())) {
    104115                    final StringAppender appender = new StringAppender();
    105116                    appender.append(message);
     
    109120                        appender.toString(),
    110121                        options));
    111                 }
    112                 else {
    113                     credentials.setPassword(password);
    114                     // No need to reinsert found password to the keychain.
    115                     credentials.setSaved(false);
    116122                }
    117123            }
     
    127133            }
    128134        }
    129         else {
    130             if(!credentials.isPassed()) {
    131                 final String password = keychain.find(bookmark);
    132                 if(StringUtils.isNotBlank(password)) {
    133                     if(log.isInfoEnabled()) {
    134                         log.info(String.format("Fetched password from keychain for %s", bookmark));
    135                     }
    136                     credentials.setPassword(password);
    137                     // No need to reinsert found password to the keychain.
    138                     credentials.setSaved(false);
    139                 }
    140             }
    141             else {
    142                 log.warn(String.format("Skip password lookup for previously authenticated connection %s", bookmark));
    143             }
    144         }
    145135    }
    146136}
  • trunk/core/src/main/java/ch/cyberduck/core/LoginOptions.java

    r43211 r43439  
    3939    public boolean keychain = true;
    4040    /**
     41     * Save in keychain checked by default
     42     */
     43    public boolean save = PreferencesFactory.get().getBoolean("connection.login.keychain");
     44    /**
    4145     * Enable option to select public key
    4246     */
    4347    public boolean publickey = false;
     48    /**
     49     * Enable option to select client certificate
     50     */
     51    public boolean certificate = false;
    4452    /**
    4553     * Enable option to login as anonymous user
     
    5462    public String passwordPlaceholder = StringUtils.EMPTY;
    5563
    56     /**
    57      * Save in keychain checked by default
    58      */
    59     public boolean save = PreferencesFactory.get().getBoolean("connection.login.keychain");
    60 
    6164    public LoginOptions() {
    6265        //
    6366    }
    6467
     68    public LoginOptions(final LoginOptions copy) {
     69        user = copy.user;
     70        password = copy.password;
     71        keychain = copy.keychain;
     72        save = copy.save;
     73        publickey = copy.publickey;
     74        certificate = copy.certificate;
     75        anonymous = copy.anonymous;
     76        icon = copy.icon;
     77        usernamePlaceholder = copy.usernamePlaceholder;
     78        passwordPlaceholder = copy.passwordPlaceholder;
     79    }
     80
    6581    public LoginOptions user(boolean e) {
    6682        user = e;
     
    114130    }
    115131
     132    public boolean certificate() {
     133        return certificate;
     134    }
     135
    116136    public boolean anonymous() {
    117137        return anonymous;
     
    153173    public void configure(final Protocol protocol) {
    154174        publickey = protocol.isPrivateKeyConfigurable();
     175        certificate = protocol.isCertificateConfigurable();
    155176        anonymous = protocol.isAnonymousConfigurable();
    156177        user = protocol.isUsernameConfigurable();
     
    171192        final LoginOptions that = (LoginOptions) o;
    172193        return user == that.user &&
    173                 password == that.password &&
    174                 keychain == that.keychain &&
    175                 publickey == that.publickey &&
    176                 anonymous == that.anonymous &&
    177                 Objects.equals(icon, that.icon);
     194            password == that.password &&
     195            keychain == that.keychain &&
     196            publickey == that.publickey &&
     197            anonymous == that.anonymous &&
     198            Objects.equals(icon, that.icon);
    178199    }
    179200
  • trunk/core/src/main/java/ch/cyberduck/core/Protocol.java

    r43211 r43439  
    5454        sftp,
    5555        s3,
    56         googlestorage {
    57             @Override
    58             public boolean validate(final Credentials credentials, final LoginOptions options) {
    59                 // OAuth only requires the project token
    60                 return true;
    61             }
    62         },
     56        googlestorage,
    6357        dropbox,
    64         googledrive {
    65             @Override
    66             public boolean validate(final Credentials credentials, final LoginOptions options) {
    67                 // OAuth only
    68                 return true;
    69             }
    70         },
     58        googledrive,
    7159        swift,
    7260        dav,
     
    8371            }
    8472        },
    85         onedrive {
    86             @Override
    87             public boolean validate(final Credentials credentials, final LoginOptions options) {
    88                 // OAuth only
    89                 return true;
    90             }
    91         },
     73        onedrive,
    9274        irods,
    9375        b2,
     
    10991                }
    11092            }
     93            if(options.certificate) {
     94                if(credentials.isCertificateAuthentication()) {
     95                    return true;
     96                }
     97            }
    11198            if(options.publickey) {
    11299                // No password may be required to decrypt private key
     
    120107            }
    121108            if(options.password) {
    122                 if(StringUtils.isEmpty(credentials.getPassword())) {
    123                     return false;
    124                 }
     109                if(credentials.isPasswordAuthentication()) {
     110                    return true;
     111                }
     112                return false;
    125113            }
    126114            return true;
  • trunk/core/src/test/java/ch/cyberduck/core/CredentialsTest.java

    r37062 r43439  
    6666        Credentials c = new Credentials("user", " ");
    6767        assertTrue(c.validate(new TestProtocol(Scheme.ftp), new LoginOptions()));
    68         assertTrue(c.validate(new TestProtocol(Scheme.http), new LoginOptions()));
     68        assertFalse(c.validate(new TestProtocol(Scheme.http), new LoginOptions()));
    6969        assertTrue(c.validate(new TestProtocol(Scheme.sftp), new LoginOptions()));
    7070    }
  • trunk/core/src/test/java/ch/cyberduck/core/KeychainLoginServiceTest.java

    r43408 r43439  
    9797        }, new DisabledPasswordStore() {
    9898            @Override
    99             public String find(final Host host) {
     99            public String findLoginPassword(final Host bookmark) {
    100100                keychain.set(true);
    101101                return "P";
  • trunk/core/src/test/java/ch/cyberduck/core/LoginConnectionServiceTest.java

    r42631 r43439  
    105105        }, new DisabledHostKeyCallback(), new DisabledPasswordStore() {
    106106            @Override
    107             public String find(final Host host) {
     107            public String findLoginPassword(final Host bookmark) {
    108108                keychain.set(true);
    109109                // Old password stored
  • trunk/hubic/src/main/java/ch/cyberduck/core/hubic/HubicProtocol.java

    r42039 r43439  
    1717
    1818import ch.cyberduck.core.AbstractProtocol;
    19 import ch.cyberduck.core.Credentials;
    2019import ch.cyberduck.core.LocaleFactory;
    21 import ch.cyberduck.core.LoginOptions;
    2220import ch.cyberduck.core.Scheme;
    2321import ch.cyberduck.core.openstack.SwiftProtocol;
     
    9593        return new SwiftProtocol().icon();
    9694    }
    97 
    98     @Override
    99     public boolean validate(final Credentials credentials, final LoginOptions options) {
    100         // OAuth only requires the project token
    101         return true;
    102     }
    10395}
  • trunk/manta/src/main/java/ch/cyberduck/core/manta/MantaPublicKeyAuthentication.java

    r43406 r43439  
    8181                @Override
    8282                public char[] reqPassword(Resource<?> resource) {
    83                     String password = keychain.find(bookmark);
     83                    String password = keychain.findPrivateKeyPassphrase(bookmark);
    8484                    if(StringUtils.isEmpty(password)) {
    8585                        try {
     
    116116
    117117        return this.computeFingerprint(provider);
     118    }
     119
     120    @Override
     121    public String getMethod() {
     122        return "publickey";
    118123    }
    119124
  • trunk/osx/src/main/java/ch/cyberduck/ui/cocoa/callback/PromptLoginCallback.java

    r42522 r43439  
    8282        }
    8383        final Credentials credentials = new Credentials(username);
     84        credentials.setSaved(options.save);
    8485        final LoginController controller = new LoginController(title, reason, bookmark, credentials, options);
    8586        final SheetInvoker sheet = new SheetInvoker(controller, parent, controller);
  • trunk/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/BookmarkController.java

    r43211 r43439  
    371371            @Override
    372372            public void change(final Host bookmark) {
    373                 anonymousCheckbox.setEnabled(options.anonymous && bookmark.getProtocol().isAnonymousConfigurable());
     373                anonymousCheckbox.setEnabled(options.anonymous);
    374374                anonymousCheckbox.setState(credentials.isAnonymousLogin() ? NSCell.NSOnState : NSCell.NSOffState);
    375375            }
     
    457457            public void change(final Host bookmark) {
    458458
    459                 privateKeyPopup.setEnabled(bookmark.getProtocol().getType() == Protocol.Type.sftp || bookmark.getProtocol().getType() == Protocol.Type.manta);
     459                privateKeyPopup.setEnabled(options.publickey);
    460460                if(credentials.isPublicKeyAuthentication()) {
    461461                    privateKeyPopup.selectItemAtIndex(privateKeyPopup.indexOfItemWithRepresentedObject(credentials.getIdentity().getAbsolute()));
  • trunk/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/ConnectionController.java

    r43002 r43439  
    112112                passwordField.cell().setPlaceholderString(options.getPasswordPlaceholder());
    113113                passwordField.setEnabled(options.password && !credentials.isAnonymousLogin());
    114                 if(preferences.getBoolean("connection.login.keychain")) {
     114                if(options.keychain) {
    115115                    if(StringUtils.isBlank(bookmark.getHostname())) {
    116116                        return;
  • trunk/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/DefaultBookmarkController.java

    r42979 r43439  
    102102            @Override
    103103            public void change(final Host bookmark) {
    104                 certificatePopup.setEnabled(bookmark.getProtocol().isCertificateConfigurable());
     104                certificatePopup.setEnabled(options.certificate);
    105105                certificatePopup.removeAllItems();
    106106                certificatePopup.addItemWithTitle(LocaleFactory.localizedString("None"));
    107                 if(bookmark.getProtocol().isCertificateConfigurable()) {
     107                if(options.certificate) {
    108108                    certificatePopup.menu().addItem(NSMenuItem.separatorItem());
    109109                    for(String certificate : new KeychainX509KeyManager(bookmark).list()) {
  • trunk/osx/src/main/java/ch/cyberduck/ui/cocoa/controller/LoginController.java

    r42522 r43439  
    1818import ch.cyberduck.binding.HyperlinkAttributedStringFactory;
    1919import ch.cyberduck.binding.Outlet;
    20 import ch.cyberduck.binding.application.NSCell;
    2120import ch.cyberduck.binding.application.NSImage;
    2221import ch.cyberduck.binding.application.NSImageView;
     
    4746        this.title = title;
    4847        this.reason = reason;
    49         this.addObserver(new BookmarkObserver() {
    50             @Override
    51             public void change(final Host bookmark) {
    52                 if(!options.user) {
    53                     usernameField.setEnabled(false);
    54                 }
    55                 if(!options.anonymous) {
    56                     anonymousCheckbox.setEnabled(false);
    57                     anonymousCheckbox.setState(NSCell.NSOffState);
    58                 }
    59                 if(!options.publickey) {
    60                     privateKeyPopup.setEnabled(false);
    61                     privateKeyPopup.selectItemWithTitle(LocaleFactory.localizedString("None"));
    62                 }
    63             }
    64         });
    6548    }
    6649
  • trunk/s3/src/main/java/ch/cyberduck/core/s3/S3UrlProvider.java

    r36095 r43439  
    153153        final Calendar expiry = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    154154        expiry.add(Calendar.SECOND, seconds);
    155         final String secret = store.find(session.getHost());
     155        final String secret = store.findLoginPassword(session.getHost());
    156156        if(StringUtils.isBlank(secret)) {
    157157            log.warn("No secret found in keychain required to sign temporary URL");
  • trunk/s3/src/test/java/ch/cyberduck/core/s3/S3UrlProviderTest.java

    r35652 r43439  
    2727        assertEquals(5, new S3UrlProvider(session, new DisabledPasswordStore() {
    2828            @Override
    29             public String find(final Host host) {
     29            public String findLoginPassword(final Host bookmark) {
    3030                return "k";
    3131            }
     
    6565                new S3UrlProvider(session, new DisabledPasswordStore() {
    6666                    @Override
    67                     public String find(final Host host) {
     67                    public String findLoginPassword(final Host bookmark) {
    6868                        return "k";
    6969                    }
     
    7878        final S3UrlProvider provider = new S3UrlProvider(session, new DisabledPasswordStore() {
    7979            @Override
    80             public String find(final Host host) {
     80            public String findLoginPassword(final Host bookmark) {
    8181                return "k";
    8282            }
     
    9494        final S3UrlProvider provider = new S3UrlProvider(session, new DisabledPasswordStore() {
    9595            @Override
    96             public String find(final Host host) {
     96            public String findLoginPassword(final Host bookmark) {
    9797                return "k";
    9898            }
  • trunk/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPSession.java

    r43241 r43439  
    232232        }
    233233        else {
    234             if(preferences.getBoolean("ssh.authentication.agent.enable")) {
    235                 methods.add(new SFTPAgentAuthentication(this, new OpenSSHAgentAuthenticator()));
    236                 methods.add(new SFTPAgentAuthentication(this, new PageantAuthenticator()));
    237             }
    238             methods.add(new SFTPPublicKeyAuthentication(this));
     234            if(credentials.isPublicKeyAuthentication()) {
     235                if(preferences.getBoolean("ssh.authentication.agent.enable")) {
     236                    methods.add(new SFTPAgentAuthentication(this, new OpenSSHAgentAuthenticator()));
     237                    methods.add(new SFTPAgentAuthentication(this, new PageantAuthenticator()));
     238                }
     239                methods.add(new SFTPPublicKeyAuthentication(this));
     240            }
     241            methods.add(new SFTPChallengeResponseAuthentication(this));
    239242            methods.add(new SFTPPasswordAuthentication(this));
    240             methods.add(new SFTPChallengeResponseAuthentication(this));
    241243        }
    242244        if(log.isDebugEnabled()) {
  • trunk/ssh/src/main/java/ch/cyberduck/core/sftp/auth/SFTPAgentAuthentication.java

    r43241 r43439  
    7070        return session.getClient().isAuthenticated();
    7171    }
     72
     73    @Override
     74    public String getMethod() {
     75        return "publickey";
     76    }
    7277}
  • trunk/ssh/src/main/java/ch/cyberduck/core/sftp/auth/SFTPChallengeResponseAuthentication.java

    r43405 r43439  
    4848    private final SFTPSession session;
    4949
    50     private static final char[] EMPTY_RESPONSE = new char[0];
    51 
    5250    public SFTPChallengeResponseAuthentication(final SFTPSession session) {
    5351        this.session = session;
     
    5957            log.debug(String.format("Login using challenge response authentication for %s", bookmark));
    6058        }
     59        final AtomicBoolean canceled = new AtomicBoolean();
    6160        try {
    6261            session.getClient().auth(bookmark.getCredentials().getUsername(), new AuthKeyboardInteractive(new ChallengeResponseProvider() {
    63                 /**
    64                  * Password sent flag
    65                  */
    66                 private final AtomicBoolean password = new AtomicBoolean();
    6762                private String name = StringUtils.EMPTY;
    6863                private String instruction = StringUtils.EMPTY;
     
    8883                        log.debug(String.format("Reply to challenge name %s with instruction %s", name, instruction));
    8984                    }
    90                     if(!password.get() && PasswordResponseProvider.DEFAULT_PROMPT_PATTERN.matcher(prompt).matches()) {
    91                         password.set(true);
     85                    if(!StringUtils.isBlank(bookmark.getCredentials().getPassword())
     86                        && PasswordResponseProvider.DEFAULT_PROMPT_PATTERN.matcher(prompt).matches()) {
    9287                        return bookmark.getCredentials().getPassword().toCharArray();
    9388                    }
     
    10297                            );
    10398                            additional = callback.prompt(bookmark, bookmark.getCredentials().getUsername(), title.toString(),
    104                                 message.toString(), new LoginOptions(bookmark.getProtocol()).user(false).publickey(false).keychain(false)
     99                                message.toString(), new LoginOptions(bookmark.getProtocol()).user(false).publickey(false).keychain(PasswordResponseProvider.DEFAULT_PROMPT_PATTERN.matcher(prompt).matches())
    105100                                    .usernamePlaceholder(bookmark.getCredentials().getUsername())
    106101                            );
    107102                        }
    108103                        catch(LoginCanceledException e) {
    109                             return EMPTY_RESPONSE;
     104                            canceled.set(true);
     105                            // Return null if user cancels
     106                            return null;
    110107                        }
    111108                        // Responses are encoded in ISO-10646 UTF-8.
     
    121118        }
    122119        catch(IOException e) {
     120            if(canceled.get()) {
     121                throw new LoginCanceledException();
     122            }
    123123            throw new SFTPExceptionMappingService().map(e);
    124124        }
    125125        return session.getClient().isAuthenticated();
    126126    }
     127
     128    @Override
     129    public String getMethod() {
     130        return "keyboard-interactive";
     131    }
    127132}
  • trunk/ssh/src/main/java/ch/cyberduck/core/sftp/auth/SFTPNoneAuthentication.java

    r43241 r43439  
    5454        }
    5555    }
     56
     57    @Override
     58    public String getMethod() {
     59        return "none";
     60    }
    5661}
  • trunk/ssh/src/main/java/ch/cyberduck/core/sftp/auth/SFTPPasswordAuthentication.java

    r43241 r43439  
    1717
    1818import ch.cyberduck.core.AuthenticationProvider;
    19 import ch.cyberduck.core.BookmarkNameProvider;
    2019import ch.cyberduck.core.Credentials;
    2120import ch.cyberduck.core.Host;
     
    3231import ch.cyberduck.core.threading.CancelCallback;
    3332
    34 import org.apache.commons.lang3.StringUtils;
    3533import org.apache.log4j.Logger;
    3634
    3735import java.io.IOException;
    38 import java.text.MessageFormat;
    3936
    4037import net.schmizz.sshj.userauth.method.AuthPassword;
     
    5552    public Boolean authenticate(final Host bookmark, final HostPasswordStore keychain, final LoginCallback callback, final CancelCallback cancel)
    5653        throws BackgroundException {
    57         if(StringUtils.isBlank(bookmark.getCredentials().getPassword())) {
    58             final String message;
    59             if(session.getClient().getUserAuth().hadPartialSuccess()) {
    60                 message = LocaleFactory.localizedString("Partial authentication success", "Credentials");
    61             }
    62             else {
    63                 message = MessageFormat.format(LocaleFactory.localizedString(
    64                     "Login {0} with username and password", "Credentials"), BookmarkNameProvider.toString(bookmark));
    65             }
    66             final Credentials additional = callback.prompt(bookmark, bookmark.getCredentials().getUsername(),
    67                 String.format("%s %s", LocaleFactory.localizedString("Login", "Login"), bookmark.getHostname()),
    68                 message,
    69                 new LoginOptions(bookmark.getProtocol()).user(false).keychain(false).publickey(false)
    70                     .usernamePlaceholder(bookmark.getCredentials().getUsername()));
    71             return this.authenticate(bookmark, additional, callback, cancel);
    72         }
    73         else {
     54        if(bookmark.getCredentials().isPasswordAuthentication()) {
    7455            return this.authenticate(bookmark, bookmark.getCredentials(), callback, cancel);
    7556        }
     57        return false;
     58    }
     59
     60    @Override
     61    public String getMethod() {
     62        return "password";
    7663    }
    7764
  • trunk/ssh/src/main/java/ch/cyberduck/core/sftp/auth/SFTPPublicKeyAuthentication.java

    r43406 r43439  
    3737import java.io.InputStreamReader;
    3838import java.nio.charset.Charset;
     39import java.util.concurrent.atomic.AtomicBoolean;
    3940
    4041import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile;
     
    6970            final Local identity = credentials.getIdentity();
    7071            final FileKeyProvider provider;
     72            final AtomicBoolean canceled = new AtomicBoolean();
    7173            try {
    7274                final KeyFormat format = KeyProviderUtil.detectKeyFileFormat(
     
    9799                    @Override
    98100                    public char[] reqPassword(Resource<?> resource) {
    99                         final String password = keychain.find(bookmark);
     101                        final String password = keychain.findPrivateKeyPassphrase(bookmark);
    100102                        if(StringUtils.isEmpty(password)) {
    101103                            try {
     
    117119                            }
    118120                            catch(LoginCanceledException e) {
     121                                canceled.set(true);
    119122                                // Return null if user cancels
    120123                                return null;
     
    133136            }
    134137            catch(IOException e) {
     138                if(canceled.get()) {
     139                    throw new LoginCanceledException();
     140                }
    135141                throw new SFTPExceptionMappingService().map(e);
    136142            }
     
    138144        return false;
    139145    }
     146
     147    @Override
     148    public String getMethod() {
     149        return "publickey";
     150    }
    140151}
  • trunk/windows/src/main/csharp/ch/cyberduck/ui/controller/BookmarkController.cs

    r43068 r43439  
    565565            View.UsernameEnabled = _options.user() && !_credentials.isAnonymousLogin();
    566566            View.UsernameLabel = _host.getProtocol().getUsernamePlaceholder() + ":";
    567             View.AnonymousEnabled = _options.anonymous() && _host.getProtocol().isAnonymousConfigurable();
     567            View.AnonymousEnabled = _options.anonymous();
    568568            View.AnonymousChecked = _credentials.isAnonymousLogin();
    569569            View.SelectedProtocol = _host.getProtocol();
     
    576576                View.SelectedConnectMode = _host.getFTPConnectMode();
    577577            }
    578             View.PrivateKeyFieldEnabled = _host.getProtocol().getType() == Protocol.Type.sftp;
     578            View.PrivateKeyFieldEnabled = _options.publickey();
    579579
    580580            if (_credentials.isPublicKeyAuthentication())
     
    592592                View.SelectedPrivateKey = LocaleFactory.localizedString("None");
    593593            }
    594             View.ClientCertificateFieldEnabled = _host.getProtocol().isCertificateConfigurable();
     594            View.ClientCertificateFieldEnabled = _options.certificate();
    595595            List<string> keys = new List<string> {LocaleFactory.localizedString("None")};
    596             if(_host.getProtocol().isCertificateConfigurable())
     596            if(_options.certificate())
    597597            {
    598598                foreach (String certificate in Utils.ConvertFromJavaList<String>(new KeychainX509KeyManager(_host).list()))
  • trunk/windows/src/main/csharp/ch/cyberduck/ui/controller/ConnectionController.cs

    r41969 r43439  
    7878        {
    7979            View.Username = PreferencesFactory.get().getProperty("connection.login.name");
    80             View.SavePasswordChecked = PreferencesFactory.get().getBoolean("connection.login.keychain");
     80            View.SavePasswordChecked = _options.save();
    8181            View.ChangedSavePasswordCheckboxEvent += View_ChangedSavePasswordCheckboxEvent;
    8282
     
    105105        public void ReadPasswordFromKeychain()
    106106        {
    107             if (PreferencesFactory.get().getBoolean("connection.login.keychain"))
     107            if (_options.keychain())
    108108            {
    109109                if (string.IsNullOrEmpty(View.Hostname))
  • trunk/windows/src/main/csharp/ch/cyberduck/ui/controller/PromptLoginController.cs

    r42522 r43439  
    8585            _bookmark = bookmark;
    8686            _options = options;
     87            _credentials.setSaved(_options.save());
    8788
    8889            View.Title = LocaleFactory.localizedString(title, "Credentials");
  • trunk/www/update/changelog.html

    r43398 r43439  
    5555            list-style-type: disc;
    5656        }
    57 
    5857    </style>
    5958</head>
     
    7877    <li><span class="label label-warning">Bugfix</span> Slow user interface performance (Mac) (<a
    7978        href="https://trac.cyberduck.io/ticket/9970">#9970</a>)
     79    </li>
     80    <li><span class="label label-warning">Bugfix</span> Prompt for credentials when using public key authentication with
     81        agent (SFTP) (<a
     82            href="https://trac.cyberduck.io/ticket/10148">#10148</a>)
    8083    </li>
    8184</ul>
Note: See TracChangeset for help on using the changeset viewer.
swiss made software