James Moger
2014-03-14 8982e6e0738c6991b9a4b864423bd4f75383c7f4
Add add-key and rm-key commands that apply only to the current user
3 files added
3 files modified
233 ■■■■ changed files
src/main/java/com/gitblit/transport/ssh/SshDaemon.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/commands/AddKeyCommand.java 54 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/commands/BaseKeyCommand.java 58 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/commands/RemoveKeyCommand.java 62 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/commands/SetAccountCommand.java 35 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/SshDaemon.java
@@ -38,9 +38,11 @@
import com.gitblit.git.GitblitUploadPackFactory;
import com.gitblit.git.RepositoryResolver;
import com.gitblit.manager.IGitblit;
import com.gitblit.transport.ssh.commands.AddKeyCommand;
import com.gitblit.transport.ssh.commands.CreateRepository;
import com.gitblit.transport.ssh.commands.DispatchCommand;
import com.gitblit.transport.ssh.commands.Receive;
import com.gitblit.transport.ssh.commands.RemoveKeyCommand;
import com.gitblit.transport.ssh.commands.ReviewCommand;
import com.gitblit.transport.ssh.commands.SetAccountCommand;
import com.gitblit.transport.ssh.commands.Upload;
@@ -67,7 +69,7 @@
    public static enum SshSessionBackend {
        MINA, NIO2
    }
    /**
     * 22: IANA assigned port number for ssh. Note that this is a distinct
     * concept from gitblit's default conf for ssh port -- this "default" is
@@ -92,7 +94,7 @@
    public SshDaemon(IGitblit gitblit, IdGenerator idGenerator) {
        this.gitblit = gitblit;
        this.injector = ObjectGraph.create(new SshModule());
        IStoredSettings settings = gitblit.getSettings();
        int port = settings.getInteger(Keys.git.sshPort, 0);
        String bindInterface = settings.getString(Keys.git.sshBindInterface,
@@ -107,7 +109,7 @@
            backend == SshSessionBackend.MINA
                ? MinaServiceFactoryFactory.class.getName()
                : Nio2ServiceFactoryFactory.class.getName());
        InetSocketAddress addr;
        if (StringUtils.isEmpty(bindInterface)) {
            addr = new InetSocketAddress(port);
@@ -131,6 +133,8 @@
        DispatchCommand gitblitCmd = new DispatchCommand();
        gitblitCmd.registerCommand(CreateRepository.class);
        gitblitCmd.registerCommand(VersionCommand.class);
        gitblitCmd.registerCommand(AddKeyCommand.class);
        gitblitCmd.registerCommand(RemoveKeyCommand.class);
        gitblitCmd.registerCommand(SetAccountCommand.class);
        gitblitCmd.registerCommand(ReviewCommand.class);
@@ -210,14 +214,14 @@
            }
        }
    }
    protected IKeyManager getKeyManager() {
        IKeyManager keyManager = null;
        IStoredSettings settings = gitblit.getSettings();
        String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName());
        if (StringUtils.isEmpty(clazz)) {
            clazz = FileKeyManager.class.getName();
        }
        }
        try {
            Class<? extends IKeyManager> managerClass = (Class<? extends IKeyManager>) Class.forName(clazz);
            keyManager = injector.get(managerClass).start();
@@ -232,7 +236,7 @@
        }
        return keyManager;
    }
    /**
     * A nested Dagger graph is used for constructor dependency injection of
     * complex classes.
@@ -252,7 +256,7 @@
        @Provides @Singleton NullKeyManager provideNullKeyManager() {
            return new NullKeyManager();
        }
        @Provides @Singleton FileKeyManager provideFileKeyManager() {
            return new FileKeyManager(SshDaemon.this.gitblit);
        }
src/main/java/com/gitblit/transport/ssh/commands/AddKeyCommand.java
New file
@@ -0,0 +1,54 @@
/*
 * Copyright 2014 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.gitblit.transport.ssh.commands;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.kohsuke.args4j.Argument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.transport.ssh.CommandMetaData;
import com.gitblit.transport.ssh.IKeyManager;
/**
 * Add a key to the current user's authorized keys list.
 *
 * @author James Moger
 *
 */
@CommandMetaData(name = "add-key", description = "Add an SSH public key to your account")
public class AddKeyCommand extends BaseKeyCommand {
    protected final Logger log = LoggerFactory.getLogger(getClass());
    @Argument(metaVar = "<stdin>|KEY", usage = "the key to add")
    private List<String> addKeys = new ArrayList<String>();
    @Override
    public void run() throws IOException, UnloggedFailure {
        String username = ctx.getClient().getUsername();
        List<String> keys = readKeys(addKeys);
        IKeyManager keyManager = authenticator.getKeyManager();
        for (String key : keys) {
            keyManager.addKey(username, key);
            log.info("added SSH public key for {}", username);
        }
        authenticator.getKeyCache().invalidate(username);
    }
}
src/main/java/com/gitblit/transport/ssh/commands/BaseKeyCommand.java
New file
@@ -0,0 +1,58 @@
/*
 * Copyright 2014 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.gitblit.transport.ssh.commands;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import com.gitblit.transport.ssh.SshKeyAuthenticator;
import com.google.common.base.Charsets;
/**
 *
 * Base class for commands that read SSH keys from stdin or a parameter list.
 *
 */
public abstract class BaseKeyCommand extends SshCommand {
    protected List<String> readKeys(List<String> sshKeys)
            throws UnsupportedEncodingException, IOException {
        int idx = -1;
        if (sshKeys.isEmpty() || ((idx = sshKeys.indexOf("-")) >= 0)) {
            String sshKey = "";
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    in, Charsets.UTF_8));
            String line;
            while ((line = br.readLine()) != null) {
                sshKey += line + "\n";
            }
            if (idx == -1) {
                sshKeys.add(sshKey.trim());
            } else {
                sshKeys.set(idx, sshKey.trim());
            }
        }
        return sshKeys;
    }
    protected SshKeyAuthenticator authenticator;
    public void setAuthenticator(SshKeyAuthenticator authenticator) {
        this.authenticator = authenticator;
    }
}
src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
@@ -198,9 +198,9 @@
        d.setUploadPackFactory(gitblitUploadPackFactory);
        d.setReceivePackFactory(gitblitReceivePackFactory);
        d.setAuthenticator(authenticator);
      } else if (cmd instanceof SetAccountCommand) {
          SetAccountCommand setAccountCommand = (SetAccountCommand)cmd;
          setAccountCommand.setAuthenticator(authenticator);
      } else if (cmd instanceof BaseKeyCommand) {
          BaseKeyCommand k = (BaseKeyCommand)cmd;
          k.setAuthenticator(authenticator);
      }
  }
src/main/java/com/gitblit/transport/ssh/commands/RemoveKeyCommand.java
New file
@@ -0,0 +1,62 @@
/*
 * Copyright 2014 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.gitblit.transport.ssh.commands;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.kohsuke.args4j.Argument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.transport.ssh.CommandMetaData;
import com.gitblit.transport.ssh.IKeyManager;
/**
 * Remove an SSH public key from the current user's authorized key list.
 *
 * @author James Moger
 *
 */
@CommandMetaData(name = "rm-key", description = "Remove an SSH public key from your account")
public class RemoveKeyCommand extends BaseKeyCommand {
    protected final Logger log = LoggerFactory.getLogger(getClass());
    private static final String ALL = "ALL";
    @Argument(metaVar = "<stdin>|<KEY>|ALL", usage = "the key to remove")
    private List<String> removeKeys = new ArrayList<String>();
    @Override
    public void run() throws IOException, UnloggedFailure {
        String username = ctx.getClient().getUsername();
        List<String> keys = readKeys(removeKeys);
        IKeyManager keyManager = authenticator.getKeyManager();
        if (keys.contains(ALL)) {
            keyManager.removeAllKeys(username);
            log.info("removed all SSH public keys from {}", username);
        } else {
            for (String key : keys) {
                keyManager.removeKey(username, key);
                log.info("removed SSH public key from {}", username);
            }
        }
        authenticator.getKeyCache().invalidate(username);
    }
}
src/main/java/com/gitblit/transport/ssh/commands/SetAccountCommand.java
@@ -14,10 +14,7 @@
package com.gitblit.transport.ssh.commands;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -27,12 +24,10 @@
import com.gitblit.transport.ssh.CommandMetaData;
import com.gitblit.transport.ssh.IKeyManager;
import com.gitblit.transport.ssh.SshKeyAuthenticator;
import com.google.common.base.Charsets;
/** Set a user's account settings. **/
@CommandMetaData(name = "set-account", description = "Change an account's settings")
public class SetAccountCommand extends SshCommand {
public class SetAccountCommand extends BaseKeyCommand {
    private static final String ALL = "ALL";
@@ -61,12 +56,12 @@
    }
    private void setAccount() throws IOException, UnloggedFailure {
        addSshKeys = readSshKey(addSshKeys);
        addSshKeys = readKeys(addSshKeys);
        if (!addSshKeys.isEmpty()) {
            addSshKeys(addSshKeys);
        }
        deleteSshKeys = readSshKey(deleteSshKeys);
        deleteSshKeys = readKeys(deleteSshKeys);
        if (!deleteSshKeys.isEmpty()) {
            deleteSshKeys(deleteSshKeys);
        }
@@ -90,29 +85,5 @@
                keyManager.removeKey(user, sshKey);
            }
        }
    }
    private List<String> readSshKey(List<String> sshKeys)
            throws UnsupportedEncodingException, IOException {
        if (!sshKeys.isEmpty()) {
            String sshKey;
            int idx = sshKeys.indexOf("-");
            if (idx >= 0) {
                sshKey = "";
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        in, Charsets.UTF_8));
                String line;
                while ((line = br.readLine()) != null) {
                    sshKey += line + "\n";
                }
                sshKeys.set(idx, sshKey);
            }
        }
        return sshKeys;
    }
    private SshKeyAuthenticator authenticator;
    public void setAuthenticator(SshKeyAuthenticator authenticator) {
        this.authenticator = authenticator;
    }
}