Changeset 1363 for trunk/src/org/expeditee/auth/account
- Timestamp:
- 05/17/19 14:37:12 (5 years ago)
- Location:
- trunk/src/org/expeditee/auth/account
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/auth/account/Authenticate.java
r1359 r1363 25 25 import org.expeditee.auth.Actions; 26 26 import org.expeditee.auth.AuthenticatorBrowser; 27 import org.expeditee.auth. gui.MailBay;27 import org.expeditee.auth.mail.gui.MailBay; 28 28 import org.expeditee.auth.tags.AuthenticationTag; 29 29 import org.expeditee.gui.Browser; … … 41 41 public class Authenticate implements CryptographyConstants { 42 42 43 /** 44 * Given a username and password, potentially login. 45 * @param userdata 46 * @return AuthenticationResult.SuccessLogin if login works, AuthenticationResult.ErrorLoginNobody or AuthenticationResult.ErrorLoginUsernamePasswordCombo otherwise. 47 */ 43 48 public static AuthenticationResult login(Map<AuthenticationTag, String> userdata) { 44 49 String username = userdata.get(AuthenticationTag.Username); … … 76 81 if(data != null && data.contains("MultiuserCredentials")) { 77 82 AuthenticatorBrowser.CREDENTIALS_FRAME = f.getNumber(); 83 } else if (data != null && data.contains("PasswordColleagues")) { 84 AuthenticatorBrowser.PASSWORD_RECOVERY_FRAME = f.getNumber(); 85 } else if (data != null && data.contains("SecretsFrame")) { 86 AuthenticatorBrowser.SECRETS_FRAME = f.getNumber(); 78 87 } 79 }88 } 80 89 } 81 90 … … 103 112 byte[] keyBytes = Base64.getDecoder().decode(keyEncoded); 104 113 PrivateKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(keyBytes)); 105 org.expeditee.auth. Mail.checkMail(key);114 org.expeditee.auth.mail.Mail.checkMail(key); 106 115 } else { 107 116 res.additionalInfo.add("No private key present: your communication with other Expeditee users will be limited until this is resolved."); … … 129 138 } 130 139 140 /** 141 * Logs out the current authenticated user. 142 * @return AuthenticationResult.SuccessLogout to signal the logout has occured. 143 */ 131 144 public static AuthenticationResult logout() { 132 145 // Set user to nobody. -
trunk/src/org/expeditee/auth/account/Create.java
r1356 r1363 125 125 return CreateResult.SuccessCreateAccount; 126 126 } 127 128 public static CreateResult createAlternativeAccess(Map<AuthenticationTag, String> userdata) { 129 String username = userdata.get(AuthenticationTag.Username); 130 FrameIO.CreateFrame(username, null, "default1"); 131 return null; 132 } 133 127 134 128 public enum CreateResult { 135 129 SuccessCreateAccount ("Account created."), … … 193 187 FrameIO.migrateFrame(credentialsFrame, destinationFile); 194 188 // pwcolleagues.inf file. 195 String pwColleaguesPath = credentialsDir.getAbsolutePath() + File.separator + "pwcolleagues.inf"; 196 File pwColleaguesFile = new File(pwColleaguesPath); 189 File pwColleaguesFile = Paths.get(FrameIO.PROFILE_PATH).resolve(username).resolve("pwcolleagues.inf").toFile(); 197 190 pwColleaguesFile.createNewFile(); 198 191 out = new FileWriter(pwColleaguesFile); … … 234 227 } 235 228 }); 236 notifiers.put("settings.identity.passwordrecovery", frame -> { 229 notifiers.put("settings.identity.passwordrecovery", frame -> { 230 frame.addToData("PasswordColleagues"); 237 231 AuthenticatorBrowser.PASSWORD_RECOVERY_FRAME = frame.getNumber(); 238 232 }); 239 233 notifiers.put("settings.identity.secrets", frame -> { 234 frame.addToData("SecretsFrame"); 235 AuthenticatorBrowser.SECRETS_FRAME = frame.getNumber(); 236 }); 240 237 241 238 // Create users profile -
trunk/src/org/expeditee/auth/account/Password.java
r1357 r1363 1 1 package org.expeditee.auth.account; 2 2 3 import java.io.File; 3 4 import java.io.FileNotFoundException; 4 5 import java.io.IOException; 6 import java.nio.file.Path; 7 import java.nio.file.Paths; 5 8 import java.security.KeyStoreException; 6 9 import java.security.NoSuchAlgorithmException; 10 import java.security.SecureRandom; 7 11 import java.security.cert.CertificateException; 8 12 import java.sql.SQLException; 13 import java.util.Base64; 14 import java.util.Collection; 15 import java.util.HashMap; 16 import java.util.Iterator; 9 17 import java.util.Map; 10 18 import java.util.Properties; 19 import java.util.Scanner; 11 20 12 21 import javax.crypto.SecretKey; 22 import javax.crypto.spec.SecretKeySpec; 13 23 import javax.mail.Message; 14 24 import javax.mail.MessagingException; … … 16 26 import javax.mail.Session; 17 27 import javax.mail.Transport; 28 import javax.mail.internet.AddressException; 18 29 import javax.mail.internet.InternetAddress; 19 30 import javax.mail.internet.MimeMessage; 20 31 21 32 import org.expeditee.auth.AuthenticatorBrowser; 33 import org.expeditee.auth.mail.Mail; 34 import org.expeditee.auth.mail.Mail.MailEntry; 22 35 import org.expeditee.auth.tags.AuthenticationTag; 23 36 import org.expeditee.gui.DisplayController; 37 import org.expeditee.gui.Frame; 24 38 import org.expeditee.gui.FrameIO; 25 39 import org.expeditee.gui.MessageBay; 40 import org.expeditee.items.Text; 41 import org.expeditee.settings.UserSettings; 42 import org.expeditee.settings.identity.passwordrecovery.Colleagues; 43 import org.expeditee.settings.identity.secrets.KeyList; 44 import org.expeditee.stats.Formatter; 26 45 import org.ngikm.cryptography.CryptographyConstants; 27 46 47 import com.codahale.shamir.Scheme; 48 28 49 public class Password implements CryptographyConstants { 29 /* 30 * Changes the recorded password for a user in the key store .50 /** 51 * Changes the recorded password for a user in the key store; given the username signaling whose password to change, along with the existing and new password. 31 52 */ 32 53 public static void changePassword(Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, IOException, ClassNotFoundException, SQLException { … … 45 66 } 46 67 68 /** 69 * Generates a intergalaictic number for a specified user and emails that number using the specified email. 70 * @param userData 71 */ 47 72 public static void generateAndDeliverIntergalacticNumber(Map<AuthenticationTag, String> userData) { 48 73 String username = userData.get(AuthenticationTag.Username); … … 57 82 sb.append("If it was you who made this request, the following string of characters is your intergalactic number: " + intergalacticNumber + nl); 58 83 59 // Establish properties for email. 60 Properties properties = System.getProperties(); 61 properties.setProperty("mail.transport.protocol", "smtp"); 62 properties.setProperty("mail.smtp.host", "smtp.gmail.com"); 63 properties.setProperty("mail.smtp.port", "465"); 64 properties.setProperty("mail.smtp.starttls.enable", "true"); 65 properties.setProperty("mail.smtp.auth", "true"); 66 properties.setProperty("mail.smtp.debug", "true"); 67 properties.setProperty("mail.smtp.auth", "true"); 68 properties.setProperty("mail.smtp.socketFactory.port", "465"); 69 properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 70 properties.setProperty("mail.smtp.socketFactory.fallback", "false"); 71 72 Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() { 73 @Override 74 protected PasswordAuthentication getPasswordAuthentication() { 75 return new PasswordAuthentication("noreply.expeditee", "intergalacticnumber"); 76 }; 77 }); 78 79 // construct email message 80 final MimeMessage message = new MimeMessage(session); 81 message.setFrom(new InternetAddress("[email protected]")); 82 message.addRecipient(Message.RecipientType.TO, new InternetAddress(email)); 83 message.setSubject("Expeditee Password Recovery"); 84 message.setText(sb.toString()); 85 86 // send email message 87 Transport.send(message); 84 sendEmail(email, sb); 88 85 } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | ClassNotFoundException 89 86 | IOException | SQLException | MessagingException e) { … … 92 89 } 93 90 94 public static void confirmIntergalacticNumberAndAlertColleagues(Map<AuthenticationTag, String> userData, String[] colleagues) { 95 System.err.println("Colleague One: " + colleagues[0] + " @" + colleagues[2]); 96 System.err.println("Colleague Two: " + colleagues[1] + " @" + colleagues[3]); 91 /** 92 * Confirms that the specified intergalaictic number matches the one of file for the specified username. 93 * Passing this test it then alerts the users pw colleagues through a one-off secure Expeditee message. 94 * @param tags 95 */ 96 public static void confirmIntergalacticNumberAndAlertColleagues(Map<AuthenticationTag, String> tags) { 97 // Confirm intergalactic numbers match 98 String username = tags.get(AuthenticationTag.Username); 99 String intergalacticNumber = tags.get(AuthenticationTag.IntergalacticNumber); 100 boolean match = false; 101 try { 102 match = AuthenticatorBrowser.getInstance().confirmIntergalaticNumber(username, intergalacticNumber); 103 } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | ClassNotFoundException 104 | IOException | SQLException e) { 105 e.printStackTrace(); 106 return; 107 } 108 if (!match) { 109 MessageBay.errorMessage("The provided identity number does not match the one stored on file."); 110 return; 111 } 112 113 // Get colleagues to distribute messages too. 114 String[] colleagues = getPasswordColleaguesFromUsername(username); 115 // Send secure message to colleague one 116 String colleagueOne = colleagues[0]; 117 String time = Formatter.getDateTime(); 118 String topic = "Password Recovery for " + username; 119 String message = "Your colleague " + username + " would like you to help them recover access to their account."; 120 Map<String, String> options = new HashMap<String, String>(); 121 options.put("Provide assistance", "AuthEmailPasswordShare " + username); 122 MailEntry mail = new MailEntry(time, username, colleagueOne, topic, message, options); 123 Mail.sendOneOffMail(mail, colleagueOne, Base64.getDecoder().decode(intergalacticNumber)); 124 125 // Send secure message to colleague two 126 String colleagueTwo = colleagues[1]; 127 Mail.sendOneOffMail(mail, colleagueTwo, Base64.getDecoder().decode(intergalacticNumber)); 128 129 String nl = System.getProperty("line.separator"); 130 StringBuilder sb = new StringBuilder(); 131 sb.append("You are receiving this email because one of your Expeditee contacts has sent you a one-off secure message." + nl); 132 sb.append("When you log into Expeditee and check your mail it will be there waiting for you." + nl); 133 sb.append("You will need the following key to read this message: " + nl); 134 sb.append(intergalacticNumber); 135 try { 136 // Send email with key to colleague one 137 String colleagueOneEmail = colleagues[2]; 138 sendEmail(colleagueOneEmail, sb); 139 // Send email with key to colleague two 140 String colleagueTwoEmail = colleagues[3]; 141 sendEmail(colleagueTwoEmail, sb); 142 } catch (MessagingException e) { 143 e.printStackTrace(); 144 } 145 } 146 147 private static String[] getPasswordColleaguesFromUsername(String username) { 148 Path credentialsFilePath = Paths.get(FrameIO.PROFILE_PATH).resolve(username).resolve("pwcolleagues.inf"); 149 String fileName = null; 150 if (credentialsFilePath.toFile().exists()) { 151 try (Scanner in = new Scanner(credentialsFilePath)) { 152 fileName = in.nextLine(); 153 } catch (IOException e) { 154 MessageBay.errorMessage("Unable to password colleague frame for specified user, are they registered on this computer?"); 155 return null; 156 } 157 } else { 158 MessageBay.errorMessage("Unable to password colleague frame for specified user, are they registered on this computer?"); 159 return null; 160 } 161 162 int number = Integer.parseInt(fileName.replace(".exp", "")); 163 Frame pwColleagueFrame = FrameIO.LoadFrame(username + number, FrameIO.PROFILE_PATH); 164 Collection<Text> textItems = pwColleagueFrame.getTextItems(); 165 textItems.removeIf(text -> !text.getText().startsWith("Colleague")); 166 167 String[] ret = new String[4]; 168 Iterator<Text> it = textItems.iterator(); 169 while(it.hasNext()) { 170 String content = it.next().getText().toLowerCase().trim(); 171 if (content.contains("colleague_one:")) { 172 ret[0] = content.replace("colleague_one:", "").trim(); 173 } else if (content.contains("colleague_two:")) { 174 ret[1] = content.replace("colleague_two:", "").trim(); 175 } 176 } 177 178 // find colleague one email 179 Path credentialsDirectoryPath = UserSettings.PublicAndPrivateResources 180 ? Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-" + username) 181 : Paths.get(FrameIO.PARENT_FOLDER); 182 credentialsDirectoryPath = credentialsDirectoryPath.resolve("contacts").resolve(ret[0] + "-credentials"); 183 try (Scanner in = new Scanner(credentialsDirectoryPath.resolve("credentials.inf").toFile())) { 184 int parseInt = Integer.parseInt(in.nextLine().replace(".exp", "")); 185 Frame frame = FrameIO.LoadFrame(ret[0] + "-credentials" + parseInt, credentialsDirectoryPath.toAbsolutePath().getParent().toString() + File.separator); 186 textItems = frame.getTextItems(); 187 textItems.removeIf(text -> !text.getText().startsWith("Email:")); 188 ret[2] = textItems.iterator().next().getText().replace("Email:", "").trim(); 189 } catch (FileNotFoundException e) { 190 MessageBay.errorMessage("You do not appear to have contact with your nominated password colleague: " + ret[0]); 191 return null; 192 } 193 194 195 // find colleague two email 196 credentialsDirectoryPath = UserSettings.PublicAndPrivateResources 197 ? Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-" + username) 198 : Paths.get(FrameIO.PARENT_FOLDER); 199 credentialsDirectoryPath = credentialsDirectoryPath.resolve("contacts").resolve(ret[1] + "-credentials"); 200 try (Scanner in = new Scanner(credentialsDirectoryPath.resolve("credentials.inf").toFile())) { 201 int parseInt = Integer.parseInt(in.nextLine().replace(".exp", "")); 202 Frame frame = FrameIO.LoadFrame(ret[1] + "-credentials" + parseInt, credentialsDirectoryPath.toAbsolutePath().getParent().toString() + File.separator); 203 textItems = frame.getTextItems(); 204 textItems.removeIf(text -> !text.getText().startsWith("Email:")); 205 ret[3] = textItems.iterator().next().getText().replace("Email:", "").trim(); 206 } catch (FileNotFoundException e) { 207 MessageBay.errorMessage("You do not appear to have contact with your nominated password colleague: " + ret[1]); 208 return null; 209 } 210 211 return ret; 212 } 213 214 215 public static void sendEmail(String email, StringBuilder sb) throws MessagingException, AddressException { 216 // Establish properties for email. 217 Properties properties = System.getProperties(); 218 properties.setProperty("mail.transport.protocol", "smtp"); 219 properties.setProperty("mail.smtp.host", "smtp.gmail.com"); 220 properties.setProperty("mail.smtp.port", "465"); 221 properties.setProperty("mail.smtp.starttls.enable", "true"); 222 properties.setProperty("mail.smtp.auth", "true"); 223 properties.setProperty("mail.smtp.debug", "true"); 224 properties.setProperty("mail.smtp.auth", "true"); 225 properties.setProperty("mail.smtp.socketFactory.port", "465"); 226 properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 227 properties.setProperty("mail.smtp.socketFactory.fallback", "false"); 228 229 Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() { 230 @Override 231 protected PasswordAuthentication getPasswordAuthentication() { 232 return new PasswordAuthentication("noreply.expeditee", "intergalacticnumber"); 233 }; 234 }); 235 236 // construct email message 237 final MimeMessage message = new MimeMessage(session); 238 message.setFrom(new InternetAddress("[email protected]")); 239 message.addRecipient(Message.RecipientType.TO, new InternetAddress(email)); 240 message.setSubject("Expeditee Password Recovery"); 241 message.setText(sb.toString()); 242 243 // send email message 244 Transport.send(message); 245 } 246 247 public static void setPWColleagues(String colleagueOne, String colleagueTwo) { 248 // Get needed text items. 249 Frame pwRecoveryFrame = FrameIO.LoadFrame(UserSettings.UserName.get() + AuthenticatorBrowser.PASSWORD_RECOVERY_FRAME); 250 Collection<Text> textItems = pwRecoveryFrame.getTextItems(); 251 textItems.removeIf(t -> !t.getText().toLowerCase().startsWith("colleague")); 252 253 // Find colleague one and two text items. Set appropriate values. 254 Iterator<Text> it = textItems.iterator(); 255 while (it.hasNext()) { 256 Text text = it.next(); 257 if (text.getText().toLowerCase().startsWith("colleague_one:")) { 258 text.setText("Colleague_one: " + colleagueOne); 259 Colleagues.Colleague_One.set(colleagueOne); 260 } else if (text.getText().toLowerCase().startsWith("colleague_two:")) { 261 text.setText("Colleague_two:" + colleagueTwo); 262 Colleagues.Colleague_Two.set(colleagueTwo); 263 } 264 } 265 FrameIO.ForceSaveFrame(pwRecoveryFrame); 266 267 // Key to split and distribute 268 String fullKey = KeyList.PersonalKey.get().getData().get(0); 269 byte[] keyBytes = Base64.getDecoder().decode(fullKey); 270 271 // Initialise Shamir 272 int totalShares = 2; 273 int requiredShares = 2; 274 Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares); 275 276 // Create shares 277 Map<Integer, byte[]> shares = scheme.split(keyBytes); 278 String colleagueOneShare = Base64.getEncoder().encodeToString(shares.get(1)); 279 String colleagueTwoShare = Base64.getEncoder().encodeToString(shares.get(2)); 280 281 // Distribute share zero to colleague one 282 String time = org.expeditee.stats.Formatter.getDateTime(); 283 String sender = UserSettings.UserName.get(); 284 String topic = "Please help me secure my Expeditee account."; 285 String message = "Run the below action to store a secret key that will help me recover access to my account should I ever loose it."; 286 Map<String, String> options = new HashMap<String, String>(); 287 options.put("Store Secret Key for " + sender, "AuthAddSecretKey " + sender + "PersonalKeyShare " + colleagueOneShare); 288 MailEntry mail = new MailEntry(time, sender, colleagueOne, topic, message, options); 289 Mail.sendMail(mail, colleagueOne); 290 291 // Distribute share one to colleague two 292 options = new HashMap<String, String>(); 293 options.put("Store Secret Key for " + sender, "AuthAddSecretKey " + sender + "PersonalKeyShare " + colleagueTwoShare); 294 mail = new MailEntry(time, sender, colleagueTwo, topic, message, options); 295 Mail.sendMail(mail, colleagueTwo); 296 297 MessageBay.displayMessage("PW Colleagues Set"); 298 } 299 300 public static void emailPasswordShare(String colleagueName) { 301 Path credentialsDirectoryPath = Paths.get(FrameIO.CONTACTS_PATH).resolve(colleagueName + "-credentials"); 302 String colleagueEmail = null; 303 try (Scanner in = new Scanner(credentialsDirectoryPath.resolve("credentials.inf").toFile())) { 304 int parseInt = Integer.parseInt(in.nextLine().replace(".exp", "")); 305 Frame frame = FrameIO.LoadFrame(colleagueName + "-credentials" + parseInt, credentialsDirectoryPath.toAbsolutePath().getParent().toString() + File.separator); 306 Collection<Text> textItems = frame.getTextItems(); 307 textItems.removeIf(text -> !text.getText().startsWith("Email:")); 308 colleagueEmail = textItems.iterator().next().getText().replace("Email:", "").trim(); 309 } catch (FileNotFoundException e) { 310 MessageBay.errorMessage("You do not appear to have contact with: " + colleagueName); 311 return; 312 } 313 314 Frame secretsFrame = FrameIO.LoadFrame(UserSettings.UserName.get() + AuthenticatorBrowser.SECRETS_FRAME); 315 Collection<Text> textItems = secretsFrame.getTextItems(); 316 textItems.removeIf(text -> !text.getText().toLowerCase().equals(colleagueName + "personalkeyshare")); 317 String key = textItems.iterator().next().getData().get(0); 318 319 String nl = System.getProperty("line.separator"); 320 StringBuilder sb = new StringBuilder(); 321 sb.append("In responce to your request for assistance regaining access to your Expeditee account, your colleague " + UserSettings.UserName.get() + " has provided you with the following key share:" + nl); 322 sb.append(key + nl); 323 324 try { 325 sendEmail(colleagueEmail, sb); 326 } catch (MessagingException e) { 327 MessageBay.errorMessage("An error occured sending a email to your colleage " + colleagueName + " with the email " + colleagueEmail); 328 } 329 } 330 331 public static void regainAccountAccess(Map<AuthenticationTag, String> userData) { 332 // Store shares in map 333 Map<Integer, byte[]> contributingParts = new HashMap<Integer, byte[]>(); 334 contributingParts.put(1, Base64.getDecoder().decode(userData.get(AuthenticationTag.PasswordSliceOne))); 335 contributingParts.put(2, Base64.getDecoder().decode(userData.get(AuthenticationTag.PasswordSliceTwo))); 336 337 // initialise shamir 338 int totalShares = 2; 339 int requiredShares = 2; 340 Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares); 341 342 // perform joining 343 byte[] join = scheme.join(contributingParts); 344 345 try { 346 AuthenticatorBrowser.getInstance().putKey(userData.get(AuthenticationTag.Username), userData.get(AuthenticationTag.NewPassword), new SecretKeySpec(join, SymmetricAlgorithm)); 347 } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | ClassNotFoundException 348 | IOException | SQLException e) { 349 e.printStackTrace(); 350 } 351 352 MessageBay.displayMessage("Your new password has been set."); 97 353 } 98 354 }
Note:
See TracChangeset
for help on using the changeset viewer.