[1201] | 1 | package org.expeditee.auth;
|
---|
| 2 |
|
---|
| 3 | import java.io.File;
|
---|
[1277] | 4 | import java.io.FileFilter;
|
---|
[1201] | 5 | import java.io.FileInputStream;
|
---|
| 6 | import java.io.FileNotFoundException;
|
---|
| 7 | import java.io.FileOutputStream;
|
---|
[1277] | 8 | import java.io.FileWriter;
|
---|
[1201] | 9 | import java.io.IOException;
|
---|
| 10 | import java.io.InputStream;
|
---|
[1243] | 11 | import java.nio.file.Path;
|
---|
| 12 | import java.nio.file.Paths;
|
---|
[1202] | 13 | import java.security.KeyFactory;
|
---|
[1201] | 14 | import java.security.KeyStore;
|
---|
| 15 | import java.security.KeyStore.SecretKeyEntry;
|
---|
| 16 | import java.security.KeyStoreException;
|
---|
| 17 | import java.security.NoSuchAlgorithmException;
|
---|
[1202] | 18 | import java.security.PublicKey;
|
---|
| 19 | import java.security.SecureRandom;
|
---|
[1201] | 20 | import java.security.UnrecoverableEntryException;
|
---|
| 21 | import java.security.cert.CertificateException;
|
---|
[1202] | 22 | import java.security.spec.InvalidKeySpecException;
|
---|
| 23 | import java.security.spec.X509EncodedKeySpec;
|
---|
| 24 | import java.sql.Connection;
|
---|
| 25 | import java.sql.DriverManager;
|
---|
[1243] | 26 | import java.sql.PreparedStatement;
|
---|
[1202] | 27 | import java.sql.ResultSet;
|
---|
| 28 | import java.sql.SQLException;
|
---|
[1277] | 29 | import java.text.ParseException;
|
---|
| 30 | import java.text.SimpleDateFormat;
|
---|
[1202] | 31 | import java.util.Arrays;
|
---|
| 32 | import java.util.Base64;
|
---|
| 33 | import java.util.Collection;
|
---|
[1277] | 34 | import java.util.Date;
|
---|
[1202] | 35 | import java.util.HashMap;
|
---|
[1279] | 36 | import java.util.HashSet;
|
---|
[1202] | 37 | import java.util.Map;
|
---|
[1243] | 38 | import java.util.Scanner;
|
---|
[1279] | 39 | import java.util.Set;
|
---|
[1202] | 40 | import java.util.stream.Stream;
|
---|
[1201] | 41 |
|
---|
| 42 | import javax.crypto.SecretKey;
|
---|
[1202] | 43 | import javax.crypto.spec.SecretKeySpec;
|
---|
[1201] | 44 |
|
---|
[1202] | 45 | import org.expeditee.actions.Actions;
|
---|
| 46 | import org.expeditee.core.Dimension;
|
---|
| 47 | import org.expeditee.core.Point;
|
---|
| 48 | import org.expeditee.gio.EcosystemManager;
|
---|
| 49 | import org.expeditee.gio.GraphicsManager;
|
---|
| 50 | import org.expeditee.gio.InputManager;
|
---|
| 51 | import org.expeditee.gio.InputManager.WindowEventListener;
|
---|
| 52 | import org.expeditee.gio.InputManager.WindowEventType;
|
---|
| 53 | import org.expeditee.gio.gesture.StandardGestureActions;
|
---|
| 54 | import org.expeditee.gui.Browser;
|
---|
| 55 | import org.expeditee.gui.DisplayController;
|
---|
| 56 | import org.expeditee.gui.Frame;
|
---|
[1201] | 57 | import org.expeditee.gui.FrameIO;
|
---|
[1202] | 58 | import org.expeditee.gui.FrameUtils;
|
---|
| 59 | import org.expeditee.gui.MessageBay;
|
---|
[1243] | 60 | import org.expeditee.io.ExpReader;
|
---|
| 61 | import org.expeditee.items.Item;
|
---|
[1202] | 62 | import org.expeditee.items.ItemUtils;
|
---|
| 63 | import org.expeditee.items.Text;
|
---|
| 64 | import org.expeditee.settings.Settings;
|
---|
| 65 | import org.expeditee.settings.UserSettings;
|
---|
[1243] | 66 | import org.expeditee.settings.identity.secrets.KeyList;
|
---|
[1277] | 67 | import org.expeditee.stats.Formatter;
|
---|
[1201] | 68 | import org.ngikm.cryptography.CryptographyConstants;
|
---|
| 69 |
|
---|
[1282] | 70 | public final class AuthenticatorBrowser extends Browser implements CryptographyConstants {
|
---|
[1201] | 71 |
|
---|
[1202] | 72 | // The frame number of the frame containing the current authenticated users public key.
|
---|
[1270] | 73 | public static int CREDENTIALS_FRAME = -1;
|
---|
[1352] | 74 | public static int PASSWORD_RECOVERY_FRAME = -1;
|
---|
[1263] | 75 | public static final String ADMINACCOUNT = "authadmin";
|
---|
[1304] | 76 | public static final String PROFILEENCRYPTIONLABEL = "Profile";
|
---|
[1202] | 77 |
|
---|
[1243] | 78 | public static boolean Authenticated = false;
|
---|
| 79 |
|
---|
[1254] | 80 | private KeyStore keyStore = KeyStore.getInstance(KeystoreType);
|
---|
[1303] | 81 | public static String USER_NOBODY = "nobody";
|
---|
[1243] | 82 |
|
---|
[1202] | 83 | private static final byte[] TRUE = "yes".getBytes();
|
---|
| 84 | private static final byte[] FALSE = "no".getBytes();
|
---|
| 85 | private static final String KEYSTOREFILENAME = "keystore.ks" + File.separator;
|
---|
[1263] | 86 |
|
---|
[1282] | 87 | private static AuthenticatorBrowser instance;
|
---|
[1202] | 88 |
|
---|
[1282] | 89 | public static AuthenticatorBrowser getInstance() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, IOException, ClassNotFoundException, SQLException {
|
---|
| 90 | if (instance == null) { instance = new AuthenticatorBrowser(); }
|
---|
[1202] | 91 | return instance;
|
---|
| 92 | }
|
---|
| 93 |
|
---|
[1287] | 94 | public static boolean isAuthenticationRequired() {
|
---|
| 95 | return Boolean.getBoolean("expeditee.authentication");
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | public static boolean isAuthenticated() {
|
---|
[1303] | 99 | return isAuthenticationRequired() && !UserSettings.UserName.get().equals(AuthenticatorBrowser.USER_NOBODY);
|
---|
[1287] | 100 | }
|
---|
| 101 |
|
---|
[1282] | 102 | private AuthenticatorBrowser() throws KeyStoreException, FileNotFoundException, IOException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, SQLException {
|
---|
[1281] | 103 | super("Authentication");
|
---|
[1202] | 104 | UserSettings.setupDefaultFolders();
|
---|
[1252] | 105 |
|
---|
[1202] | 106 | // initialise keystore and actions
|
---|
| 107 | loadKeystore();
|
---|
| 108 | Actions.LoadMethods(org.expeditee.auth.Actions.class);
|
---|
[1259] | 109 | Actions.LoadMethods(org.expeditee.auth.sharing.Actions.class);
|
---|
[1202] | 110 |
|
---|
[1263] | 111 | // Does the account Authentication.ADMINACCOUNT exist?
|
---|
| 112 | // If not then we have get the user to assign a password to it.
|
---|
[1282] | 113 | if (!keyStore.containsAlias(AuthenticatorBrowser.ADMINACCOUNT)) {
|
---|
[1263] | 114 | new File(FrameIO.PARENT_FOLDER).mkdirs();
|
---|
| 115 | protectAdmin();
|
---|
| 116 | }
|
---|
| 117 |
|
---|
[1202] | 118 | // draw the window
|
---|
[1243] | 119 | GraphicsManager g = EcosystemManager.getGraphicsManager();
|
---|
[1202] | 120 | g.setWindowLocation(new Point(50, 50));
|
---|
| 121 | DisplayController.Init();
|
---|
| 122 | g.setWindowSize(new Dimension(UserSettings.InitialWidth.get(), UserSettings.InitialHeight.get()));
|
---|
| 123 | setInputManagerWindowRoutines();
|
---|
| 124 |
|
---|
| 125 | // Load documentation and start pages
|
---|
| 126 | FrameUtils.extractResources(false);
|
---|
| 127 |
|
---|
| 128 | // Load fonts before loading any frames so the items on the frames will be able to access their fonts
|
---|
| 129 | Text.InitFonts();
|
---|
| 130 |
|
---|
| 131 | // initialing settings does not require a user profile established
|
---|
| 132 | Settings.Init();
|
---|
| 133 |
|
---|
| 134 | // navigate to authentication frame
|
---|
[1243] | 135 | Frame authFrame = FrameIO.LoadFrame("authentication1");
|
---|
[1202] | 136 | DisplayController.setCurrentFrame(authFrame, true);
|
---|
| 137 |
|
---|
| 138 | // set initial values
|
---|
[1243] | 139 | Stream<Text> usernameItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtUsername"));
|
---|
| 140 | Stream<Text> passwordItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtPassword"));
|
---|
[1252] | 141 | usernameItemsStream.forEach(txtUsername -> txtUsername.setText(System.getProperty("startinguser.name", "")));
|
---|
| 142 | passwordItemsStream.forEach(txtPassword -> { txtPassword.setText(""); txtPassword.invalidateAll(); });
|
---|
[1202] | 143 |
|
---|
| 144 | MessageBay.warningMessages(org.expeditee.actions.Actions.Init());
|
---|
| 145 |
|
---|
[1243] | 146 | // class load database classes
|
---|
[1202] | 147 | Class.forName("org.sqlite.JDBC");
|
---|
[1243] | 148 | }
|
---|
[1263] | 149 |
|
---|
| 150 | private void protectAdmin() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
|
---|
| 151 | FileNotFoundException, IOException {
|
---|
| 152 | // Fetch desired password
|
---|
[1357] | 153 | @SuppressWarnings("resource")
|
---|
[1263] | 154 | Scanner in = new Scanner(System.in);
|
---|
[1267] | 155 | System.out.println("No administrative password set.");
|
---|
| 156 | boolean passwordIsSet = false;
|
---|
| 157 |
|
---|
| 158 | for (int i = 0; i < 3; i++) {
|
---|
| 159 | System.out.print("Please enter it now: ");
|
---|
| 160 | System.out.flush();
|
---|
| 161 | String password = in.nextLine();
|
---|
| 162 | System.out.print("And again: ");
|
---|
| 163 | System.out.flush();
|
---|
| 164 | if (in.nextLine().equals(password)) {
|
---|
| 165 | // Register account.
|
---|
| 166 | putKey(ADMINACCOUNT, password, new SecretKeySpec("null".getBytes(), AsymmetricAlgorithm));
|
---|
[1357] | 167 | //in.close();
|
---|
[1267] | 168 | passwordIsSet = true;
|
---|
| 169 | break;
|
---|
| 170 | } else {
|
---|
| 171 | System.out.println("Mismatched passwords, let's try that again.");
|
---|
| 172 | }
|
---|
[1263] | 173 | }
|
---|
[1267] | 174 |
|
---|
| 175 | if (!passwordIsSet) {
|
---|
| 176 | System.out.println("Failed to set an admin password. Exiting Expeditee.");
|
---|
| 177 | System.exit(1);
|
---|
| 178 | }
|
---|
[1263] | 179 | }
|
---|
[1243] | 180 |
|
---|
| 181 | private void loadKeystore()
|
---|
| 182 | throws IOException, NoSuchAlgorithmException, CertificateException, FileNotFoundException {
|
---|
| 183 | final File keyStoreFile = new File(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME);
|
---|
| 184 | if (!keyStoreFile.exists()) {
|
---|
[1334] | 185 | keyStore.load(null, "ExpediteeAuthPassword".toCharArray());
|
---|
[1243] | 186 | } else {
|
---|
| 187 | try (final InputStream in = new FileInputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME)) {
|
---|
[1334] | 188 | keyStore.load(in, "ExpediteeAuthPassword".toCharArray());
|
---|
[1243] | 189 | }
|
---|
[1202] | 190 | }
|
---|
| 191 | }
|
---|
| 192 |
|
---|
[1277] | 193 | final void loadMailFromFile(Path dbFile) throws SQLException {
|
---|
[1243] | 194 | // Load in all mail.
|
---|
[1277] | 195 | Connection c = DriverManager.getConnection("jdbc:sqlite:" + dbFile.toAbsolutePath().toString());
|
---|
[1243] | 196 | String sql = "SELECT * FROM EXPMAIL";
|
---|
| 197 | PreparedStatement query = c.prepareStatement(sql);
|
---|
| 198 | ResultSet allMail = query.executeQuery();
|
---|
| 199 |
|
---|
| 200 | // Construct all mail objects using content from database.
|
---|
| 201 | while(allMail.next()) {
|
---|
| 202 | String timestamp = allMail.getString("time");
|
---|
| 203 | String from = allMail.getString("snd");
|
---|
| 204 | String to = allMail.getString("rec");
|
---|
| 205 | String msg = allMail.getString("msg");
|
---|
| 206 | String msg2 = allMail.getString("msg2");
|
---|
| 207 | String[] opts = allMail.getString("opts").split(",");
|
---|
[1202] | 208 | opts[0] = opts[0].replace("[", "");
|
---|
| 209 | opts[opts.length - 1] = opts[opts.length - 1].replace("]", "");
|
---|
[1243] | 210 | String[] optsVal = allMail.getString("optsval").split(",");
|
---|
[1202] | 211 | optsVal[0] = optsVal[0].replace("[", "");
|
---|
| 212 | optsVal[optsVal.length - 1] = optsVal[optsVal.length - 1].replace("]", "");
|
---|
| 213 |
|
---|
| 214 | Map<String, String> options = new HashMap<String, String>();
|
---|
| 215 | for (int i = 0, o = 0; i < opts.length && o < optsVal.length; i++, o++) {
|
---|
| 216 | String key = opts[i].trim();
|
---|
| 217 | String val = optsVal[o].trim();
|
---|
| 218 | options.put(key, val);
|
---|
| 219 | }
|
---|
| 220 |
|
---|
[1362] | 221 | Mail.MailEntry mail = new Mail.MailEntry(timestamp, from, to, msg, msg2, options);
|
---|
| 222 | mail.deadDropSource = dbFile;
|
---|
| 223 | Mail.addEntry(mail);
|
---|
[1202] | 224 | }
|
---|
[1243] | 225 |
|
---|
| 226 | // Disconnect from database.
|
---|
| 227 | allMail.close();
|
---|
[1202] | 228 | query.close();
|
---|
| 229 | c.close();
|
---|
| 230 | }
|
---|
| 231 |
|
---|
[1303] | 232 | public final void loadMailDatabase() throws SQLException, FileNotFoundException, ParseException {
|
---|
[1277] | 233 | Path deadDropPath = Paths.get(FrameIO.DEAD_DROPS_PATH);
|
---|
| 234 | for (File connectionDir: deadDropPath.toFile().listFiles()) {
|
---|
| 235 | if (connectionDir.isDirectory()) {
|
---|
| 236 | Path deaddropforcontactPath = Paths.get(connectionDir.getAbsolutePath());
|
---|
| 237 | Path dbFile = deaddropforcontactPath.resolve(UserSettings.UserName.get() + ".db");
|
---|
| 238 | if (dbFile.toFile().exists()) {
|
---|
| 239 | loadMailFromFile(dbFile);
|
---|
| 240 | }
|
---|
| 241 | clearOldMailFromDatabase(deaddropforcontactPath);
|
---|
[1201] | 242 | }
|
---|
| 243 | }
|
---|
| 244 | }
|
---|
[1282] | 245 |
|
---|
[1303] | 246 | public final void updateLastReadMailTime(Path deaddropforcontactPath) {
|
---|
[1282] | 247 | Path timestamp = deaddropforcontactPath.resolve(UserSettings.UserName.get() + ".last-accessed");
|
---|
| 248 | try(FileWriter out = new FileWriter(timestamp.toFile())) {
|
---|
| 249 | out.write(Formatter.getDateTime() + System.getProperty("line.separator"));
|
---|
| 250 | } catch (IOException e) {
|
---|
| 251 | e.printStackTrace();
|
---|
| 252 | }
|
---|
| 253 | }
|
---|
[1201] | 254 |
|
---|
[1277] | 255 | private void clearOldMailFromDatabase(Path directory) throws FileNotFoundException, ParseException, SQLException {
|
---|
| 256 | File[] files = directory.toFile().listFiles(new FileFilter() {
|
---|
| 257 | @Override
|
---|
| 258 | public boolean accept(File file) {
|
---|
| 259 | return !file.getName().startsWith(UserSettings.UserName.get());
|
---|
| 260 | }
|
---|
| 261 | });
|
---|
| 262 |
|
---|
| 263 | File dbFile = null;
|
---|
| 264 | File lastAccessedFile = null;
|
---|
| 265 | for (File file: files) {
|
---|
| 266 | if (file.getName().endsWith(".db")) {
|
---|
| 267 | dbFile = file;
|
---|
| 268 | } else {
|
---|
| 269 | lastAccessedFile = file;
|
---|
| 270 | }
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | if (dbFile == null || lastAccessedFile == null) {
|
---|
[1282] | 274 | return; // Not the end of the world if we cannot clear out old messages, these files may not be present yet if the others are recently new.
|
---|
[1277] | 275 | }
|
---|
| 276 |
|
---|
| 277 | SimpleDateFormat format = new SimpleDateFormat("ddMMMyyyy[HH:mm]");
|
---|
| 278 | Date timestamp = null;
|
---|
| 279 | try(Scanner in = new Scanner(lastAccessedFile)) {
|
---|
| 280 | timestamp = format.parse(in.nextLine());
|
---|
[1278] | 281 | } catch (ParseException e) {
|
---|
[1282] | 282 | return; // Not the end of the world if we cannot clear out old messages, the database might be empty.
|
---|
[1277] | 283 | }
|
---|
| 284 |
|
---|
| 285 | Connection c = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath());
|
---|
| 286 | String sql = "SELECT * FROM EXPMAIL";
|
---|
| 287 | PreparedStatement query = c.prepareStatement(sql);
|
---|
| 288 | ResultSet allMail = query.executeQuery();
|
---|
[1279] | 289 | Set<String> oldTimestamps = new HashSet<String>();
|
---|
[1277] | 290 |
|
---|
| 291 | while (allMail.next()) {
|
---|
| 292 | String time = allMail.getString("time");
|
---|
| 293 | Date messageTimestamp = format.parse(time);
|
---|
| 294 | if (timestamp.after(messageTimestamp)) {
|
---|
| 295 | oldTimestamps.add(time);
|
---|
| 296 | }
|
---|
| 297 | }
|
---|
| 298 |
|
---|
[1279] | 299 | if (oldTimestamps.isEmpty()) {
|
---|
| 300 | return;
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 | for(String oldTimestamp: oldTimestamps) {
|
---|
| 304 | System.out.println("Deleting message with timestamp: " + oldTimestamp);
|
---|
| 305 | sql = "DELETE FROM EXPMAIL WHERE time='" + oldTimestamp + "'";
|
---|
| 306 | query = c.prepareStatement(sql);
|
---|
| 307 | query.executeUpdate();
|
---|
| 308 | }
|
---|
[1277] | 309 | }
|
---|
| 310 |
|
---|
[1303] | 311 | public final SecretKey getSecretKey(final String label, final String password) throws NoSuchAlgorithmException, KeyStoreException {
|
---|
[1244] | 312 |
|
---|
| 313 | char[] password_ca = password.toCharArray();
|
---|
| 314 |
|
---|
| 315 | SecretKey secret_key;
|
---|
[1202] | 316 | try {
|
---|
[1253] | 317 | secret_key = (SecretKey) keyStore.getKey(label, password_ca);
|
---|
[1202] | 318 | } catch (final UnrecoverableEntryException e) {
|
---|
[1279] | 319 | return null;
|
---|
[1202] | 320 | }
|
---|
[1244] | 321 |
|
---|
| 322 | return secret_key;
|
---|
[1201] | 323 | }
|
---|
| 324 |
|
---|
[1303] | 325 | public final void putKey(final String label, final String password, final SecretKey key) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {
|
---|
[1201] | 326 | final KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(key);
|
---|
| 327 | final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password.toCharArray());
|
---|
| 328 | keyStore.setEntry(label, entry, entryPassword);
|
---|
[1334] | 329 | keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
|
---|
[1201] | 330 | }
|
---|
[1202] | 331 |
|
---|
[1357] | 332 | public final boolean confirmIntergalaticNumber(final String username, final String intergalacticNumber) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException {
|
---|
[1202] | 333 | try {
|
---|
[1357] | 334 | KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(intergalacticNumber.toCharArray());
|
---|
| 335 | KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(username + "_IntergalacticNumber", entryPassword);
|
---|
| 336 | if (entry == null) {
|
---|
[1202] | 337 | return false;
|
---|
[1347] | 338 | } else if (Arrays.equals(entry.getSecretKey().getEncoded(), TRUE)) {
|
---|
[1357] | 339 | keyStore.deleteEntry(username + "_IntergalacticNumber");
|
---|
[1334] | 340 | keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
|
---|
[1202] | 341 | return true;
|
---|
[1357] | 342 | } else {
|
---|
| 343 | return false;
|
---|
| 344 | }
|
---|
[1202] | 345 | } catch (final UnrecoverableEntryException e) {
|
---|
| 346 | return false;
|
---|
| 347 | }
|
---|
| 348 | }
|
---|
| 349 |
|
---|
[1303] | 350 | public final String newIntergalacticNumber(final String username, final String email) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {
|
---|
[1202] | 351 | // generate intergalactic number
|
---|
[1347] | 352 | SecureRandom rand = new SecureRandom();
|
---|
| 353 | byte[] intergalacticNumberBytes = new byte[10];
|
---|
[1202] | 354 | rand.nextBytes(intergalacticNumberBytes);
|
---|
[1347] | 355 | String intergalacticNumber = Base64.getEncoder().encodeToString(intergalacticNumberBytes);
|
---|
[1202] | 356 |
|
---|
| 357 | // store intergalactic number
|
---|
[1357] | 358 | KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(TRUE, SymmetricAlgorithm));
|
---|
| 359 | KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(intergalacticNumber.toCharArray());
|
---|
| 360 | keyStore.setEntry(username + "_IntergalacticNumber", entry, entryPassword);
|
---|
[1334] | 361 | keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
|
---|
[1202] | 362 |
|
---|
| 363 | return intergalacticNumber;
|
---|
| 364 | }
|
---|
| 365 |
|
---|
[1303] | 366 | public final PublicKey getPublicKey(String username) throws InvalidKeySpecException, NoSuchAlgorithmException, FileNotFoundException {
|
---|
[1243] | 367 | // load in frame with public key on it.
|
---|
| 368 | String credentialsFramesetPath = FrameIO.CONTACTS_PATH + username + "-credentials" + File.separator;
|
---|
| 369 | if (!new File(credentialsFramesetPath).exists()) {
|
---|
| 370 | return null;
|
---|
| 371 | }
|
---|
| 372 | Scanner in = new Scanner(new File(credentialsFramesetPath + "credentials.inf"));
|
---|
| 373 | String credentialsFrameNumber = in.nextLine().replace(ExpReader.EXTENTION, "");
|
---|
| 374 | in.close();
|
---|
| 375 | Frame frame = FrameIO.LoadFrame(username + "-credentials" + credentialsFrameNumber, FrameIO.CONTACTS_PATH);
|
---|
| 376 | if (frame == null) {
|
---|
| 377 | return null;
|
---|
| 378 | }
|
---|
[1202] | 379 |
|
---|
[1243] | 380 | // obtain public key from frame
|
---|
| 381 | Collection<Item> canditates = org.expeditee.auth.Actions.getByContent(frame, "PublicKey");
|
---|
| 382 | String keyEncoded = "";
|
---|
| 383 | for (Item i: canditates) {
|
---|
| 384 | if (i.getData() != null) {
|
---|
| 385 | keyEncoded = i.getData().get(0);
|
---|
| 386 | }
|
---|
| 387 | }
|
---|
| 388 | if (keyEncoded.isEmpty()) {
|
---|
[1202] | 389 | return null;
|
---|
| 390 | }
|
---|
[1243] | 391 | byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
|
---|
| 392 | return KeyFactory.getInstance(AsymmetricAlgorithm).generatePublic(new X509EncodedKeySpec(keyBytes));
|
---|
[1202] | 393 | }
|
---|
| 394 |
|
---|
[1303] | 395 | public final void markRequestedColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {
|
---|
[1202] | 396 | KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(TRUE, SymmetricAlgorithm));
|
---|
| 397 | KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
|
---|
| 398 | keyStore.setEntry(username + "colleaguesRequested", entry, entryPassword);
|
---|
[1334] | 399 | keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
|
---|
[1202] | 400 | }
|
---|
| 401 |
|
---|
[1303] | 402 | public final void clearRequestedColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {
|
---|
[1202] | 403 | KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(FALSE, SymmetricAlgorithm));
|
---|
| 404 | KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
|
---|
| 405 | keyStore.setEntry(username + "colleaguesRequested", entry, entryPassword);
|
---|
[1334] | 406 | keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
|
---|
[1202] | 407 | }
|
---|
| 408 |
|
---|
[1303] | 409 | public final boolean hasRequestedColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException {
|
---|
[1202] | 410 | String alias = username + "colleaguesRequested";
|
---|
| 411 | if (!keyStore.containsAlias(alias)) {
|
---|
| 412 | return false;
|
---|
| 413 | } else {
|
---|
| 414 | KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
|
---|
| 415 | KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, entryPassword);
|
---|
| 416 | return Arrays.equals(entry.getSecretKey().getEncoded(), TRUE);
|
---|
| 417 | }
|
---|
| 418 | }
|
---|
| 419 |
|
---|
[1243] | 420 | // final void putColleagues(String username, String[] colleagues) throws KeyStoreException {
|
---|
| 421 | // String alias = username + "colleagues";
|
---|
| 422 | // final SecretKeySpec secretKeySpec = new SecretKeySpec((colleagues[0] + System.getProperty("line.separator") + colleagues[1]).getBytes(), SymmetricAlgorithm);
|
---|
| 423 | // KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKeySpec);
|
---|
| 424 | // KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
|
---|
| 425 | // keyStore.setEntry(alias, entry, entryPassword);
|
---|
| 426 | // }
|
---|
| 427 | //
|
---|
| 428 | // final String[] getColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException {
|
---|
| 429 | // String alias = username + "colleagues";
|
---|
| 430 | // if (!keyStore.containsAlias(alias)) {
|
---|
| 431 | // return null;
|
---|
| 432 | // } else {
|
---|
| 433 | // KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
|
---|
| 434 | // KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, entryPassword);
|
---|
| 435 | // byte[] colleaguesEncoded = entry.getSecretKey().getEncoded();
|
---|
| 436 | // String colleagues = new String(colleaguesEncoded);
|
---|
| 437 | // return colleagues.split(System.getProperty("line.separator"));
|
---|
| 438 | // }
|
---|
| 439 | // }
|
---|
[1202] | 440 |
|
---|
| 441 | private static void setInputManagerWindowRoutines() {
|
---|
| 442 | InputManager manager = EcosystemManager.getInputManager();
|
---|
| 443 |
|
---|
| 444 | // Refresh the layout when the window resizes
|
---|
| 445 | manager.addWindowEventListener(new WindowEventListener() {
|
---|
| 446 | @Override
|
---|
| 447 | public void onWindowEvent(WindowEventType type)
|
---|
| 448 | {
|
---|
| 449 | if (type != WindowEventType.WINDOW_RESIZED) {
|
---|
| 450 | return;
|
---|
| 451 | }
|
---|
| 452 | DisplayController.refreshWindowSize();
|
---|
| 453 | FrameIO.RefreshCacheImages();
|
---|
| 454 | for (Frame frame : DisplayController.getFrames()) {
|
---|
| 455 | if (frame != null) {
|
---|
| 456 | ItemUtils.Justify(frame);
|
---|
| 457 | frame.refreshSize();
|
---|
| 458 | }
|
---|
| 459 | }
|
---|
| 460 | DisplayController.requestRefresh(false);
|
---|
| 461 | }
|
---|
| 462 | });
|
---|
| 463 |
|
---|
| 464 | manager.addWindowEventListener(new WindowEventListener() {
|
---|
| 465 | @Override
|
---|
| 466 | public void onWindowEvent(WindowEventType type)
|
---|
| 467 | {
|
---|
| 468 | if (type != WindowEventType.MOUSE_EXITED_WINDOW) {
|
---|
| 469 | return;
|
---|
| 470 | }
|
---|
| 471 | StandardGestureActions.mouseExitedWindow();
|
---|
| 472 | }
|
---|
| 473 | });
|
---|
| 474 |
|
---|
| 475 | manager.addWindowEventListener(new WindowEventListener() {
|
---|
| 476 | @Override
|
---|
| 477 | public void onWindowEvent(WindowEventType type)
|
---|
| 478 | {
|
---|
| 479 | if (type != WindowEventType.MOUSE_ENTERED_WINDOW) {
|
---|
| 480 | return;
|
---|
| 481 | }
|
---|
| 482 | StandardGestureActions.mouseEnteredWindow();
|
---|
| 483 | }
|
---|
| 484 | });
|
---|
| 485 |
|
---|
| 486 | manager.addWindowEventListener(new WindowEventListener() {
|
---|
| 487 | @Override
|
---|
| 488 | public void onWindowEvent(WindowEventType type)
|
---|
| 489 | {
|
---|
| 490 | if (type != WindowEventType.WINDOW_CLOSED) {
|
---|
| 491 | return;
|
---|
| 492 | }
|
---|
| 493 | if (Browser._theBrowser != null) {
|
---|
| 494 | Browser._theBrowser.exit();
|
---|
| 495 | }
|
---|
| 496 | }
|
---|
| 497 | });
|
---|
| 498 | }
|
---|
[1201] | 499 | }
|
---|