summaryrefslogtreecommitdiffstats
path: root/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java')
-rw-r--r--gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java80
1 files changed, 80 insertions, 0 deletions
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
new file mode 100644
index 0000000000..45d4ab2009
--- /dev/null
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
@@ -0,0 +1,80 @@
+// Copyright (C) 2008 The Android Open Source Project
+//
+// 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.google.gerrit.sshd;
+
+import com.google.gerrit.reviewdb.AccountSshKey;
+import com.google.gerrit.reviewdb.ReviewDb;
+import com.google.gwtorm.client.SchemaFactory;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import org.apache.sshd.server.PublickeyAuthenticator;
+import org.apache.sshd.server.session.ServerSession;
+
+import java.security.PublicKey;
+
+/**
+ * Authenticates by public key through {@link AccountSshKey} entities.
+ * <p>
+ * The username supplied by the client must be the user's preferred email
+ * address, as listed in their Account entity. Only keys listed under that
+ * account as authorized keys are permitted to access the account.
+ */
+@Singleton
+class DatabasePubKeyAuth implements PublickeyAuthenticator {
+ private final SshKeyCacheImpl sshKeyCache;
+ private final SchemaFactory<ReviewDb> schema;
+
+ @Inject
+ DatabasePubKeyAuth(final SshKeyCacheImpl skc, final SchemaFactory<ReviewDb> sf) {
+ sshKeyCache = skc;
+ schema = sf;
+ }
+
+ public boolean hasKey(final String username, final PublicKey suppliedKey,
+ final ServerSession session) {
+ final Iterable<SshKeyCacheEntry> keyList = sshKeyCache.get(username);
+ final SshKeyCacheEntry key = find(keyList, suppliedKey);
+ if (key == null) {
+ return false;
+ }
+
+ // Double check that all of the keys are for the same user account.
+ // This should have been true when the cache factory method loaded
+ // the list into memory, but we want to be extra paranoid about our
+ // security check to ensure there aren't two users sharing the same
+ // user name on the server.
+ //
+ for (final SshKeyCacheEntry otherKey : keyList) {
+ if (!key.getAccount().equals(otherKey.getAccount())) {
+ return false;
+ }
+ }
+
+ key.updateLastUsed(schema);
+ session.setAttribute(SshUtil.CURRENT_ACCOUNT, key.getAccount());
+ return true;
+ }
+
+ private SshKeyCacheEntry find(final Iterable<SshKeyCacheEntry> keyList,
+ final PublicKey suppliedKey) {
+ for (final SshKeyCacheEntry k : keyList) {
+ if (k.match(suppliedKey)) {
+ return k;
+ }
+ }
+ return null;
+ }
+}