1 /*
2 * Copyright (C) 2010, Google Inc. and others
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Distribution License v. 1.0 which is available at
6 * https://www.eclipse.org/org/documents/edl-v10.php.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 */
10
11 package org.eclipse.jgit.transport;
12
13 import java.util.Arrays;
14
15 import org.eclipse.jgit.internal.JGitText;
16
17 /**
18 * A credential requested from a
19 * {@link org.eclipse.jgit.transport.CredentialsProvider}.
20 *
21 * Most users should work with the specialized subclasses:
22 * <ul>
23 * <li>{@link org.eclipse.jgit.transport.CredentialItem.Username} for
24 * usernames</li>
25 * <li>{@link org.eclipse.jgit.transport.CredentialItem.Password} for
26 * passwords</li>
27 * <li>{@link org.eclipse.jgit.transport.CredentialItem.StringType} for other
28 * general string information</li>
29 * <li>{@link org.eclipse.jgit.transport.CredentialItem.CharArrayType} for other
30 * general secret information</li>
31 * </ul>
32 *
33 * This class is not thread-safe. Applications should construct their own
34 * instance for each use, as the value is held within the CredentialItem object.
35 */
36 public abstract class CredentialItem {
37 private final String promptText;
38
39 private final boolean valueSecure;
40
41 /**
42 * Initialize a prompt.
43 *
44 * @param promptText
45 * prompt to display to the user alongside of the input field.
46 * Should be sufficient text to indicate what to supply for this
47 * item.
48 * @param maskValue
49 * true if the value should be masked from displaying during
50 * input. This should be true for passwords and other secrets,
51 * false for names and other public data.
52 */
53 public CredentialItem(String promptText, boolean maskValue) {
54 this.promptText = promptText;
55 this.valueSecure = maskValue;
56 }
57
58 /**
59 * Get prompt to display to the user.
60 *
61 * @return prompt to display to the user.
62 */
63 public String getPromptText() {
64 return promptText;
65 }
66
67 /**
68 * Whether the value should be masked when entered.
69 *
70 * @return true if the value should be masked when entered.
71 */
72 public boolean isValueSecure() {
73 return valueSecure;
74 }
75
76 /**
77 * Clear the stored value, destroying it as much as possible.
78 */
79 public abstract void clear();
80
81 /**
82 * An item whose value is stored as a string.
83 *
84 * When working with secret data, consider {@link CharArrayType} instead, as
85 * the internal members of the array can be cleared, reducing the chances
86 * that the password is left in memory after authentication is completed.
87 */
88 public static class StringType extends CredentialItem {
89 private String value;
90
91 /**
92 * Initialize a prompt for a single string.
93 *
94 * @param promptText
95 * prompt to display to the user alongside of the input
96 * field. Should be sufficient text to indicate what to
97 * supply for this item.
98 * @param maskValue
99 * true if the value should be masked from displaying during
100 * input. This should be true for passwords and other
101 * secrets, false for names and other public data.
102 */
103 public StringType(String promptText, boolean maskValue) {
104 super(promptText, maskValue);
105 }
106
107 @Override
108 public void clear() {
109 value = null;
110 }
111
112 /** @return the current value */
113 public String getValue() {
114 return value;
115 }
116
117 /**
118 *
119 * @param newValue
120 */
121 public void setValue(String newValue) {
122 value = newValue;
123 }
124 }
125
126 /** An item whose value is stored as a char[] and is therefore clearable. */
127 public static class CharArrayType extends CredentialItem {
128 private char[] value;
129
130 /**
131 * Initialize a prompt for a secure value stored in a character array.
132 *
133 * @param promptText
134 * prompt to display to the user alongside of the input
135 * field. Should be sufficient text to indicate what to
136 * supply for this item.
137 * @param maskValue
138 * true if the value should be masked from displaying during
139 * input. This should be true for passwords and other
140 * secrets, false for names and other public data.
141 */
142 public CharArrayType(String promptText, boolean maskValue) {
143 super(promptText, maskValue);
144 }
145
146 /** Destroys the current value, clearing the internal array. */
147 @Override
148 public void clear() {
149 if (value != null) {
150 Arrays.fill(value, (char) 0);
151 value = null;
152 }
153 }
154
155 /**
156 * Get the current value.
157 *
158 * The returned array will be cleared out when {@link #clear()} is
159 * called. Callers that need the array elements to survive should delay
160 * invoking {@code clear()} until the value is no longer necessary.
161 *
162 * @return the current value array. The actual internal array is
163 * returned, reducing the number of copies present in memory.
164 */
165 public char[] getValue() {
166 return value;
167 }
168
169 /**
170 * Set the new value, clearing the old value array.
171 *
172 * @param newValue
173 * if not null, the array is copied.
174 */
175 public void setValue(char[] newValue) {
176 clear();
177
178 if (newValue != null) {
179 value = new char[newValue.length];
180 System.arraycopy(newValue, 0, value, 0, newValue.length);
181 }
182 }
183
184 /**
185 * Set the new value, clearing the old value array.
186 *
187 * @param newValue
188 * the new internal array. The array is <b>NOT</b> copied.
189 */
190 public void setValueNoCopy(char[] newValue) {
191 clear();
192 value = newValue;
193 }
194 }
195
196 /** An item whose value is a boolean choice, presented as Yes/No. */
197 public static class YesNoType extends CredentialItem {
198 private boolean value;
199
200 /**
201 * Initialize a prompt for a single boolean answer.
202 *
203 * @param promptText
204 * prompt to display to the user alongside of the input
205 * field. Should be sufficient text to indicate what to
206 * supply for this item.
207 */
208 public YesNoType(String promptText) {
209 super(promptText, false);
210 }
211
212 @Override
213 public void clear() {
214 value = false;
215 }
216
217 /** @return the current value */
218 public boolean getValue() {
219 return value;
220 }
221
222 /**
223 * Set the new value.
224 *
225 * @param newValue
226 */
227 public void setValue(boolean newValue) {
228 value = newValue;
229 }
230 }
231
232 /** An advice message presented to the user, with no response required. */
233 public static class InformationalMessage extends CredentialItem {
234 /**
235 * Initialize an informational message.
236 *
237 * @param messageText
238 * message to display to the user.
239 */
240 public InformationalMessage(String messageText) {
241 super(messageText, false);
242 }
243
244 @Override
245 public void clear() {
246 // Nothing to clear.
247 }
248 }
249
250 /** Prompt for a username, which is not masked on input. */
251 public static class Username extends StringType {
252 /** Initialize a new username item, with a default username prompt. */
253 public Username() {
254 super(JGitText.get().credentialUsername, false);
255 }
256 }
257
258 /** Prompt for a password, which is masked on input. */
259 public static class Password extends CharArrayType {
260 /** Initialize a new password item, with a default password prompt. */
261 public Password() {
262 super(JGitText.get().credentialPassword, true);
263 }
264
265 /**
266 * Initialize a new password item, with given prompt.
267 *
268 * @param msg
269 * prompt message
270 */
271 public Password(String msg) {
272 super(msg, true);
273 }
274 }
275 }