Skip to content

Commit

Permalink
Made public/private keys actually work
Browse files Browse the repository at this point in the history
  • Loading branch information
Ignas committed Dec 16, 2023
1 parent 9f111c6 commit 0f0ffe1
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import lt.pow.nukagit.db.entities.UserPublicKey;

import javax.inject.Inject;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
Expand Down Expand Up @@ -48,7 +46,7 @@ public void addUserWithKey(String username, String publicKey) throws InvalidKeyS
publicKeysDao.addPublicKey(userId, publicKeyData.fingerprint(), publicKeyData);
}

public Collection<UserPublicKey> getPublicKeyCollection() {
return publicKeyCache.get();
public Supplier<List<UserPublicKey>> getPublicKeySupplier() {
return publicKeyCache;
}
}
14 changes: 7 additions & 7 deletions src/main/java/lt/pow/nukagit/ssh/SshModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
import lt.pow.nukagit.db.repositories.PublicKeyRepository;
import lt.pow.nukagit.dfs.DfsRepositoryResolver;
import lt.pow.nukagit.dfs.GitDfsPackCommandFactory;
import lt.pow.nukagit.lib.lifecycle.Managed;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.github.gestalt.config.Gestalt;
import org.github.gestalt.config.exceptions.GestaltException;
Expand All @@ -35,18 +35,18 @@ static SshServerConfig configuration(Gestalt configurationProvider) {
@Provides
@Singleton
static SshServer createServer(
DfsRepositoryResolver dfsRepositoryResolver, SshServerConfig sshServerConfig) {
DfsRepositoryResolver dfsRepositoryResolver,
SshServerConfig sshServerConfig,
PublicKeyRepository publicKeyRepository) {
var sshServer = SshServer.setUpDefaultServer();
sshServer.setHost(sshServerConfig.hostname());
sshServer.setPort(sshServerConfig.port());
var keyPairGenerator = new SimpleGeneratorHostKeyProvider(Path.of(sshServerConfig.hostKey()));
keyPairGenerator.setAlgorithm(sshServerConfig.hostKeyAlgorithm());
sshServer.setKeyPairProvider(keyPairGenerator);
// sshServer.setPublickeyAuthenticator(new CachingPublicKeyAuthenticator(new KeySetPublickeyAuthenticator(
// "PublicKeyAuthenticator",
// ImmutableList.of()
// )));
sshServer.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
sshServer.setPublickeyAuthenticator(new UsernameResolvingPublickeyAuthenticator(
publicKeyRepository.getPublicKeySupplier()
));
sshServer.setCommandFactory(
new GitDfsPackCommandFactory().withDfsRepositoryResolver(dfsRepositoryResolver));
return sshServer;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package lt.pow.nukagit.ssh;

import lt.pow.nukagit.db.entities.UserPublicKey;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.server.auth.AsyncAuthException;
import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.PublicKey;
import java.util.List;
import java.util.function.Supplier;

public class UsernameResolvingPublickeyAuthenticator implements PublickeyAuthenticator {

Logger LOGGER = LoggerFactory.getLogger(UsernameResolvingPublickeyAuthenticator.class);
private final Supplier<List<UserPublicKey>> keySetSupplier;

public UsernameResolvingPublickeyAuthenticator(Supplier<List<UserPublicKey>> keySetSupplier) {
this.keySetSupplier = keySetSupplier;
}

@Override
public boolean authenticate(String username, PublicKey key, ServerSession session) throws AsyncAuthException {
if (!username.equals("git")) {
LOGGER.warn("User {} tried to authenticate with public key, but all users should" +
" use git as their username", username);
return false;
}
var allKeys = keySetSupplier.get();
LOGGER.info("Trying to authenticate user {} with public key against {} keys", username, allKeys.size());
for (var userPublicKey : allKeys) {
if (KeyUtils.compareKeys(userPublicKey.publicKeyData().key(), key)) {
session.setUsername(userPublicKey.username());
LOGGER.info("User {} authenticated with public key", userPublicKey.username());
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ class PublicKeyRepositoryDaoTest extends DatabaseTestBase {
when:
repository.addUserWithKey(username, publicKey)
then:
repository.publicKeyCollection.size() == 1
def userKey = repository.publicKeyCollection[0]
def keyList = repository.publicKeySupplier.get()
keyList.size() == 1
def userKey = keyList[0]
userKey.username() == username
userKey.publicKeyData() == testKeyData
}
Expand Down

0 comments on commit 0f0ffe1

Please sign in to comment.