diff --git a/.travis.yml b/.travis.yml index cf501986..4fab439b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,6 @@ language: objective-c xcode_project: MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj xcode_scheme: MasterPassword iOS (Development) xcode_sdk: iphonesimulator +env: TERM=dumb git: submodules: true diff --git a/External/iOS/Crashlytics.framework/Versions/A/Crashlytics b/External/iOS/Crashlytics.framework/Versions/A/Crashlytics index b05e091c..ec79a372 100644 Binary files a/External/iOS/Crashlytics.framework/Versions/A/Crashlytics and b/External/iOS/Crashlytics.framework/Versions/A/Crashlytics differ diff --git a/External/iOS/Crashlytics.framework/submit b/External/iOS/Crashlytics.framework/submit index aec35d10..c34d5c2e 100755 Binary files a/External/iOS/Crashlytics.framework/submit and b/External/iOS/Crashlytics.framework/submit differ diff --git a/MasterPassword/C/build b/MasterPassword/C/build index c6824e95..e4d655dc 100755 --- a/MasterPassword/C/build +++ b/MasterPassword/C/build @@ -2,6 +2,9 @@ # # TROUBLESHOOTING # - To enable verbose algorithm/implementation debugging, use ./build -DDEBUG +# - If you see 'undefined reference to `AES_encrypt'', +# make sure you have openssl installed. +# If libcrypto.a is in a non-standard directory, try ./build -L[your-lib-dir] # - If you see 'undefined reference to `clock_gettime'', # try ./build -lrt instead. # - If you see 'x86.S:202: Error: junk at end of line, first unrecognized character is `,'', @@ -189,7 +192,7 @@ mpw() { # library paths -L"." -L"lib/scrypt" # link libraries - -l"crypto" + -l"crypto" -l"curses" # scrypt "lib/scrypt/scrypt-crypto_aesctr.o" "lib/scrypt/scrypt-sha256.o" @@ -245,6 +248,9 @@ mpw-bench() { ### TARGETS +haslib() { + ! LC_ALL=C cc -l"$1" 2>&1 | grep -q 'library not found' +} cc() { if hash llvm-gcc 2>/dev/null; then llvm-gcc "$@" diff --git a/MasterPassword/C/mpw.c b/MasterPassword/C/mpw.c index 13994a09..73ce75f4 100644 --- a/MasterPassword/C/mpw.c +++ b/MasterPassword/C/mpw.c @@ -95,13 +95,24 @@ char *homedir(const char *filename) { return homefile; } +char *getlinep(const char *prompt) { + char *buf = NULL; + size_t bufSize = 0; + ssize_t lineSize; + fprintf(stderr, "%s", prompt); + fprintf(stderr, " "); + if ((lineSize = getline(&buf, &bufSize, stdin)) < 0) { + free(buf); + return NULL; + } + buf[lineSize - 1]=0; + return buf; +} + int main(int argc, char *const argv[]) { - if (argc < 2) - usage(); - // Read the environment. - const char *userName = getenv( MP_env_username ); + char *userName = getenv( MP_env_username ); const char *masterPassword = NULL; const char *siteName = NULL; MPElementType siteType = MPElementTypeGeneratedLong; @@ -156,13 +167,17 @@ int main(int argc, char *const argv[]) { // Convert and validate input. if (!userName) { - fprintf(stderr, "Missing user name.\n"); - return 1; + if (!(userName = getlinep("Your user name:"))) { + fprintf(stderr, "Missing user name.\n"); + return 1; + } } trc("userName: %s\n", userName); if (!siteName) { - fprintf(stderr, "Missing site name.\n"); - return 1; + if (!(siteName = getlinep("Site name:"))) { + fprintf(stderr, "Missing site name.\n"); + return 1; + } } trc("siteName: %s\n", siteName); if (siteCounterString) @@ -206,6 +221,9 @@ int main(int argc, char *const argv[]) { masterPassword = getpass( "Your master password: " ); trc("masterPassword: %s\n", masterPassword); + // Summarize operation. + fprintf(stderr, "%s's password for %s:\n[ %s ]: ", userName, siteName, Identicon( userName, masterPassword )); + // Calculate the master key salt. const char *mpKeyScope = ScopeForVariant(MPElementVariantPassword); trc("key scope: %s\n", mpKeyScope); diff --git a/MasterPassword/C/types.c b/MasterPassword/C/types.c index 5eaf7104..fc342a9f 100644 --- a/MasterPassword/C/types.c +++ b/MasterPassword/C/types.c @@ -10,9 +10,13 @@ #include #include #include +#include #include +#include +#include + #include "types.h" const MPElementType TypeWithName(const char *typeName) { @@ -171,6 +175,7 @@ const char CharacterFromClass(char characterClass, uint8_t seedByte) { return classCharacters[seedByte % strlen(classCharacters)]; } + const char *IDForBuf(const void *buf, size_t length) { uint8_t hash[32]; SHA256_Buf(buf, length, hash); @@ -186,5 +191,48 @@ const char *Hex(const void *buf, size_t length) { char *id = (char *)calloc(length*2+1, sizeof(char)); for (int kH = 0; kH < length; kH++) sprintf(&(id[kH * 2]), "%02X", ((const uint8_t*)buf)[kH]); + return id; } + +int putvari; +char *putvarc = NULL; +static void initputvar() { + if (putvarc) + free(putvarc); + putvari=0; + putvarc=(char *)calloc(256, sizeof(char)); +} +static int putvar(int c) { + putvarc[putvari++]=c; + return 0; +} + +const char *Identicon(const char *userName, const char *masterPassword) { + const char *left[] = { "╔", "╚", "╰", "═" }; + const char *right[] = { "╗", "╝", "╯", "═" }; + const char *body[] = { "█", "░", "▒", "▓", "☺", "☻" }; + const char *accessory[] = { "◈", "◎", "◐", "◑", "◒", "◓", "☀", "☁", "☂", "☃", "☄", "★", "☆", "☎", "☏", "⎈", "⌂", "☘", "☢", "☣", "☕", "⌚", "⌛", "⏰", "⚡", "⛄", "⛅", "☔", "♔", "♕", "♖", "♗", "♘", "♙", "♚", "♛", "♜", "♝", "♞", "♟", "♨", "♩", "♪", "♫", "⚐", "⚑", "⚔", "⚖", "⚙", "⚠", "⌘", "⏎", "✄", "✆", "✈", "✉", "✌" }; + + uint8_t identiconSeed[32]; + HMAC_SHA256_Buf(masterPassword, strlen(masterPassword), userName, strlen(userName), identiconSeed); + + char *identicon = (char *)calloc(20, sizeof(char)); + setupterm(NULL, 2, NULL); + initputvar(); + tputs(tparm(tgetstr("AF", NULL), identiconSeed[4] % 7 + 1), 1, putvar); + char red[strlen(putvarc)]; + strcpy(red, putvarc); + tputs(tgetstr("me", NULL), 1, putvar); + char reset[strlen(putvarc)]; + strcpy(reset, putvarc); + sprintf(identicon, "%s%s%s%s%s%s", + red, + left[identiconSeed[0] % (sizeof(left) / sizeof(left[0]))], + body[identiconSeed[1] % (sizeof(body) / sizeof(body[0]))], + right[identiconSeed[2] % (sizeof(right) / sizeof(right[0]))], + accessory[identiconSeed[3] % (sizeof(accessory) / sizeof(accessory[0]))], + reset); + + return identicon; +} diff --git a/MasterPassword/C/types.h b/MasterPassword/C/types.h index 4cde84c9..c3ef0b61 100644 --- a/MasterPassword/C/types.h +++ b/MasterPassword/C/types.h @@ -56,4 +56,5 @@ const char *CipherForType(MPElementType type, uint8_t seedByte); const char CharacterFromClass(char characterClass, uint8_t seedByte); const char *IDForBuf(const void *buf, size_t length); const char *Hex(const void *buf, size_t length); +const char *Identicon(const char *userName, const char *masterPassword); diff --git a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m index 3ab72444..27a6079d 100644 --- a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m +++ b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m @@ -109,8 +109,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven // Global hotkey. EventHotKeyRef hotKeyRef; EventTypeSpec hotKeyEvents[1] = { { .eventClass = kEventClassKeyboard, .eventKind = kEventHotKeyPressed } }; - OSStatus status = InstallApplicationEventHandler( NewEventHandlerUPP( MPHotKeyHander ), GetEventTypeCount( hotKeyEvents ), - hotKeyEvents, (__bridge void *)self, NULL ); + OSStatus status = InstallApplicationEventHandler( NewEventHandlerUPP( MPHotKeyHander ), GetEventTypeCount( hotKeyEvents ), hotKeyEvents, (__bridge void *)self, NULL ); if (status != noErr) err( @"Error installing application event handler: %i", (int)status ); status = RegisterEventHotKey( 35 /* p */, controlKey + cmdKey, MPShowHotKey, GetApplicationEventTarget(), 0, &hotKeyRef ); diff --git a/MasterPassword/ObjC/iOS/MPUsersViewController.m b/MasterPassword/ObjC/iOS/MPUsersViewController.m index c64d76eb..f25869bc 100644 --- a/MasterPassword/ObjC/iOS/MPUsersViewController.m +++ b/MasterPassword/ObjC/iOS/MPUsersViewController.m @@ -682,8 +682,10 @@ referenceSizeForFooterInSection:(NSInteger)section { } ); PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil, ^(MPUsersViewController *self, NSNotification *note) { - [self registerObservers]; - [self reloadUsers]; + PearlMainQueue( ^{ + [self registerObservers]; + [self reloadUsers]; + } ); } ); } diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index cedb53e9..c433b284 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -3492,6 +3492,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = "/bin/sh -e"; shellScript = "exec ../../../Scripts/updatePlist"; + showEnvVarsInLog = 0; }; DA8D88E019DA412A00B189D0 /* Run Script: genassets */ = { isa = PBXShellScriptBuildPhase; diff --git a/Scripts/bashlib b/Scripts/bashlib index 07982472..0399f604 100644 --- a/Scripts/bashlib +++ b/Scripts/bashlib @@ -27,7 +27,7 @@ # ______________________________________________________________________ # | | -# | .:: TABLE OF CONTENTS ::. | +# | .: TABLE OF CONTENTS :. | # |______________________________________________________________________| # # chr decimal @@ -132,7 +132,7 @@ _tocHash=71e13f42e1ea82c1c7019b27a3bc71f3 # ______________________________________________________________________ # | | -# | .:: GLOBAL CONFIGURATION ::. | +# | .: GLOBAL CONFIGURATION :. | # |______________________________________________________________________| # Unset all exported functions. Exported functions are evil. @@ -177,7 +177,7 @@ genToc() { # ______________________________________________________________________ # | | -# | .:: GLOBAL DECLARATIONS ::. | +# | .: GLOBAL DECLARATIONS :. | # |______________________________________________________________________| # Variables for convenience sequences. @@ -230,7 +230,7 @@ runner=( '> >' \ tput eA; tput as; tput ac; tput ae; } ) # Drawing characters back=$'\b' -} 2>/dev/null ||: +} ||: @@ -238,7 +238,7 @@ runner=( '> >' \ # ______________________________________________________________________ # | | -# | .:: FUNCTION DECLARATIONS ::. | +# | .: FUNCTION DECLARATIONS :. | # |______________________________________________________________________| @@ -1549,7 +1549,7 @@ stackTrace() { # ______________________________________________________________________ # | | -# | .:: ENTRY POINT ::. | +# | .: ENTRY POINT :. | # |______________________________________________________________________| # Make sure this file is sourced and not executed. @@ -1569,6 +1569,6 @@ stackTrace() { } : -: .:: END SOURCING ::. +: .: END SOURCING :. : ______________________________________________________________________ : diff --git a/Scripts/updatePlist b/Scripts/updatePlist index a42f7e3d..aabaf3e5 100755 --- a/Scripts/updatePlist +++ b/Scripts/updatePlist @@ -1,7 +1,6 @@ #!/usr/bin/env bash cd "${BASH_SOURCE%/*}" -source bashlib -set -e +source ./bashlib cd .. export PATH+=:/usr/libexec diff --git a/Site/2013-05/404.html b/Site/2013-05/404.html index 04465441..7f4cc4ef 100755 --- a/Site/2013-05/404.html +++ b/Site/2013-05/404.html @@ -151,7 +151,7 @@ - + diff --git a/Site/2013-05/algorithm.html b/Site/2013-05/algorithm.html index b1d48785..ba10c80a 100644 --- a/Site/2013-05/algorithm.html +++ b/Site/2013-05/algorithm.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + @@ -55,13 +55,6 @@
- -

The Master Password Algorithm

diff --git a/Site/2013-05/faq.html b/Site/2013-05/faq.html index 692ce39f..3b641ec0 100644 --- a/Site/2013-05/faq.html +++ b/Site/2013-05/faq.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + @@ -54,13 +54,6 @@
- -

Security Overview

@@ -94,7 +87,7 @@

Can an officer force me to divulge my master password?

Cryptography only provides technical security. It does not protect you from situations where you are legally required or forced by peers to surrender your key.

- +

In fact, many countries provide their officers with a legal grounds for forcing you to divulge your encryption keys to any encrypted information they've recovered during a warranted search.

Again, unlike ordinary password managers, Master Password might have an edge here. If you make no use of stored passwords, Master Password doesn't actually encrypt anything with your master password. That means, when your devices are seized, these legal grounds may no longer apply. Note however that this does not constitute legal advice and that this theory has never been tested in practice.

For your safety, we recommend that in preparation of travelling, you change the master password for your user on the device. That way, if your device is seized by a foreign entity and they force you to divulge your master password, you'll likely be fully compliant by simply giving up the new master password even though it will cause the app to generate invalid passwords for all your sites. Later, you can always change the master password back to the real one.

@@ -102,7 +95,7 @@

What should my master password be?

The simple answer to that question is: First and foremost, memorable and unrelated to you. What that means is that the most important thing about your master password is that you need to be able to recall it any time and yet it should not be derived from anything personal.

That advice usually doesn't help very much with actually picking a good master password. The goal of a good password is that it'll take an attacker a lot of guesses before he'll find it. That is the core idea behind good passwords.

- +

There are a few strategies of getting good passwords. The speed with which an attacker can guess your password depends a lot on whether he knows what kind of password you're using or not. So we'll compare a few password strategies, their strength and how memorable they are.

The simplest strategy for picking good passwords is by just picking a bunch of random letters, digits and symbols and mixing them up. This is a great strategy for strong passwords but those passwords are usually not very memorable.

Another strategy is by "encoding" something you already know. This can seem like a good way to make memorable passwords, but recalling the "encoding" you used two years later can be tricky. This also makes it much easier for attackers that know you to find your password.

@@ -151,7 +144,7 @@ Difficult - Encoding a word, Tr0ub4dor style + Encoding a word, Tr0ub4dor style Tr0ub4dor @@ -169,7 +162,7 @@ Moderate - Nonsense sentence, correct horse style + Nonsense sentence, correct horse style correct horse battery staple diff --git a/Site/2013-05/index.html b/Site/2013-05/index.html index 126ff59f..84be9266 100644 --- a/Site/2013-05/index.html +++ b/Site/2013-05/index.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + diff --git a/Site/2013-05/news-dev.html b/Site/2013-05/news-dev.html deleted file mode 100644 index 59085c74..00000000 --- a/Site/2013-05/news-dev.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - -

- - diff --git a/Site/2013-05/news.html b/Site/2013-05/news.html deleted file mode 100644 index d44cc776..00000000 --- a/Site/2013-05/news.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - -

Open support if you have any issues.

- - diff --git a/Site/2013-05/privacy.html b/Site/2013-05/privacy.html index 1092216b..630adb7b 100644 --- a/Site/2013-05/privacy.html +++ b/Site/2013-05/privacy.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + @@ -55,13 +55,6 @@
- -

Privacy Policy

diff --git a/Site/2013-05/security.html b/Site/2013-05/security.html index 6d1cde5e..1aad4e6e 100644 --- a/Site/2013-05/security.html +++ b/Site/2013-05/security.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + diff --git a/Site/2013-05/support.html b/Site/2013-05/support.html index 7b49744e..4fcb6816 100644 --- a/Site/2013-05/support.html +++ b/Site/2013-05/support.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + @@ -55,13 +55,6 @@
- -

Support

diff --git a/Site/2013-05/trouble.html b/Site/2013-05/trouble.html index 51d63b1e..fc45c2da 100644 --- a/Site/2013-05/trouble.html +++ b/Site/2013-05/trouble.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + diff --git a/Site/2013-05/what.html b/Site/2013-05/what.html index abb40c52..0cd75a58 100644 --- a/Site/2013-05/what.html +++ b/Site/2013-05/what.html @@ -1,11 +1,11 @@ - + Master Password — Secure your life, forget your passwords. - + @@ -19,7 +19,7 @@ - + diff --git a/Site/mpw-js/css/main.css b/Site/mpw-js/css/main.css index ed0a108f..336855b9 100644 --- a/Site/mpw-js/css/main.css +++ b/Site/mpw-js/css/main.css @@ -1,4 +1,4 @@ -@import url(http://fonts.googleapis.com/css?family=Flamenco:300|Exo+2:400,100,900); +@import url(://fonts.googleapis.com/css?family=Flamenco:300|Exo+2:400,100,900); /**** BASE STYLE ****/ html { diff --git a/Site/mpw-js/js/dependencies.js b/Site/mpw-js/js/dependencies.js index 0d54f51c..ebd155ea 100644 --- a/Site/mpw-js/js/dependencies.js +++ b/Site/mpw-js/js/dependencies.js @@ -37,7 +37,7 @@ try { ES6 || document.write("