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 }