1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.internal.transport.sshd;
11
12 import java.io.IOException;
13 import java.net.URISyntaxException;
14 import java.security.GeneralSecurityException;
15 import java.util.Arrays;
16 import java.util.Map;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.atomic.AtomicInteger;
19
20 import org.apache.sshd.common.NamedResource;
21 import org.apache.sshd.common.session.SessionContext;
22 import org.eclipse.jgit.annotations.NonNull;
23 import org.eclipse.jgit.transport.CredentialsProvider;
24 import org.eclipse.jgit.transport.URIish;
25 import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;
26
27
28
29
30
31 public class PasswordProviderWrapper implements RepeatingFilePasswordProvider {
32
33 private final KeyPasswordProvider delegate;
34
35 private Map<String, AtomicInteger> counts = new ConcurrentHashMap<>();
36
37
38
39
40 public PasswordProviderWrapper(@NonNull KeyPasswordProvider delegate) {
41 this.delegate = delegate;
42 }
43
44 @Override
45 public void setAttempts(int numberOfPasswordPrompts) {
46 delegate.setAttempts(numberOfPasswordPrompts);
47 }
48
49 @Override
50 public int getAttempts() {
51 return delegate.getAttempts();
52 }
53
54 @Override
55 public String getPassword(SessionContext session, NamedResource resource,
56 int attemptIndex) throws IOException {
57 String key = resource.getName();
58 int attempt = counts
59 .computeIfAbsent(key, k -> new AtomicInteger()).get();
60 char[] passphrase = delegate.getPassphrase(toUri(key), attempt);
61 if (passphrase == null) {
62 return null;
63 }
64 try {
65 return new String(passphrase);
66 } finally {
67 Arrays.fill(passphrase, '\000');
68 }
69 }
70
71 @Override
72 public ResourceDecodeResult handleDecodeAttemptResult(
73 SessionContext session, NamedResource resource, int retryIndex,
74 String password, Exception err)
75 throws IOException, GeneralSecurityException {
76 String key = resource.getName();
77 AtomicInteger count = counts.get(key);
78 int numberOfAttempts = count == null ? 0 : count.incrementAndGet();
79 ResourceDecodeResult result = null;
80 try {
81 if (delegate.keyLoaded(toUri(key), numberOfAttempts, err)) {
82 result = ResourceDecodeResult.RETRY;
83 } else {
84 result = ResourceDecodeResult.TERMINATE;
85 }
86 } finally {
87 if (result != ResourceDecodeResult.RETRY) {
88 counts.remove(key);
89 }
90 }
91 return result;
92 }
93
94
95
96
97
98
99
100
101
102 private URIish toUri(String resourceKey) {
103 try {
104 return new URIish(resourceKey);
105 } catch (URISyntaxException e) {
106 return new URIish().setPath(resourceKey);
107 }
108 }
109
110 }