1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.internal.transport.sshd;
11
12 import java.net.InetAddress;
13 import java.net.InetSocketAddress;
14 import java.net.UnknownHostException;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.LinkedHashMap;
18 import java.util.Map;
19 import java.util.concurrent.atomic.AtomicBoolean;
20
21 import org.eclipse.jgit.annotations.NonNull;
22 import org.ietf.jgss.GSSContext;
23 import org.ietf.jgss.GSSException;
24 import org.ietf.jgss.GSSManager;
25 import org.ietf.jgss.GSSName;
26 import org.ietf.jgss.Oid;
27
28
29
30
31 public class GssApiMechanisms {
32
33 private GssApiMechanisms() {
34
35 }
36
37
38 public static final String GSSAPI_HOST_PREFIX = "host@";
39
40
41 public static final Oid KERBEROS_5 = createOid("1.2.840.113554.1.2.2");
42
43
44 public static final Oid SPNEGO = createOid("1.3.6.1.5.5.2");
45
46
47 private static final Object LOCK = new Object();
48
49
50
51
52
53 private static Map<Oid, Boolean> supportedMechanisms;
54
55
56
57
58
59
60 @NonNull
61 public static Collection<Oid> getSupportedMechanisms() {
62 synchronized (LOCK) {
63 if (supportedMechanisms == null) {
64 GSSManager manager = GSSManager.getInstance();
65 Oid[] mechs = manager.getMechs();
66 Map<Oid, Boolean> mechanisms = new LinkedHashMap<>();
67 if (mechs != null) {
68 for (Oid oid : mechs) {
69 mechanisms.put(oid, Boolean.FALSE);
70 }
71 }
72 supportedMechanisms = mechanisms;
73 }
74 return Collections.unmodifiableSet(supportedMechanisms.keySet());
75 }
76 }
77
78
79
80
81
82
83
84 public static void worked(@NonNull Oid mechanism) {
85 synchronized (LOCK) {
86 supportedMechanisms.put(mechanism, Boolean.TRUE);
87 }
88 }
89
90
91
92
93
94
95
96 public static void failed(@NonNull Oid mechanism) {
97 synchronized (LOCK) {
98 Boolean worked = supportedMechanisms.get(mechanism);
99 if (worked != null && !worked.booleanValue()) {
100
101 supportedMechanisms.remove(mechanism);
102 }
103 }
104 }
105
106
107
108
109
110
111
112
113 public static InetAddress resolve(@NonNull InetSocketAddress remote) {
114 InetAddress address = remote.getAddress();
115 if (address == null) {
116 try {
117 address = InetAddress.getByName(remote.getHostString());
118 } catch (UnknownHostException e) {
119 return null;
120 }
121 }
122 return address;
123 }
124
125
126
127
128
129
130
131
132
133 @NonNull
134 public static String getCanonicalName(@NonNull InetSocketAddress remote) {
135 InetAddress address = resolve(remote);
136 if (address == null) {
137 return remote.getHostString();
138 }
139 return address.getCanonicalHostName();
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153 public static GSSContext createContext(@NonNull Oid mechanism,
154 @NonNull String fqdn) {
155 GSSContext context = null;
156 try {
157 GSSManager manager = GSSManager.getInstance();
158 context = manager.createContext(
159 manager.createName(
160 GssApiMechanisms.GSSAPI_HOST_PREFIX + fqdn,
161 GSSName.NT_HOSTBASED_SERVICE),
162 mechanism, null, GSSContext.DEFAULT_LIFETIME);
163 } catch (GSSException e) {
164 closeContextSilently(context);
165 failed(mechanism);
166 return null;
167 }
168 worked(mechanism);
169 return context;
170 }
171
172
173
174
175
176
177
178
179 public static void closeContextSilently(GSSContext context) {
180 if (context != null) {
181 try {
182 context.dispose();
183 } catch (GSSException e) {
184
185 }
186 }
187 }
188
189 private static Oid createOid(String rep) {
190 try {
191 return new Oid(rep);
192 } catch (GSSException e) {
193
194 return null;
195 }
196 }
197
198 }