View Javadoc
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 }