1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.internal.transport.sshd;
11
12 import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.flag;
13
14 import java.net.InetSocketAddress;
15 import java.net.SocketAddress;
16 import java.security.PublicKey;
17 import java.util.Collections;
18 import java.util.List;
19 import java.util.Locale;
20
21 import org.apache.sshd.client.config.hosts.HostConfigEntry;
22 import org.apache.sshd.client.config.hosts.KnownHostHashValue;
23 import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
24 import org.apache.sshd.client.session.ClientSession;
25 import org.apache.sshd.common.util.net.SshdSocketAddress;
26 import org.eclipse.jgit.annotations.NonNull;
27 import org.eclipse.jgit.transport.CredentialsProvider;
28 import org.eclipse.jgit.transport.SshConstants;
29 import org.eclipse.jgit.transport.sshd.ServerKeyDatabase;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33
34
35
36
37 public class JGitServerKeyVerifier
38 implements ServerKeyVerifier, ServerKeyLookup {
39
40 private static final Logger LOG = LoggerFactory
41 .getLogger(JGitServerKeyVerifier.class);
42
43 private final @NonNull ServerKeyDatabase database;
44
45
46
47
48
49
50
51
52 public JGitServerKeyVerifier(@NonNull ServerKeyDatabase database) {
53 this.database = database;
54 }
55
56 @Override
57 public List<PublicKey> lookup(ClientSession session,
58 SocketAddress remoteAddress) {
59 if (!(session instanceof JGitClientSession)) {
60 LOG.warn("Internal error: wrong session kind: "
61 + session.getClass().getName());
62 return Collections.emptyList();
63 }
64 if (!(remoteAddress instanceof InetSocketAddress)) {
65 return Collections.emptyList();
66 }
67 SessionConfig config = new SessionConfig((JGitClientSession) session);
68 SshdSocketAddress connectAddress = SshdSocketAddress
69 .toSshdSocketAddress(session.getConnectAddress());
70 String connect = KnownHostHashValue.createHostPattern(
71 connectAddress.getHostName(), connectAddress.getPort());
72 return database.lookup(connect, (InetSocketAddress) remoteAddress,
73 config);
74 }
75
76 @Override
77 public boolean verifyServerKey(ClientSession session,
78 SocketAddress remoteAddress, PublicKey serverKey) {
79 if (!(session instanceof JGitClientSession)) {
80 LOG.warn("Internal error: wrong session kind: "
81 + session.getClass().getName());
82 return false;
83 }
84 if (!(remoteAddress instanceof InetSocketAddress)) {
85 return false;
86 }
87 SessionConfig config = new SessionConfig((JGitClientSession) session);
88 SshdSocketAddress connectAddress = SshdSocketAddress
89 .toSshdSocketAddress(session.getConnectAddress());
90 String connect = KnownHostHashValue.createHostPattern(
91 connectAddress.getHostName(), connectAddress.getPort());
92 CredentialsProvider provider = ((JGitClientSession) session)
93 .getCredentialsProvider();
94 return database.accept(connect, (InetSocketAddress) remoteAddress,
95 serverKey, config, provider);
96 }
97
98 private static class SessionConfig
99 implements ServerKeyDatabase.Configuration {
100
101 private final JGitClientSession session;
102
103 public SessionConfig(JGitClientSession session) {
104 this.session = session;
105 }
106
107 private List<String> get(String key) {
108 HostConfigEntry entry = session.getHostConfigEntry();
109 if (entry instanceof JGitHostConfigEntry) {
110
111 return ((JGitHostConfigEntry) entry).getMultiValuedOptions()
112 .get(key);
113 }
114 return Collections.emptyList();
115 }
116
117 @Override
118 public List<String> getUserKnownHostsFiles() {
119 return get(SshConstants.USER_KNOWN_HOSTS_FILE);
120 }
121
122 @Override
123 public List<String> getGlobalKnownHostsFiles() {
124 return get(SshConstants.GLOBAL_KNOWN_HOSTS_FILE);
125 }
126
127 @Override
128 public StrictHostKeyChecking getStrictHostKeyChecking() {
129 HostConfigEntry entry = session.getHostConfigEntry();
130 String value = entry
131 .getProperty(SshConstants.STRICT_HOST_KEY_CHECKING, "ask");
132 switch (value.toLowerCase(Locale.ROOT)) {
133 case SshConstants.YES:
134 case SshConstants.ON:
135 return StrictHostKeyChecking.REQUIRE_MATCH;
136 case SshConstants.NO:
137 case SshConstants.OFF:
138 return StrictHostKeyChecking.ACCEPT_ANY;
139 case "accept-new":
140 return StrictHostKeyChecking.ACCEPT_NEW;
141 default:
142 return StrictHostKeyChecking.ASK;
143 }
144 }
145
146 @Override
147 public boolean getHashKnownHosts() {
148 HostConfigEntry entry = session.getHostConfigEntry();
149 return flag(entry.getProperty(SshConstants.HASH_KNOWN_HOSTS));
150 }
151
152 @Override
153 public String getUsername() {
154 return session.getUsername();
155 }
156 }
157 }