Skip to content

Commit

Permalink
hacking in a way to define different keys for different 'users'
Browse files Browse the repository at this point in the history
mostly because my integration tests want to be able to go against an
account specifically requiring RSA, and another specifically requiring DSA
  • Loading branch information
rtyley committed Apr 19, 2011
1 parent 20965df commit 22c765c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 6 deletions.
6 changes: 6 additions & 0 deletions mini-git-server-sshd/pom.xml
Expand Up @@ -31,6 +31,12 @@ limitations under the License.
</description>

<dependencies>
<dependency>
<groupId>net.schmizz</groupId>
<artifactId>sshj</artifactId>
<version>0.3.1</version>
</dependency>

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
Expand Down
Expand Up @@ -14,6 +14,7 @@

package com.google.gerrit.sshd;

import net.schmizz.sshj.common.KeyType;
import org.apache.commons.codec.binary.Base64;
import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.SshException;
Expand All @@ -30,6 +31,8 @@
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;

import static net.schmizz.sshj.common.Base64.decode;

/** Utilities to support SSH operations. */
public class SshUtil {
/**
Expand Down Expand Up @@ -57,6 +60,8 @@ public static PublicKey parse(final String encodedKeyString)
}
}



/**
* Convert an RFC 4716 style key to an OpenSSH style key.
*
Expand Down Expand Up @@ -109,4 +114,11 @@ public static String toOpenSshPublicKey(final String keyStr) {
return keyStr;
}
}


public static PublicKey parseOpenSSHKey(String line) throws IOException {
String[] parts = line.split(" ");
assert parts.length >= 2;
return new net.schmizz.sshj.common.Buffer.PlainBuffer(decode(parts[1])).readPublicKey();
}
}
Expand Up @@ -15,29 +15,71 @@
package com.google.gerrit.sshd;

import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.commons.io.FileUtils;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
import org.bouncycastle.openssl.PEMReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Collection;

import static org.apache.commons.io.FileUtils.listFiles;

/**
* Authenticates by public key really permissively
*/
@Singleton
class ToyPubKeyAuth implements PublickeyAuthenticator {
private final IdentifiedUser.GenericFactory userFactory;
private static final Logger log =
LoggerFactory.getLogger(ToyPubKeyAuth.class);

private final IdentifiedUser.GenericFactory userFactory;
private final SitePaths sitePaths;

@Inject
ToyPubKeyAuth(IdentifiedUser.GenericFactory uf) {
@Inject
ToyPubKeyAuth(IdentifiedUser.GenericFactory uf, final SitePaths sitePaths) {
userFactory = uf;
}
this.sitePaths = sitePaths;
}
@Override
public boolean authenticate(String username, PublicKey publicKey, ServerSession serverSession) {
final SshSession sd = serverSession.getAttribute(SshSession.KEY);
sd.authenticationSuccess(username, userFactory.create(username));
return true; //To change body of implemented methods use File | Settings | File Templates.
File usersDir = new File(sitePaths.etc_dir, "users"); //sitePaths.
File userDir = new File(usersDir,username);
if (!userDir.exists() || !userDir.isDirectory()) {
String error = "User ssh key folder not found " + userDir;
log.warn(error);
sd.authenticationError(username, error);
return false;
}
Collection<File> files = listFiles(userDir, new String[]{"pub"}, false);
for (File publicKeyFile : files) {
log.info("Trying " + publicKeyFile);
try {
PublicKey authorisedKey=SshUtil.parseOpenSSHKey(FileUtils.readFileToString(publicKeyFile));

if (authorisedKey.equals(publicKey)) {
sd.authenticationSuccess(username, userFactory.create(username));
return true; //To change body of implemented methods use File | Settings | File Templates.
}
} catch (Exception e) {
log.error("Problem with " + publicKeyFile, e);
}
}
log.warn("No good keys found from "+files);
sd.authenticationError(username, "No matching key found");
return false;
}
}

0 comments on commit 22c765c

Please sign in to comment.