1 /*
2 * Copyright (C) 2010, Google Inc.
3 * and other copyright owners as documented in the project's IP log.
4 *
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 package org.eclipse.jgit.transport;
45
46 import java.util.Arrays;
47
48 import org.eclipse.jgit.internal.JGitText;
49
50 /**
51 * A credential requested from a
52 * {@link org.eclipse.jgit.transport.CredentialsProvider}.
53 *
54 * Most users should work with the specialized subclasses:
55 * <ul>
56 * <li>{@link org.eclipse.jgit.transport.CredentialItem.Username} for
57 * usernames</li>
58 * <li>{@link org.eclipse.jgit.transport.CredentialItem.Password} for
59 * passwords</li>
60 * <li>{@link org.eclipse.jgit.transport.CredentialItem.StringType} for other
61 * general string information</li>
62 * <li>{@link org.eclipse.jgit.transport.CredentialItem.CharArrayType} for other
63 * general secret information</li>
64 * </ul>
65 *
66 * This class is not thread-safe. Applications should construct their own
67 * instance for each use, as the value is held within the CredentialItem object.
68 */
69 public abstract class CredentialItem {
70 private final String promptText;
71
72 private final boolean valueSecure;
73
74 /**
75 * Initialize a prompt.
76 *
77 * @param promptText
78 * prompt to display to the user alongside of the input field.
79 * Should be sufficient text to indicate what to supply for this
80 * item.
81 * @param maskValue
82 * true if the value should be masked from displaying during
83 * input. This should be true for passwords and other secrets,
84 * false for names and other public data.
85 */
86 public CredentialItem(String promptText, boolean maskValue) {
87 this.promptText = promptText;
88 this.valueSecure = maskValue;
89 }
90
91 /**
92 * Get prompt to display to the user.
93 *
94 * @return prompt to display to the user.
95 */
96 public String getPromptText() {
97 return promptText;
98 }
99
100 /**
101 * Whether the value should be masked when entered.
102 *
103 * @return true if the value should be masked when entered.
104 */
105 public boolean isValueSecure() {
106 return valueSecure;
107 }
108
109 /**
110 * Clear the stored value, destroying it as much as possible.
111 */
112 public abstract void clear();
113
114 /**
115 * An item whose value is stored as a string.
116 *
117 * When working with secret data, consider {@link CharArrayType} instead, as
118 * the internal members of the array can be cleared, reducing the chances
119 * that the password is left in memory after authentication is completed.
120 */
121 public static class StringType extends CredentialItem {
122 private String value;
123
124 /**
125 * Initialize a prompt for a single string.
126 *
127 * @param promptText
128 * prompt to display to the user alongside of the input
129 * field. Should be sufficient text to indicate what to
130 * supply for this item.
131 * @param maskValue
132 * true if the value should be masked from displaying during
133 * input. This should be true for passwords and other
134 * secrets, false for names and other public data.
135 */
136 public StringType(String promptText, boolean maskValue) {
137 super(promptText, maskValue);
138 }
139
140 @Override
141 public void clear() {
142 value = null;
143 }
144
145 /** @return the current value */
146 public String getValue() {
147 return value;
148 }
149
150 /**
151 *
152 * @param newValue
153 */
154 public void setValue(String newValue) {
155 value = newValue;
156 }
157 }
158
159 /** An item whose value is stored as a char[] and is therefore clearable. */
160 public static class CharArrayType extends CredentialItem {
161 private char[] value;
162
163 /**
164 * Initialize a prompt for a secure value stored in a character array.
165 *
166 * @param promptText
167 * prompt to display to the user alongside of the input
168 * field. Should be sufficient text to indicate what to
169 * supply for this item.
170 * @param maskValue
171 * true if the value should be masked from displaying during
172 * input. This should be true for passwords and other
173 * secrets, false for names and other public data.
174 */
175 public CharArrayType(String promptText, boolean maskValue) {
176 super(promptText, maskValue);
177 }
178
179 /** Destroys the current value, clearing the internal array. */
180 @Override
181 public void clear() {
182 if (value != null) {
183 Arrays.fill(value, (char) 0);
184 value = null;
185 }
186 }
187
188 /**
189 * Get the current value.
190 *
191 * The returned array will be cleared out when {@link #clear()} is
192 * called. Callers that need the array elements to survive should delay
193 * invoking {@code clear()} until the value is no longer necessary.
194 *
195 * @return the current value array. The actual internal array is
196 * returned, reducing the number of copies present in memory.
197 */
198 public char[] getValue() {
199 return value;
200 }
201
202 /**
203 * Set the new value, clearing the old value array.
204 *
205 * @param newValue
206 * if not null, the array is copied.
207 */
208 public void setValue(char[] newValue) {
209 clear();
210
211 if (newValue != null) {
212 value = new char[newValue.length];
213 System.arraycopy(newValue, 0, value, 0, newValue.length);
214 }
215 }
216
217 /**
218 * Set the new value, clearing the old value array.
219 *
220 * @param newValue
221 * the new internal array. The array is <b>NOT</b> copied.
222 */
223 public void setValueNoCopy(char[] newValue) {
224 clear();
225 value = newValue;
226 }
227 }
228
229 /** An item whose value is a boolean choice, presented as Yes/No. */
230 public static class YesNoType extends CredentialItem {
231 private boolean value;
232
233 /**
234 * Initialize a prompt for a single boolean answer.
235 *
236 * @param promptText
237 * prompt to display to the user alongside of the input
238 * field. Should be sufficient text to indicate what to
239 * supply for this item.
240 */
241 public YesNoType(String promptText) {
242 super(promptText, false);
243 }
244
245 @Override
246 public void clear() {
247 value = false;
248 }
249
250 /** @return the current value */
251 public boolean getValue() {
252 return value;
253 }
254
255 /**
256 * Set the new value.
257 *
258 * @param newValue
259 */
260 public void setValue(boolean newValue) {
261 value = newValue;
262 }
263 }
264
265 /** An advice message presented to the user, with no response required. */
266 public static class InformationalMessage extends CredentialItem {
267 /**
268 * Initialize an informational message.
269 *
270 * @param messageText
271 * message to display to the user.
272 */
273 public InformationalMessage(String messageText) {
274 super(messageText, false);
275 }
276
277 @Override
278 public void clear() {
279 // Nothing to clear.
280 }
281 }
282
283 /** Prompt for a username, which is not masked on input. */
284 public static class Username extends StringType {
285 /** Initialize a new username item, with a default username prompt. */
286 public Username() {
287 super(JGitText.get().credentialUsername, false);
288 }
289 }
290
291 /** Prompt for a password, which is masked on input. */
292 public static class Password extends CharArrayType {
293 /** Initialize a new password item, with a default password prompt. */
294 public Password() {
295 super(JGitText.get().credentialPassword, true);
296 }
297
298 /**
299 * Initialize a new password item, with given prompt.
300 *
301 * @param msg
302 * prompt message
303 */
304 public Password(String msg) {
305 super(msg, true);
306 }
307 }
308 }