From 40040b656299bfafcaa92b12b916f93e8c5aed1d Mon Sep 17 00:00:00 2001 From: Florian Zschocke Date: Tue, 29 Nov 2016 22:08:50 +0100 Subject: [PATCH] The public key manager can disable writing keys, which hides commands Some public key mangers may be read-only, i.e. not allow to add or delete keys, or to change the key comment or assigned permissions. In such a case the respective commands should not be available on the SSH shell and the SSH Keys panel should also not offer the possibility. The `IPublicKeyManager` gets three new methods, modelled after the `AuthenticationManager`: `supportsWritingKeys`, `supportsCommentChanges` and `supportsPermissionChanges`. They return true if a key manager allows for keys to be written or updated. For example the existing `FileKeyManager` will return true for all three since it allows to store and update keys in a file. The new `LdapKeyManager` returns false since it only accesses LDAP and can not add or update any keys in the directory. A future key manager might get keys from an LDAP directory but still keep comments and permissions for it in a local copy. If writing of keys is not supported: * the welcome shell does not suggest adding a key, * the `SshKeysDispatcher` does not offer the "add", "remove", "comment" and "permission" commands, and * the SSH keys panel hides the "delete" button in the key list, and the "Add Key" form. The hiding of the "Add key" form is not perfect since the surrounding div is still shown, but I don't know how to hide it and it didn't look too bad, either. --- .../transport/ssh/IPublicKeyManager.java | 13 ++++++++++++ .../gitblit/transport/ssh/LdapKeyManager.java | 13 ++++++++++++ .../com/gitblit/transport/ssh/SshDaemon.java | 2 +- .../gitblit/transport/ssh/WelcomeShell.java | 21 ++++++++++++------- .../transport/ssh/keys/KeysDispatcher.java | 17 +++++++++++---- .../gitblit/wicket/panels/SshKeysPanel.java | 9 ++++++++ 6 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java b/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java index 1e74b2f0..ffe64f59 100644 --- a/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java +++ b/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.manager.IManager; +import com.gitblit.models.UserModel; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader.InvalidCacheLoadException; @@ -99,4 +100,16 @@ public abstract class IPublicKeyManager implements IManager { public abstract boolean removeKey(String username, SshKey key); public abstract boolean removeAllKeys(String username); + + public boolean supportsWritingKeys(UserModel user) { + return (user != null); + } + + public boolean supportsCommentChanges(UserModel user) { + return (user != null); + } + + public boolean supportsPermissionChanges(UserModel user) { + return (user != null); + } } diff --git a/src/main/java/com/gitblit/transport/ssh/LdapKeyManager.java b/src/main/java/com/gitblit/transport/ssh/LdapKeyManager.java index 9612a96b..6b8f1e45 100644 --- a/src/main/java/com/gitblit/transport/ssh/LdapKeyManager.java +++ b/src/main/java/com/gitblit/transport/ssh/LdapKeyManager.java @@ -34,6 +34,7 @@ import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.Constants.AccessPermission; import com.gitblit.ldap.LdapConnection; +import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; import com.google.common.base.Joiner; import com.google.inject.Inject; @@ -219,6 +220,18 @@ public class LdapKeyManager extends IPublicKeyManager { } + public boolean supportsWritingKeys(UserModel user) { + return false; + } + + public boolean supportsCommentChanges(UserModel user) { + return false; + } + + public boolean supportsPermissionChanges(UserModel user) { + return false; + } + private void setKeyPermissions(SshKey key, GbAuthorizedKeyEntry keyEntry) { List env = keyEntry.getLoginOptionValues("environment"); diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java index 5a94c9a3..4fb05f79 100644 --- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java +++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java @@ -134,7 +134,7 @@ public class SshDaemon { sshd.setFileSystemFactory(new DisabledFilesystemFactory()); sshd.setTcpipForwardingFilter(new NonForwardingFilter()); sshd.setCommandFactory(new SshCommandFactory(gitblit, workQueue)); - sshd.setShellFactory(new WelcomeShell(settings)); + sshd.setShellFactory(new WelcomeShell(gitblit)); // Set the server id. This can be queried with: // ssh-keyscan -t rsa,dsa -p 29418 localhost diff --git a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java index ec6f7291..7c407d36 100644 --- a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java +++ b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java @@ -34,6 +34,7 @@ import org.eclipse.jgit.util.SystemReader; import com.gitblit.IStoredSettings; import com.gitblit.Keys; +import com.gitblit.manager.IGitblit; import com.gitblit.models.UserModel; import com.gitblit.transport.ssh.commands.DispatchCommand; import com.gitblit.transport.ssh.commands.SshCommandFactory; @@ -45,19 +46,20 @@ import com.gitblit.utils.StringUtils; */ public class WelcomeShell implements Factory { - private final IStoredSettings settings; + private final IGitblit gitblit; - public WelcomeShell(IStoredSettings settings) { - this.settings = settings; + public WelcomeShell(IGitblit gitblit) { + this.gitblit = gitblit; } @Override public Command create() { - return new SendMessage(settings); + return new SendMessage(gitblit); } private static class SendMessage implements Command, SessionAware { + private final IPublicKeyManager km; private final IStoredSettings settings; private ServerSession session; @@ -66,8 +68,9 @@ public class WelcomeShell implements Factory { private OutputStream err; private ExitCallback exit; - SendMessage(IStoredSettings settings) { - this.settings = settings; + SendMessage(IGitblit gitblit) { + this.km = gitblit.getPublicKeyManager(); + this.settings = gitblit.getSettings(); } @Override @@ -116,6 +119,10 @@ public class WelcomeShell implements Factory { UserModel user = client.getUser(); String hostname = getHostname(); int port = settings.getInteger(Keys.git.sshPort, 0); + boolean writeKeysIsSupported = true; + if (km != null) { + writeKeysIsSupported = km.supportsWritingKeys(user); + } final String b1 = StringUtils.rightPad("", 72, '═'); final String b2 = StringUtils.rightPad("", 72, '─'); @@ -159,7 +166,7 @@ public class WelcomeShell implements Factory { msg.append(nl); msg.append(nl); - if (client.getKey() == null) { + if (writeKeysIsSupported && client.getKey() == null) { // user has authenticated with a password // display add public key instructions msg.append(" You may upload an SSH public key with the following syntax:"); diff --git a/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java b/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java index da58584c..817a98ff 100644 --- a/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java +++ b/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.Constants.AccessPermission; +import com.gitblit.models.UserModel; import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.transport.ssh.SshKey; import com.gitblit.transport.ssh.commands.CommandMetaData; @@ -47,12 +48,20 @@ public class KeysDispatcher extends DispatchCommand { @Override protected void setup() { - register(AddKey.class); - register(RemoveKey.class); + IPublicKeyManager km = getContext().getGitblit().getPublicKeyManager(); + UserModel user = getContext().getClient().getUser(); + if (km != null && km.supportsWritingKeys(user)) { + register(AddKey.class); + register(RemoveKey.class); + } register(ListKeys.class); register(WhichKey.class); - register(CommentKey.class); - register(PermissionKey.class); + if (km != null && km.supportsCommentChanges(user)) { + register(CommentKey.class); + } + if (km != null && km.supportsPermissionChanges(user)) { + register(PermissionKey.class); + } } @CommandMetaData(name = "add", description = "Add an SSH public key to your account") diff --git a/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java index 15ebd67b..4b878763 100644 --- a/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java @@ -48,11 +48,13 @@ public class SshKeysPanel extends BasePanel { private static final long serialVersionUID = 1L; private final UserModel user; + private final boolean canWriteKeys; public SshKeysPanel(String wicketId, UserModel user) { super(wicketId); this.user = user; + this.canWriteKeys = app().keys().supportsWritingKeys(user); } @Override @@ -90,6 +92,9 @@ public class SshKeysPanel extends BasePanel { } } }; + if (!canWriteKeys) { + delete.setVisibilityAllowed(false); + } item.add(delete); } }; @@ -164,6 +169,10 @@ public class SshKeysPanel extends BasePanel { } }); + if (! canWriteKeys) { + addKeyForm.setVisibilityAllowed(false); + } + add(addKeyForm); } } -- 2.39.5