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 {@link CredentialsProvider}.
52 *
53 * Most users should work with the specialized subclasses:
54 * <ul>
55 * <li>{@link Username} for usernames</li>
56 * <li>{@link Password} for passwords</li>
57 * <li>{@link StringType} for other general string information</li>
58 * <li>{@link CharArrayType} for other general secret information</li>
59 * </ul>
60 *
61 * This class is not thread-safe. Applications should construct their own
62 * instance for each use, as the value is held within the CredentialItem object.
63 */
64 public abstract class CredentialItem {
65 private final String promptText;
66
67 private final boolean valueSecure;
68
69 /**
70 * Initialize a prompt.
71 *
72 * @param promptText
73 * prompt to display to the user alongside of the input field.
74 * Should be sufficient text to indicate what to supply for this
75 * item.
76 * @param maskValue
77 * true if the value should be masked from displaying during
78 * input. This should be true for passwords and other secrets,
79 * false for names and other public data.
80 */
81 public CredentialItem(String promptText, boolean maskValue) {
82 this.promptText = promptText;
83 this.valueSecure = maskValue;
84 }
85
86 /** @return prompt to display to the user. */
87 public String getPromptText() {
88 return promptText;
89 }
90
91 /** @return true if the value should be masked when entered. */
92 public boolean isValueSecure() {
93 return valueSecure;
94 }
95
96 /** Clear the stored value, destroying it as much as possible. */
97 public abstract void clear();
98
99 /**
100 * An item whose value is stored as a string.
101 *
102 * When working with secret data, consider {@link CharArrayType} instead, as
103 * the internal members of the array can be cleared, reducing the chances
104 * that the password is left in memory after authentication is completed.
105 */
106 public static class StringType extends CredentialItem {
107 private String value;
108
109 /**
110 * Initialize a prompt for a single string.
111 *
112 * @param promptText
113 * prompt to display to the user alongside of the input
114 * field. Should be sufficient text to indicate what to
115 * supply for this item.
116 * @param maskValue
117 * true if the value should be masked from displaying during
118 * input. This should be true for passwords and other
119 * secrets, false for names and other public data.
120 */
121 public StringType(String promptText, boolean maskValue) {
122 super(promptText, maskValue);
123 }
124
125 @Override
126 public void clear() {
127 value = null;
128 }
129
130 /** @return the current value */
131 public String getValue() {
132 return value;
133 }
134
135 /**
136 *
137 * @param newValue
138 */
139 public void setValue(String newValue) {
140 value = newValue;
141 }
142 }
143
144 /** An item whose value is stored as a char[] and is therefore clearable. */
145 public static class CharArrayType extends CredentialItem {
146 private char[] value;
147
148 /**
149 * Initialize a prompt for a secure value stored in a character array.
150 *
151 * @param promptText
152 * prompt to display to the user alongside of the input
153 * field. Should be sufficient text to indicate what to
154 * supply for this item.
155 * @param maskValue
156 * true if the value should be masked from displaying during
157 * input. This should be true for passwords and other
158 * secrets, false for names and other public data.
159 */
160 public CharArrayType(String promptText, boolean maskValue) {
161 super(promptText, maskValue);
162 }
163
164 /** Destroys the current value, clearing the internal array. */
165 @Override
166 public void clear() {
167 if (value != null) {
168 Arrays.fill(value, (char) 0);
169 value = null;
170 }
171 }
172
173 /**
174 * Get the current value.
175 *
176 * The returned array will be cleared out when {@link #clear()} is
177 * called. Callers that need the array elements to survive should delay
178 * invoking {@code clear()} until the value is no longer necessary.
179 *
180 * @return the current value array. The actual internal array is
181 * returned, reducing the number of copies present in memory.
182 */
183 public char[] getValue() {
184 return value;
185 }
186
187 /**
188 * Set the new value, clearing the old value array.
189 *
190 * @param newValue
191 * if not null, the array is copied.
192 */
193 public void setValue(char[] newValue) {
194 clear();
195
196 if (newValue != null) {
197 value = new char[newValue.length];
198 System.arraycopy(newValue, 0, value, 0, newValue.length);
199 }
200 }
201
202 /**
203 * Set the new value, clearing the old value array.
204 *
205 * @param newValue
206 * the new internal array. The array is <b>NOT</b> copied.
207 */
208 public void setValueNoCopy(char[] newValue) {
209 clear();
210 value = newValue;
211 }
212 }
213
214 /** An item whose value is a boolean choice, presented as Yes/No. */
215 public static class YesNoType extends CredentialItem {
216 private boolean value;
217
218 /**
219 * Initialize a prompt for a single boolean answer.
220 *
221 * @param promptText
222 * prompt to display to the user alongside of the input
223 * field. Should be sufficient text to indicate what to
224 * supply for this item.
225 */
226 public YesNoType(String promptText) {
227 super(promptText, false);
228 }
229
230 @Override
231 public void clear() {
232 value = false;
233 }
234
235 /** @return the current value */
236 public boolean getValue() {
237 return value;
238 }
239
240 /**
241 * Set the new value.
242 *
243 * @param newValue
244 */
245 public void setValue(boolean newValue) {
246 value = newValue;
247 }
248 }
249
250 /** An advice message presented to the user, with no response required. */
251 public static class InformationalMessage extends CredentialItem {
252 /**
253 * Initialize an informational message.
254 *
255 * @param messageText
256 * message to display to the user.
257 */
258 public InformationalMessage(String messageText) {
259 super(messageText, false);
260 }
261
262 @Override
263 public void clear() {
264 // Nothing to clear.
265 }
266 }
267
268 /** Prompt for a username, which is not masked on input. */
269 public static class Username extends StringType {
270 /** Initialize a new username item, with a default username prompt. */
271 public Username() {
272 super(JGitText.get().credentialUsername, false);
273 }
274 }
275
276 /** Prompt for a password, which is masked on input. */
277 public static class Password extends CharArrayType {
278 /** Initialize a new password item, with a default password prompt. */
279 public Password() {
280 super(JGitText.get().credentialPassword, true);
281 }
282
283 /**
284 * Initialize a new password item, with given prompt.
285 *
286 * @param msg
287 * prompt message
288 */
289 public Password(String msg) {
290 super(msg, true);
291 }
292 }
293 }