Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6b2287778 | ||
|
|
f4e90bb839 | ||
|
|
21630e919b | ||
|
|
ae74ab6906 | ||
|
|
caf361cd10 | ||
|
|
aeedc1946e | ||
|
|
93ae31f679 | ||
|
|
d5ff215da2 | ||
|
|
b34f7377da | ||
|
|
0c2e182039 | ||
|
|
438daf27ee | ||
|
|
aa6634970a | ||
|
|
9052416786 | ||
|
|
9d19eaf667 | ||
|
|
7ae9afa63a | ||
|
|
3d856b3773 | ||
|
|
7617b2382a | ||
|
|
a03dcf6859 | ||
|
|
57769ba199 | ||
|
|
6304b3a619 | ||
|
|
d1649f3c33 | ||
|
|
80f507b4cc | ||
|
|
f8a665db65 | ||
|
|
b15f2a8a26 | ||
|
|
e9094097a2 | ||
|
|
bea6ac5e68 | ||
|
|
778533ac7f | ||
|
|
83fcde5bd0 | ||
|
|
c9ec5874d3 | ||
|
|
4ce5fd25bc | ||
|
|
1ed28ebc9b | ||
|
|
c03199f7e5 | ||
|
|
9f10bcdec4 | ||
|
|
82c96ddfe3 | ||
|
|
c0fea076b9 |
2
External/Pearl
vendored
2
External/Pearl
vendored
Submodule External/Pearl updated: 8c646abdae...6abdab7168
@@ -81,11 +81,15 @@ unpack() {
|
|||||||
mv "$files"/* .
|
mv "$files"/* .
|
||||||
rmdir "$files"
|
rmdir "$files"
|
||||||
fi
|
fi
|
||||||
|
touch .unpacked
|
||||||
}
|
}
|
||||||
fetchSource() (
|
fetchSource() (
|
||||||
source .source
|
source .source
|
||||||
|
|
||||||
if [[ $pkg && -e "${pkg##*/}" ]]; then
|
if [[ -e .unpacked ]]; then
|
||||||
|
true
|
||||||
|
|
||||||
|
elif [[ $pkg && -e "${pkg##*/}" ]]; then
|
||||||
files=( !("${pkg##*/}") )
|
files=( !("${pkg##*/}") )
|
||||||
[[ -e $files ]] || {
|
[[ -e $files ]] || {
|
||||||
echo
|
echo
|
||||||
@@ -135,11 +139,14 @@ fetchSource() (
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for patch in "${patches[@]}"; do
|
if [[ ! -e .patched ]] && (( ${#patches[@]} )); then
|
||||||
echo
|
for patch in "${patches[@]}"; do
|
||||||
echo "Patching: ${PWD##*/}, for $patch..."
|
echo
|
||||||
patch -p0 < ../"${PWD##*/}-$patch.patch"
|
echo "Patching: ${PWD##*/}, for $patch..."
|
||||||
done
|
patch -p0 < ../"${PWD##*/}-$patch.patch"
|
||||||
|
done
|
||||||
|
touch .patched
|
||||||
|
fi
|
||||||
)
|
)
|
||||||
depend() {
|
depend() {
|
||||||
|
|
||||||
@@ -273,6 +280,7 @@ mpw-tests() {
|
|||||||
# include paths
|
# include paths
|
||||||
-I"lib/include"
|
-I"lib/include"
|
||||||
-I"/usr/include/libxml2"
|
-I"/usr/include/libxml2"
|
||||||
|
-I"/usr/local/include/libxml2"
|
||||||
)
|
)
|
||||||
LDFLAGS=(
|
LDFLAGS=(
|
||||||
# scrypt
|
# scrypt
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ set -e
|
|||||||
cd "${BASH_SOURCE%/*}"
|
cd "${BASH_SOURCE%/*}"
|
||||||
tag=$(git describe)
|
tag=$(git describe)
|
||||||
commit=$(git describe --long --dirty)
|
commit=$(git describe --long --dirty)
|
||||||
[[ $tag && $commit = $tag-* ]] || exit 1
|
[[ $tag && $commit = $tag* ]] || exit 1
|
||||||
git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION
|
git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION
|
||||||
|
|
||||||
mpwArchive=mpw-$commit.tar.gz
|
mpwArchive=mpw-$commit.tar.gz
|
||||||
[[ -e $mpwArchive ]] && echo "WARNING: $mpwArchive already exists. Will overwrite."
|
[[ -e $mpwArchive ]] && echo "WARNING: $mpwArchive already exists. Will overwrite."
|
||||||
read -n1 -p "Will prepare and release $mpwArchive. Press a key to continue or ^C to abort."
|
read -n1 -p "Will prepare and release $mpwArchive. Press a key to continue or ^C to abort."
|
||||||
|
|
||||||
git ls-files -z . | xargs -0 tar -cvzf "$mpwArchive"
|
git ls-files -z . | xargs -0 tar -Lcvzf "$mpwArchive"
|
||||||
echo "$mpwArchive ready, SHA256: $(openssl sha -sha256 < "$mpwArchive")"
|
echo "$mpwArchive ready, SHA256: $(openssl sha -sha256 < "$mpwArchive")"
|
||||||
|
|
||||||
cd ../../Site/current
|
cd ../../Site/current
|
||||||
|
|||||||
@@ -6,106 +6,48 @@
|
|||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "mpw-types.h"
|
|
||||||
#include "mpw-util.h"
|
|
||||||
#include "mpw-algorithm.h"
|
#include "mpw-algorithm.h"
|
||||||
|
#include "mpw-algorithm_v0.c"
|
||||||
|
#include "mpw-algorithm_v1.c"
|
||||||
|
#include "mpw-algorithm_v2.c"
|
||||||
|
#include "mpw-algorithm_v3.c"
|
||||||
|
|
||||||
#define MP_N 32768
|
#define MP_N 32768
|
||||||
#define MP_r 8
|
#define MP_r 8
|
||||||
#define MP_p 2
|
#define MP_p 2
|
||||||
#define MP_hash PearlHashSHA256
|
#define MP_hash PearlHashSHA256
|
||||||
|
|
||||||
const uint8_t *mpw_masterKeyForUser(const char *fullName, const char *masterPassword) {
|
const uint8_t *mpw_masterKeyForUser(const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion) {
|
||||||
|
|
||||||
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
|
switch (algorithmVersion) {
|
||||||
trc( "fullName: %s\n", fullName );
|
case MPAlgorithmVersion0:
|
||||||
trc( "masterPassword: %s\n", masterPassword );
|
return mpw_masterKeyForUser_v0( fullName, masterPassword );
|
||||||
trc( "key scope: %s\n", mpKeyScope );
|
case MPAlgorithmVersion1:
|
||||||
|
return mpw_masterKeyForUser_v1( fullName, masterPassword );
|
||||||
// Calculate the master key salt.
|
case MPAlgorithmVersion2:
|
||||||
// masterKeySalt = mpKeyScope . #fullName . fullName
|
return mpw_masterKeyForUser_v2( fullName, masterPassword );
|
||||||
size_t masterKeySaltSize = 0;
|
case MPAlgorithmVersion3:
|
||||||
uint8_t *masterKeySalt = NULL;
|
return mpw_masterKeyForUser_v3( fullName, masterPassword );
|
||||||
mpw_pushString( &masterKeySalt, &masterKeySaltSize, mpKeyScope );
|
default:
|
||||||
mpw_pushInt( &masterKeySalt, &masterKeySaltSize, htonl( strlen( fullName ) ) );
|
ftl( "Unsupported version: %d", algorithmVersion );
|
||||||
mpw_pushString( &masterKeySalt, &masterKeySaltSize, fullName );
|
return NULL;
|
||||||
if (!masterKeySalt) {
|
|
||||||
ftl( "Could not allocate master key salt: %d\n", errno );
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
trc( "masterKeySalt ID: %s\n", mpw_idForBuf( masterKeySalt, masterKeySaltSize ) );
|
|
||||||
|
|
||||||
// Calculate the master key.
|
|
||||||
// masterKey = scrypt( masterPassword, masterKeySalt )
|
|
||||||
const uint8_t *masterKey = mpw_scrypt( MP_dkLen, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
|
|
||||||
mpw_free( masterKeySalt, masterKeySaltSize );
|
|
||||||
if (!masterKey) {
|
|
||||||
ftl( "Could not allocate master key: %d\n", errno );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trc( "masterKey ID: %s\n", mpw_idForBuf( masterKey, MP_dkLen ) );
|
|
||||||
|
|
||||||
return masterKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *mpw_passwordForSite(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
const char *mpw_passwordForSite(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
||||||
const MPSiteVariant siteVariant, const char *siteContext) {
|
const MPSiteVariant siteVariant, const char *siteContext, const MPAlgorithmVersion algorithmVersion) {
|
||||||
|
|
||||||
const char *siteScope = mpw_scopeForVariant( siteVariant );
|
switch (algorithmVersion) {
|
||||||
trc( "siteName: %s\n", siteName );
|
case MPAlgorithmVersion0:
|
||||||
trc( "siteCounter: %d\n", siteCounter );
|
return mpw_passwordForSite_v0( masterKey, siteName, siteType, siteCounter, siteVariant, siteContext );
|
||||||
trc( "siteVariant: %d\n", siteVariant );
|
case MPAlgorithmVersion1:
|
||||||
trc( "siteType: %d\n", siteType );
|
return mpw_passwordForSite_v1( masterKey, siteName, siteType, siteCounter, siteVariant, siteContext );
|
||||||
trc( "site scope: %s, context: %s\n", siteScope, siteContext == NULL? "<empty>": siteContext );
|
case MPAlgorithmVersion2:
|
||||||
|
return mpw_passwordForSite_v2( masterKey, siteName, siteType, siteCounter, siteVariant, siteContext );
|
||||||
// Calculate the site seed.
|
case MPAlgorithmVersion3:
|
||||||
// sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
|
return mpw_passwordForSite_v3( masterKey, siteName, siteType, siteCounter, siteVariant, siteContext );
|
||||||
size_t sitePasswordInfoSize = 0;
|
default:
|
||||||
uint8_t *sitePasswordInfo = NULL;
|
ftl( "Unsupported version: %d", algorithmVersion );
|
||||||
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
|
return NULL;
|
||||||
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteName ) ) );
|
|
||||||
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
|
|
||||||
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
|
|
||||||
if (siteContext) {
|
|
||||||
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteContext ) ) );
|
|
||||||
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
|
|
||||||
}
|
}
|
||||||
if (!sitePasswordInfo) {
|
|
||||||
ftl( "Could not allocate site seed info: %d\n", errno );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trc( "sitePasswordInfo ID: %s\n", mpw_idForBuf( sitePasswordInfo, sitePasswordInfoSize ) );
|
|
||||||
|
|
||||||
const uint8_t *sitePasswordSeed = mpw_hmac_sha256( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoSize );
|
|
||||||
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
|
|
||||||
if (!sitePasswordSeed) {
|
|
||||||
ftl( "Could not allocate site seed: %d\n", errno );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trc( "sitePasswordSeed ID: %s\n", mpw_idForBuf( sitePasswordSeed, 32 ) );
|
|
||||||
|
|
||||||
// Determine the template.
|
|
||||||
const char *template = mpw_templateForType( siteType, sitePasswordSeed[0] );
|
|
||||||
trc( "type %d, template: %s\n", siteType, template );
|
|
||||||
if (strlen( template ) > 32) {
|
|
||||||
ftl( "Template too long for password seed: %lu", strlen( template ) );
|
|
||||||
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode the password from the seed using the template.
|
|
||||||
char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
|
|
||||||
for (size_t c = 0; c < strlen( template ); ++c) {
|
|
||||||
sitePassword[c] = mpw_characterFromClass( template[c], sitePasswordSeed[c + 1] );
|
|
||||||
trc( "class %c, index %u (0x%02X) -> character: %c\n", template[c], sitePasswordSeed[c + 1], sitePasswordSeed[c + 1],
|
|
||||||
sitePassword[c] );
|
|
||||||
}
|
|
||||||
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
|
||||||
|
|
||||||
return sitePassword;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,27 @@
|
|||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define MP_dkLen 64
|
#include "mpw-types.h"
|
||||||
|
|
||||||
|
typedef enum(unsigned int, MPAlgorithmVersion) {
|
||||||
|
/** V0 did math with chars whose signedness was platform-dependent. */
|
||||||
|
MPAlgorithmVersion0,
|
||||||
|
/** V1 miscounted the byte-length of multi-byte site names. */
|
||||||
|
MPAlgorithmVersion1,
|
||||||
|
/** V2 miscounted the byte-length of multi-byte user names. */
|
||||||
|
MPAlgorithmVersion2,
|
||||||
|
/** V3 is the current version. */
|
||||||
|
MPAlgorithmVersion3,
|
||||||
|
};
|
||||||
|
#define MPAlgorithmVersionCurrent MPAlgorithmVersion3
|
||||||
|
|
||||||
/** Derive the master key for a user based on their name and master password.
|
/** Derive the master key for a user based on their name and master password.
|
||||||
* @return A new MP_dkLen-byte allocated buffer or NULL if an allocation error occurred. */
|
* @return A new MP_dkLen-byte allocated buffer or NULL if an allocation error occurred. */
|
||||||
const uint8_t *mpw_masterKeyForUser(
|
const uint8_t *mpw_masterKeyForUser(
|
||||||
const char *fullName, const char *masterPassword);
|
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion);
|
||||||
|
|
||||||
/** Encode a password for the site from the given master key and site parameters.
|
/** Encode a password for the site from the given master key and site parameters.
|
||||||
* @return A newly allocated string or NULL if an allocation error occurred. */
|
* @return A newly allocated string or NULL if an allocation error occurred. */
|
||||||
const char *mpw_passwordForSite(
|
const char *mpw_passwordForSite(
|
||||||
const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
||||||
const MPSiteVariant siteVariant, const char *siteContext);
|
const MPSiteVariant siteVariant, const char *siteContext, const MPAlgorithmVersion algorithmVersion);
|
||||||
|
|||||||
125
MasterPassword/C/mpw-algorithm_v0.c
Normal file
125
MasterPassword/C/mpw-algorithm_v0.c
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
//
|
||||||
|
// mpw-algorithm.c
|
||||||
|
// MasterPassword
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2014-12-20.
|
||||||
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "mpw-util.h"
|
||||||
|
|
||||||
|
#define MP_N 32768
|
||||||
|
#define MP_r 8
|
||||||
|
#define MP_p 2
|
||||||
|
#define MP_hash PearlHashSHA256
|
||||||
|
|
||||||
|
static const char *mpw_templateForType_v0(MPSiteType type, uint16_t seedByte) {
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
|
const char **templates = mpw_templatesForType( type, &count );
|
||||||
|
if (!count)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return templates[seedByte % count];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char mpw_characterFromClass_v0(char characterClass, uint16_t seedByte) {
|
||||||
|
|
||||||
|
const char *classCharacters = mpw_charactersInClass( characterClass );
|
||||||
|
return classCharacters[seedByte % strlen( classCharacters )];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t *mpw_masterKeyForUser_v0(const char *fullName, const char *masterPassword) {
|
||||||
|
|
||||||
|
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
|
||||||
|
trc( "fullName: %s\n", fullName );
|
||||||
|
trc( "masterPassword: %s\n", masterPassword );
|
||||||
|
trc( "key scope: %s\n", mpKeyScope );
|
||||||
|
|
||||||
|
// Calculate the master key salt.
|
||||||
|
// masterKeySalt = mpKeyScope . #fullName . fullName
|
||||||
|
size_t masterKeySaltSize = 0;
|
||||||
|
uint8_t *masterKeySalt = NULL;
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, mpKeyScope );
|
||||||
|
mpw_pushInt( &masterKeySalt, &masterKeySaltSize, htonl( mpw_charlen( fullName ) ) );
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, fullName );
|
||||||
|
if (!masterKeySalt) {
|
||||||
|
ftl( "Could not allocate master key salt: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKeySalt ID: %s\n", mpw_idForBuf( masterKeySalt, masterKeySaltSize ) );
|
||||||
|
|
||||||
|
// Calculate the master key.
|
||||||
|
// masterKey = scrypt( masterPassword, masterKeySalt )
|
||||||
|
const uint8_t *masterKey = mpw_scrypt( MP_dkLen, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
|
||||||
|
mpw_free( masterKeySalt, masterKeySaltSize );
|
||||||
|
if (!masterKey) {
|
||||||
|
ftl( "Could not allocate master key: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKey ID: %s\n", mpw_idForBuf( masterKey, MP_dkLen ) );
|
||||||
|
|
||||||
|
return masterKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mpw_passwordForSite_v0(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
||||||
|
const MPSiteVariant siteVariant, const char *siteContext) {
|
||||||
|
|
||||||
|
const char *siteScope = mpw_scopeForVariant( siteVariant );
|
||||||
|
trc( "siteName: %s\n", siteName );
|
||||||
|
trc( "siteCounter: %d\n", siteCounter );
|
||||||
|
trc( "siteVariant: %d\n", siteVariant );
|
||||||
|
trc( "siteType: %d\n", siteType );
|
||||||
|
trc( "site scope: %s, context: %s\n", siteScope, siteContext == NULL? "<empty>": siteContext );
|
||||||
|
|
||||||
|
// Calculate the site seed.
|
||||||
|
// sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
|
||||||
|
size_t sitePasswordInfoSize = 0;
|
||||||
|
uint8_t *sitePasswordInfo = NULL;
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_charlen( siteName ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
|
||||||
|
if (siteContext) {
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_charlen( siteContext ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
|
||||||
|
}
|
||||||
|
if (!sitePasswordInfo) {
|
||||||
|
ftl( "Could not allocate site seed info: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordInfo ID: %s\n", mpw_idForBuf( sitePasswordInfo, sitePasswordInfoSize ) );
|
||||||
|
|
||||||
|
const char *sitePasswordSeed = (const char *)mpw_hmac_sha256( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
if (!sitePasswordSeed) {
|
||||||
|
ftl( "Could not allocate site seed: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordSeed ID: %s\n", mpw_idForBuf( sitePasswordSeed, 32 ) );
|
||||||
|
|
||||||
|
// Determine the template.
|
||||||
|
const char *template = mpw_templateForType_v0( siteType, htons( sitePasswordSeed[0] ) );
|
||||||
|
trc( "type %d, template: %s\n", siteType, template );
|
||||||
|
if (strlen( template ) > 32) {
|
||||||
|
ftl( "Template too long for password seed: %lu", strlen( template ) );
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode the password from the seed using the template.
|
||||||
|
char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
|
||||||
|
for (size_t c = 0; c < strlen( template ); ++c) {
|
||||||
|
sitePassword[c] = mpw_characterFromClass_v0( template[c], htons( sitePasswordSeed[c + 1] ) );
|
||||||
|
trc( "class %c, index %u (0x%02X) -> character: %c\n",
|
||||||
|
template[c], htons( sitePasswordSeed[c + 1] ), htons( sitePasswordSeed[c + 1] ), sitePassword[c] );
|
||||||
|
}
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
|
||||||
|
return sitePassword;
|
||||||
|
}
|
||||||
109
MasterPassword/C/mpw-algorithm_v1.c
Normal file
109
MasterPassword/C/mpw-algorithm_v1.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
//
|
||||||
|
// mpw-algorithm.c
|
||||||
|
// MasterPassword
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2014-12-20.
|
||||||
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "mpw-util.h"
|
||||||
|
|
||||||
|
#define MP_N 32768
|
||||||
|
#define MP_r 8
|
||||||
|
#define MP_p 2
|
||||||
|
#define MP_hash PearlHashSHA256
|
||||||
|
|
||||||
|
static const uint8_t *mpw_masterKeyForUser_v1(const char *fullName, const char *masterPassword) {
|
||||||
|
|
||||||
|
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
|
||||||
|
trc( "fullName: %s\n", fullName );
|
||||||
|
trc( "masterPassword: %s\n", masterPassword );
|
||||||
|
trc( "key scope: %s\n", mpKeyScope );
|
||||||
|
|
||||||
|
// Calculate the master key salt.
|
||||||
|
// masterKeySalt = mpKeyScope . #fullName . fullName
|
||||||
|
size_t masterKeySaltSize = 0;
|
||||||
|
uint8_t *masterKeySalt = NULL;
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, mpKeyScope );
|
||||||
|
mpw_pushInt( &masterKeySalt, &masterKeySaltSize, htonl( mpw_charlen( fullName ) ) );
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, fullName );
|
||||||
|
if (!masterKeySalt) {
|
||||||
|
ftl( "Could not allocate master key salt: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKeySalt ID: %s\n", mpw_idForBuf( masterKeySalt, masterKeySaltSize ) );
|
||||||
|
|
||||||
|
// Calculate the master key.
|
||||||
|
// masterKey = scrypt( masterPassword, masterKeySalt )
|
||||||
|
const uint8_t *masterKey = mpw_scrypt( MP_dkLen, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
|
||||||
|
mpw_free( masterKeySalt, masterKeySaltSize );
|
||||||
|
if (!masterKey) {
|
||||||
|
ftl( "Could not allocate master key: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKey ID: %s\n", mpw_idForBuf( masterKey, MP_dkLen ) );
|
||||||
|
|
||||||
|
return masterKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mpw_passwordForSite_v1(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
||||||
|
const MPSiteVariant siteVariant, const char *siteContext) {
|
||||||
|
|
||||||
|
const char *siteScope = mpw_scopeForVariant( siteVariant );
|
||||||
|
trc( "siteName: %s\n", siteName );
|
||||||
|
trc( "siteCounter: %d\n", siteCounter );
|
||||||
|
trc( "siteVariant: %d\n", siteVariant );
|
||||||
|
trc( "siteType: %d\n", siteType );
|
||||||
|
trc( "site scope: %s, context: %s\n", siteScope, siteContext == NULL? "<empty>": siteContext );
|
||||||
|
|
||||||
|
// Calculate the site seed.
|
||||||
|
// sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
|
||||||
|
size_t sitePasswordInfoSize = 0;
|
||||||
|
uint8_t *sitePasswordInfo = NULL;
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_charlen( siteName ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
|
||||||
|
if (siteContext) {
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_charlen( siteContext ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
|
||||||
|
}
|
||||||
|
if (!sitePasswordInfo) {
|
||||||
|
ftl( "Could not allocate site seed info: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordInfo ID: %s\n", mpw_idForBuf( sitePasswordInfo, sitePasswordInfoSize ) );
|
||||||
|
|
||||||
|
const uint8_t *sitePasswordSeed = mpw_hmac_sha256( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
if (!sitePasswordSeed) {
|
||||||
|
ftl( "Could not allocate site seed: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordSeed ID: %s\n", mpw_idForBuf( sitePasswordSeed, 32 ) );
|
||||||
|
|
||||||
|
// Determine the template.
|
||||||
|
const char *template = mpw_templateForType( siteType, sitePasswordSeed[0] );
|
||||||
|
trc( "type %d, template: %s\n", siteType, template );
|
||||||
|
if (strlen( template ) > 32) {
|
||||||
|
ftl( "Template too long for password seed: %lu", strlen( template ) );
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode the password from the seed using the template.
|
||||||
|
char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
|
||||||
|
for (size_t c = 0; c < strlen( template ); ++c) {
|
||||||
|
sitePassword[c] = mpw_characterFromClass( template[c], sitePasswordSeed[c + 1] );
|
||||||
|
trc( "class %c, index %u (0x%02X) -> character: %c\n", template[c], sitePasswordSeed[c + 1], sitePasswordSeed[c + 1],
|
||||||
|
sitePassword[c] );
|
||||||
|
}
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
|
||||||
|
return sitePassword;
|
||||||
|
}
|
||||||
109
MasterPassword/C/mpw-algorithm_v2.c
Normal file
109
MasterPassword/C/mpw-algorithm_v2.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
//
|
||||||
|
// mpw-algorithm.c
|
||||||
|
// MasterPassword
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2014-12-20.
|
||||||
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "mpw-util.h"
|
||||||
|
|
||||||
|
#define MP_N 32768
|
||||||
|
#define MP_r 8
|
||||||
|
#define MP_p 2
|
||||||
|
#define MP_hash PearlHashSHA256
|
||||||
|
|
||||||
|
static const uint8_t *mpw_masterKeyForUser_v2(const char *fullName, const char *masterPassword) {
|
||||||
|
|
||||||
|
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
|
||||||
|
trc( "fullName: %s\n", fullName );
|
||||||
|
trc( "masterPassword: %s\n", masterPassword );
|
||||||
|
trc( "key scope: %s\n", mpKeyScope );
|
||||||
|
|
||||||
|
// Calculate the master key salt.
|
||||||
|
// masterKeySalt = mpKeyScope . #fullName . fullName
|
||||||
|
size_t masterKeySaltSize = 0;
|
||||||
|
uint8_t *masterKeySalt = NULL;
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, mpKeyScope );
|
||||||
|
mpw_pushInt( &masterKeySalt, &masterKeySaltSize, htonl( mpw_charlen( fullName ) ) );
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, fullName );
|
||||||
|
if (!masterKeySalt) {
|
||||||
|
ftl( "Could not allocate master key salt: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKeySalt ID: %s\n", mpw_idForBuf( masterKeySalt, masterKeySaltSize ) );
|
||||||
|
|
||||||
|
// Calculate the master key.
|
||||||
|
// masterKey = scrypt( masterPassword, masterKeySalt )
|
||||||
|
const uint8_t *masterKey = mpw_scrypt( MP_dkLen, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
|
||||||
|
mpw_free( masterKeySalt, masterKeySaltSize );
|
||||||
|
if (!masterKey) {
|
||||||
|
ftl( "Could not allocate master key: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKey ID: %s\n", mpw_idForBuf( masterKey, MP_dkLen ) );
|
||||||
|
|
||||||
|
return masterKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mpw_passwordForSite_v2(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
||||||
|
const MPSiteVariant siteVariant, const char *siteContext) {
|
||||||
|
|
||||||
|
const char *siteScope = mpw_scopeForVariant( siteVariant );
|
||||||
|
trc( "siteName: %s\n", siteName );
|
||||||
|
trc( "siteCounter: %d\n", siteCounter );
|
||||||
|
trc( "siteVariant: %d\n", siteVariant );
|
||||||
|
trc( "siteType: %d\n", siteType );
|
||||||
|
trc( "site scope: %s, context: %s\n", siteScope, siteContext == NULL? "<empty>": siteContext );
|
||||||
|
|
||||||
|
// Calculate the site seed.
|
||||||
|
// sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
|
||||||
|
size_t sitePasswordInfoSize = 0;
|
||||||
|
uint8_t *sitePasswordInfo = NULL;
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteName ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
|
||||||
|
if (siteContext) {
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteContext ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
|
||||||
|
}
|
||||||
|
if (!sitePasswordInfo) {
|
||||||
|
ftl( "Could not allocate site seed info: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordInfo ID: %s\n", mpw_idForBuf( sitePasswordInfo, sitePasswordInfoSize ) );
|
||||||
|
|
||||||
|
const uint8_t *sitePasswordSeed = mpw_hmac_sha256( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
if (!sitePasswordSeed) {
|
||||||
|
ftl( "Could not allocate site seed: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordSeed ID: %s\n", mpw_idForBuf( sitePasswordSeed, 32 ) );
|
||||||
|
|
||||||
|
// Determine the template.
|
||||||
|
const char *template = mpw_templateForType( siteType, sitePasswordSeed[0] );
|
||||||
|
trc( "type %d, template: %s\n", siteType, template );
|
||||||
|
if (strlen( template ) > 32) {
|
||||||
|
ftl( "Template too long for password seed: %lu", strlen( template ) );
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode the password from the seed using the template.
|
||||||
|
char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
|
||||||
|
for (size_t c = 0; c < strlen( template ); ++c) {
|
||||||
|
sitePassword[c] = mpw_characterFromClass( template[c], sitePasswordSeed[c + 1] );
|
||||||
|
trc( "class %c, index %u (0x%02X) -> character: %c\n", template[c], sitePasswordSeed[c + 1], sitePasswordSeed[c + 1],
|
||||||
|
sitePassword[c] );
|
||||||
|
}
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
|
||||||
|
return sitePassword;
|
||||||
|
}
|
||||||
109
MasterPassword/C/mpw-algorithm_v3.c
Normal file
109
MasterPassword/C/mpw-algorithm_v3.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
//
|
||||||
|
// mpw-algorithm.c
|
||||||
|
// MasterPassword
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2014-12-20.
|
||||||
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "mpw-util.h"
|
||||||
|
|
||||||
|
#define MP_N 32768
|
||||||
|
#define MP_r 8
|
||||||
|
#define MP_p 2
|
||||||
|
#define MP_hash PearlHashSHA256
|
||||||
|
|
||||||
|
static const uint8_t *mpw_masterKeyForUser_v3(const char *fullName, const char *masterPassword) {
|
||||||
|
|
||||||
|
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
|
||||||
|
trc( "fullName: %s\n", fullName );
|
||||||
|
trc( "masterPassword: %s\n", masterPassword );
|
||||||
|
trc( "key scope: %s\n", mpKeyScope );
|
||||||
|
|
||||||
|
// Calculate the master key salt.
|
||||||
|
// masterKeySalt = mpKeyScope . #fullName . fullName
|
||||||
|
size_t masterKeySaltSize = 0;
|
||||||
|
uint8_t *masterKeySalt = NULL;
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, mpKeyScope );
|
||||||
|
mpw_pushInt( &masterKeySalt, &masterKeySaltSize, htonl( strlen( fullName ) ) );
|
||||||
|
mpw_pushString( &masterKeySalt, &masterKeySaltSize, fullName );
|
||||||
|
if (!masterKeySalt) {
|
||||||
|
ftl( "Could not allocate master key salt: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKeySalt ID: %s\n", mpw_idForBuf( masterKeySalt, masterKeySaltSize ) );
|
||||||
|
|
||||||
|
// Calculate the master key.
|
||||||
|
// masterKey = scrypt( masterPassword, masterKeySalt )
|
||||||
|
const uint8_t *masterKey = mpw_scrypt( MP_dkLen, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p );
|
||||||
|
mpw_free( masterKeySalt, masterKeySaltSize );
|
||||||
|
if (!masterKey) {
|
||||||
|
ftl( "Could not allocate master key: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "masterKey ID: %s\n", mpw_idForBuf( masterKey, MP_dkLen ) );
|
||||||
|
|
||||||
|
return masterKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *mpw_passwordForSite_v3(const uint8_t *masterKey, const char *siteName, const MPSiteType siteType, const uint32_t siteCounter,
|
||||||
|
const MPSiteVariant siteVariant, const char *siteContext) {
|
||||||
|
|
||||||
|
const char *siteScope = mpw_scopeForVariant( siteVariant );
|
||||||
|
trc( "siteName: %s\n", siteName );
|
||||||
|
trc( "siteCounter: %d\n", siteCounter );
|
||||||
|
trc( "siteVariant: %d\n", siteVariant );
|
||||||
|
trc( "siteType: %d\n", siteType );
|
||||||
|
trc( "site scope: %s, context: %s\n", siteScope, siteContext == NULL? "<empty>": siteContext );
|
||||||
|
|
||||||
|
// Calculate the site seed.
|
||||||
|
// sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
|
||||||
|
size_t sitePasswordInfoSize = 0;
|
||||||
|
uint8_t *sitePasswordInfo = NULL;
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteName ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
|
||||||
|
if (siteContext) {
|
||||||
|
mpw_pushInt( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteContext ) ) );
|
||||||
|
mpw_pushString( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
|
||||||
|
}
|
||||||
|
if (!sitePasswordInfo) {
|
||||||
|
ftl( "Could not allocate site seed info: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordInfo ID: %s\n", mpw_idForBuf( sitePasswordInfo, sitePasswordInfoSize ) );
|
||||||
|
|
||||||
|
const uint8_t *sitePasswordSeed = mpw_hmac_sha256( masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
|
||||||
|
if (!sitePasswordSeed) {
|
||||||
|
ftl( "Could not allocate site seed: %d\n", errno );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
trc( "sitePasswordSeed ID: %s\n", mpw_idForBuf( sitePasswordSeed, 32 ) );
|
||||||
|
|
||||||
|
// Determine the template.
|
||||||
|
const char *template = mpw_templateForType( siteType, sitePasswordSeed[0] );
|
||||||
|
trc( "type %d, template: %s\n", siteType, template );
|
||||||
|
if (strlen( template ) > 32) {
|
||||||
|
ftl( "Template too long for password seed: %lu", strlen( template ) );
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode the password from the seed using the template.
|
||||||
|
char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) );
|
||||||
|
for (size_t c = 0; c < strlen( template ); ++c) {
|
||||||
|
sitePassword[c] = mpw_characterFromClass( template[c], sitePasswordSeed[c + 1] );
|
||||||
|
trc( "class %c, index %u (0x%02X) -> character: %c\n", template[c], sitePasswordSeed[c + 1], sitePasswordSeed[c + 1],
|
||||||
|
sitePassword[c] );
|
||||||
|
}
|
||||||
|
mpw_free( sitePasswordSeed, sizeof( sitePasswordSeed ) );
|
||||||
|
|
||||||
|
return sitePassword;
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <scrypt/sha256.h>
|
#include <scrypt/sha256.h>
|
||||||
#include <bcrypt/ow-crypt.h>
|
#include <bcrypt/ow-crypt.h>
|
||||||
|
|
||||||
#include "mpw-types.h"
|
|
||||||
#include "mpw-algorithm.h"
|
#include "mpw-algorithm.h"
|
||||||
#include "mpw-util.h"
|
#include "mpw-util.h"
|
||||||
|
|
||||||
@@ -62,10 +61,12 @@ int main(int argc, char *const argv[]) {
|
|||||||
unsigned int iterations = 100;
|
unsigned int iterations = 100;
|
||||||
mpw_getTime( &startTime );
|
mpw_getTime( &startTime );
|
||||||
for (int i = 0; i < iterations; ++i) {
|
for (int i = 0; i < iterations; ++i) {
|
||||||
const uint8_t *masterKey = mpw_masterKeyForUser( fullName, masterPassword );
|
const uint8_t *masterKey = mpw_masterKeyForUser(
|
||||||
|
fullName, masterPassword, MPAlgorithmVersionCurrent );
|
||||||
if (!masterKey)
|
if (!masterKey)
|
||||||
ftl( "Could not allocate master key: %d\n", errno );
|
ftl( "Could not allocate master key: %d\n", errno );
|
||||||
free( (void *)mpw_passwordForSite( masterKey, siteName, siteType, siteCounter, siteVariant, siteContext ) );
|
free( (void *)mpw_passwordForSite(
|
||||||
|
masterKey, siteName, siteType, siteCounter, siteVariant, siteContext, MPAlgorithmVersionCurrent ) );
|
||||||
free( (void *)masterKey );
|
free( (void *)masterKey );
|
||||||
|
|
||||||
if (i % 1 == 0)
|
if (i % 1 == 0)
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
|
|
||||||
#define ftl(...) do { fprintf( stderr, __VA_ARGS__ ); exit(2); } while (0)
|
#define ftl(...) do { fprintf( stderr, __VA_ARGS__ ); exit(2); } while (0)
|
||||||
|
|
||||||
#include "mpw-types.h"
|
|
||||||
#include "mpw-algorithm.h"
|
#include "mpw-algorithm.h"
|
||||||
#include "mpw-util.h"
|
#include "mpw-util.h"
|
||||||
|
|
||||||
#define MP_env_fullname "MP_FULLNAME"
|
#define MP_env_fullname "MP_FULLNAME"
|
||||||
#define MP_env_sitetype "MP_SITETYPE"
|
#define MP_env_sitetype "MP_SITETYPE"
|
||||||
#define MP_env_sitecounter "MP_SITECOUNTER"
|
#define MP_env_sitecounter "MP_SITECOUNTER"
|
||||||
|
#define MP_env_algorithm "MP_ALGORITHM"
|
||||||
|
|
||||||
static void usage() {
|
static void usage() {
|
||||||
|
|
||||||
@@ -39,7 +39,9 @@ static void usage() {
|
|||||||
" n, name | 9 letter name.\n"
|
" n, name | 9 letter name.\n"
|
||||||
" p, phrase | 20 character sentence.\n\n", MP_env_sitetype );
|
" p, phrase | 20 character sentence.\n\n", MP_env_sitetype );
|
||||||
fprintf( stderr, " -c counter The value of the counter.\n"
|
fprintf( stderr, " -c counter The value of the counter.\n"
|
||||||
" Defaults to %s in env or '1'.\n\n", MP_env_sitecounter );
|
" Defaults to %s in env or 1.\n\n", MP_env_sitecounter );
|
||||||
|
fprintf( stderr, " -V version The algorithm version to use.\n"
|
||||||
|
" Defaults to %s in env or %d.\n\n", MP_env_algorithm, MPAlgorithmVersionCurrent );
|
||||||
fprintf( stderr, " -v variant The kind of content to generate.\n"
|
fprintf( stderr, " -v variant The kind of content to generate.\n"
|
||||||
" Defaults to 'password'.\n"
|
" Defaults to 'password'.\n"
|
||||||
" p, password | The password to log in with.\n"
|
" p, password | The password to log in with.\n"
|
||||||
@@ -102,13 +104,23 @@ int main(int argc, char *const argv[]) {
|
|||||||
const char *siteContextString = NULL;
|
const char *siteContextString = NULL;
|
||||||
uint32_t siteCounter = 1;
|
uint32_t siteCounter = 1;
|
||||||
const char *siteCounterString = getenv( MP_env_sitecounter );
|
const char *siteCounterString = getenv( MP_env_sitecounter );
|
||||||
|
MPAlgorithmVersion algorithmVersion = MPAlgorithmVersionCurrent;
|
||||||
|
const char *algorithmVersionString = getenv( MP_env_algorithm );
|
||||||
|
if (algorithmVersionString && strlen( algorithmVersionString ))
|
||||||
|
if (sscanf( algorithmVersionString, "%u", &algorithmVersion ) != 1)
|
||||||
|
ftl( "Invalid %s: %s\n", MP_env_algorithm, algorithmVersionString );
|
||||||
|
|
||||||
// Read the options.
|
// Read the options.
|
||||||
for (int opt; (opt = getopt( argc, argv, "u:t:c:v:C:h" )) != -1;)
|
for (int opt; (opt = getopt( argc, argv, "u:P:t:c:v:V:C:h" )) != -1;)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'u':
|
case 'u':
|
||||||
fullName = optarg;
|
fullName = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
// Do not use this. Passing your master password via the command-line
|
||||||
|
// is insecure. This is here for non-interactive testing purposes only.
|
||||||
|
masterPassword = strcpy( malloc( strlen( optarg ) + 1 ), optarg );
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
siteTypeString = optarg;
|
siteTypeString = optarg;
|
||||||
break;
|
break;
|
||||||
@@ -118,6 +130,10 @@ int main(int argc, char *const argv[]) {
|
|||||||
case 'v':
|
case 'v':
|
||||||
siteVariantString = optarg;
|
siteVariantString = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'V':
|
||||||
|
if (sscanf( optarg, "%u", &algorithmVersion ) != 1)
|
||||||
|
ftl( "Not a version: %s\n", optarg );
|
||||||
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
siteContextString = optarg;
|
siteContextString = optarg;
|
||||||
break;
|
break;
|
||||||
@@ -161,6 +177,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
siteType = MPSiteTypeGeneratedPhrase;
|
siteType = MPSiteTypeGeneratedPhrase;
|
||||||
if (siteTypeString)
|
if (siteTypeString)
|
||||||
siteType = mpw_typeWithName( siteTypeString );
|
siteType = mpw_typeWithName( siteTypeString );
|
||||||
|
trc( "algorithmVersion: %u\n", algorithmVersion );
|
||||||
|
|
||||||
// Read the master password.
|
// Read the master password.
|
||||||
char *mpwConfigPath = homedir( ".mpw" );
|
char *mpwConfigPath = homedir( ".mpw" );
|
||||||
@@ -188,12 +205,14 @@ int main(int argc, char *const argv[]) {
|
|||||||
fprintf( stderr, "%s's password for %s:\n[ %s ]: ", fullName, siteName, mpw_identicon( fullName, masterPassword ) );
|
fprintf( stderr, "%s's password for %s:\n[ %s ]: ", fullName, siteName, mpw_identicon( fullName, masterPassword ) );
|
||||||
|
|
||||||
// Output the password.
|
// Output the password.
|
||||||
const uint8_t *masterKey = mpw_masterKeyForUser( fullName, masterPassword );
|
const uint8_t *masterKey = mpw_masterKeyForUser(
|
||||||
|
fullName, masterPassword, algorithmVersion );
|
||||||
mpw_freeString( masterPassword );
|
mpw_freeString( masterPassword );
|
||||||
if (!masterKey)
|
if (!masterKey)
|
||||||
ftl( "Couldn't derive master key." );
|
ftl( "Couldn't derive master key." );
|
||||||
|
|
||||||
const char *sitePassword = mpw_passwordForSite( masterKey, siteName, siteType, siteCounter, siteVariant, siteContextString );
|
const char *sitePassword = mpw_passwordForSite(
|
||||||
|
masterKey, siteName, siteType, siteCounter, siteVariant, siteContextString, algorithmVersion );
|
||||||
mpw_free( masterKey, MP_dkLen );
|
mpw_free( masterKey, MP_dkLen );
|
||||||
if (!sitePassword)
|
if (!sitePassword)
|
||||||
ftl( "Couldn't derive site password." );
|
ftl( "Couldn't derive site password." );
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#define ftl(...) do { fprintf( stderr, __VA_ARGS__ ); exit(2); } while (0)
|
#define ftl(...) do { fprintf( stderr, __VA_ARGS__ ); exit(2); } while (0)
|
||||||
|
|
||||||
#include "mpw-types.h"
|
|
||||||
#include "mpw-algorithm.h"
|
#include "mpw-algorithm.h"
|
||||||
#include "mpw-util.h"
|
#include "mpw-util.h"
|
||||||
|
|
||||||
@@ -40,13 +39,13 @@ int main(int argc, char *const argv[]) {
|
|||||||
|
|
||||||
// 1. calculate the master key.
|
// 1. calculate the master key.
|
||||||
const uint8_t *masterKey = mpw_masterKeyForUser(
|
const uint8_t *masterKey = mpw_masterKeyForUser(
|
||||||
(char *)fullName, (char *)masterPassword );
|
(char *)fullName, (char *)masterPassword, MPAlgorithmVersionCurrent );
|
||||||
if (!masterKey)
|
if (!masterKey)
|
||||||
ftl( "Couldn't derive master key." );
|
ftl( "Couldn't derive master key." );
|
||||||
|
|
||||||
// 2. calculate the site password.
|
// 2. calculate the site password.
|
||||||
const char *sitePassword = mpw_passwordForSite(
|
const char *sitePassword = mpw_passwordForSite(
|
||||||
masterKey, (char *)siteName, siteType, siteCounter, siteVariant, (char *)siteContext );
|
masterKey, (char *)siteName, siteType, siteCounter, siteVariant, (char *)siteContext, MPAlgorithmVersionCurrent );
|
||||||
mpw_free( masterKey, MP_dkLen );
|
mpw_free( masterKey, MP_dkLen );
|
||||||
if (!sitePassword)
|
if (!sitePassword)
|
||||||
ftl( "Couldn't derive site password." );
|
ftl( "Couldn't derive site password." );
|
||||||
|
|||||||
@@ -51,56 +51,71 @@ const MPSiteType mpw_typeWithName(const char *typeName) {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *mpw_templateForType(MPSiteType type, uint8_t seedByte) {
|
inline const char **mpw_templatesForType(MPSiteType type, size_t *count) {
|
||||||
|
|
||||||
if (!(type & MPSiteTypeClassGenerated)) {
|
if (!(type & MPSiteTypeClassGenerated)) {
|
||||||
fprintf( stderr, "Not a generated type: %d", type );
|
ftl( "Not a generated type: %d", type );
|
||||||
abort();
|
*count = 0;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MPSiteTypeGeneratedMaximum: {
|
case MPSiteTypeGeneratedMaximum: {
|
||||||
const char *templates[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
|
*count = 2;
|
||||||
return templates[seedByte % 2];
|
return (const char *[]){ "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedLong: {
|
case MPSiteTypeGeneratedLong: {
|
||||||
const char *templates[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno",
|
*count = 21;
|
||||||
|
return (const char *[]){ "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno",
|
||||||
"CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno",
|
"CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno",
|
||||||
"CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno",
|
"CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno",
|
||||||
"CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno",
|
"CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno",
|
||||||
"CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno",
|
"CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno",
|
||||||
"CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno",
|
"CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno",
|
||||||
"CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
|
"CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
|
||||||
return templates[seedByte % 21];
|
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedMedium: {
|
case MPSiteTypeGeneratedMedium: {
|
||||||
const char *templates[] = { "CvcnoCvc", "CvcCvcno" };
|
*count = 2;
|
||||||
return templates[seedByte % 2];
|
return (const char *[]){ "CvcnoCvc", "CvcCvcno" };
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedBasic: {
|
case MPSiteTypeGeneratedBasic: {
|
||||||
const char *templates[] = { "aaanaaan", "aannaaan", "aaannaaa" };
|
*count = 3;
|
||||||
return templates[seedByte % 3];
|
return (const char *[]){ "aaanaaan", "aannaaan", "aaannaaa" };
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedShort: {
|
case MPSiteTypeGeneratedShort: {
|
||||||
return "Cvcn";
|
*count = 1;
|
||||||
|
return (const char *[]){"Cvcn"};
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedPIN: {
|
case MPSiteTypeGeneratedPIN: {
|
||||||
return "nnnn";
|
*count = 1;
|
||||||
|
return (const char *[]){ "nnnn" };
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedName: {
|
case MPSiteTypeGeneratedName: {
|
||||||
return "cvccvcvcv";
|
*count = 1;
|
||||||
|
return (const char *[]) {"cvccvcvcv"};
|
||||||
}
|
}
|
||||||
case MPSiteTypeGeneratedPhrase: {
|
case MPSiteTypeGeneratedPhrase: {
|
||||||
const char *templates[] = { "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
|
*count = 3;
|
||||||
return templates[seedByte % 3];
|
return (const char *[]){ "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
fprintf( stderr, "Unknown generated type: %d", type );
|
ftl( "Unknown generated type: %d", type );
|
||||||
abort();
|
*count = 0;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *mpw_templateForType(MPSiteType type, uint8_t seedByte) {
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
|
const char **templates = mpw_templatesForType( type, &count );
|
||||||
|
if (!count)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return templates[seedByte % count];
|
||||||
|
}
|
||||||
|
|
||||||
const MPSiteVariant mpw_variantWithName(const char *variantName) {
|
const MPSiteVariant mpw_variantWithName(const char *variantName) {
|
||||||
|
|
||||||
char stdVariantName[strlen( variantName )];
|
char stdVariantName[strlen( variantName )];
|
||||||
@@ -138,55 +153,38 @@ const char *mpw_scopeForVariant(MPSiteVariant variant) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char mpw_characterFromClass(char characterClass, uint8_t seedByte) {
|
const char *mpw_charactersInClass(char characterClass) {
|
||||||
|
|
||||||
const char *classCharacters;
|
|
||||||
switch (characterClass) {
|
switch (characterClass) {
|
||||||
case 'V': {
|
case 'V':
|
||||||
classCharacters = "AEIOU";
|
return "AEIOU";
|
||||||
break;
|
case 'C':
|
||||||
}
|
return "BCDFGHJKLMNPQRSTVWXYZ";
|
||||||
case 'C': {
|
case 'v':
|
||||||
classCharacters = "BCDFGHJKLMNPQRSTVWXYZ";
|
return "aeiou";
|
||||||
break;
|
case 'c':
|
||||||
}
|
return "bcdfghjklmnpqrstvwxyz";
|
||||||
case 'v': {
|
case 'A':
|
||||||
classCharacters = "aeiou";
|
return "AEIOUBCDFGHJKLMNPQRSTVWXYZ";
|
||||||
break;
|
case 'a':
|
||||||
}
|
return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";
|
||||||
case 'c': {
|
case 'n':
|
||||||
classCharacters = "bcdfghjklmnpqrstvwxyz";
|
return "0123456789";
|
||||||
break;
|
case 'o':
|
||||||
}
|
return "@&%?,=[]_:-+*$#!'^~;()/.";
|
||||||
case 'A': {
|
case 'x':
|
||||||
classCharacters = "AEIOUBCDFGHJKLMNPQRSTVWXYZ";
|
return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()";
|
||||||
break;
|
case ' ':
|
||||||
}
|
return " ";
|
||||||
case 'a': {
|
|
||||||
classCharacters = "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'n': {
|
|
||||||
classCharacters = "0123456789";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'o': {
|
|
||||||
classCharacters = "@&%?,=[]_:-+*$#!'^~;()/.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'x': {
|
|
||||||
classCharacters = "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ' ': {
|
|
||||||
classCharacters = " ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
fprintf( stderr, "Unknown character class: %c", characterClass );
|
fprintf( stderr, "Unknown character class: %c", characterClass );
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char mpw_characterFromClass(char characterClass, uint8_t seedByte) {
|
||||||
|
|
||||||
|
const char *classCharacters = mpw_charactersInClass( characterClass );
|
||||||
return classCharacters[seedByte % strlen( classCharacters )];
|
return classCharacters[seedByte % strlen( classCharacters )];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,32 +6,43 @@
|
|||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef NS_ENUM
|
||||||
|
#define enum(_type, _name) NS_ENUM(_type, _name)
|
||||||
|
#else
|
||||||
|
#define enum(_type, _name) _type _name; enum
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MP_dkLen 64
|
||||||
|
|
||||||
//// Types.
|
//// Types.
|
||||||
|
|
||||||
typedef enum {
|
typedef enum( unsigned int, MPSiteVariant ) {
|
||||||
/** Generate the password to log in with. */
|
/** Generate the password to log in with. */
|
||||||
MPSiteVariantPassword,
|
MPSiteVariantPassword,
|
||||||
/** Generate the login name to log in as. */
|
/** Generate the login name to log in as. */
|
||||||
MPSiteVariantLogin,
|
MPSiteVariantLogin,
|
||||||
/** Generate the answer to a security question. */
|
/** Generate the answer to a security question. */
|
||||||
MPSiteVariantAnswer,
|
MPSiteVariantAnswer,
|
||||||
} MPSiteVariant;
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum( unsigned int, MPSiteTypeClass ) {
|
||||||
/** Generate the password. */
|
/** Generate the password. */
|
||||||
MPSiteTypeClassGenerated = 1 << 4,
|
MPSiteTypeClassGenerated = 1 << 4,
|
||||||
/** Store the password. */
|
/** Store the password. */
|
||||||
MPSiteTypeClassStored = 1 << 5,
|
MPSiteTypeClassStored = 1 << 5,
|
||||||
} MPSiteTypeClass;
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum( unsigned int, MPSiteFeature ) {
|
||||||
/** Export the key-protected content data. */
|
/** Export the key-protected content data. */
|
||||||
MPSiteFeatureExportContent = 1 << 10,
|
MPSiteFeatureExportContent = 1 << 10,
|
||||||
/** Never export content. */
|
/** Never export content. */
|
||||||
MPSiteFeatureDevicePrivate = 1 << 11,
|
MPSiteFeatureDevicePrivate = 1 << 11,
|
||||||
} MPSiteFeature;
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum( unsigned int, MPSiteType) {
|
||||||
MPSiteTypeGeneratedMaximum = 0x0 | MPSiteTypeClassGenerated | 0x0,
|
MPSiteTypeGeneratedMaximum = 0x0 | MPSiteTypeClassGenerated | 0x0,
|
||||||
MPSiteTypeGeneratedLong = 0x1 | MPSiteTypeClassGenerated | 0x0,
|
MPSiteTypeGeneratedLong = 0x1 | MPSiteTypeClassGenerated | 0x0,
|
||||||
MPSiteTypeGeneratedMedium = 0x2 | MPSiteTypeClassGenerated | 0x0,
|
MPSiteTypeGeneratedMedium = 0x2 | MPSiteTypeClassGenerated | 0x0,
|
||||||
@@ -43,13 +54,42 @@ typedef enum {
|
|||||||
|
|
||||||
MPSiteTypeStoredPersonal = 0x0 | MPSiteTypeClassStored | MPSiteFeatureExportContent,
|
MPSiteTypeStoredPersonal = 0x0 | MPSiteTypeClassStored | MPSiteFeatureExportContent,
|
||||||
MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate,
|
MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate,
|
||||||
} MPSiteType;
|
};
|
||||||
|
|
||||||
//// Type utilities.
|
//// Type utilities.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The variant represented by the given name.
|
||||||
|
*/
|
||||||
const MPSiteVariant mpw_variantWithName(const char *variantName);
|
const MPSiteVariant mpw_variantWithName(const char *variantName);
|
||||||
|
/**
|
||||||
|
* @return An internal string containing the scope identifier to apply when encoding for the given variant.
|
||||||
|
*/
|
||||||
const char *mpw_scopeForVariant(MPSiteVariant variant);
|
const char *mpw_scopeForVariant(MPSiteVariant variant);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The type represented by the given name.
|
||||||
|
*/
|
||||||
const MPSiteType mpw_typeWithName(const char *typeName);
|
const MPSiteType mpw_typeWithName(const char *typeName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return An array of internal strings that express the templates to use for the given type.
|
||||||
|
* The amount of elements in the array is stored in count.
|
||||||
|
* If an unsupported type is given, count will be 0 and will return NULL.
|
||||||
|
*/
|
||||||
|
const char **mpw_templatesForType(MPSiteType type, size_t *count);
|
||||||
|
/**
|
||||||
|
* @return An internal string that contains the password encoding template of the given type
|
||||||
|
* for a seed that starts with the given byte.
|
||||||
|
*/
|
||||||
const char *mpw_templateForType(MPSiteType type, uint8_t seedByte);
|
const char *mpw_templateForType(MPSiteType type, uint8_t seedByte);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return An internal string that contains all the characters that occur in the given character class.
|
||||||
|
*/
|
||||||
|
const char *mpw_charactersInClass(char characterClass);
|
||||||
|
/**
|
||||||
|
* @return A character from given character class that encodes the given byte.
|
||||||
|
*/
|
||||||
const char mpw_characterFromClass(char characterClass, uint8_t seedByte);
|
const char mpw_characterFromClass(char characterClass, uint8_t seedByte);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#include <scrypt/sha256.h>
|
#include <scrypt/sha256.h>
|
||||||
#include <scrypt/crypto_scrypt.h>
|
#include <scrypt/crypto_scrypt.h>
|
||||||
@@ -163,3 +164,9 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword) {
|
|||||||
free( resetString );
|
free( resetString );
|
||||||
return identicon;
|
return identicon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t mpw_charlen(const char *string) {
|
||||||
|
|
||||||
|
setlocale( LC_ALL, "en_US.UTF-8" );
|
||||||
|
return mbstowcs( NULL, string, strlen( string ) );
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,10 +6,14 @@
|
|||||||
// Copyright (c) 2014 Lyndir. All rights reserved.
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
//// Logging.
|
//// Logging.
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
#ifndef trc
|
||||||
#define trc(...) fprintf( stderr, __VA_ARGS__ )
|
#define trc(...) fprintf( stderr, __VA_ARGS__ )
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define trc(...) do {} while (0)
|
#define trc(...) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
@@ -50,11 +54,15 @@ uint8_t const *mpw_hmac_sha256(
|
|||||||
//// Visualizers.
|
//// Visualizers.
|
||||||
|
|
||||||
/** Encode a buffer as a string of hexadecimal characters.
|
/** Encode a buffer as a string of hexadecimal characters.
|
||||||
* @return A reused buffer, do not free or store it. */
|
* @return A C-string in a reused buffer, do not free or store it. */
|
||||||
const char *mpw_hex(const void *buf, size_t length);
|
const char *mpw_hex(const void *buf, size_t length);
|
||||||
/** Encode a fingerprint for a buffer.
|
/** Encode a fingerprint for a buffer.
|
||||||
* @return A reused buffer, do not free or store it. */
|
* @return A C-string in a reused buffer, do not free or store it. */
|
||||||
const char *mpw_idForBuf(const void *buf, size_t length);
|
const char *mpw_idForBuf(const void *buf, size_t length);
|
||||||
/** Encode a visual fingerprint for a user.
|
/** Encode a visual fingerprint for a user.
|
||||||
* @return A newly allocated string. */
|
* @return A newly allocated string. */
|
||||||
const char *mpw_identicon(const char *fullName, const char *masterPassword);
|
const char *mpw_identicon(const char *fullName, const char *masterPassword);
|
||||||
|
|
||||||
|
//// String utilities.
|
||||||
|
|
||||||
|
const size_t mpw_charlen(const char *string);
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
package com.lyndir.masterpassword.model;
|
package com.lyndir.masterpassword.model;
|
||||||
|
|
||||||
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lhunath, 2014-08-20
|
* @author lhunath, 2014-08-20
|
||||||
*/
|
*/
|
||||||
public class User {
|
public class User {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Avatar avatar;
|
private Avatar avatar;
|
||||||
|
|
||||||
public User(final String name, final Avatar avatar) {
|
public User(final String name, final Avatar avatar) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -20,4 +25,19 @@ public class User {
|
|||||||
public Avatar getAvatar() {
|
public Avatar getAvatar() {
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
return this == obj || obj instanceof User && name.equals( ((User) obj).name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return strf( "{User: %s}", name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class AppleGUI extends GUI {
|
|||||||
@Override
|
@Override
|
||||||
protected PasswordFrame newPasswordFrame(final User user) {
|
protected PasswordFrame newPasswordFrame(final User user) {
|
||||||
PasswordFrame frame = super.newPasswordFrame( user );
|
PasswordFrame frame = super.newPasswordFrame( user );
|
||||||
frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
|
frame.setDefaultCloseOperation( WindowConstants.HIDE_ON_CLOSE );
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import com.google.common.base.Charsets;
|
|||||||
import com.google.common.io.*;
|
import com.google.common.io.*;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import com.lyndir.lhunath.opal.system.util.TypeUtils;
|
import com.lyndir.lhunath.opal.system.util.TypeUtils;
|
||||||
import com.lyndir.masterpassword.MasterKey;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@@ -117,9 +116,6 @@ public class GUI implements UnlockFrame.SignInCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected PasswordFrame newPasswordFrame(final User user) {
|
protected PasswordFrame newPasswordFrame(final User user) {
|
||||||
PasswordFrame frame = new PasswordFrame( user );
|
return new PasswordFrame( user );
|
||||||
frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,4 +48,9 @@ public class ModelSite extends Site {
|
|||||||
MPUserFileManager.get().save();
|
MPUserFileManager.get().save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void use() {
|
||||||
|
model.updateLastUsed();
|
||||||
|
MPUserFileManager.get().save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
|||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.FluentIterable;
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.lyndir.lhunath.opal.system.util.ObjectUtils;
|
||||||
import com.lyndir.masterpassword.MasterKey;
|
import com.lyndir.masterpassword.MasterKey;
|
||||||
import com.lyndir.masterpassword.model.*;
|
import com.lyndir.masterpassword.model.*;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -57,12 +58,21 @@ public class ModelUser extends User {
|
|||||||
if (!model.hasKeyID()) {
|
if (!model.hasKeyID()) {
|
||||||
model.setKeyID( key.getKeyID() );
|
model.setKeyID( key.getKeyID() );
|
||||||
MPUserFileManager.get().save();
|
MPUserFileManager.get().save();
|
||||||
} else if (!model.hasKeyID( key.getKeyID() ))
|
} else if (!model.hasKeyID( key.getKeyID() )) {
|
||||||
|
reset();
|
||||||
throw new MasterKeyException( strf( "Incorrect master password for user: %s", getFullName() ) );
|
throw new MasterKeyException( strf( "Incorrect master password for user: %s", getFullName() ) );
|
||||||
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
|
||||||
|
masterPassword = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Site> findSitesByName(final String query) {
|
public Iterable<Site> findSitesByName(final String query) {
|
||||||
return FluentIterable.from( model.findSitesByName( query ) ).transform( new Function<MPSiteResult, Site>() {
|
return FluentIterable.from( model.findSitesByName( query ) ).transform( new Function<MPSiteResult, Site>() {
|
||||||
@@ -76,7 +86,8 @@ public class ModelUser extends User {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addSite(final Site site) {
|
public void addSite(final Site site) {
|
||||||
model.addSite( new MPSite( site.getSiteName(), site.getSiteType(), site.getSiteCounter() ) );
|
model.addSite( new MPSite( model, site.getSiteName(), site.getSiteType(), site.getSiteCounter() ) );
|
||||||
|
model.updateLastUsed();
|
||||||
MPUserFileManager.get().save();
|
MPUserFileManager.get().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.util.concurrent.*;
|
import com.google.common.util.concurrent.*;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
|
||||||
import com.lyndir.masterpassword.*;
|
import com.lyndir.masterpassword.*;
|
||||||
import com.lyndir.masterpassword.util.Components;
|
import com.lyndir.masterpassword.util.Components;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -27,8 +26,11 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
private final JButton siteAddButton;
|
private final JButton siteAddButton;
|
||||||
private final JComboBox<MPSiteType> siteTypeField;
|
private final JComboBox<MPSiteType> siteTypeField;
|
||||||
private final JSpinner siteCounterField;
|
private final JSpinner siteCounterField;
|
||||||
private final JTextField passwordField;
|
private final JPasswordField passwordField;
|
||||||
private final JLabel tipLabel;
|
private final JLabel tipLabel;
|
||||||
|
private final JCheckBox maskPasswordField;
|
||||||
|
private final char passwordEchoChar;
|
||||||
|
private final Font passwordEchoFont;
|
||||||
private boolean updatingUI;
|
private boolean updatingUI;
|
||||||
private Site currentSite;
|
private Site currentSite;
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
|
|
||||||
JLabel label;
|
JLabel label;
|
||||||
|
|
||||||
|
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
|
||||||
setContentPane( new JPanel( new BorderLayout( 20, 20 ) ) {
|
setContentPane( new JPanel( new BorderLayout( 20, 20 ) ) {
|
||||||
{
|
{
|
||||||
setBorder( new EmptyBorder( 20, 20, 20, 20 ) );
|
setBorder( new EmptyBorder( 20, 20, 20, 20 ) );
|
||||||
@@ -104,10 +107,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
passwordField.setText( null );
|
passwordField.setText( null );
|
||||||
siteNameField.setText( null );
|
siteNameField.setText( null );
|
||||||
|
|
||||||
if (getDefaultCloseOperation() == WindowConstants.EXIT_ON_CLOSE)
|
dispatchEvent( new WindowEvent( PasswordFrame.this, WindowEvent.WINDOW_CLOSING ) );
|
||||||
System.exit( 0 );
|
|
||||||
else
|
|
||||||
dispose();
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@@ -153,19 +153,34 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
// Mask
|
||||||
|
maskPasswordField = new JCheckBox();
|
||||||
|
maskPasswordField.setFont( Res.exoRegular().deriveFont( 12f ) );
|
||||||
|
maskPasswordField.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
|
maskPasswordField.setText( "Hide Password" );
|
||||||
|
maskPasswordField.setSelected( true );
|
||||||
|
maskPasswordField.addItemListener( new ItemListener() {
|
||||||
|
@Override
|
||||||
|
public void itemStateChanged(ItemEvent e) {
|
||||||
|
updateMask();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
// Password
|
// Password
|
||||||
passwordField = new JTextField( " " );
|
passwordField = new JPasswordField();
|
||||||
passwordField.setFont( Res.sourceCodeProBlack().deriveFont( 40f ) );
|
|
||||||
passwordField.setHorizontalAlignment( JTextField.CENTER );
|
passwordField.setHorizontalAlignment( JTextField.CENTER );
|
||||||
passwordField.setAlignmentX( Component.CENTER_ALIGNMENT );
|
passwordField.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
passwordField.setEditable( false );
|
passwordField.setEditable( false );
|
||||||
|
passwordEchoChar = passwordField.getEchoChar();
|
||||||
|
passwordEchoFont = passwordField.getFont().deriveFont( 40f );
|
||||||
|
updateMask();
|
||||||
|
|
||||||
// Tip
|
// Tip
|
||||||
tipLabel = new JLabel( " ", JLabel.CENTER );
|
tipLabel = new JLabel( " ", JLabel.CENTER );
|
||||||
tipLabel.setFont( Res.exoRegular().deriveFont( 9f ) );
|
tipLabel.setFont( Res.exoRegular().deriveFont( 9f ) );
|
||||||
tipLabel.setAlignmentX( Component.CENTER_ALIGNMENT );
|
tipLabel.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
|
|
||||||
add( Components.boxLayout( BoxLayout.PAGE_AXIS, passwordField, tipLabel ), BorderLayout.SOUTH );
|
add( Components.boxLayout( BoxLayout.PAGE_AXIS, maskPasswordField, passwordField, tipLabel ), BorderLayout.SOUTH );
|
||||||
|
|
||||||
pack();
|
pack();
|
||||||
setMinimumSize( getSize() );
|
setMinimumSize( getSize() );
|
||||||
@@ -176,6 +191,11 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
setLocationRelativeTo( null );
|
setLocationRelativeTo( null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateMask() {
|
||||||
|
passwordField.setEchoChar( maskPasswordField.isSelected()? passwordEchoChar: (char) 0 );
|
||||||
|
passwordField.setFont( maskPasswordField.isSelected()? passwordEchoFont: Res.sourceCodeProBlack().deriveFont( 40f ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private ListenableFuture<String> updatePassword() {
|
private ListenableFuture<String> updatePassword() {
|
||||||
|
|
||||||
@@ -183,8 +203,8 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
if (updatingUI)
|
if (updatingUI)
|
||||||
return Futures.immediateCancelledFuture();
|
return Futures.immediateCancelledFuture();
|
||||||
if (siteNameQuery == null || siteNameQuery.isEmpty() || !user.hasKey()) {
|
if (siteNameQuery == null || siteNameQuery.isEmpty() || !user.hasKey()) {
|
||||||
passwordField.setText( null );
|
|
||||||
tipLabel.setText( null );
|
tipLabel.setText( null );
|
||||||
|
passwordField.setText( null );
|
||||||
return Futures.immediateCancelledFuture();
|
return Futures.immediateCancelledFuture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +218,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
site.setSiteCounter( siteCounter );
|
site.setSiteCounter( siteCounter );
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenableFuture<String> passwordFuture = Res.execute( new Callable<String>() {
|
ListenableFuture<String> passwordFuture = Res.execute( this, new Callable<String>() {
|
||||||
@Override
|
@Override
|
||||||
public String call()
|
public String call()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import com.google.common.io.Resources;
|
|||||||
import com.google.common.util.concurrent.*;
|
import com.google.common.util.concurrent.*;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
import java.awt.image.ImageObserver;
|
import java.awt.image.ImageObserver;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@@ -22,8 +24,8 @@ import javax.swing.*;
|
|||||||
*/
|
*/
|
||||||
public abstract class Res {
|
public abstract class Res {
|
||||||
|
|
||||||
private static final ExecutorService executor = Executors.newSingleThreadExecutor();
|
private static final WeakHashMap<Window, ExecutorService> executorByWindow = new WeakHashMap<>();
|
||||||
private static final Logger logger = Logger.get( Res.class );
|
private static final Logger logger = Logger.get( Res.class );
|
||||||
|
|
||||||
private static Font sourceCodeProRegular;
|
private static Font sourceCodeProRegular;
|
||||||
private static Font sourceCodeProBlack;
|
private static Font sourceCodeProBlack;
|
||||||
@@ -32,8 +34,8 @@ public abstract class Res {
|
|||||||
private static Font exoRegular;
|
private static Font exoRegular;
|
||||||
private static Font exoThin;
|
private static Font exoThin;
|
||||||
|
|
||||||
public static Future<?> execute(final Runnable job) {
|
public static Future<?> execute(final Window host, final Runnable job) {
|
||||||
return executor.submit( new Runnable() {
|
return getExecutor( host ).submit( new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@@ -46,7 +48,8 @@ public abstract class Res {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V> ListenableFuture<V> execute(final Callable<V> job) {
|
public static <V> ListenableFuture<V> execute(final Window host, final Callable<V> job) {
|
||||||
|
ExecutorService executor = getExecutor( host );
|
||||||
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
|
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
|
||||||
@Override
|
@Override
|
||||||
public V call()
|
public V call()
|
||||||
@@ -62,6 +65,25 @@ public abstract class Res {
|
|||||||
} ), executor );
|
} ), executor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ExecutorService getExecutor(final Window host) {
|
||||||
|
ExecutorService executor = executorByWindow.get( host );
|
||||||
|
|
||||||
|
if (executor == null) {
|
||||||
|
executorByWindow.put( host, executor = Executors.newSingleThreadExecutor() );
|
||||||
|
|
||||||
|
host.addWindowListener( new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosed(final WindowEvent e) {
|
||||||
|
ExecutorService executor = executorByWindow.remove( host );
|
||||||
|
if (executor != null)
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
public static Icon iconAdd() {
|
public static Icon iconAdd() {
|
||||||
return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) );
|
return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class UnlockFrame extends JFrame {
|
|||||||
signInButton.setEnabled( false );
|
signInButton.setEnabled( false );
|
||||||
signInButton.setText( "Signing In..." );
|
signInButton.setText( "Signing In..." );
|
||||||
|
|
||||||
Res.execute( new Runnable() {
|
Res.execute( this, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final boolean success = signInCallback.signedIn( user );
|
final boolean success = signInCallback.signedIn( user );
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package com.lyndir.masterpassword.gui;
|
|||||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
||||||
|
|
||||||
import com.lyndir.masterpassword.MasterKey;
|
import com.lyndir.masterpassword.MasterKey;
|
||||||
|
import com.lyndir.masterpassword.model.MPUser;
|
||||||
import java.security.KeyException;
|
import java.security.KeyException;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
|
||||||
@@ -30,25 +32,38 @@ public abstract class User {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public MasterKey getKey() throws MasterKeyException {
|
public MasterKey getKey() throws MasterKeyException {
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
if (!hasKey())
|
String masterPassword = getMasterPassword();
|
||||||
|
if (masterPassword == null || masterPassword.isEmpty()) {
|
||||||
|
reset();
|
||||||
throw new MasterKeyException( strf( "Master password unknown for user: %s", getFullName() ) );
|
throw new MasterKeyException( strf( "Master password unknown for user: %s", getFullName() ) );
|
||||||
key = new MasterKey( getFullName(), getMasterPassword() );
|
}
|
||||||
|
|
||||||
|
key = new MasterKey( getFullName(), masterPassword );
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
key = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Iterable<Site> findSitesByName(final String siteName);
|
||||||
|
|
||||||
|
public abstract void addSite(final Site site);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
return this == obj || obj instanceof User && Objects.equals( getFullName(), ((User) obj).getFullName() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return getFullName().hashCode();
|
return Objects.hashCode( getFullName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getFullName();
|
return getFullName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Iterable<Site> findSitesByName(final String siteName);
|
|
||||||
|
|
||||||
public abstract void addSite(final Site site);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,13 @@
|
|||||||
<version>GIT-SNAPSHOT</version>
|
<version>GIT-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.auto.value</groupId>
|
||||||
|
<artifactId>auto-value</artifactId>
|
||||||
|
<version>1.0-rc1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- TESTING -->
|
<!-- TESTING -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.testng</groupId>
|
<groupId>org.testng</groupId>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse;
|
|||||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||||
|
|
||||||
import com.lyndir.masterpassword.*;
|
import com.lyndir.masterpassword.*;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.Instant;
|
import org.joda.time.Instant;
|
||||||
@@ -17,7 +18,8 @@ public class MPSite {
|
|||||||
public static final MPSiteType DEFAULT_TYPE = MPSiteType.GeneratedLong;
|
public static final MPSiteType DEFAULT_TYPE = MPSiteType.GeneratedLong;
|
||||||
public static final int DEFAULT_COUNTER = 1;
|
public static final int DEFAULT_COUNTER = 1;
|
||||||
|
|
||||||
private int mpVersion;
|
private final MPUser user;
|
||||||
|
private int mpVersion;
|
||||||
private Instant lastUsed;
|
private Instant lastUsed;
|
||||||
private String siteName;
|
private String siteName;
|
||||||
private MPSiteType siteType;
|
private MPSiteType siteType;
|
||||||
@@ -25,11 +27,12 @@ public class MPSite {
|
|||||||
private int uses;
|
private int uses;
|
||||||
private String loginName;
|
private String loginName;
|
||||||
|
|
||||||
public MPSite(final String siteName) {
|
public MPSite(final MPUser user, final String siteName) {
|
||||||
this( siteName, DEFAULT_TYPE, DEFAULT_COUNTER );
|
this( user, siteName, DEFAULT_TYPE, DEFAULT_COUNTER );
|
||||||
}
|
}
|
||||||
|
|
||||||
public MPSite(final String siteName, final MPSiteType siteType, final int siteCounter) {
|
public MPSite(final MPUser user, final String siteName, final MPSiteType siteType, final int siteCounter) {
|
||||||
|
this.user = user;
|
||||||
this.mpVersion = MasterKey.ALGORITHM;
|
this.mpVersion = MasterKey.ALGORITHM;
|
||||||
this.lastUsed = new Instant();
|
this.lastUsed = new Instant();
|
||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
@@ -37,8 +40,9 @@ public class MPSite {
|
|||||||
this.siteCounter = siteCounter;
|
this.siteCounter = siteCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MPSite(final int mpVersion, final Instant lastUsed, final String siteName, final MPSiteType siteType, final int siteCounter,
|
protected MPSite(final MPUser user, final int mpVersion, final Instant lastUsed, final String siteName, final MPSiteType siteType, final int siteCounter,
|
||||||
final int uses, final String loginName, final String importContent) {
|
final int uses, final String loginName, final String importContent) {
|
||||||
|
this.user = user;
|
||||||
this.mpVersion = mpVersion;
|
this.mpVersion = mpVersion;
|
||||||
this.lastUsed = lastUsed;
|
this.lastUsed = lastUsed;
|
||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
@@ -56,6 +60,10 @@ public class MPSite {
|
|||||||
return masterKey.encode( siteName, siteType, siteCounter, variant, context );
|
return masterKey.encode( siteName, siteType, siteCounter, variant, context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MPUser getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected String exportContent() {
|
protected String exportContent() {
|
||||||
return null;
|
return null;
|
||||||
@@ -73,8 +81,9 @@ public class MPSite {
|
|||||||
return lastUsed;
|
return lastUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastUsed(final Instant lastUsed) {
|
public void updateLastUsed() {
|
||||||
this.lastUsed = lastUsed;
|
lastUsed = new Instant();
|
||||||
|
user.updateLastUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSiteName() {
|
public String getSiteName() {
|
||||||
@@ -116,4 +125,19 @@ public class MPSite {
|
|||||||
public void setLoginName(final String loginName) {
|
public void setLoginName(final String loginName) {
|
||||||
this.loginName = loginName;
|
this.loginName = loginName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
return this == obj || obj instanceof MPSite && Objects.equals( siteName, ((MPSite) obj).siteName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode( siteName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return strf( "{MPSite: %s}", siteName );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package com.lyndir.masterpassword.model;
|
package com.lyndir.masterpassword.model;
|
||||||
|
|
||||||
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lhunath, 14-12-07
|
* @author lhunath, 14-12-07
|
||||||
*/
|
*/
|
||||||
@@ -14,4 +19,19 @@ public class MPSiteResult {
|
|||||||
public MPSite getSite() {
|
public MPSite getSite() {
|
||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
return this == obj || obj instanceof MPSiteResult && Objects.equals( site, ((MPSiteResult) obj).site );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode( site );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return strf( "{MPSiteResult: %s}", site );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
@@ -123,7 +122,8 @@ public class MPSiteUnmarshaller {
|
|||||||
MPSite site;
|
MPSite site;
|
||||||
switch (importFormat) {
|
switch (importFormat) {
|
||||||
case 0:
|
case 0:
|
||||||
site = new MPSite( ConversionUtils.toIntegerNN( siteMatcher.group( 4 ).replace( ":", "" ) ), //
|
site = new MPSite( user, //
|
||||||
|
ConversionUtils.toIntegerNN( siteMatcher.group( 4 ).replace( ":", "" ) ), //
|
||||||
rfc3339.parseDateTime( siteMatcher.group( 1 ) ).toInstant(), //
|
rfc3339.parseDateTime( siteMatcher.group( 1 ) ).toInstant(), //
|
||||||
siteMatcher.group( 5 ), //
|
siteMatcher.group( 5 ), //
|
||||||
MPSiteType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
|
MPSiteType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
|
||||||
@@ -134,7 +134,8 @@ public class MPSiteUnmarshaller {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
site = new MPSite( ConversionUtils.toIntegerNN( siteMatcher.group( 4 ).replace( ":", "" ) ), //
|
site = new MPSite( user, //
|
||||||
|
ConversionUtils.toIntegerNN( siteMatcher.group( 4 ).replace( ":", "" ) ), //
|
||||||
rfc3339.parseDateTime( siteMatcher.group( 1 ) ).toInstant(), //
|
rfc3339.parseDateTime( siteMatcher.group( 1 ) ).toInstant(), //
|
||||||
siteMatcher.group( 7 ), //
|
siteMatcher.group( 7 ), //
|
||||||
MPSiteType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
|
MPSiteType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.lyndir.masterpassword.model;
|
package com.lyndir.masterpassword.model;
|
||||||
|
|
||||||
|
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||||
@@ -11,7 +13,7 @@ import org.joda.time.*;
|
|||||||
/**
|
/**
|
||||||
* @author lhunath, 14-12-07
|
* @author lhunath, 14-12-07
|
||||||
*/
|
*/
|
||||||
public class MPUser {
|
public class MPUser implements Comparable<MPUser> {
|
||||||
|
|
||||||
private final String fullName;
|
private final String fullName;
|
||||||
private final Collection<MPSite> sites = Sets.newHashSet();
|
private final Collection<MPSite> sites = Sets.newHashSet();
|
||||||
@@ -98,4 +100,28 @@ public class MPUser {
|
|||||||
public Iterable<MPSite> getSites() {
|
public Iterable<MPSite> getSites() {
|
||||||
return sites;
|
return sites;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
return this == obj || obj instanceof MPUser && Objects.equals( fullName, ((MPUser) obj).fullName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode( fullName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return strf( "{MPUser: %s}", fullName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final MPUser o) {
|
||||||
|
int comparison = lastUsed.compareTo( o.lastUsed );
|
||||||
|
if (comparison == 0)
|
||||||
|
comparison = fullName.compareTo( o.fullName );
|
||||||
|
|
||||||
|
return comparison;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,17 @@ public class MPUserFileManager extends MPUserManager {
|
|||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
private static final Logger logger = Logger.get( MPUserFileManager.class );
|
private static final Logger logger = Logger.get( MPUserFileManager.class );
|
||||||
private static final MPUserFileManager instance = create( new File( System.getProperty( "user.home" ), ".mpwrc" ) );
|
private static final File mpwd = new File( System.getProperty( "user.home" ), ".mpw.d" );
|
||||||
|
private static final MPUserFileManager instance;
|
||||||
|
|
||||||
|
static {
|
||||||
|
File mpwrc = new File( System.getProperty( "user.home" ), ".mpwrc" );
|
||||||
|
if (mpwrc.exists() && !mpwd.exists())
|
||||||
|
if (!mpwrc.renameTo( mpwd ))
|
||||||
|
logger.err( "Couldn't migrate: %s -> %s", mpwrc, mpwd );
|
||||||
|
|
||||||
|
instance = create( mpwd );
|
||||||
|
}
|
||||||
|
|
||||||
private final File userFilesDirectory;
|
private final File userFilesDirectory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.lyndir.masterpassword.model;
|
package com.lyndir.masterpassword.model;
|
||||||
|
|
||||||
import com.google.common.collect.FluentIterable;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
@@ -23,12 +22,7 @@ public abstract class MPUserManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<MPUser> getUsers() {
|
public SortedSet<MPUser> getUsers() {
|
||||||
return FluentIterable.from( usersByName.values() ).toSortedSet( new Comparator<MPUser>() {
|
return FluentIterable.from( usersByName.values() ).toSortedSet( Ordering.natural() );
|
||||||
@Override
|
|
||||||
public int compare(final MPUser user1, final MPUser user2) {
|
|
||||||
return user1.getLastUsed().compareTo( user2.getLastUsed() );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUser(final MPUser user) {
|
public void addUser(final MPUser user) {
|
||||||
|
|||||||
@@ -19,8 +19,9 @@
|
|||||||
#import "MPStoredSiteEntity.h"
|
#import "MPStoredSiteEntity.h"
|
||||||
#import "MPGeneratedSiteEntity.h"
|
#import "MPGeneratedSiteEntity.h"
|
||||||
#import "MPSiteQuestionEntity.h"
|
#import "MPSiteQuestionEntity.h"
|
||||||
|
#import "mpw-algorithm.h"
|
||||||
|
|
||||||
#define MPAlgorithmDefaultVersion 2
|
#define MPAlgorithmDefaultVersion MPAlgorithmVersionCurrent
|
||||||
#define MPAlgorithmDefault MPAlgorithmForVersion(MPAlgorithmDefaultVersion)
|
#define MPAlgorithmDefault MPAlgorithmForVersion(MPAlgorithmDefaultVersion)
|
||||||
|
|
||||||
id<MPAlgorithm> MPAlgorithmForVersion(NSUInteger version);
|
id<MPAlgorithm> MPAlgorithmForVersion(NSUInteger version);
|
||||||
@@ -43,7 +44,7 @@ NSString *NSStringFromTimeToCrack(TimeToCrack timeToCrack);
|
|||||||
@protocol MPAlgorithm<NSObject>
|
@protocol MPAlgorithm<NSObject>
|
||||||
|
|
||||||
@required
|
@required
|
||||||
- (NSUInteger)version;
|
- (MPAlgorithmVersion)version;
|
||||||
- (BOOL)tryMigrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc;
|
- (BOOL)tryMigrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc;
|
||||||
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit;
|
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit;
|
||||||
|
|
||||||
@@ -51,7 +52,6 @@ NSString *NSStringFromTimeToCrack(TimeToCrack timeToCrack);
|
|||||||
- (MPKey *)keyFromKeyData:(NSData *)keyData;
|
- (MPKey *)keyFromKeyData:(NSData *)keyData;
|
||||||
- (NSData *)keyIDForKeyData:(NSData *)keyData;
|
- (NSData *)keyIDForKeyData:(NSData *)keyData;
|
||||||
|
|
||||||
- (NSString *)scopeForVariant:(MPSiteVariant)variant;
|
|
||||||
- (NSString *)nameOfType:(MPSiteType)type;
|
- (NSString *)nameOfType:(MPSiteType)type;
|
||||||
- (NSString *)shortNameOfType:(MPSiteType)type;
|
- (NSString *)shortNameOfType:(MPSiteType)type;
|
||||||
- (NSString *)classNameOfType:(MPSiteType)type;
|
- (NSString *)classNameOfType:(MPSiteType)type;
|
||||||
|
|||||||
@@ -18,11 +18,4 @@
|
|||||||
#import "MPAlgorithm.h"
|
#import "MPAlgorithm.h"
|
||||||
|
|
||||||
@interface MPAlgorithmV0 : NSObject<MPAlgorithm>
|
@interface MPAlgorithmV0 : NSObject<MPAlgorithm>
|
||||||
|
|
||||||
- (NSDictionary *)allCiphers;
|
|
||||||
- (NSArray *)ciphersForType:(MPSiteType)type;
|
|
||||||
- (NSArray *)cipherClasses;
|
|
||||||
- (NSArray *)cipherClassCharacters;
|
|
||||||
- (NSString *)charactersForCipherClass:(NSString *)cipherClass;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -19,16 +19,11 @@
|
|||||||
#import "MPEntities.h"
|
#import "MPEntities.h"
|
||||||
#import "MPAppDelegate_Shared.h"
|
#import "MPAppDelegate_Shared.h"
|
||||||
#import "MPAppDelegate_InApp.h"
|
#import "MPAppDelegate_InApp.h"
|
||||||
#import "MPSiteQuestionEntity.h"
|
#import "mpw-util.h"
|
||||||
|
#import "mpw-types.h"
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#define MP_N 32768
|
|
||||||
#define MP_r 8
|
|
||||||
#define MP_p 2
|
|
||||||
#define MP_dkLen 64
|
|
||||||
#define MP_hash PearlHashSHA256
|
|
||||||
|
|
||||||
/* An AMD HD 7970 calculates 2495M SHA-1 hashes per second at a cost of ~350$ per GPU */
|
/* An AMD HD 7970 calculates 2495M SHA-1 hashes per second at a cost of ~350$ per GPU */
|
||||||
#define CRACKING_PER_SECOND 2495000000UL
|
#define CRACKING_PER_SECOND 2495000000UL
|
||||||
#define CRACKING_PRICE 350
|
#define CRACKING_PRICE 350
|
||||||
@@ -53,9 +48,9 @@
|
|||||||
ctx = NULL;
|
ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger)version {
|
- (MPAlgorithmVersion)version {
|
||||||
|
|
||||||
return 0;
|
return MPAlgorithmVersion0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)description {
|
- (NSString *)description {
|
||||||
@@ -112,21 +107,13 @@
|
|||||||
|
|
||||||
- (MPKey *)keyForPassword:(NSString *)password ofUserNamed:(NSString *)userName {
|
- (MPKey *)keyForPassword:(NSString *)password ofUserNamed:(NSString *)userName {
|
||||||
|
|
||||||
uint32_t nuserNameLength = htonl( userName.length );
|
|
||||||
NSDate *start = [NSDate date];
|
NSDate *start = [NSDate date];
|
||||||
NSData *keyData = [PearlSCrypt deriveKeyWithLength:MP_dkLen fromPassword:[password dataUsingEncoding:NSUTF8StringEncoding]
|
uint8_t const *masterKeyBytes = mpw_masterKeyForUser( userName.UTF8String, password.UTF8String, [self version] );
|
||||||
usingSalt:[NSData dataByConcatenatingDatas:
|
MPKey *masterKey = [self keyFromKeyData:[NSData dataWithBytes:masterKeyBytes length:MP_dkLen]];
|
||||||
[@"com.lyndir.masterpassword" dataUsingEncoding:NSUTF8StringEncoding],
|
mpw_free( masterKeyBytes, MP_dkLen );
|
||||||
[NSData dataWithBytes:&nuserNameLength
|
trc( @"User: %@, password: %@ derives to key ID: %@ (took %0.2fs)", userName, password, [masterKey.keyID encodeHex],
|
||||||
length:sizeof( nuserNameLength )],
|
|
||||||
[userName dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
nil] N:MP_N r:MP_r p:MP_p];
|
|
||||||
|
|
||||||
MPKey *key = [self keyFromKeyData:keyData];
|
|
||||||
trc( @"User: %@, password: %@ derives to key ID: %@ (took %0.2fs)", userName, password, [key.keyID encodeHex],
|
|
||||||
-[start timeIntervalSinceNow] );
|
-[start timeIntervalSinceNow] );
|
||||||
|
return masterKey;
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MPKey *)keyFromKeyData:(NSData *)keyData {
|
- (MPKey *)keyFromKeyData:(NSData *)keyData {
|
||||||
@@ -136,21 +123,7 @@
|
|||||||
|
|
||||||
- (NSData *)keyIDForKeyData:(NSData *)keyData {
|
- (NSData *)keyIDForKeyData:(NSData *)keyData {
|
||||||
|
|
||||||
return [keyData hashWith:MP_hash];
|
return [keyData hashWith:PearlHashSHA256];
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)scopeForVariant:(MPSiteVariant)variant {
|
|
||||||
|
|
||||||
switch (variant) {
|
|
||||||
case MPSiteVariantPassword:
|
|
||||||
return @"com.lyndir.masterpassword";
|
|
||||||
case MPSiteVariantLogin:
|
|
||||||
return @"com.lyndir.masterpassword.login";
|
|
||||||
case MPSiteVariantAnswer:
|
|
||||||
return @"com.lyndir.masterpassword.answer";
|
|
||||||
}
|
|
||||||
|
|
||||||
Throw( @"Unsupported variant: %ld", (long)variant );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)nameOfType:(MPSiteType)type {
|
- (NSString *)nameOfType:(MPSiteType)type {
|
||||||
@@ -327,40 +300,6 @@
|
|||||||
return previousType;
|
return previousType;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)allCiphers {
|
|
||||||
|
|
||||||
static NSDictionary *ciphers = nil;
|
|
||||||
static dispatch_once_t once = 0;
|
|
||||||
dispatch_once( &once, ^{
|
|
||||||
ciphers = [NSDictionary dictionaryWithContentsOfURL:
|
|
||||||
[[NSBundle mainBundle] URLForResource:@"ciphers" withExtension:@"plist"]];
|
|
||||||
} );
|
|
||||||
|
|
||||||
return ciphers;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *)ciphersForType:(MPSiteType)type {
|
|
||||||
|
|
||||||
NSString *typeClass = [self classNameOfType:type];
|
|
||||||
NSString *typeName = [self nameOfType:type];
|
|
||||||
return [[[self allCiphers] valueForKey:typeClass] valueForKey:typeName];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *)cipherClasses {
|
|
||||||
|
|
||||||
return [[[self allCiphers] valueForKey:@"MPCharacterClasses"] allKeys];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *)cipherClassCharacters {
|
|
||||||
|
|
||||||
return [[[self allCiphers] valueForKey:@"MPCharacterClasses"] allValues];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)charactersForCipherClass:(NSString *)cipherClass {
|
|
||||||
|
|
||||||
return [NSNullToNil( [NSNullToNil( [[self allCiphers] valueForKey:@"MPCharacterClasses"] ) valueForKey:cipherClass] ) copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key {
|
- (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key {
|
||||||
|
|
||||||
return [self generateContentForSiteNamed:name ofType:MPSiteTypeGeneratedName withCounter:1
|
return [self generateContentForSiteNamed:name ofType:MPSiteTypeGeneratedName withCounter:1
|
||||||
@@ -383,44 +322,10 @@
|
|||||||
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
|
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
|
||||||
variant:(MPSiteVariant)variant context:(NSString *)context usingKey:(MPKey *)key {
|
variant:(MPSiteVariant)variant context:(NSString *)context usingKey:(MPKey *)key {
|
||||||
|
|
||||||
// Determine the seed whose bytes will be used for calculating a password
|
char const *contentBytes = mpw_passwordForSite( key.keyData.bytes, name.UTF8String, type, (uint32_t)counter,
|
||||||
uint32_t ncounter = htonl( counter ), nnameLength = htonl( name.length ), ncontextLength = htonl( context.length );
|
variant, context.UTF8String, [self version] );
|
||||||
NSData *counterBytes = [NSData dataWithBytes:&ncounter length:sizeof( ncounter )];
|
NSString *content = [NSString stringWithCString:contentBytes encoding:NSUTF8StringEncoding];
|
||||||
NSData *nameLengthBytes = [NSData dataWithBytes:&nnameLength length:sizeof( nnameLength )];
|
mpw_freeString( contentBytes );
|
||||||
NSData *contextLengthBytes = [NSData dataWithBytes:&ncontextLength length:sizeof( ncontextLength )];
|
|
||||||
NSString *scope = [self scopeForVariant:variant];
|
|
||||||
trc( @"seed from: hmac-sha256(%@, %@ | %@ | %@ | %@ | %@)",
|
|
||||||
[[key keyID] encodeHex], scope, [nameLengthBytes encodeHex], name, [counterBytes encodeHex], context );
|
|
||||||
NSData *seed = [[NSData dataByConcatenatingDatas:
|
|
||||||
[scope dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
nameLengthBytes,
|
|
||||||
[name dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
counterBytes,
|
|
||||||
context? contextLengthBytes: nil,
|
|
||||||
[context dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
nil]
|
|
||||||
hmacWith:PearlHashSHA256 key:key.keyData];
|
|
||||||
trc( @"seed is: %@", [seed encodeHex] );
|
|
||||||
const char *seedBytes = seed.bytes;
|
|
||||||
|
|
||||||
// Determine the cipher from the first seed byte.
|
|
||||||
NSAssert( [seed length], @"Missing seed." );
|
|
||||||
NSArray *typeCiphers = [self ciphersForType:type];
|
|
||||||
NSString *cipher = typeCiphers[htons( seedBytes[0] ) % [typeCiphers count]];
|
|
||||||
trc( @"type %@ (%lu), ciphers: %@, selected: %@", [self nameOfType:type], (unsigned long)type, typeCiphers, cipher );
|
|
||||||
|
|
||||||
// Encode the content, character by character, using subsequent seed bytes and the cipher.
|
|
||||||
NSAssert( [seed length] >= [cipher length] + 1, @"Insufficient seed bytes to encode cipher." );
|
|
||||||
NSMutableString *content = [NSMutableString stringWithCapacity:[cipher length]];
|
|
||||||
for (NSUInteger c = 0; c < [cipher length]; ++c) {
|
|
||||||
uint16_t keyByte = htons( seedBytes[c + 1] );
|
|
||||||
NSString *cipherClass = [cipher substringWithRange:NSMakeRange( c, 1 )];
|
|
||||||
NSString *cipherClassCharacters = [self charactersForCipherClass:cipherClass];
|
|
||||||
NSString *character = [cipherClassCharacters substringWithRange:NSMakeRange( keyByte % [cipherClassCharacters length], 1 )];
|
|
||||||
|
|
||||||
trc( @"class %@ has characters: %@, index: %u, selected: %@", cipherClass, cipherClassCharacters, keyByte, character );
|
|
||||||
[content appendString:character];
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@@ -793,6 +698,8 @@
|
|||||||
|
|
||||||
- (NSString *)decryptContent:(NSData *)encryptedContent usingKey:(MPKey *)key {
|
- (NSString *)decryptContent:(NSData *)encryptedContent usingKey:(MPKey *)key {
|
||||||
|
|
||||||
|
if (!key)
|
||||||
|
return nil;
|
||||||
NSData *decryptedContent = nil;
|
NSData *decryptedContent = nil;
|
||||||
if ([encryptedContent length])
|
if ([encryptedContent length])
|
||||||
decryptedContent = [encryptedContent decryptWithSymmetricKey:[key subKeyOfLength:PearlCryptKeySize].keyData padding:YES];
|
decryptedContent = [encryptedContent decryptWithSymmetricKey:[key subKeyOfLength:PearlCryptKeySize].keyData padding:YES];
|
||||||
@@ -806,21 +713,23 @@
|
|||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
return NO;
|
return NO;
|
||||||
NSArray *ciphers = [self ciphersForType:type];
|
size_t count = 0;
|
||||||
if (!ciphers)
|
const char **templates = mpw_templatesForType( type, &count );
|
||||||
|
if (!templates)
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
BIGNUM *permutations = BN_new(), *cipherPermutations = BN_new();
|
BIGNUM *permutations = BN_new(), *templatePermutations = BN_new();
|
||||||
for (NSString *cipher in ciphers) {
|
for (size_t t = 0; t < count; ++t) {
|
||||||
BN_one( cipherPermutations );
|
const char *template = templates[t];
|
||||||
|
BN_one( templatePermutations );
|
||||||
|
|
||||||
for (NSUInteger c = 0; c < [cipher length]; ++c)
|
for (NSUInteger c = 0; c < strlen( template ); ++c)
|
||||||
BN_mul_word( cipherPermutations,
|
BN_mul_word( templatePermutations,
|
||||||
(BN_ULONG)[[self charactersForCipherClass:[cipher substringWithRange:NSMakeRange( c, 1 )]] length] );
|
(BN_ULONG)strlen( mpw_charactersInClass( template[c] ) ) );
|
||||||
|
|
||||||
BN_add( permutations, permutations, cipherPermutations );
|
BN_add( permutations, permutations, templatePermutations );
|
||||||
}
|
}
|
||||||
BN_free( cipherPermutations );
|
BN_free( templatePermutations );
|
||||||
|
|
||||||
return [self timeToCrack:timeToCrack permutations:permutations forAttacker:attacker];
|
return [self timeToCrack:timeToCrack permutations:permutations forAttacker:attacker];
|
||||||
}
|
}
|
||||||
@@ -830,25 +739,21 @@
|
|||||||
BIGNUM *permutations = BN_new();
|
BIGNUM *permutations = BN_new();
|
||||||
BN_one( permutations );
|
BN_one( permutations );
|
||||||
|
|
||||||
NSMutableString *cipher = [NSMutableString new];
|
|
||||||
for (NSUInteger c = 0; c < [password length]; ++c) {
|
for (NSUInteger c = 0; c < [password length]; ++c) {
|
||||||
NSString *passwordCharacter = [password substringWithRange:NSMakeRange( c, 1 )];
|
const char passwordCharacter = [password substringWithRange:NSMakeRange( c, 1 )].UTF8String[0];
|
||||||
|
|
||||||
unsigned int characterEntropy = 0;
|
unsigned int characterEntropy = 0;
|
||||||
for (NSString *cipherClass in @[ @"v", @"c", @"a", @"x" ]) {
|
for (NSString *characterClass in @[ @"v", @"c", @"a", @"x" ]) {
|
||||||
NSString *charactersForClass = [self charactersForCipherClass:cipherClass];
|
char const *charactersForClass = mpw_charactersInClass( characterClass.UTF8String[0] );
|
||||||
|
|
||||||
if ([charactersForClass rangeOfString:passwordCharacter].location != NSNotFound) {
|
if (strchr( charactersForClass, passwordCharacter )) {
|
||||||
// Found class for password character.
|
// Found class for password character.
|
||||||
characterEntropy = (BN_ULONG)[charactersForClass length];
|
characterEntropy = (BN_ULONG)strlen(charactersForClass);
|
||||||
[cipher appendString:cipherClass];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!characterEntropy) {
|
if (!characterEntropy)
|
||||||
[cipher appendString:@"b"];
|
|
||||||
characterEntropy = 256 /* a byte */;
|
characterEntropy = 256 /* a byte */;
|
||||||
}
|
|
||||||
|
|
||||||
BN_mul_word( permutations, characterEntropy );
|
BN_mul_word( permutations, characterEntropy );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
@implementation MPAlgorithmV1
|
@implementation MPAlgorithmV1
|
||||||
|
|
||||||
- (NSUInteger)version {
|
- (MPAlgorithmVersion)version {
|
||||||
|
|
||||||
return 1;
|
return MPAlgorithmVersion1;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
|
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
|
||||||
@@ -45,49 +45,4 @@
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
|
|
||||||
variant:(MPSiteVariant)variant context:(NSString *)context usingKey:(MPKey *)key {
|
|
||||||
|
|
||||||
// Determine the seed whose bytes will be used for calculating a password
|
|
||||||
uint32_t ncounter = htonl( counter ), nnameLength = htonl( name.length ), ncontextLength = htonl( context.length );
|
|
||||||
NSData *counterBytes = [NSData dataWithBytes:&ncounter length:sizeof( ncounter )];
|
|
||||||
NSData *nameLengthBytes = [NSData dataWithBytes:&nnameLength length:sizeof( nnameLength )];
|
|
||||||
NSData *contextLengthBytes = [NSData dataWithBytes:&ncontextLength length:sizeof( ncontextLength )];
|
|
||||||
NSString *scope = [self scopeForVariant:variant];
|
|
||||||
trc( @"seed from: hmac-sha256(%@, %@ | %@ | %@ | %@)",
|
|
||||||
[[key keyID] encodeHex], scope, [nameLengthBytes encodeHex], name, [counterBytes encodeHex] );
|
|
||||||
NSData *seed = [[NSData dataByConcatenatingDatas:
|
|
||||||
[scope dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
nameLengthBytes,
|
|
||||||
[name dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
counterBytes,
|
|
||||||
context? contextLengthBytes: nil,
|
|
||||||
[context dataUsingEncoding:NSUTF8StringEncoding],
|
|
||||||
nil]
|
|
||||||
hmacWith:PearlHashSHA256 key:key.keyData];
|
|
||||||
trc( @"seed is: %@", [seed encodeHex] );
|
|
||||||
const unsigned char *seedBytes = seed.bytes;
|
|
||||||
|
|
||||||
// Determine the cipher from the first seed byte.
|
|
||||||
NSAssert( [seed length], @"Missing seed." );
|
|
||||||
NSArray *typeCiphers = [self ciphersForType:type];
|
|
||||||
NSString *cipher = typeCiphers[seedBytes[0] % [typeCiphers count]];
|
|
||||||
trc( @"type %@ (%lu), ciphers: %@, selected: %@", [self nameOfType:type], (unsigned long)type, typeCiphers, cipher );
|
|
||||||
|
|
||||||
// Encode the content, character by character, using subsequent seed bytes and the cipher.
|
|
||||||
NSAssert( [seed length] >= [cipher length] + 1, @"Insufficient seed bytes to encode cipher." );
|
|
||||||
NSMutableString *content = [NSMutableString stringWithCapacity:[cipher length]];
|
|
||||||
for (NSUInteger c = 0; c < [cipher length]; ++c) {
|
|
||||||
uint16_t keyByte = seedBytes[c + 1];
|
|
||||||
NSString *cipherClass = [cipher substringWithRange:NSMakeRange( c, 1 )];
|
|
||||||
NSString *cipherClassCharacters = [self charactersForCipherClass:cipherClass];
|
|
||||||
NSString *character = [cipherClassCharacters substringWithRange:NSMakeRange( keyByte % [cipherClassCharacters length], 1 )];
|
|
||||||
|
|
||||||
trc( @"class %@ has characters: %@, index: %u, selected: %@", cipherClass, cipherClassCharacters, keyByte, character );
|
|
||||||
[content appendString:character];
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
// MPAlgorithmV1
|
// MPAlgorithmV2
|
||||||
//
|
//
|
||||||
// Created by Maarten Billemont on 17/07/12.
|
// Created by Maarten Billemont on 17/07/12.
|
||||||
// Copyright 2012 lhunath (Maarten Billemont). All rights reserved.
|
// Copyright 2012 lhunath (Maarten Billemont). All rights reserved.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
// MPAlgorithmV1
|
// MPAlgorithmV2
|
||||||
//
|
//
|
||||||
// Created by Maarten Billemont on 17/07/12.
|
// Created by Maarten Billemont on 17/07/12.
|
||||||
// Copyright 2012 lhunath (Maarten Billemont). All rights reserved.
|
// Copyright 2012 lhunath (Maarten Billemont). All rights reserved.
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
@implementation MPAlgorithmV2
|
@implementation MPAlgorithmV2
|
||||||
|
|
||||||
- (NSUInteger)version {
|
- (MPAlgorithmVersion)version {
|
||||||
|
|
||||||
return 2;
|
return MPAlgorithmVersion2;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
|
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
|
||||||
@@ -46,52 +46,4 @@
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
|
|
||||||
variant:(MPSiteVariant)variant context:(NSString *)context usingKey:(MPKey *)key {
|
|
||||||
|
|
||||||
// Determine the seed whose bytes will be used for calculating a password
|
|
||||||
NSData *nameBytes = [name dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
NSData *contextBytes = [context dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
uint32_t ncounter = htonl( counter ), nnameLength = htonl( nameBytes.length ), ncontextLength = htonl( contextBytes.length );
|
|
||||||
NSData *counterBytes = [NSData dataWithBytes:&ncounter length:sizeof( ncounter )];
|
|
||||||
NSData *nameLengthBytes = [NSData dataWithBytes:&nnameLength length:sizeof( nnameLength )];
|
|
||||||
NSData *contextLengthBytes = [NSData dataWithBytes:&ncontextLength length:sizeof( ncontextLength )];
|
|
||||||
NSString *scope = [self scopeForVariant:variant];
|
|
||||||
NSData *scopeBytes = [scope dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
trc( @"seed from: hmac-sha256(%@, %@ | %@ | %@ | %@)",
|
|
||||||
[[key keyID] encodeHex], scope, [nameLengthBytes encodeHex], name, [counterBytes encodeHex] );
|
|
||||||
NSData *seed = [[NSData dataByConcatenatingDatas:
|
|
||||||
scopeBytes,
|
|
||||||
nameLengthBytes,
|
|
||||||
nameBytes,
|
|
||||||
counterBytes,
|
|
||||||
context? contextLengthBytes: nil,
|
|
||||||
contextBytes,
|
|
||||||
nil]
|
|
||||||
hmacWith:PearlHashSHA256 key:key.keyData];
|
|
||||||
trc( @"seed is: %@", [seed encodeHex] );
|
|
||||||
const unsigned char *seedBytes = seed.bytes;
|
|
||||||
|
|
||||||
// Determine the cipher from the first seed byte.
|
|
||||||
NSAssert( [seed length], @"Missing seed." );
|
|
||||||
NSArray *typeCiphers = [self ciphersForType:type];
|
|
||||||
NSString *cipher = typeCiphers[seedBytes[0] % [typeCiphers count]];
|
|
||||||
trc( @"type %@ (%lu), ciphers: %@, selected: %@", [self nameOfType:type], (unsigned long)type, typeCiphers, cipher );
|
|
||||||
|
|
||||||
// Encode the content, character by character, using subsequent seed bytes and the cipher.
|
|
||||||
NSAssert( [seed length] >= [cipher length] + 1, @"Insufficient seed bytes to encode cipher." );
|
|
||||||
NSMutableString *content = [NSMutableString stringWithCapacity:[cipher length]];
|
|
||||||
for (NSUInteger c = 0; c < [cipher length]; ++c) {
|
|
||||||
uint16_t keyByte = seedBytes[c + 1];
|
|
||||||
NSString *cipherClass = [cipher substringWithRange:NSMakeRange( c, 1 )];
|
|
||||||
NSString *cipherClassCharacters = [self charactersForCipherClass:cipherClass];
|
|
||||||
NSString *character = [cipherClassCharacters substringWithRange:NSMakeRange( keyByte % [cipherClassCharacters length], 1 )];
|
|
||||||
|
|
||||||
trc( @"class %@ has characters: %@, index: %u, selected: %@", cipherClass, cipherClassCharacters, keyByte, character );
|
|
||||||
[content appendString:character];
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
21
MasterPassword/ObjC/MPAlgorithmV3.h
Normal file
21
MasterPassword/ObjC/MPAlgorithmV3.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
|
||||||
|
*
|
||||||
|
* See the enclosed file LICENSE for license information (LGPLv3). If you did
|
||||||
|
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||||
|
*
|
||||||
|
* @author Maarten Billemont <lhunath@lyndir.com>
|
||||||
|
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// MPAlgorithmV3
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 13/01/15.
|
||||||
|
// Copyright 2015 lhunath (Maarten Billemont). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPAlgorithmV2.h"
|
||||||
|
|
||||||
|
@interface MPAlgorithmV3 : MPAlgorithmV2
|
||||||
|
@end
|
||||||
48
MasterPassword/ObjC/MPAlgorithmV3.m
Normal file
48
MasterPassword/ObjC/MPAlgorithmV3.m
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
|
||||||
|
*
|
||||||
|
* See the enclosed file LICENSE for license information (LGPLv3). If you did
|
||||||
|
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||||
|
*
|
||||||
|
* @author Maarten Billemont <lhunath@lyndir.com>
|
||||||
|
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// MPAlgorithmV3
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 13/01/15.
|
||||||
|
// Copyright 2015 lhunath (Maarten Billemont). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPAlgorithmV3.h"
|
||||||
|
#import "MPEntities.h"
|
||||||
|
|
||||||
|
@implementation MPAlgorithmV3
|
||||||
|
|
||||||
|
- (MPAlgorithmVersion)version {
|
||||||
|
|
||||||
|
return MPAlgorithmVersion3;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)tryMigrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
|
||||||
|
|
||||||
|
if (site.version != [self version] - 1)
|
||||||
|
// Only migrate from previous version.
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
if (!explicit) {
|
||||||
|
if (site.type & MPSiteTypeClassGenerated && site.name.length != [site.name dataUsingEncoding:NSUTF8StringEncoding].length) {
|
||||||
|
// This migration requires explicit permission for types of the generated class.
|
||||||
|
site.requiresExplicitMigration = YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply migration.
|
||||||
|
site.requiresExplicitMigration = NO;
|
||||||
|
site.version = [self version];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -611,7 +611,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
}
|
}
|
||||||
if (!headerEnded)
|
if (!headerEnded)
|
||||||
continue;
|
continue;
|
||||||
if (!importKeyID || ![importUserName length])
|
if (![importUserName length])
|
||||||
return MPImportResultMalformedInput;
|
return MPImportResultMalformedInput;
|
||||||
if (![importedSiteLine length])
|
if (![importedSiteLine length])
|
||||||
continue;
|
continue;
|
||||||
@@ -689,12 +689,11 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
if (user && ![userKey.keyID isEqualToData:user.keyID])
|
if (user && ![userKey.keyID isEqualToData:user.keyID])
|
||||||
return MPImportResultInvalidPassword;
|
return MPImportResultInvalidPassword;
|
||||||
__block MPKey *importKey = userKey;
|
__block MPKey *importKey = userKey;
|
||||||
if (![importKey.keyID isEqualToData:importKeyID])
|
if (importKeyID && ![importKey.keyID isEqualToData:importKeyID])
|
||||||
importKey = [importAlgorithm keyForPassword:askImportPassword( importUserName ) ofUserNamed:importUserName];
|
importKey = [importAlgorithm keyForPassword:askImportPassword( importUserName ) ofUserNamed:importUserName];
|
||||||
if (![importKey.keyID isEqualToData:importKeyID])
|
if (importKeyID && ![importKey.keyID isEqualToData:importKeyID])
|
||||||
return MPImportResultInvalidPassword;
|
return MPImportResultInvalidPassword;
|
||||||
|
|
||||||
|
|
||||||
// Delete existing sites.
|
// Delete existing sites.
|
||||||
if (sitesToDelete.count)
|
if (sitesToDelete.count)
|
||||||
[sitesToDelete enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
|
[sitesToDelete enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
|
||||||
@@ -711,7 +710,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
|
|||||||
else {
|
else {
|
||||||
user = [MPUserEntity insertNewObjectInContext:context];
|
user = [MPUserEntity insertNewObjectInContext:context];
|
||||||
user.name = importUserName;
|
user.name = importUserName;
|
||||||
user.keyID = importKeyID;
|
user.keyID = [userKey keyID];
|
||||||
if (importAvatar != NSNotFound)
|
if (importAvatar != NSNotFound)
|
||||||
user.avatar = importAvatar;
|
user.avatar = importAvatar;
|
||||||
dbg( @"Created User: %@", [user debugDescription] );
|
dbg( @"Created User: %@", [user debugDescription] );
|
||||||
|
|||||||
@@ -6,45 +6,6 @@
|
|||||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "MPKey.h"
|
|
||||||
|
|
||||||
typedef NS_ENUM( NSUInteger, MPSiteTypeClass ) {
|
|
||||||
/** Generate the password. */
|
|
||||||
MPSiteTypeClassGenerated = 1 << 4,
|
|
||||||
/** Store the password. */
|
|
||||||
MPSiteTypeClassStored = 1 << 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM( NSUInteger, MPSiteVariant ) {
|
|
||||||
/** Generate the password. */
|
|
||||||
MPSiteVariantPassword,
|
|
||||||
/** Generate the login name. */
|
|
||||||
MPSiteVariantLogin,
|
|
||||||
/** Generate a security answer. */
|
|
||||||
MPSiteVariantAnswer,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM( NSUInteger, MPSiteFeature ) {
|
|
||||||
/** Export the key-protected content data. */
|
|
||||||
MPSiteFeatureExportContent = 1 << 10,
|
|
||||||
/** Never export content. */
|
|
||||||
MPSiteFeatureDevicePrivate = 1 << 11,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, MPSiteType) {
|
|
||||||
MPSiteTypeGeneratedMaximum = 0x0 | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedLong = 0x1 | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedMedium = 0x2 | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedBasic = 0x4 | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedShort = 0x3 | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedPIN = 0x5 | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedName = 0xE | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
MPSiteTypeGeneratedPhrase = 0xF | MPSiteTypeClassGenerated | 0x0,
|
|
||||||
|
|
||||||
MPSiteTypeStoredPersonal = 0x0 | MPSiteTypeClassStored | MPSiteFeatureExportContent,
|
|
||||||
MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MPErrorDomain @"MPErrorDomain"
|
#define MPErrorDomain @"MPErrorDomain"
|
||||||
|
|
||||||
#define MPSignedInNotification @"MPSignedInNotification"
|
#define MPSignedInNotification @"MPSignedInNotification"
|
||||||
|
|||||||
@@ -58,6 +58,33 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||||
|
|
||||||
|
#ifdef CRASHLYTICS
|
||||||
|
NSString *crashlyticsAPIKey = [self crashlyticsAPIKey];
|
||||||
|
if ([crashlyticsAPIKey length]) {
|
||||||
|
inf(@"Initializing Crashlytics");
|
||||||
|
#if defined (DEBUG) || defined (ADHOC)
|
||||||
|
[Crashlytics sharedInstance].debugMode = YES;
|
||||||
|
#endif
|
||||||
|
[Crashlytics setUserIdentifier:[PearlKeyChain deviceIdentifier]];
|
||||||
|
[Crashlytics setObjectValue:[PearlKeyChain deviceIdentifier] forKey:@"deviceIdentifier"];
|
||||||
|
[Crashlytics setUserName:@"Anonymous"];
|
||||||
|
[Crashlytics setObjectValue:@"Anonymous" forKey:@"username"];
|
||||||
|
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
||||||
|
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
||||||
|
PearlLogLevel level = PearlLogLevelInfo;
|
||||||
|
if ([[MPConfig get].sendInfo boolValue])
|
||||||
|
level = PearlLogLevelDebug;
|
||||||
|
|
||||||
|
if (message.level >= level)
|
||||||
|
CLSLog( @"%@", [message messageDescription] );
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}];
|
||||||
|
CLSLog( @"Crashlytics (%@) initialized for: %@ v%@.", //
|
||||||
|
[Crashlytics sharedInstance].version, [PearlInfoPlist get].CFBundleName, [PearlInfoPlist get].CFBundleVersion );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Setup delegates and listeners.
|
// Setup delegates and listeners.
|
||||||
[MPConfig get].delegate = self;
|
[MPConfig get].delegate = self;
|
||||||
__weak id weakSelf = self;
|
__weak id weakSelf = self;
|
||||||
@@ -224,6 +251,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
NSURL *url = openPanel.URL;
|
NSURL *url = openPanel.URL;
|
||||||
|
[openPanel close];
|
||||||
|
|
||||||
PearlNotMainQueue( ^{
|
PearlNotMainQueue( ^{
|
||||||
NSError *error;
|
NSError *error;
|
||||||
@@ -285,19 +313,19 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
case MPImportResultCancelled:
|
case MPImportResultCancelled:
|
||||||
break;
|
break;
|
||||||
case MPImportResultInternalError:
|
case MPImportResultInternalError:
|
||||||
[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
|
[[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
|
||||||
NSLocalizedDescriptionKey : @"Import failed because of an internal error."
|
NSLocalizedDescriptionKey : @"Import failed because of an internal error."
|
||||||
}]];
|
}]] runModal];
|
||||||
break;
|
break;
|
||||||
case MPImportResultMalformedInput:
|
case MPImportResultMalformedInput:
|
||||||
[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
|
[[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
|
||||||
NSLocalizedDescriptionKey : @"The import doesn't look like a Master Password export."
|
NSLocalizedDescriptionKey : @"The import doesn't look like a Master Password export."
|
||||||
}]];
|
}]] runModal];
|
||||||
break;
|
break;
|
||||||
case MPImportResultInvalidPassword:
|
case MPImportResultInvalidPassword:
|
||||||
[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
|
[[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
|
||||||
NSLocalizedDescriptionKey : @"Incorrect master password for the import sites."
|
NSLocalizedDescriptionKey : @"Incorrect master password for the import sites."
|
||||||
}]];
|
}]] runModal];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
@@ -604,4 +632,25 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
|
|||||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:NSStringFromSelector( configKey )];
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:NSStringFromSelector( configKey )];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Crashlytics
|
||||||
|
|
||||||
|
- (NSDictionary *)crashlyticsInfo {
|
||||||
|
|
||||||
|
static NSDictionary *crashlyticsInfo = nil;
|
||||||
|
if (crashlyticsInfo == nil)
|
||||||
|
crashlyticsInfo = [[NSDictionary alloc] initWithContentsOfURL:
|
||||||
|
[[NSBundle mainBundle] URLForResource:@"Crashlytics" withExtension:@"plist"]];
|
||||||
|
|
||||||
|
return crashlyticsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)crashlyticsAPIKey {
|
||||||
|
|
||||||
|
NSString *crashlyticsAPIKey = NSNullToNil( [[self crashlyticsInfo] valueForKeyPath:@"API Key"] );
|
||||||
|
if (![crashlyticsAPIKey length])
|
||||||
|
wrn( @"Crashlytics API key not set. Crash logs won't be recorded." );
|
||||||
|
|
||||||
|
return crashlyticsAPIKey;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -44,6 +44,8 @@
|
|||||||
|
|
||||||
[super windowDidLoad];
|
[super windowDidLoad];
|
||||||
|
|
||||||
|
[self replaceFonts:self.window.contentView];
|
||||||
|
|
||||||
// [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification object:nil
|
// [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification object:nil
|
||||||
// queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
// queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||||
// [self fadeIn];
|
// [self fadeIn];
|
||||||
@@ -95,6 +97,20 @@
|
|||||||
self.siteTable.controller = self;
|
self.siteTable.controller = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)replaceFonts:(NSView *)view {
|
||||||
|
|
||||||
|
if (view.window.backingScaleFactor == 1)
|
||||||
|
[view enumerateViews:^(NSView *subview, BOOL *stop, BOOL *recurse) {
|
||||||
|
if ([subview respondsToSelector:@selector( setFont: )]) {
|
||||||
|
NSFont *font = [(id)subview font];
|
||||||
|
if ([font.fontName isEqualToString:@"HelveticaNeue-Thin"])
|
||||||
|
[(id)subview setFont:[NSFont fontWithName:@"HelveticaNeue" matrix:font.matrix]];
|
||||||
|
if ([font.fontName isEqualToString:@"HelveticaNeue-Light"])
|
||||||
|
[(id)subview setFont:[NSFont fontWithName:@"HelveticaNeue" matrix:font.matrix]];
|
||||||
|
}
|
||||||
|
} recurse:YES];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)flagsChanged:(NSEvent *)theEvent {
|
- (void)flagsChanged:(NSEvent *)theEvent {
|
||||||
|
|
||||||
BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0;
|
BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0;
|
||||||
@@ -186,6 +202,11 @@
|
|||||||
|
|
||||||
#pragma mark - NSTableViewDelegate
|
#pragma mark - NSTableViewDelegate
|
||||||
|
|
||||||
|
- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
|
||||||
|
|
||||||
|
[self replaceFonts:rowView];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - NSAlert
|
#pragma mark - NSAlert
|
||||||
|
|
||||||
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
|
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
|
||||||
@@ -391,7 +412,7 @@
|
|||||||
NSArray *types = [site.algorithm allTypesStartingWith:MPSiteTypeGeneratedPIN];
|
NSArray *types = [site.algorithm allTypesStartingWith:MPSiteTypeGeneratedPIN];
|
||||||
[self.passwordTypesMatrix renewRows:(NSInteger)[types count] columns:1];
|
[self.passwordTypesMatrix renewRows:(NSInteger)[types count] columns:1];
|
||||||
for (NSUInteger t = 0; t < [types count]; ++t) {
|
for (NSUInteger t = 0; t < [types count]; ++t) {
|
||||||
MPSiteType type = [types[t] unsignedIntegerValue];
|
MPSiteType type = (MPSiteType)[types[t] unsignedIntegerValue];
|
||||||
NSString *title = [site.algorithm nameOfType:type];
|
NSString *title = [site.algorithm nameOfType:type];
|
||||||
if (type & MPSiteTypeClassGenerated)
|
if (type & MPSiteTypeClassGenerated)
|
||||||
title = [site.algorithm generatePasswordForSiteNamed:site.name ofType:type
|
title = [site.algorithm generatePasswordForSiteNamed:site.name ofType:type
|
||||||
@@ -513,13 +534,13 @@
|
|||||||
NSMutableArray *fuzzyGroups = [NSMutableArray new];
|
NSMutableArray *fuzzyGroups = [NSMutableArray new];
|
||||||
[fuzzyRE enumerateMatchesInString:queryString options:0 range:NSMakeRange( 0, queryString.length )
|
[fuzzyRE enumerateMatchesInString:queryString options:0 range:NSMakeRange( 0, queryString.length )
|
||||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
|
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
|
||||||
[fuzzyGroups addObject:[queryString substringWithRange:result.range] ];
|
[fuzzyGroups addObject:[queryString substringWithRange:result.range]];
|
||||||
}];
|
}];
|
||||||
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
|
||||||
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
|
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
|
||||||
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name LIKE[cd] %@) AND user == %@",
|
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name LIKE[cd] %@) AND user == %@",
|
||||||
queryPattern, queryPattern, [MPMacAppDelegate get].activeUserOID];
|
queryPattern, queryPattern, [MPMacAppDelegate get].activeUserOID];
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
|
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6250"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordWindowController">
|
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordWindowController">
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<windowCollectionBehavior key="collectionBehavior" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="640" height="560"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="640" height="560"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
|
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
</binding>
|
</binding>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Bme-XK-MMc" userLabel="Sites Table">
|
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Bme-XK-MMc" userLabel="Sites Table">
|
||||||
<rect key="frame" x="64" y="80" width="512" height="147"/>
|
<rect key="frame" x="64" y="80" width="512" height="147"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="e11-59-xSS">
|
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="e11-59-xSS">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/>
|
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/>
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "MPSiteEntity.h"
|
#import "MPSiteEntity.h"
|
||||||
|
#import "MPAlgorithm.h"
|
||||||
|
|
||||||
@class MPSiteEntity;
|
@class MPSiteEntity;
|
||||||
|
|
||||||
@interface MPSiteModel : NSObject
|
@interface MPSiteModel : NSObject
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */; };
|
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */; };
|
||||||
|
93D391E61DC23E128DA4446C /* NSView+Traversing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393EE88DE554BCCBC1C2D /* NSView+Traversing.h */; };
|
||||||
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
|
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
|
||||||
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */; };
|
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */; };
|
||||||
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39538C4CEFF46DF379254 /* MPNoStateButton.m */; };
|
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39538C4CEFF46DF379254 /* MPNoStateButton.m */; };
|
||||||
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
|
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
|
||||||
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; };
|
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; };
|
||||||
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; };
|
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; };
|
||||||
|
93D3987F6D9046DBEE4D8364 /* NSView+Traversing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D392870DF659AFC1870521 /* NSView+Traversing.m */; };
|
||||||
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
||||||
93D39C5789EFA607CF788082 /* MPSiteModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E73BF5CBF8E5B005CD3 /* MPSiteModel.m */; };
|
93D39C5789EFA607CF788082 /* MPSiteModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E73BF5CBF8E5B005CD3 /* MPSiteModel.m */; };
|
||||||
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D394EEFF5BF555A55AF361 /* PearlProfiler.h */; };
|
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D394EEFF5BF555A55AF361 /* PearlProfiler.h */; };
|
||||||
@@ -83,12 +85,13 @@
|
|||||||
DA67742F1A4746AF004F356A /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C21A4746AF004F356A /* mpw-types.c */; };
|
DA67742F1A4746AF004F356A /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C21A4746AF004F356A /* mpw-types.c */; };
|
||||||
DA6774311A4746AF004F356A /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C51A4746AF004F356A /* mpw-util.c */; };
|
DA6774311A4746AF004F356A /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C51A4746AF004F356A /* mpw-util.c */; };
|
||||||
DA6774331A4746AF004F356A /* mpw.bashrc in Resources */ = {isa = PBXBuildFile; fileRef = DA6773C81A4746AF004F356A /* mpw.bashrc */; };
|
DA6774331A4746AF004F356A /* mpw.bashrc in Resources */ = {isa = PBXBuildFile; fileRef = DA6773C81A4746AF004F356A /* mpw.bashrc */; };
|
||||||
DA6774341A4746AF004F356A /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = DA6773C91A4746AF004F356A /* VERSION */; };
|
|
||||||
DA6774431A474A3B004F356A /* mpw-algorithm.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773BB1A4746AF004F356A /* mpw-algorithm.c */; };
|
DA6774431A474A3B004F356A /* mpw-algorithm.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773BB1A4746AF004F356A /* mpw-algorithm.c */; };
|
||||||
DA6774441A474A3B004F356A /* mpw-tests.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C11A4746AF004F356A /* mpw-tests.c */; };
|
DA6774441A474A3B004F356A /* mpw-tests.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C11A4746AF004F356A /* mpw-tests.c */; };
|
||||||
DA6774451A474A3B004F356A /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C21A4746AF004F356A /* mpw-types.c */; };
|
DA6774451A474A3B004F356A /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C21A4746AF004F356A /* mpw-types.c */; };
|
||||||
DA6774461A474A3B004F356A /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C51A4746AF004F356A /* mpw-util.c */; };
|
DA6774461A474A3B004F356A /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C51A4746AF004F356A /* mpw-util.c */; };
|
||||||
DA67744A1A47C8F7004F356A /* mpw-tests-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6774481A47C8F7004F356A /* mpw-tests-util.c */; };
|
DA67744A1A47C8F7004F356A /* mpw-tests-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6774481A47C8F7004F356A /* mpw-tests-util.c */; };
|
||||||
|
DA89D4EC1A51EABD00AC64D7 /* Pearl-Cocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */; };
|
||||||
|
DA89D4ED1A51EABD00AC64D7 /* Pearl-Cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */; };
|
||||||
DA8ED895192906920099B726 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8ED891192906920099B726 /* PearlTween.m */; };
|
DA8ED895192906920099B726 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8ED891192906920099B726 /* PearlTween.m */; };
|
||||||
DA8ED896192906920099B726 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED892192906920099B726 /* PearlTween.h */; };
|
DA8ED896192906920099B726 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED892192906920099B726 /* PearlTween.h */; };
|
||||||
DA8ED897192906920099B726 /* map-macro.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED894192906920099B726 /* map-macro.h */; };
|
DA8ED897192906920099B726 /* map-macro.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED894192906920099B726 /* map-macro.h */; };
|
||||||
@@ -259,10 +262,12 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
||||||
93D39240B5143E01F0B75E96 /* MPSiteModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteModel.h; sourceTree = "<group>"; };
|
93D39240B5143E01F0B75E96 /* MPSiteModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteModel.h; sourceTree = "<group>"; };
|
||||||
|
93D392870DF659AFC1870521 /* NSView+Traversing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSView+Traversing.m"; sourceTree = "<group>"; };
|
||||||
93D392A4F3DE0BD758B9B056 /* MPNoStateButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNoStateButton.h; sourceTree = "<group>"; };
|
93D392A4F3DE0BD758B9B056 /* MPNoStateButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNoStateButton.h; sourceTree = "<group>"; };
|
||||||
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = "<group>"; };
|
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = "<group>"; };
|
||||||
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = "<group>"; };
|
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = "<group>"; };
|
||||||
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
|
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
|
||||||
|
93D393EE88DE554BCCBC1C2D /* NSView+Traversing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSView+Traversing.h"; sourceTree = "<group>"; };
|
||||||
93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSitesTableView.m; sourceTree = "<group>"; };
|
93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSitesTableView.m; sourceTree = "<group>"; };
|
||||||
93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = "<group>"; };
|
93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = "<group>"; };
|
||||||
93D39538C4CEFF46DF379254 /* MPNoStateButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNoStateButton.m; sourceTree = "<group>"; };
|
93D39538C4CEFF46DF379254 /* MPNoStateButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNoStateButton.m; sourceTree = "<group>"; };
|
||||||
@@ -779,10 +784,15 @@
|
|||||||
DA6773C51A4746AF004F356A /* mpw-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-util.c"; sourceTree = "<group>"; };
|
DA6773C51A4746AF004F356A /* mpw-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-util.c"; sourceTree = "<group>"; };
|
||||||
DA6773C61A4746AF004F356A /* mpw-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-util.h"; sourceTree = "<group>"; };
|
DA6773C61A4746AF004F356A /* mpw-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-util.h"; sourceTree = "<group>"; };
|
||||||
DA6773C81A4746AF004F356A /* mpw.bashrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mpw.bashrc; sourceTree = "<group>"; };
|
DA6773C81A4746AF004F356A /* mpw.bashrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mpw.bashrc; sourceTree = "<group>"; };
|
||||||
DA6773C91A4746AF004F356A /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
|
||||||
DA67743B1A474A03004F356A /* mpw-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "mpw-test"; sourceTree = BUILT_PRODUCTS_DIR; };
|
DA67743B1A474A03004F356A /* mpw-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "mpw-test"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
DA6774481A47C8F7004F356A /* mpw-tests-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-tests-util.c"; sourceTree = "<group>"; };
|
DA6774481A47C8F7004F356A /* mpw-tests-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-tests-util.c"; sourceTree = "<group>"; };
|
||||||
DA6774491A47C8F7004F356A /* mpw-tests-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-tests-util.h"; sourceTree = "<group>"; };
|
DA6774491A47C8F7004F356A /* mpw-tests-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-tests-util.h"; sourceTree = "<group>"; };
|
||||||
|
DA831A271A6E1146000AC234 /* mpw-algorithm_v0.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v0.c"; sourceTree = "<group>"; };
|
||||||
|
DA831A281A6E1146000AC234 /* mpw-algorithm_v1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v1.c"; sourceTree = "<group>"; };
|
||||||
|
DA831A291A6E1146000AC234 /* mpw-algorithm_v2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v2.c"; sourceTree = "<group>"; };
|
||||||
|
DA831A2A1A6E1146000AC234 /* mpw-algorithm_v3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v3.c"; sourceTree = "<group>"; };
|
||||||
|
DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Pearl-Cocoa.h"; sourceTree = "<group>"; };
|
||||||
|
DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Cocoa.m"; sourceTree = "<group>"; };
|
||||||
DA8ED891192906920099B726 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
|
DA8ED891192906920099B726 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
|
||||||
DA8ED892192906920099B726 /* PearlTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlTween.h; sourceTree = "<group>"; };
|
DA8ED892192906920099B726 /* PearlTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlTween.h; sourceTree = "<group>"; };
|
||||||
DA8ED894192906920099B726 /* map-macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-macro.h"; sourceTree = "<group>"; };
|
DA8ED894192906920099B726 /* map-macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-macro.h"; sourceTree = "<group>"; };
|
||||||
@@ -1533,6 +1543,10 @@
|
|||||||
DA67732B1A4746AF004F356A /* build */,
|
DA67732B1A4746AF004F356A /* build */,
|
||||||
DA67732C1A4746AF004F356A /* distribute */,
|
DA67732C1A4746AF004F356A /* distribute */,
|
||||||
DA67732D1A4746AF004F356A /* install */,
|
DA67732D1A4746AF004F356A /* install */,
|
||||||
|
DA831A271A6E1146000AC234 /* mpw-algorithm_v0.c */,
|
||||||
|
DA831A281A6E1146000AC234 /* mpw-algorithm_v1.c */,
|
||||||
|
DA831A291A6E1146000AC234 /* mpw-algorithm_v2.c */,
|
||||||
|
DA831A2A1A6E1146000AC234 /* mpw-algorithm_v3.c */,
|
||||||
DA6773BB1A4746AF004F356A /* mpw-algorithm.c */,
|
DA6773BB1A4746AF004F356A /* mpw-algorithm.c */,
|
||||||
DA6773BC1A4746AF004F356A /* mpw-algorithm.h */,
|
DA6773BC1A4746AF004F356A /* mpw-algorithm.h */,
|
||||||
DA6773BF1A4746AF004F356A /* mpw-bench.c */,
|
DA6773BF1A4746AF004F356A /* mpw-bench.c */,
|
||||||
@@ -1545,12 +1559,22 @@
|
|||||||
DA6773C51A4746AF004F356A /* mpw-util.c */,
|
DA6773C51A4746AF004F356A /* mpw-util.c */,
|
||||||
DA6773C61A4746AF004F356A /* mpw-util.h */,
|
DA6773C61A4746AF004F356A /* mpw-util.h */,
|
||||||
DA6773C81A4746AF004F356A /* mpw.bashrc */,
|
DA6773C81A4746AF004F356A /* mpw.bashrc */,
|
||||||
DA6773C91A4746AF004F356A /* VERSION */,
|
|
||||||
);
|
);
|
||||||
name = C;
|
name = C;
|
||||||
path = ../../C;
|
path = ../../C;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
DA89D4E51A51E53100AC64D7 /* Pearl-Cocoa */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */,
|
||||||
|
DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */,
|
||||||
|
93D392870DF659AFC1870521 /* NSView+Traversing.m */,
|
||||||
|
93D393EE88DE554BCCBC1C2D /* NSView+Traversing.h */,
|
||||||
|
);
|
||||||
|
path = "Pearl-Cocoa";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
DA8ED893192906920099B726 /* include */ = {
|
DA8ED893192906920099B726 /* include */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1572,6 +1596,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DAFE45D715039823003ABA7C /* Pearl */,
|
DAFE45D715039823003ABA7C /* Pearl */,
|
||||||
|
DA89D4E51A51E53100AC64D7 /* Pearl-Cocoa */,
|
||||||
DAFE45FC15039823003ABA7C /* Pearl-Crypto */,
|
DAFE45FC15039823003ABA7C /* Pearl-Crypto */,
|
||||||
DAC77CB1148291A600BCF976 /* Pearl-Prefix.pch */,
|
DAC77CB1148291A600BCF976 /* Pearl-Prefix.pch */,
|
||||||
);
|
);
|
||||||
@@ -1857,6 +1882,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
DA10007F1998A4C6002B873F /* scrypt in Headers */,
|
DA10007F1998A4C6002B873F /* scrypt in Headers */,
|
||||||
|
DA89D4EC1A51EABD00AC64D7 /* Pearl-Cocoa.h in Headers */,
|
||||||
DA1000801998A4C6002B873F /* openssl in Headers */,
|
DA1000801998A4C6002B873F /* openssl in Headers */,
|
||||||
DA2CA4F218D323D3007798F8 /* NSTimer+PearlBlock.h in Headers */,
|
DA2CA4F218D323D3007798F8 /* NSTimer+PearlBlock.h in Headers */,
|
||||||
DAFE4A1315039824003ABA7C /* NSObject+PearlExport.h in Headers */,
|
DAFE4A1315039824003ABA7C /* NSObject+PearlExport.h in Headers */,
|
||||||
@@ -1894,6 +1920,7 @@
|
|||||||
DA2CA4EE18D323D3007798F8 /* NSError+PearlFullDescription.h in Headers */,
|
DA2CA4EE18D323D3007798F8 /* NSError+PearlFullDescription.h in Headers */,
|
||||||
DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */,
|
DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */,
|
||||||
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */,
|
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */,
|
||||||
|
93D391E61DC23E128DA4446C /* NSView+Traversing.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -2103,7 +2130,6 @@
|
|||||||
DACA272C1705DF81002C6C22 /* avatar-14@2x.png in Resources */,
|
DACA272C1705DF81002C6C22 /* avatar-14@2x.png in Resources */,
|
||||||
DACA272D1705DF81002C6C22 /* avatar-4@2x.png in Resources */,
|
DACA272D1705DF81002C6C22 /* avatar-4@2x.png in Resources */,
|
||||||
DACA272E1705DF81002C6C22 /* avatar-9@2x.png in Resources */,
|
DACA272E1705DF81002C6C22 /* avatar-9@2x.png in Resources */,
|
||||||
DA6774341A4746AF004F356A /* VERSION in Resources */,
|
|
||||||
DACA272F1705DF81002C6C22 /* avatar-3.png in Resources */,
|
DACA272F1705DF81002C6C22 /* avatar-3.png in Resources */,
|
||||||
DACA27301705DF81002C6C22 /* avatar-18.png in Resources */,
|
DACA27301705DF81002C6C22 /* avatar-18.png in Resources */,
|
||||||
DACA27311705DF81002C6C22 /* avatar-4.png in Resources */,
|
DACA27311705DF81002C6C22 /* avatar-4.png in Resources */,
|
||||||
@@ -2191,7 +2217,7 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = "/bin/bash -e";
|
shellPath = "/bin/bash -e";
|
||||||
shellScript = "../../../External/Mac/Crashlytics.framework/run \\\n \"$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" ../../Resources/Crashlytics/Crashlytics.plist)\"";
|
shellScript = "../../../External/Mac/Crashlytics.framework/run \\\n \"$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" ../../Resources/Crashlytics/Crashlytics.plist)\" 410fb41450e3a2e50fa8357682d812ecd3e1846f2141a99bdb9d3a6a981ad69c";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
@@ -2281,6 +2307,7 @@
|
|||||||
DAFE4A2E15039824003ABA7C /* PearlStrings.m in Sources */,
|
DAFE4A2E15039824003ABA7C /* PearlStrings.m in Sources */,
|
||||||
DAFE4A3015039824003ABA7C /* PearlStringUtils.m in Sources */,
|
DAFE4A3015039824003ABA7C /* PearlStringUtils.m in Sources */,
|
||||||
DAFE4A3515039824003ABA7C /* PearlCryptUtils.m in Sources */,
|
DAFE4A3515039824003ABA7C /* PearlCryptUtils.m in Sources */,
|
||||||
|
DA89D4ED1A51EABD00AC64D7 /* Pearl-Cocoa.m in Sources */,
|
||||||
DAFE4A3715039824003ABA7C /* PearlKeyChain.m in Sources */,
|
DAFE4A3715039824003ABA7C /* PearlKeyChain.m in Sources */,
|
||||||
DAFE4A3915039824003ABA7C /* PearlRSAKey.m in Sources */,
|
DAFE4A3915039824003ABA7C /* PearlRSAKey.m in Sources */,
|
||||||
DAFE4A3B15039824003ABA7C /* PearlSCrypt.m in Sources */,
|
DAFE4A3B15039824003ABA7C /* PearlSCrypt.m in Sources */,
|
||||||
@@ -2298,6 +2325,7 @@
|
|||||||
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */,
|
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */,
|
||||||
DA3509FF15F101A500C14A8E /* PearlQueue.m in Sources */,
|
DA3509FF15F101A500C14A8E /* PearlQueue.m in Sources */,
|
||||||
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */,
|
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */,
|
||||||
|
93D3987F6D9046DBEE4D8364 /* NSView+Traversing.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -2351,16 +2379,21 @@
|
|||||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
|
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
|
||||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
|
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||||
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
|
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
|
||||||
@@ -2388,7 +2421,7 @@
|
|||||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
|
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES;
|
GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES;
|
||||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||||
@@ -2432,16 +2465,21 @@
|
|||||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
|
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
|
||||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
|
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||||
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
|
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
|
||||||
@@ -2449,6 +2487,7 @@
|
|||||||
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
|
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||||
@@ -2457,6 +2496,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"NDEBUG=1",
|
"NDEBUG=1",
|
||||||
"NS_BLOCK_ASSERTIONS=1",
|
"NS_BLOCK_ASSERTIONS=1",
|
||||||
|
"CRASHLYTICS=1",
|
||||||
);
|
);
|
||||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||||
@@ -2469,7 +2509,7 @@
|
|||||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
|
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES;
|
GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES;
|
||||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||||
@@ -2480,7 +2520,7 @@
|
|||||||
GCC_WARN_SIGN_COMPARE = YES;
|
GCC_WARN_SIGN_COMPARE = YES;
|
||||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||||
GCC_WARN_UNUSED_FUNCTION = NO;
|
GCC_WARN_UNUSED_FUNCTION = NO;
|
||||||
GCC_WARN_UNUSED_LABEL = YES;
|
GCC_WARN_UNUSED_LABEL = YES;
|
||||||
@@ -2598,16 +2638,21 @@
|
|||||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
|
||||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
|
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
|
||||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
|
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
CLANG_WARN_CXX0X_EXTENSIONS = YES;
|
||||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||||
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
CLANG_WARN_OBJC_RECEIVER_WEAK = NO;
|
||||||
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = NO;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
|
CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES;
|
||||||
@@ -2615,6 +2660,7 @@
|
|||||||
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
|
CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||||
@@ -2623,6 +2669,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"NDEBUG=1",
|
"NDEBUG=1",
|
||||||
"NS_BLOCK_ASSERTIONS=1",
|
"NS_BLOCK_ASSERTIONS=1",
|
||||||
|
"CRASHLYTICS=1",
|
||||||
);
|
);
|
||||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||||
@@ -2635,7 +2682,7 @@
|
|||||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
|
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES;
|
GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES;
|
||||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||||
@@ -2646,7 +2693,7 @@
|
|||||||
GCC_WARN_SIGN_COMPARE = YES;
|
GCC_WARN_SIGN_COMPARE = YES;
|
||||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||||
GCC_WARN_UNUSED_FUNCTION = NO;
|
GCC_WARN_UNUSED_FUNCTION = NO;
|
||||||
GCC_WARN_UNUSED_LABEL = YES;
|
GCC_WARN_UNUSED_LABEL = YES;
|
||||||
|
|||||||
@@ -29,6 +29,15 @@
|
|||||||
buildConfiguration = "AppStore-Mac">
|
buildConfiguration = "AppStore-Mac">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
|
||||||
|
BuildableName = "Master Password.app"
|
||||||
|
BlueprintName = "MasterPassword"
|
||||||
|
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
|||||||
@@ -29,6 +29,15 @@
|
|||||||
buildConfiguration = "Debug-Mac">
|
buildConfiguration = "Debug-Mac">
|
||||||
<Testables>
|
<Testables>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
|
||||||
|
BuildableName = "Master Password.app"
|
||||||
|
BlueprintName = "MasterPassword"
|
||||||
|
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
// Prefix header for all source files of the 'MasterPassword' target in the 'MasterPassword' project
|
// Prefix header for all source files of the 'MasterPassword' target in the 'MasterPassword' project
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
|
||||||
|
#warning "This project uses features only available in Mac OS X 10.8 and later."
|
||||||
|
#endif
|
||||||
|
|
||||||
#import "Pearl-Prefix.pch"
|
#import "Pearl-Prefix.pch"
|
||||||
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
@@ -10,6 +14,10 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <CoreData/CoreData.h>
|
#import <CoreData/CoreData.h>
|
||||||
|
|
||||||
|
#ifdef CRASHLYTICS
|
||||||
|
#import <Crashlytics/Crashlytics.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#import "MPTypes.h"
|
#import "MPTypes.h"
|
||||||
#import "MPMacConfig.h"
|
#import "MPMacConfig.h"
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,7 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>com.apple.security.files.user-selected.read-write</key>
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -13,10 +13,16 @@
|
|||||||
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
|
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||||
#define PEARL_UIKIT
|
#define PEARL_UIKIT
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
#define PEARL_COCOA
|
||||||
|
#endif
|
||||||
|
|
||||||
#import "Pearl.h"
|
#import "Pearl.h"
|
||||||
#import "Pearl-Crypto.h"
|
#import "Pearl-Crypto.h"
|
||||||
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
|
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||||
#import "Pearl-UIKit.h"
|
#import "Pearl-UIKit.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
#import "Pearl-Cocoa.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
initSheet:^(UIActionSheet *sheet) {
|
initSheet:^(UIActionSheet *sheet) {
|
||||||
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
|
||||||
for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) {
|
for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) {
|
||||||
MPSiteType type = [typeNumber unsignedIntegerValue];
|
MPSiteType type = (MPSiteType)[typeNumber unsignedIntegerValue];
|
||||||
NSString *typeName = [MPAlgorithmDefault nameOfType:type];
|
NSString *typeName = [MPAlgorithmDefault nameOfType:type];
|
||||||
if (type == mainSite.type)
|
if (type == mainSite.type)
|
||||||
[sheet addButtonWithTitle:strf( @"● %@", typeName )];
|
[sheet addButtonWithTitle:strf( @"● %@", typeName )];
|
||||||
@@ -295,7 +295,7 @@
|
|||||||
if (buttonIndex == [sheet cancelButtonIndex])
|
if (buttonIndex == [sheet cancelButtonIndex])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MPSiteType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPSiteTypeGeneratedLong;
|
MPSiteType type = (MPSiteType)[[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPSiteTypeGeneratedLong;
|
||||||
|
|
||||||
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
|
||||||
MPSiteEntity *site = [self siteInContext:context];
|
MPSiteEntity *site = [self siteInContext:context];
|
||||||
|
|||||||
@@ -182,7 +182,7 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (enum MPSiteType)typeForSelectedSegment {
|
- (MPSiteType)typeForSelectedSegment {
|
||||||
|
|
||||||
NSInteger selectedGeneratedIndex = self.generatedTypeControl.selectedSegmentIndex;
|
NSInteger selectedGeneratedIndex = self.generatedTypeControl.selectedSegmentIndex;
|
||||||
NSInteger selectedStoredIndex = self.storedTypeControl.selectedSegmentIndex;
|
NSInteger selectedStoredIndex = self.storedTypeControl.selectedSegmentIndex;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
[Crashlytics startWithAPIKey:crashlyticsAPIKey];
|
||||||
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
|
||||||
PearlLogLevel level = PearlLogLevelInfo;
|
PearlLogLevel level = PearlLogLevelInfo;
|
||||||
if ([[MPiOSConfig get].sendInfo boolValue])
|
if ([[MPConfig get].sendInfo boolValue])
|
||||||
level = PearlLogLevelDebug;
|
level = PearlLogLevelDebug;
|
||||||
|
|
||||||
if (message.level >= level)
|
if (message.level >= level)
|
||||||
@@ -333,7 +333,7 @@
|
|||||||
|
|
||||||
NSString *userName = [[MPiOSAppDelegate get] activeUserForMainThread].name;
|
NSString *userName = [[MPiOSAppDelegate get] activeUserForMainThread].name;
|
||||||
PearlLogLevel logLevel = PearlLogLevelInfo;
|
PearlLogLevel logLevel = PearlLogLevelInfo;
|
||||||
if (logs && ([[MPiOSConfig get].sendInfo boolValue] || [[MPiOSConfig get].traceMode boolValue]))
|
if (logs && ([[MPConfig get].sendInfo boolValue] || [[MPiOSConfig get].traceMode boolValue]))
|
||||||
logLevel = PearlLogLevelDebug;
|
logLevel = PearlLogLevelDebug;
|
||||||
|
|
||||||
[[[PearlEMail alloc] initForEMailTo:@"Master Password Development <masterpassword@lyndir.com>"
|
[[[PearlEMail alloc] initForEMailTo:@"Master Password Development <masterpassword@lyndir.com>"
|
||||||
@@ -530,13 +530,13 @@
|
|||||||
[PearlLogger get].historyLevel = [[MPiOSConfig get].traceMode boolValue]? PearlLogLevelTrace: PearlLogLevelInfo;
|
[PearlLogger get].historyLevel = [[MPiOSConfig get].traceMode boolValue]? PearlLogLevelTrace: PearlLogLevelInfo;
|
||||||
|
|
||||||
// Send info
|
// Send info
|
||||||
if ([[MPiOSConfig get].sendInfo boolValue]) {
|
if ([[MPConfig get].sendInfo boolValue]) {
|
||||||
if ([PearlLogger get].printLevel > PearlLogLevelInfo)
|
if ([PearlLogger get].printLevel > PearlLogLevelInfo)
|
||||||
[PearlLogger get].printLevel = PearlLogLevelInfo;
|
[PearlLogger get].printLevel = PearlLogLevelInfo;
|
||||||
|
|
||||||
#ifdef CRASHLYTICS
|
#ifdef CRASHLYTICS
|
||||||
[[Crashlytics sharedInstance] setBoolValue:[[MPConfig get].rememberLogin boolValue] forKey:@"rememberLogin"];
|
[[Crashlytics sharedInstance] setBoolValue:[[MPConfig get].rememberLogin boolValue] forKey:@"rememberLogin"];
|
||||||
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].sendInfo boolValue] forKey:@"sendInfo"];
|
[[Crashlytics sharedInstance] setBoolValue:[[MPConfig get].sendInfo boolValue] forKey:@"sendInfo"];
|
||||||
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].helpHidden boolValue] forKey:@"helpHidden"];
|
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].helpHidden boolValue] forKey:@"helpHidden"];
|
||||||
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].showSetup boolValue] forKey:@"showQuickStart"];
|
[[Crashlytics sharedInstance] setBoolValue:[[MPiOSConfig get].showSetup boolValue] forKey:@"showQuickStart"];
|
||||||
[[Crashlytics sharedInstance] setBoolValue:[[PearlConfig get].firstRun boolValue] forKey:@"firstRun"];
|
[[Crashlytics sharedInstance] setBoolValue:[[PearlConfig get].firstRun boolValue] forKey:@"firstRun"];
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
93D3954E96236384AFA00453 /* UIScrollView+PearlAdjustInsets.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */; };
|
93D3954E96236384AFA00453 /* UIScrollView+PearlAdjustInsets.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */; };
|
||||||
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399E571F61E50A9BF8FAF /* MPUsersViewController.m */; };
|
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399E571F61E50A9BF8FAF /* MPUsersViewController.m */; };
|
||||||
93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39B381350802A194BF332 /* MPAvatarCell.m */; };
|
93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39B381350802A194BF332 /* MPAvatarCell.m */; };
|
||||||
|
93D39577FD8BB0945DB2F0A3 /* MPAlgorithmV3.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39FD9623E8D5571C0AEB3 /* MPAlgorithmV3.m */; };
|
||||||
93D3958C13B557F60F63C72B /* distribute in Resources */ = {isa = PBXBuildFile; fileRef = 93D3979016BF0C5B29D1340D /* distribute */; };
|
93D3958C13B557F60F63C72B /* distribute in Resources */ = {isa = PBXBuildFile; fileRef = 93D3979016BF0C5B29D1340D /* distribute */; };
|
||||||
93D395B715D15F2B56F2A2EE /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = 93D392C5A6572DB0EB5B82C8 /* mpw-types.c */; };
|
93D395B715D15F2B56F2A2EE /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = 93D392C5A6572DB0EB5B82C8 /* mpw-types.c */; };
|
||||||
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
|
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
|
||||||
@@ -33,7 +34,6 @@
|
|||||||
93D396AA30690B256F30378A /* PearlNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3956915634581E737B38C /* PearlNavigationController.m */; };
|
93D396AA30690B256F30378A /* PearlNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3956915634581E737B38C /* PearlNavigationController.m */; };
|
||||||
93D396BA1C74C4A06FD86437 /* PearlOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D3942A356B639724157982 /* PearlOverlay.h */; };
|
93D396BA1C74C4A06FD86437 /* PearlOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D3942A356B639724157982 /* PearlOverlay.h */; };
|
||||||
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3995B1D4DCE5A30D882BA /* MPCoachmarkViewController.m */; };
|
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3995B1D4DCE5A30D882BA /* MPCoachmarkViewController.m */; };
|
||||||
93D39711B6D873F37E8B9B2D /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 93D3944F4D55D2A37EF6021B /* VERSION */; };
|
|
||||||
93D397952F5635C793C24DF1 /* NSError+PearlFullDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */; };
|
93D397952F5635C793C24DF1 /* NSError+PearlFullDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */; };
|
||||||
93D3980046016EFD05B35BC5 /* PearlUICollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39B1D8177A86C5B9EDDE3 /* PearlUICollectionView.h */; };
|
93D3980046016EFD05B35BC5 /* PearlUICollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39B1D8177A86C5B9EDDE3 /* PearlUICollectionView.h */; };
|
||||||
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39ACBA9F4878B6A1CC33B /* MPEmergencyViewController.m */; };
|
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39ACBA9F4878B6A1CC33B /* MPEmergencyViewController.m */; };
|
||||||
@@ -167,7 +167,6 @@
|
|||||||
DA67460E18DE7F0C00DFE240 /* Exo2.0-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA67460A18DE7F0C00DFE240 /* Exo2.0-Regular.otf */; };
|
DA67460E18DE7F0C00DFE240 /* Exo2.0-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA67460A18DE7F0C00DFE240 /* Exo2.0-Regular.otf */; };
|
||||||
DA67460F18DE7F0C00DFE240 /* Exo2.0-ExtraBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA67460B18DE7F0C00DFE240 /* Exo2.0-ExtraBold.otf */; };
|
DA67460F18DE7F0C00DFE240 /* Exo2.0-ExtraBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA67460B18DE7F0C00DFE240 /* Exo2.0-ExtraBold.otf */; };
|
||||||
DA67461018DE7F0C00DFE240 /* Exo2.0-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA67460C18DE7F0C00DFE240 /* Exo2.0-Bold.otf */; };
|
DA67461018DE7F0C00DFE240 /* Exo2.0-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA67460C18DE7F0C00DFE240 /* Exo2.0-Bold.otf */; };
|
||||||
DA6773251A43B660004F356A /* libscryptenc-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAFFC63E17EDDA7C007BB020 /* libscryptenc-ios.a */; };
|
|
||||||
DA69540617D975D900BF294E /* icon_gears.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37841711E29500CF925C /* icon_gears.png */; };
|
DA69540617D975D900BF294E /* icon_gears.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37841711E29500CF925C /* icon_gears.png */; };
|
||||||
DA69540717D975D900BF294E /* icon_gears@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37851711E29500CF925C /* icon_gears@2x.png */; };
|
DA69540717D975D900BF294E /* icon_gears@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37851711E29500CF925C /* icon_gears@2x.png */; };
|
||||||
DA72BD7919C137DE00E6ACFE /* libopensslcrypto-ios-dev.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA72BD7719C137D500E6ACFE /* libopensslcrypto-ios-dev.a */; };
|
DA72BD7919C137DE00E6ACFE /* libopensslcrypto-ios-dev.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA72BD7719C137D500E6ACFE /* libopensslcrypto-ios-dev.a */; };
|
||||||
@@ -218,6 +217,7 @@
|
|||||||
DAA1765219D8B82B0044227B /* copy_pw.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763C19D8B82B0044227B /* copy_pw.png */; };
|
DAA1765219D8B82B0044227B /* copy_pw.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763C19D8B82B0044227B /* copy_pw.png */; };
|
||||||
DAA1765319D8B82B0044227B /* choose_type@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763D19D8B82B0044227B /* choose_type@2x.png */; };
|
DAA1765319D8B82B0044227B /* choose_type@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763D19D8B82B0044227B /* choose_type@2x.png */; };
|
||||||
DAA1765419D8B82B0044227B /* choose_type.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763E19D8B82B0044227B /* choose_type.png */; };
|
DAA1765419D8B82B0044227B /* choose_type.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA1763E19D8B82B0044227B /* choose_type.png */; };
|
||||||
|
DAADBFE01A68763B00F7A756 /* mpw-algorithm.c in Sources */ = {isa = PBXBuildFile; fileRef = 93D3969393A3A46BD27D7078 /* mpw-algorithm.c */; };
|
||||||
DABB981615100B4000B05417 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABB981515100B4000B05417 /* SystemConfiguration.framework */; };
|
DABB981615100B4000B05417 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABB981515100B4000B05417 /* SystemConfiguration.framework */; };
|
||||||
DABD39371711E29700CF925C /* avatar-0.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD366C1711E29400CF925C /* avatar-0.png */; };
|
DABD39371711E29700CF925C /* avatar-0.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD366C1711E29400CF925C /* avatar-0.png */; };
|
||||||
DABD39381711E29700CF925C /* avatar-0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD366D1711E29400CF925C /* avatar-0@2x.png */; };
|
DABD39381711E29700CF925C /* avatar-0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD366D1711E29400CF925C /* avatar-0@2x.png */; };
|
||||||
@@ -464,6 +464,8 @@
|
|||||||
93D390519405B76CC6A57C4F /* MPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCell.h; sourceTree = "<group>"; };
|
93D390519405B76CC6A57C4F /* MPCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCell.h; sourceTree = "<group>"; };
|
||||||
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
||||||
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+PearlReloadFromArray.m"; sourceTree = "<group>"; };
|
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+PearlReloadFromArray.m"; sourceTree = "<group>"; };
|
||||||
|
93D390A3B351FEF1B9EDAB56 /* mpw-algorithm_v2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v2.c"; sourceTree = "<group>"; };
|
||||||
|
93D390A99850139D0FF0211E /* mpw-algorithm_v0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v0.c"; sourceTree = "<group>"; };
|
||||||
93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = "<group>"; };
|
93D390FADEB325D8D54A957D /* PearlOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlOverlay.m; sourceTree = "<group>"; };
|
||||||
93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+PearlAdjustInsets.m"; sourceTree = "<group>"; };
|
93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+PearlAdjustInsets.m"; sourceTree = "<group>"; };
|
||||||
93D39149A5F1F9B174D6D061 /* MPStoreViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPStoreViewController.h; sourceTree = "<group>"; };
|
93D39149A5F1F9B174D6D061 /* MPStoreViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPStoreViewController.h; sourceTree = "<group>"; };
|
||||||
@@ -485,14 +487,15 @@
|
|||||||
93D394077F8FAB8167647187 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; };
|
93D394077F8FAB8167647187 /* Twitter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Twitter.framework; path = System/Library/Frameworks/Twitter.framework; sourceTree = SDKROOT; };
|
||||||
93D3942A356B639724157982 /* PearlOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlOverlay.h; sourceTree = "<group>"; };
|
93D3942A356B639724157982 /* PearlOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlOverlay.h; sourceTree = "<group>"; };
|
||||||
93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+PearlFirstResponder.h"; sourceTree = "<group>"; };
|
93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+PearlFirstResponder.h"; sourceTree = "<group>"; };
|
||||||
93D3944F4D55D2A37EF6021B /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
|
||||||
93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_InApp.m; sourceTree = "<group>"; };
|
93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_InApp.m; sourceTree = "<group>"; };
|
||||||
|
93D394D73F5BC92297CE8D7B /* MPAlgorithmV3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAlgorithmV3.h; sourceTree = "<group>"; };
|
||||||
93D395105935859D71679931 /* MPOverlayViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOverlayViewController.m; sourceTree = "<group>"; };
|
93D395105935859D71679931 /* MPOverlayViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOverlayViewController.m; sourceTree = "<group>"; };
|
||||||
93D3956915634581E737B38C /* PearlNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlNavigationController.m; sourceTree = "<group>"; };
|
93D3956915634581E737B38C /* PearlNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlNavigationController.m; sourceTree = "<group>"; };
|
||||||
93D3957D76F71A652716EECC /* MPStoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPStoreViewController.m; sourceTree = "<group>"; };
|
93D3957D76F71A652716EECC /* MPStoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPStoreViewController.m; sourceTree = "<group>"; };
|
||||||
93D3969393A3A46BD27D7078 /* mpw-algorithm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm.c"; sourceTree = "<group>"; };
|
93D3969393A3A46BD27D7078 /* mpw-algorithm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm.c"; sourceTree = "<group>"; };
|
||||||
93D396C311C3725870343EE0 /* mpw-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-util.c"; sourceTree = "<group>"; };
|
93D396C311C3725870343EE0 /* mpw-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-util.c"; sourceTree = "<group>"; };
|
||||||
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
|
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
|
||||||
|
93D396F918E6470DB846C17F /* mpw-algorithm_v1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v1.c"; sourceTree = "<group>"; };
|
||||||
93D3970502644794E8A027BE /* MPNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNavigationController.h; sourceTree = "<group>"; };
|
93D3970502644794E8A027BE /* MPNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNavigationController.h; sourceTree = "<group>"; };
|
||||||
93D3971FE104BB4052484151 /* MPUsersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUsersViewController.h; sourceTree = "<group>"; };
|
93D3971FE104BB4052484151 /* MPUsersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUsersViewController.h; sourceTree = "<group>"; };
|
||||||
93D397288D0655822A73A539 /* mpw-tests-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-tests-util.c"; sourceTree = "<group>"; };
|
93D397288D0655822A73A539 /* mpw-tests-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-tests-util.c"; sourceTree = "<group>"; };
|
||||||
@@ -541,6 +544,7 @@
|
|||||||
93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = "<group>"; };
|
93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = "<group>"; };
|
||||||
93D39CF7DB942C69D1C5D6BE /* mpw-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-util.h"; sourceTree = "<group>"; };
|
93D39CF7DB942C69D1C5D6BE /* mpw-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-util.h"; sourceTree = "<group>"; };
|
||||||
93D39CF8ADF4542CDC4CD385 /* MPCombinedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCombinedViewController.h; sourceTree = "<group>"; };
|
93D39CF8ADF4542CDC4CD385 /* MPCombinedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCombinedViewController.h; sourceTree = "<group>"; };
|
||||||
|
93D39D4E713564B7654341B0 /* mpw-algorithm_v3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v3.c"; sourceTree = "<group>"; };
|
||||||
93D39D6604447D7708039155 /* MPAnswersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAnswersViewController.h; sourceTree = "<group>"; };
|
93D39D6604447D7708039155 /* MPAnswersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAnswersViewController.h; sourceTree = "<group>"; };
|
||||||
93D39D8A953779B35403AF6E /* PearlUICollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUICollectionView.m; sourceTree = "<group>"; };
|
93D39D8A953779B35403AF6E /* PearlUICollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUICollectionView.m; sourceTree = "<group>"; };
|
||||||
93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = "<group>"; };
|
93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = "<group>"; };
|
||||||
@@ -551,6 +555,7 @@
|
|||||||
93D39F556F2F142740A65E59 /* MPWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPWebViewController.h; sourceTree = "<group>"; };
|
93D39F556F2F142740A65E59 /* MPWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPWebViewController.h; sourceTree = "<group>"; };
|
||||||
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = "<group>"; };
|
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = "<group>"; };
|
||||||
93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+PearlFullDescription.m"; sourceTree = "<group>"; };
|
93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+PearlFullDescription.m"; sourceTree = "<group>"; };
|
||||||
|
93D39FD9623E8D5571C0AEB3 /* MPAlgorithmV3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV3.m; sourceTree = "<group>"; };
|
||||||
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||||
DA071BF1190187FE00179766 /* empty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "empty@2x.png"; sourceTree = "<group>"; };
|
DA071BF1190187FE00179766 /* empty@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "empty@2x.png"; sourceTree = "<group>"; };
|
||||||
DA071BF2190187FE00179766 /* empty.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = empty.png; sourceTree = "<group>"; };
|
DA071BF2190187FE00179766 /* empty.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = empty.png; sourceTree = "<group>"; };
|
||||||
@@ -1592,7 +1597,6 @@
|
|||||||
DA4DA1DA1564471F00F6F596 /* libuicolor-utilities.a in Frameworks */,
|
DA4DA1DA1564471F00F6F596 /* libuicolor-utilities.a in Frameworks */,
|
||||||
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */,
|
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */,
|
||||||
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */,
|
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */,
|
||||||
DA6773251A43B660004F356A /* libscryptenc-ios.a in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -1614,6 +1618,10 @@
|
|||||||
93D39B573E4DE98BAE518215 /* build */,
|
93D39B573E4DE98BAE518215 /* build */,
|
||||||
93D3979016BF0C5B29D1340D /* distribute */,
|
93D3979016BF0C5B29D1340D /* distribute */,
|
||||||
93D39ACD33E79386E6F33601 /* install */,
|
93D39ACD33E79386E6F33601 /* install */,
|
||||||
|
93D390A99850139D0FF0211E /* mpw-algorithm_v0.c */,
|
||||||
|
93D396F918E6470DB846C17F /* mpw-algorithm_v1.c */,
|
||||||
|
93D390A3B351FEF1B9EDAB56 /* mpw-algorithm_v2.c */,
|
||||||
|
93D39D4E713564B7654341B0 /* mpw-algorithm_v3.c */,
|
||||||
93D3969393A3A46BD27D7078 /* mpw-algorithm.c */,
|
93D3969393A3A46BD27D7078 /* mpw-algorithm.c */,
|
||||||
93D3990D850D76A94C6B7A4D /* mpw-algorithm.h */,
|
93D3990D850D76A94C6B7A4D /* mpw-algorithm.h */,
|
||||||
93D39B70138D0E28F7D5E86B /* mpw-bench.c */,
|
93D39B70138D0E28F7D5E86B /* mpw-bench.c */,
|
||||||
@@ -1626,7 +1634,6 @@
|
|||||||
93D396C311C3725870343EE0 /* mpw-util.c */,
|
93D396C311C3725870343EE0 /* mpw-util.c */,
|
||||||
93D39CF7DB942C69D1C5D6BE /* mpw-util.h */,
|
93D39CF7DB942C69D1C5D6BE /* mpw-util.h */,
|
||||||
93D39245A478883C672818F3 /* mpw.bashrc */,
|
93D39245A478883C672818F3 /* mpw.bashrc */,
|
||||||
93D3944F4D55D2A37EF6021B /* VERSION */,
|
|
||||||
);
|
);
|
||||||
name = C;
|
name = C;
|
||||||
path = ../../C;
|
path = ../../C;
|
||||||
@@ -2586,6 +2593,8 @@
|
|||||||
93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */,
|
93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */,
|
||||||
93D399A8E3181B442D347CD7 /* MPAlgorithmV2.m */,
|
93D399A8E3181B442D347CD7 /* MPAlgorithmV2.m */,
|
||||||
93D39A97A7D48CB3B784194D /* MPAlgorithmV2.h */,
|
93D39A97A7D48CB3B784194D /* MPAlgorithmV2.h */,
|
||||||
|
93D394D73F5BC92297CE8D7B /* MPAlgorithmV3.h */,
|
||||||
|
93D39FD9623E8D5571C0AEB3 /* MPAlgorithmV3.m */,
|
||||||
);
|
);
|
||||||
name = ObjC;
|
name = ObjC;
|
||||||
path = ..;
|
path = ..;
|
||||||
@@ -3527,7 +3536,6 @@
|
|||||||
93D39CEA71BD460ED4876920 /* build in Resources */,
|
93D39CEA71BD460ED4876920 /* build in Resources */,
|
||||||
93D390228D0B8ED51C0AFDB4 /* bashlib in Resources */,
|
93D390228D0B8ED51C0AFDB4 /* bashlib in Resources */,
|
||||||
93D39DF2E77B937D77C10414 /* install in Resources */,
|
93D39DF2E77B937D77C10414 /* install in Resources */,
|
||||||
93D39711B6D873F37E8B9B2D /* VERSION in Resources */,
|
|
||||||
93D3958C13B557F60F63C72B /* distribute in Resources */,
|
93D3958C13B557F60F63C72B /* distribute in Resources */,
|
||||||
93D39FAE1BB6A393BFE15FD0 /* mpw.bashrc in Resources */,
|
93D39FAE1BB6A393BFE15FD0 /* mpw.bashrc in Resources */,
|
||||||
);
|
);
|
||||||
@@ -3628,6 +3636,7 @@
|
|||||||
93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */,
|
93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */,
|
||||||
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */,
|
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */,
|
||||||
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */,
|
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */,
|
||||||
|
DAADBFE01A68763B00F7A756 /* mpw-algorithm.c in Sources */,
|
||||||
93D39EAA4D064193074D3021 /* MPFixable.m in Sources */,
|
93D39EAA4D064193074D3021 /* MPFixable.m in Sources */,
|
||||||
DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */,
|
DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */,
|
||||||
93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */,
|
93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */,
|
||||||
@@ -3642,6 +3651,7 @@
|
|||||||
93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */,
|
93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */,
|
||||||
93D395B715D15F2B56F2A2EE /* mpw-types.c in Sources */,
|
93D395B715D15F2B56F2A2EE /* mpw-types.c in Sources */,
|
||||||
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */,
|
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */,
|
||||||
|
93D39577FD8BB0945DB2F0A3 /* MPAlgorithmV3.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -3994,6 +4004,13 @@
|
|||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
"-lscryptenc-ios",
|
||||||
|
"-framework",
|
||||||
|
Reveal,
|
||||||
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-lscryptenc-ios-sim",
|
||||||
"-framework",
|
"-framework",
|
||||||
Reveal,
|
Reveal,
|
||||||
);
|
);
|
||||||
@@ -4023,6 +4040,14 @@
|
|||||||
"\"$(SRCROOT)/../../../External/Pearl/Pearl-Crypto/lib\"",
|
"\"$(SRCROOT)/../../../External/Pearl/Pearl-Crypto/lib\"",
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
);
|
);
|
||||||
|
OTHER_LDFLAGS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-lscryptenc-ios",
|
||||||
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-lscryptenc-ios-sim",
|
||||||
|
);
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "59b587d0-3ef3-4691-9f12-c48f7f283002";
|
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "59b587d0-3ef3-4691-9f12-c48f7f283002";
|
||||||
SKIP_INSTALL = NO;
|
SKIP_INSTALL = NO;
|
||||||
@@ -4130,6 +4155,14 @@
|
|||||||
"\"$(SRCROOT)/../../../External/Pearl/Pearl-Crypto/lib\"",
|
"\"$(SRCROOT)/../../../External/Pearl/Pearl-Crypto/lib\"",
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
);
|
);
|
||||||
|
OTHER_LDFLAGS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-lscryptenc-ios",
|
||||||
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-lscryptenc-ios-sim",
|
||||||
|
);
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "a1d8cfc8-b8db-4544-af34-28cc75e46c40";
|
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "a1d8cfc8-b8db-4544-af34-28cc75e46c40";
|
||||||
SKIP_INSTALL = NO;
|
SKIP_INSTALL = NO;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6245" systemVersion="13E28" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="Q1S-vU-GGO">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="Q1S-vU-GGO">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment defaultVersion="1792" identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||||
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
|
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
|
||||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||||
@@ -182,10 +182,10 @@
|
|||||||
<constraint firstAttribute="width" secondItem="Aca-he-7Qi" secondAttribute="height" multiplier="1:1" id="a8Q-UO-SH0"/>
|
<constraint firstAttribute="width" secondItem="Aca-he-7Qi" secondAttribute="height" multiplier="1:1" id="a8Q-UO-SH0"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</imageView>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0Sa-Vg-EEI" userLabel="Name Backdrop">
|
<view contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Sa-Vg-EEI" userLabel="Name Backdrop">
|
||||||
<rect key="frame" x="43" y="263" width="128.5" height="16"/>
|
<rect key="frame" x="43" y="263" width="128.5" height="16"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalCompressionResistancePriority="1000" text="Maarten Billemont" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cLT-s0-4SQ" userLabel="Name Field">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalCompressionResistancePriority="1000" misplaced="YES" text="Maarten Billemont" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cLT-s0-4SQ" userLabel="Name Field">
|
||||||
<rect key="frame" x="5" y="0.0" width="118.5" height="16"/>
|
<rect key="frame" x="5" y="0.0" width="118.5" height="16"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-ExtraBold" family="Exo 2.0" pointSize="13"/>
|
<fontDescription key="fontDescription" name="Exo2.0-ExtraBold" family="Exo 2.0" pointSize="13"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
<outlet property="delegate" destination="S8q-YF-Kt9" id="det-Eh-phM"/>
|
<outlet property="delegate" destination="S8q-YF-Kt9" id="det-Eh-phM"/>
|
||||||
</connections>
|
</connections>
|
||||||
</collectionView>
|
</collectionView>
|
||||||
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9u7-pu-Wtv" userLabel="Previous Avatar">
|
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9u7-pu-Wtv" userLabel="Previous Avatar">
|
||||||
<rect key="frame" x="0.0" y="244" width="44" height="53"/>
|
<rect key="frame" x="0.0" y="244" width="44" height="53"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="44" id="Ay6-Jg-c3T"/>
|
<constraint firstAttribute="width" constant="44" id="Ay6-Jg-c3T"/>
|
||||||
@@ -262,7 +262,7 @@
|
|||||||
<action selector="changeAvatar:" destination="S8q-YF-Kt9" eventType="touchUpInside" id="lNu-mK-3zD"/>
|
<action selector="changeAvatar:" destination="S8q-YF-Kt9" eventType="touchUpInside" id="lNu-mK-3zD"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fUK-gJ-NRE" userLabel="Next Avatar">
|
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fUK-gJ-NRE" userLabel="Next Avatar">
|
||||||
<rect key="frame" x="331" y="244" width="44" height="53"/>
|
<rect key="frame" x="331" y="244" width="44" height="53"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="44" id="oAm-YX-Fx5"/>
|
<constraint firstAttribute="width" constant="44" id="oAm-YX-Fx5"/>
|
||||||
@@ -297,20 +297,20 @@
|
|||||||
<outlet property="delegate" destination="S8q-YF-Kt9" id="5u3-XN-LOe"/>
|
<outlet property="delegate" destination="S8q-YF-Kt9" id="5u3-XN-LOe"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fdS-zb-K9I" userLabel="Entry Tip">
|
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fdS-zb-K9I" userLabel="Entry Tip">
|
||||||
<rect key="frame" x="71" y="-33" width="234.5" height="82.5"/>
|
<rect key="frame" x="71" y="-33" width="234.5" height="82.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="g2g-5i-er4">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="g2g-5i-er4">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="234.5" height="82.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="234.5" height="82.5"/>
|
||||||
<rect key="contentStretch" x="0.15000000000000002" y="0.14999999999999999" width="0.69999999999999973" height="0.44999999999999996"/>
|
<rect key="contentStretch" x="0.15000000000000002" y="0.14999999999999999" width="0.69999999999999973" height="0.44999999999999996"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Looks like a typo!" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="ZI7-qg-7OW">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Looks like a typo!" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="ZI7-qg-7OW">
|
||||||
<rect key="frame" x="20" y="12" width="194.5" height="17"/>
|
<rect key="frame" x="20" y="12" width="194.5" height="17"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Try again; the password was wrong." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KhE-Yj-Kvm">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Try again; the password was wrong." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KhE-Yj-Kvm">
|
||||||
<rect key="frame" x="20" y="37" width="194.5" height="14.5"/>
|
<rect key="frame" x="20" y="37" width="194.5" height="14.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
@@ -369,14 +369,14 @@
|
|||||||
<segue destination="Sd5-eW-Cx2" kind="modal" identifier="web" id="gtb-zE-u9H"/>
|
<segue destination="Sd5-eW-Cx2" kind="modal" identifier="web" id="gtb-zE-u9H"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="069-Pu-yXe" userLabel="Thanks Tip">
|
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="069-Pu-yXe" userLabel="Thanks Tip">
|
||||||
<rect key="frame" x="72" y="0.0" width="232.5" height="60"/>
|
<rect key="frame" x="72" y="0.0" width="232.5" height="60"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="Z8P-ZK-aS0">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="Z8P-ZK-aS0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="232.5" height="60"/>
|
<rect key="frame" x="0.0" y="0.0" width="232.5" height="60"/>
|
||||||
<rect key="contentStretch" x="0.15000000000000002" y="0.0" width="0.69999999999999973" height="1"/>
|
<rect key="contentStretch" x="0.15000000000000002" y="0.0" width="0.69999999999999973" height="1"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Why is Master Password free?" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="BLV-3x-Q0z">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Why is Master Password free?" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="BLV-3x-Q0z">
|
||||||
<rect key="frame" x="20" y="12" width="192.5" height="17"/>
|
<rect key="frame" x="20" y="12" width="192.5" height="17"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
@@ -407,14 +407,14 @@
|
|||||||
<userDefinedRuntimeAttribute type="boolean" keyPath="ignoreTouches" value="YES"/>
|
<userDefinedRuntimeAttribute type="boolean" keyPath="ignoreTouches" value="YES"/>
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
</view>
|
</view>
|
||||||
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cF4-TE-GEj" userLabel="Avatar Tip">
|
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cF4-TE-GEj" userLabel="Avatar Tip">
|
||||||
<rect key="frame" x="49.5" y="184" width="276" height="60"/>
|
<rect key="frame" x="49.5" y="184" width="276" height="60"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="V4W-bK-age">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="V4W-bK-age">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="276" height="60"/>
|
<rect key="frame" x="0.0" y="0.0" width="276" height="60"/>
|
||||||
<rect key="contentStretch" x="0.15000000000000002" y="0.0" width="0.69999999999999973" height="1"/>
|
<rect key="contentStretch" x="0.15000000000000002" y="0.0" width="0.69999999999999973" height="1"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Change your avatar using the arrows." textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="MoM-8d-jlm">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Change your avatar using the arrows." textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="MoM-8d-jlm">
|
||||||
<rect key="frame" x="20" y="12" width="236" height="17"/>
|
<rect key="frame" x="20" y="12" width="236" height="17"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
@@ -432,14 +432,14 @@
|
|||||||
<constraint firstAttribute="trailing" secondItem="MoM-8d-jlm" secondAttribute="trailing" constant="20" id="Hc3-Mb-x5c"/>
|
<constraint firstAttribute="trailing" secondItem="MoM-8d-jlm" secondAttribute="trailing" constant="20" id="Hc3-Mb-x5c"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0Um-Ot-hI6" userLabel="Preferences Tip">
|
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Um-Ot-hI6" userLabel="Preferences Tip">
|
||||||
<rect key="frame" x="72" y="42" width="230" height="60"/>
|
<rect key="frame" x="72" y="42" width="230" height="60"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="5H0-ml-Uso">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="5H0-ml-Uso">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="230" height="60"/>
|
<rect key="frame" x="0.0" y="0.0" width="230" height="60"/>
|
||||||
<rect key="contentStretch" x="0.15000000000000002" y="0.0" width="0.69999999999999973" height="1"/>
|
<rect key="contentStretch" x="0.15000000000000002" y="0.0" width="0.69999999999999973" height="1"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Tap for preferences and more." textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Er5-X1-ejQ">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Tap for preferences and more." textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Er5-X1-ejQ">
|
||||||
<rect key="frame" x="20" y="31.5" width="190" height="17"/>
|
<rect key="frame" x="20" y="31.5" width="190" height="17"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
@@ -847,7 +847,7 @@
|
|||||||
<constraint firstAttribute="height" constant="110" id="zBf-EA-iDN"/>
|
<constraint firstAttribute="height" constant="110" id="zBf-EA-iDN"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</imageView>
|
||||||
<button opaque="NO" alpha="0.69999998807907104" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DzC-Ts-gew" userLabel="Previous Avatar">
|
<button opaque="NO" alpha="0.69999998807907104" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DzC-Ts-gew" userLabel="Previous Avatar">
|
||||||
<rect key="frame" x="20" y="117" width="44" height="53"/>
|
<rect key="frame" x="20" y="117" width="44" height="53"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="44" id="1Wu-gS-flK"/>
|
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="44" id="1Wu-gS-flK"/>
|
||||||
@@ -861,7 +861,7 @@
|
|||||||
<action selector="previousAvatar:" destination="JFc-sj-awD" eventType="touchUpInside" id="D92-6I-zFd"/>
|
<action selector="previousAvatar:" destination="JFc-sj-awD" eventType="touchUpInside" id="D92-6I-zFd"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" alpha="0.69999998807907104" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yAf-fc-SKl" userLabel="Next Avatar">
|
<button opaque="NO" alpha="0.69999998807907104" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yAf-fc-SKl" userLabel="Next Avatar">
|
||||||
<rect key="frame" x="311" y="117" width="44" height="53"/>
|
<rect key="frame" x="311" y="117" width="44" height="53"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="44" id="pEf-Vp-D7s"/>
|
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="44" id="pEf-Vp-D7s"/>
|
||||||
@@ -1040,13 +1040,13 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="152"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="152"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sPw-mV-mFF">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sPw-mV-mFF">
|
||||||
<rect key="frame" x="20" y="4" width="335" height="12"/>
|
<rect key="frame" x="20" y="4" width="335" height="12"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="10"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="10"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rl7-cr-FHf">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rl7-cr-FHf">
|
||||||
<rect key="frame" x="20" y="24" width="335" height="26"/>
|
<rect key="frame" x="20" y="24" width="335" height="26"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<state key="normal" title="Home Page">
|
<state key="normal" title="Home Page">
|
||||||
@@ -1056,7 +1056,7 @@
|
|||||||
<action selector="homePageButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="ptD-cv-NMr"/>
|
<action selector="homePageButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="ptD-cv-NMr"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="epW-Rm-9St">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="epW-Rm-9St">
|
||||||
<rect key="frame" x="20" y="58" width="335" height="26"/>
|
<rect key="frame" x="20" y="58" width="335" height="26"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<state key="normal" title="Understanding Master Password's Security">
|
<state key="normal" title="Understanding Master Password's Security">
|
||||||
@@ -1066,7 +1066,7 @@
|
|||||||
<action selector="securityButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="Efv-cp-Xfh"/>
|
<action selector="securityButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="Efv-cp-Xfh"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LTN-ch-h8D">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LTN-ch-h8D">
|
||||||
<rect key="frame" x="20" y="92" width="335" height="26"/>
|
<rect key="frame" x="20" y="92" width="335" height="26"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<state key="normal" title="Get the Master Password source code">
|
<state key="normal" title="Get the Master Password source code">
|
||||||
@@ -1076,7 +1076,7 @@
|
|||||||
<action selector="sourceButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="Y3O-di-CZo"/>
|
<action selector="sourceButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="Y3O-di-CZo"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z60-lc-Nka">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z60-lc-Nka">
|
||||||
<rect key="frame" x="20" y="126" width="335" height="26"/>
|
<rect key="frame" x="20" y="126" width="335" height="26"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<state key="normal" title="Send Thanks">
|
<state key="normal" title="Send Thanks">
|
||||||
@@ -1235,10 +1235,10 @@
|
|||||||
<constraint firstItem="Iwe-rQ-ma0" firstAttribute="top" secondItem="w2g-zN-1wZ" secondAttribute="top" id="q2j-Aa-lEd"/>
|
<constraint firstItem="Iwe-rQ-ma0" firstAttribute="top" secondItem="w2g-zN-1wZ" secondAttribute="top" id="q2j-Aa-lEd"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2tX-WK-ASq" userLabel="Password Container">
|
<view contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2tX-WK-ASq" userLabel="Password Container">
|
||||||
<rect key="frame" x="0.0" y="20" width="300" height="43"/>
|
<rect key="frame" x="0.0" y="20" width="300" height="43"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="CuzaSasy3*Rimo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="blw-Ou-8I8" userLabel="Password">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="CuzaSasy3*Rimo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="blw-Ou-8I8" userLabel="Password">
|
||||||
<rect key="frame" x="8" y="0.0" width="284" height="31"/>
|
<rect key="frame" x="8" y="0.0" width="284" height="31"/>
|
||||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
||||||
@@ -1248,7 +1248,7 @@
|
|||||||
<outlet property="delegate" destination="W2g-yv-V3V" id="YKp-IE-zEQ"/>
|
<outlet property="delegate" destination="W2g-yv-V3V" id="YKp-IE-zEQ"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="left" text="> age of the universe" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="wfM-xz-roR" userLabel="Strength">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="left" misplaced="YES" text="> age of the universe" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="wfM-xz-roR" userLabel="Strength">
|
||||||
<rect key="frame" x="0.0" y="31" width="300" height="12"/>
|
<rect key="frame" x="0.0" y="31" width="300" height="12"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="10"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="10"/>
|
||||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -1298,7 +1298,7 @@
|
|||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LvK-28-fbm" userLabel="Settings Container">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LvK-28-fbm" userLabel="Settings Container">
|
||||||
<rect key="frame" x="300" y="0.0" width="300" height="100"/>
|
<rect key="frame" x="300" y="0.0" width="300" height="100"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IKd-Ot-0n4" userLabel="Upgrade">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IKd-Ot-0n4" userLabel="Upgrade">
|
||||||
<rect key="frame" x="-15" y="56" width="44" height="44"/>
|
<rect key="frame" x="-15" y="56" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||||
<constraints>
|
<constraints>
|
||||||
@@ -1318,7 +1318,7 @@
|
|||||||
<action selector="doUpgrade:" destination="W2g-yv-V3V" eventType="touchUpInside" id="kTZ-AM-qGa"/>
|
<action selector="doUpgrade:" destination="W2g-yv-V3V" eventType="touchUpInside" id="kTZ-AM-qGa"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vGk-t6-hZn" userLabel="Answers">
|
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vGk-t6-hZn" userLabel="Answers">
|
||||||
<rect key="frame" x="29" y="56" width="44" height="44"/>
|
<rect key="frame" x="29" y="56" width="44" height="44"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
<accessibility key="accessibilityConfiguration" hint="Upgrades the password."/>
|
||||||
<constraints>
|
<constraints>
|
||||||
@@ -1338,7 +1338,7 @@
|
|||||||
<segue destination="aow-In-vb8" kind="custom" identifier="answers" customClass="MPOverlaySegue" id="5Wo-YZ-8HZ"/>
|
<segue destination="aow-In-vb8" kind="custom" identifier="answers" customClass="MPOverlaySegue" id="5Wo-YZ-8HZ"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="PKP-M9-T8E" userLabel="Counter">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" misplaced="YES" text="1" textAlignment="right" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="PKP-M9-T8E" userLabel="Counter">
|
||||||
<rect key="frame" x="73" y="67" width="7" height="21.5"/>
|
<rect key="frame" x="73" y="67" width="7" height="21.5"/>
|
||||||
<accessibility key="accessibilityConfiguration" hint="Site's counter."/>
|
<accessibility key="accessibilityConfiguration" hint="Site's counter."/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
||||||
@@ -1599,14 +1599,14 @@
|
|||||||
<outlet property="delegate" destination="nkY-z6-8jd" id="ENG-q5-XwX"/>
|
<outlet property="delegate" destination="nkY-z6-8jd" id="ENG-q5-XwX"/>
|
||||||
</connections>
|
</connections>
|
||||||
</searchBar>
|
</searchBar>
|
||||||
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LEX-BK-PdS" userLabel="Bad Name Tip">
|
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LEX-BK-PdS" userLabel="Bad Name Tip">
|
||||||
<rect key="frame" x="37" y="86" width="300.5" height="75.5"/>
|
<rect key="frame" x="37" y="86" width="300.5" height="75.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Rt5-v4-I0R">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Rt5-v4-I0R">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="300.5" height="75.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="300.5" height="75.5"/>
|
||||||
<rect key="contentStretch" x="0.050000000000000003" y="0.49999999999999994" width="0.90000000000000002" height="0.20000000000000001"/>
|
<rect key="contentStretch" x="0.050000000000000003" y="0.49999999999999994" width="0.90000000000000002" height="0.20000000000000001"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" verticalCompressionResistancePriority="1000" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Eie-8u-hV2">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" verticalCompressionResistancePriority="1000" misplaced="YES" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Eie-8u-hV2">
|
||||||
<rect key="frame" x="20" y="26" width="260.5" height="43.5"/>
|
<rect key="frame" x="20" y="26" width="260.5" height="43.5"/>
|
||||||
<string key="text">Try using exclusively bare domain names.
|
<string key="text">Try using exclusively bare domain names.
|
||||||
Avoid capitals and use @ to include a user name.
|
Avoid capitals and use @ to include a user name.
|
||||||
@@ -1750,7 +1750,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<rect key="frame" x="0.0" y="0.5" width="375" height="333.5"/>
|
<rect key="frame" x="0.0" y="0.5" width="375" height="333.5"/>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1lc-e7-Qme" userLabel="Emergency Generator">
|
<view contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1lc-e7-Qme" userLabel="Emergency Generator">
|
||||||
<rect key="frame" x="20" y="140" width="335" height="387"/>
|
<rect key="frame" x="20" y="140" width="335" height="387"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Emergency Generator" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="4Lh-s0-Dbt">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Emergency Generator" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="4Lh-s0-Dbt">
|
||||||
@@ -1761,7 +1761,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
<size key="shadowOffset" width="0.0" height="1"/>
|
<size key="shadowOffset" width="0.0" height="1"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Generate your password without logging in. Great for if you're borrowing a friend's device or are having trouble logging in." lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="vHS-3A-Tae">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Generate your password without logging in. Great for if you're borrowing a friend's device or are having trouble logging in." lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="vHS-3A-Tae">
|
||||||
<rect key="frame" x="20" y="49" width="295" height="51.5"/>
|
<rect key="frame" x="20" y="49" width="295" height="51.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -1769,7 +1769,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
<size key="shadowOffset" width="0.0" height="1"/>
|
<size key="shadowOffset" width="0.0" height="1"/>
|
||||||
</label>
|
</label>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Name" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="XAC-Da-lpf" userLabel="User Name">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Name" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="XAC-Da-lpf" userLabel="User Name">
|
||||||
<rect key="frame" x="20" y="109" width="295" height="30"/>
|
<rect key="frame" x="20" y="109" width="295" height="30"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES"/>
|
<textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES"/>
|
||||||
@@ -1778,7 +1778,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<outlet property="delegate" destination="osn-5H-SWW" id="VQI-Lq-GWG"/>
|
<outlet property="delegate" destination="osn-5H-SWW" id="VQI-Lq-GWG"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Master Password" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="J46-0E-no3" userLabel="Master Password">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Master Password" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="J46-0E-no3" userLabel="Master Password">
|
||||||
<rect key="frame" x="20" y="147" width="295" height="30"/>
|
<rect key="frame" x="20" y="147" width="295" height="30"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES" secureTextEntry="YES"/>
|
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES" secureTextEntry="YES"/>
|
||||||
@@ -1787,7 +1787,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<outlet property="delegate" destination="osn-5H-SWW" id="bpf-YA-5XP"/>
|
<outlet property="delegate" destination="osn-5H-SWW" id="bpf-YA-5XP"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Site Name" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="56H-xR-09J" userLabel="Site Name">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Site Name" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="56H-xR-09J" userLabel="Site Name">
|
||||||
<rect key="frame" x="20" y="185" width="295" height="30"/>
|
<rect key="frame" x="20" y="185" width="295" height="30"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL" keyboardAppearance="alert" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
|
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL" keyboardAppearance="alert" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
|
||||||
@@ -1796,7 +1796,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<outlet property="delegate" destination="osn-5H-SWW" id="QgA-TS-5KG"/>
|
<outlet property="delegate" destination="osn-5H-SWW" id="QgA-TS-5KG"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="e4b-Iv-Pk9" userLabel="Type">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="e4b-Iv-Pk9" userLabel="Type">
|
||||||
<rect key="frame" x="20" y="223" width="295" height="29"/>
|
<rect key="frame" x="20" y="223" width="295" height="29"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Max"/>
|
<segment title="Max"/>
|
||||||
@@ -1811,7 +1811,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="valueChanged" id="sRc-3g-wqY"/>
|
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="valueChanged" id="sRc-3g-wqY"/>
|
||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Counter" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="cAo-K2-E23">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Counter" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="cAo-K2-E23">
|
||||||
<rect key="frame" x="20" y="262.5" width="64" height="21.5"/>
|
<rect key="frame" x="20" y="262.5" width="64" height="21.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -1819,13 +1819,13 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
<size key="shadowOffset" width="0.0" height="1"/>
|
<size key="shadowOffset" width="0.0" height="1"/>
|
||||||
</label>
|
</label>
|
||||||
<stepper opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" maximumValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="ZPT-EI-yuv" userLabel="Counter">
|
<stepper opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" maximumValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="ZPT-EI-yuv" userLabel="Counter">
|
||||||
<rect key="frame" x="221" y="259" width="94" height="29"/>
|
<rect key="frame" x="221" y="259" width="94" height="29"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="valueChanged" id="eQA-3X-uc9"/>
|
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="valueChanged" id="eQA-3X-uc9"/>
|
||||||
</connections>
|
</connections>
|
||||||
</stepper>
|
</stepper>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="3Cd-XH-Wau">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="1" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="3Cd-XH-Wau">
|
||||||
<rect key="frame" x="206" y="262.5" width="7" height="20.5"/>
|
<rect key="frame" x="206" y="262.5" width="7" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -1866,10 +1866,10 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</state>
|
</state>
|
||||||
</button>
|
</button>
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="4sN-hm-xio">
|
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" misplaced="YES" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="4sN-hm-xio">
|
||||||
<rect key="frame" x="149" y="329" width="37" height="37"/>
|
<rect key="frame" x="149" y="329" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="XapaNuwjFihn6$" textAlignment="center" lineBreakMode="clip" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bHR-he-dnZ" userLabel="Password Label">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="XapaNuwjFihn6$" textAlignment="center" lineBreakMode="clip" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bHR-he-dnZ" userLabel="Password Label">
|
||||||
<rect key="frame" x="20" y="328" width="295" height="39"/>
|
<rect key="frame" x="20" y="328" width="295" height="39"/>
|
||||||
<gestureRecognizers/>
|
<gestureRecognizers/>
|
||||||
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="30"/>
|
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="30"/>
|
||||||
@@ -1880,7 +1880,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<outletCollection property="gestureRecognizers" destination="gJb-50-mjy" appends="YES" id="3Ho-tp-mDE"/>
|
<outletCollection property="gestureRecognizers" destination="gJb-50-mjy" appends="YES" id="3Ho-tp-mDE"/>
|
||||||
</connections>
|
</connections>
|
||||||
</label>
|
</label>
|
||||||
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="beo-cJ-jIn" userLabel="View - Content Tip">
|
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="beo-cJ-jIn" userLabel="View - Content Tip">
|
||||||
<rect key="frame" x="62" y="287.5" width="210" height="60"/>
|
<rect key="frame" x="62" y="287.5" width="210" height="60"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="nyL-cO-aPa">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="nyL-cO-aPa">
|
||||||
@@ -2082,7 +2082,7 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<pageControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="3" translatesAutoresizingMaskIntoConstraints="NO" id="8A2-ly-WTX">
|
<pageControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="3" translatesAutoresizingMaskIntoConstraints="NO" id="8A2-ly-WTX">
|
||||||
<rect key="frame" x="168" y="630" width="39" height="37"/>
|
<rect key="frame" x="168" y="630" width="39" height="37"/>
|
||||||
</pageControl>
|
</pageControl>
|
||||||
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="i2y-lo-HXR">
|
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" misplaced="YES" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="i2y-lo-HXR">
|
||||||
<rect key="frame" x="0.0" y="64" width="375" height="476"/>
|
<rect key="frame" x="0.0" y="64" width="375" height="476"/>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="m8O-kY-22j">
|
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="m8O-kY-22j">
|
||||||
@@ -2122,13 +2122,13 @@ eg. apple.com, rmitchell@twitter.com</string>
|
|||||||
<outlet property="delegate" destination="z9O-w0-6oR" id="RcD-gy-C1W"/>
|
<outlet property="delegate" destination="z9O-w0-6oR" id="RcD-gy-C1W"/>
|
||||||
</connections>
|
</connections>
|
||||||
</collectionView>
|
</collectionView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="To begin, tap the "New User" icon and add yourself as a user to the application." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ciw-56-nNy" userLabel="Caption">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="To begin, tap the "New User" icon and add yourself as a user to the application." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ciw-56-nNy" userLabel="Caption">
|
||||||
<rect key="frame" x="8" y="548" width="359" height="82"/>
|
<rect key="frame" x="8" y="548" width="359" height="82"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="13"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="13"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label hidden="YES" opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oop-Ff-gbz" userLabel="Caption Height Strut">
|
<label hidden="YES" opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oop-Ff-gbz" userLabel="Caption Height Strut">
|
||||||
<rect key="frame" x="8" y="548" width="1" height="82"/>
|
<rect key="frame" x="8" y="548" width="1" height="82"/>
|
||||||
<string key="text" base64-UTF8="YES">
|
<string key="text" base64-UTF8="YES">
|
||||||
CgoKCgoKCgoKCgoKCg
|
CgoKCgoKCgoKCgoKCg
|
||||||
@@ -2308,7 +2308,7 @@ Suspendisse potenti. Etiam ut nisi id augue tempor ultrices et sit amet sapien.
|
|||||||
<rect key="frame" x="163" y="532" width="51" height="31"/>
|
<rect key="frame" x="163" y="532" width="51" height="31"/>
|
||||||
<color key="onTintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="onTintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
</switch>
|
</switch>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e80-98-V6D">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e80-98-V6D">
|
||||||
<rect key="frame" x="20" y="137" width="335" height="151.5"/>
|
<rect key="frame" x="20" y="137" width="335" height="151.5"/>
|
||||||
<string key="text">The right balance between security and convenience is often very personal.
|
<string key="text">The right balance between security and convenience is often very personal.
|
||||||
|
|
||||||
@@ -2392,7 +2392,7 @@ However, it means that anyone who finds your device unlocked can do the same.</s
|
|||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="J90-SQ-ljR">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="J90-SQ-ljR">
|
||||||
<rect key="frame" x="20" y="136" width="335" height="522.5"/>
|
<rect key="frame" x="20" y="136" width="335" height="522.5"/>
|
||||||
<attributedString key="attributedText">
|
<attributedString key="attributedText">
|
||||||
<fragment content="The passwords generated by this app are not stored but ">
|
<fragment content="The passwords generated by this app are not stored but ">
|
||||||
@@ -2580,7 +2580,7 @@ See </string>
|
|||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="cef-sc-aph">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="cef-sc-aph">
|
||||||
<rect key="frame" x="168" y="100" width="37" height="37"/>
|
<rect key="frame" x="168" y="100" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="3" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FWu-V6-mLT">
|
<label opaque="NO" userInteractionEnabled="NO" tag="3" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FWu-V6-mLT">
|
||||||
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2645,7 +2645,7 @@ See </string>
|
|||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="X2g-Go-2Hz">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="X2g-Go-2Hz">
|
||||||
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="N9y-ue-L8d">
|
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="N9y-ue-L8d">
|
||||||
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2691,7 +2691,7 @@ See </string>
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="iOS Integration" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zch-DS-J3I">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" misplaced="YES" text="iOS Integration" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zch-DS-J3I">
|
||||||
<rect key="frame" x="20" y="226" width="244" height="20.5"/>
|
<rect key="frame" x="20" y="226" width="244" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2710,13 +2710,13 @@ See </string>
|
|||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="yUe-TX-fli">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="yUe-TX-fli">
|
||||||
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ec8-P9-KPY">
|
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ec8-P9-KPY">
|
||||||
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Coming Soon" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3jH-eX-9N2">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" misplaced="YES" text="Coming Soon" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3jH-eX-9N2">
|
||||||
<rect key="frame" x="272" y="226" width="83" height="20.5"/>
|
<rect key="frame" x="272" y="226" width="83" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2756,7 +2756,7 @@ See </string>
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="TouchID Login" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e1D-jp-GBs">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" misplaced="YES" text="TouchID Login" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e1D-jp-GBs">
|
||||||
<rect key="frame" x="20" y="226" width="244.5" height="20.5"/>
|
<rect key="frame" x="20" y="226" width="244.5" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2775,13 +2775,13 @@ See </string>
|
|||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="Dv5-t7-lL1">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="Dv5-t7-lL1">
|
||||||
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yZX-ns-8oV">
|
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="✔︎" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yZX-ns-8oV">
|
||||||
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
<rect key="frame" x="200" y="-6" width="92.5" height="132"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="110"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Coming Soon" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZGg-O6-rsg">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" misplaced="YES" text="Coming Soon" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZGg-O6-rsg">
|
||||||
<rect key="frame" x="272" y="226" width="83" height="20.5"/>
|
<rect key="frame" x="272" y="226" width="83" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2821,13 +2821,13 @@ See </string>
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Fuel Top-Up" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jnv-uN-xeg">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" ambiguous="YES" misplaced="YES" text="Fuel Top-Up" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jnv-uN-xeg">
|
||||||
<rect key="frame" x="20" y="226" width="292" height="20.5"/>
|
<rect key="frame" x="20" y="226" width="292" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fz2-AO-aGW">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" ambiguous="YES" misplaced="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fz2-AO-aGW">
|
||||||
<rect key="frame" x="20" y="254" width="335" height="132"/>
|
<rect key="frame" x="20" y="254" width="335" height="132"/>
|
||||||
<string key="text">You really love Master Password and how it's solving your password problems. You're eager to encourage the maintenance, technical support and development of new features. I am a one-man shop, fuel enables me to allocate more work hours to Master Password.
|
<string key="text">You really love Master Password and how it's solving your password problems. You're eager to encourage the maintenance, technical support and development of new features. I am a one-man shop, fuel enables me to allocate more work hours to Master Password.
|
||||||
|
|
||||||
@@ -2840,22 +2840,22 @@ UPCOMING:
|
|||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_fuel.png" translatesAutoresizingMaskIntoConstraints="NO" id="PnG-hP-syh">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" image="thumb_fuel.png" translatesAutoresizingMaskIntoConstraints="NO" id="PnG-hP-syh">
|
||||||
<rect key="frame" x="88" y="20" width="198" height="198"/>
|
<rect key="frame" x="88" y="20" width="198" height="198"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="eS4-59-Xny">
|
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="eS4-59-Xny">
|
||||||
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
<rect key="frame" x="169" y="100" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="$2.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EbU-DV-fKF">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" ambiguous="YES" misplaced="YES" text="$2.95" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EbU-DV-fKF">
|
||||||
<rect key="frame" x="320" y="226" width="34.5" height="20.5"/>
|
<rect key="frame" x="320" y="226" width="34.5" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="meter_fuel.png" translatesAutoresizingMaskIntoConstraints="NO" id="aGb-QC-A92">
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" image="meter_fuel.png" translatesAutoresizingMaskIntoConstraints="NO" id="aGb-QC-A92">
|
||||||
<rect key="frame" x="261" y="208" width="12" height="10"/>
|
<rect key="frame" x="261" y="208" width="12" height="10"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dsR-fr-dY4">
|
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dsR-fr-dY4">
|
||||||
<rect key="frame" x="20" y="20" width="107" height="44"/>
|
<rect key="frame" x="20" y="20" width="107" height="44"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="44" id="W6p-kB-VBX"/>
|
<constraint firstAttribute="height" constant="44" id="W6p-kB-VBX"/>
|
||||||
@@ -2868,7 +2868,7 @@ UPCOMING:
|
|||||||
<action selector="toggleFuelConsumption:" destination="pdl-xv-zjX" eventType="touchUpInside" id="NkB-Dy-IeY"/>
|
<action selector="toggleFuelConsumption:" destination="pdl-xv-zjX" eventType="touchUpInside" id="NkB-Dy-IeY"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kYb-j4-32C">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" misplaced="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kYb-j4-32C">
|
||||||
<rect key="frame" x="20" y="64" width="117.5" height="26.5"/>
|
<rect key="frame" x="20" y="64" width="117.5" height="26.5"/>
|
||||||
<string key="text">fuel left: 0.3 work hours
|
<string key="text">fuel left: 0.3 work hours
|
||||||
invested: 3.7 work hours</string>
|
invested: 3.7 work hours</string>
|
||||||
@@ -2920,7 +2920,7 @@ invested: 3.7 work hours</string>
|
|||||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="Vjt-7c-BJ4">
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="Vjt-7c-BJ4">
|
||||||
<rect key="frame" x="169" y="20" width="37" height="37"/>
|
<rect key="frame" x="169" y="20" width="37" height="37"/>
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" text="Loading products..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ARC-xH-0U0">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" misplaced="YES" text="Loading products..." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ARC-xH-0U0">
|
||||||
<rect key="frame" x="114.5" y="97" width="145.5" height="20.5"/>
|
<rect key="frame" x="114.5" y="97" width="145.5" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -2944,7 +2944,7 @@ invested: 3.7 work hours</string>
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="152"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="152"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IOk-WZ-HJ8">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IOk-WZ-HJ8">
|
||||||
<rect key="frame" x="20" y="58" width="335" height="26"/>
|
<rect key="frame" x="20" y="58" width="335" height="26"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<state key="normal" title="Restore Previous Purchases">
|
<state key="normal" title="Restore Previous Purchases">
|
||||||
@@ -2954,7 +2954,7 @@ invested: 3.7 work hours</string>
|
|||||||
<action selector="restorePurchases:" destination="pdl-xv-zjX" eventType="touchUpInside" id="lKu-PL-PfX"/>
|
<action selector="restorePurchases:" destination="pdl-xv-zjX" eventType="touchUpInside" id="lKu-PL-PfX"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bCe-a3-cDC">
|
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bCe-a3-cDC">
|
||||||
<rect key="frame" x="8" y="24" width="359" height="26"/>
|
<rect key="frame" x="8" y="24" width="359" height="26"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
|
||||||
<state key="normal" title="Send Thanks">
|
<state key="normal" title="Send Thanks">
|
||||||
@@ -2964,7 +2964,7 @@ invested: 3.7 work hours</string>
|
|||||||
<action selector="sendThanks:" destination="pdl-xv-zjX" eventType="touchUpInside" id="r5l-3U-jCA"/>
|
<action selector="sendThanks:" destination="pdl-xv-zjX" eventType="touchUpInside" id="r5l-3U-jCA"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DxV-2L-bxL">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DxV-2L-bxL">
|
||||||
<rect key="frame" x="20" y="4" width="335" height="12"/>
|
<rect key="frame" x="20" y="4" width="335" height="12"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="10"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="10"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -3042,13 +3042,13 @@ invested: 3.7 work hours</string>
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Answer for lyndir.com:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tal-1I-HQw" userLabel="Title Label">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" misplaced="YES" text="Answer for lyndir.com:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tal-1I-HQw" userLabel="Title Label">
|
||||||
<rect key="frame" x="8" y="8" width="180" height="20.5"/>
|
<rect key="frame" x="8" y="8" width="180" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="hok petwuvaqu xixo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="GfC-j4-Qx7" userLabel="Answer Field">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="hok petwuvaqu xixo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="GfC-j4-Qx7" userLabel="Answer Field">
|
||||||
<rect key="frame" x="8" y="48" width="359" height="43"/>
|
<rect key="frame" x="8" y="48" width="359" height="43"/>
|
||||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
||||||
@@ -3132,7 +3132,7 @@ invested: 3.7 work hours</string>
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
<rect key="frame" x="0.0" y="0.0" width="287" height="96"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="mother" textAlignment="center" minimumFontSize="14" clearButtonMode="unlessEditing" translatesAutoresizingMaskIntoConstraints="NO" id="T2F-PD-Nw8" userLabel="Question Field">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="mother" textAlignment="center" minimumFontSize="14" clearButtonMode="unlessEditing" translatesAutoresizingMaskIntoConstraints="NO" id="T2F-PD-Nw8" userLabel="Question Field">
|
||||||
<rect key="frame" x="8" y="19" width="359" height="30"/>
|
<rect key="frame" x="8" y="19" width="359" height="30"/>
|
||||||
<color key="backgroundColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="0.5" colorSpace="calibratedRGB"/>
|
<color key="backgroundColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -3143,13 +3143,13 @@ invested: 3.7 work hours</string>
|
|||||||
<outlet property="delegate" destination="iFm-3w-hOv" id="olS-Rx-56Y"/>
|
<outlet property="delegate" destination="iFm-3w-hOv" id="olS-Rx-56Y"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="pifm gup balvabi yiz" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="3xA-ez-efa" userLabel="Answer Field">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="pifm gup balvabi yiz" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="3xA-ez-efa" userLabel="Answer Field">
|
||||||
<rect key="frame" x="20" y="90" width="335" height="31"/>
|
<rect key="frame" x="20" y="90" width="335" height="31"/>
|
||||||
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" keyboardAppearance="alert" returnKeyType="next"/>
|
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" keyboardAppearance="alert" returnKeyType="next"/>
|
||||||
</textField>
|
</textField>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Enter the single most significant word in the question above." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qqg-Ny-7Po">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" misplaced="YES" text="Enter the single most significant word in the question above." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qqg-Ny-7Po">
|
||||||
<rect key="frame" x="8" y="57" width="359" height="13.5"/>
|
<rect key="frame" x="8" y="57" width="359" height="13.5"/>
|
||||||
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="11"/>
|
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="11"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
@@ -3242,7 +3242,7 @@ invested: 3.7 work hours</string>
|
|||||||
<rect key="frame" x="163" y="532" width="51" height="31"/>
|
<rect key="frame" x="163" y="532" width="51" height="31"/>
|
||||||
<color key="onTintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="onTintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
</switch>
|
</switch>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yx2-Eh-hM0">
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yx2-Eh-hM0">
|
||||||
<rect key="frame" x="20" y="137" width="335" height="202"/>
|
<rect key="frame" x="20" y="137" width="335" height="202"/>
|
||||||
<string key="text">To make it easy for you to recognize and copy passwords manually using a keyboard or other means, Master Password makes your site passwords visible on your screen by default.
|
<string key="text">To make it easy for you to recognize and copy passwords manually using a keyboard or other means, Master Password makes your site passwords visible on your screen by default.
|
||||||
|
|
||||||
|
|||||||
32
MasterPassword/homebrew-mpw.rb
Normal file
32
MasterPassword/homebrew-mpw.rb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
require "formula"
|
||||||
|
|
||||||
|
class Mpw < Formula
|
||||||
|
homepage "http://masterpasswordapp.com"
|
||||||
|
url "https://ssl.masterpasswordapp.com/mpw-2.1-cli3-3-gd5ff215.tar.gz"
|
||||||
|
sha1 "c9fca230cd0c2b22082bc54fe85053219888212a"
|
||||||
|
|
||||||
|
depends_on "automake" => :build
|
||||||
|
depends_on "autoconf" => :build
|
||||||
|
depends_on "openssl"
|
||||||
|
|
||||||
|
resource "libscrypt" do
|
||||||
|
url "http://masterpasswordapp.com/libscrypt-b12b554.tar.gz"
|
||||||
|
sha1 "ee871e0f93a786c4e3622561f34565337cfdb815"
|
||||||
|
end
|
||||||
|
|
||||||
|
def install
|
||||||
|
resource("libscrypt").stage buildpath/"lib/scrypt"
|
||||||
|
touch "lib/scrypt/.unpacked"
|
||||||
|
|
||||||
|
ENV["targets"]="mpw mpw-tests"
|
||||||
|
system "./build"
|
||||||
|
system "./mpw-tests"
|
||||||
|
|
||||||
|
bin.install "mpw"
|
||||||
|
end
|
||||||
|
|
||||||
|
test do
|
||||||
|
assert_equal "Jejr5[RepuSosp",
|
||||||
|
shell_output("mpw -u 'Robert Lee Mitchell' -P 'banana colored duckling' masterpasswordapp.com").strip
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -101,6 +101,7 @@
|
|||||||
<p>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.</p>
|
<p>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.</p>
|
||||||
<p>Master Password itself generates very random passwords that look semi-legible, for instance <code>Togu3]ToxiBuzb</code>. Such passwords have been found to be very memorable while also being very high in entropy (hard to guess).</p>
|
<p>Master Password itself generates very random passwords that look semi-legible, for instance <code>Togu3]ToxiBuzb</code>. Such passwords have been found to be very memorable while also being very high in entropy (hard to guess).</p>
|
||||||
<p>A strategy that's gaining traction lately is that of combining words into a sentence. Some claim it's best for the sentence to make no grammatical sense, others dispute these claims. It's a fact, though, that if your attacker doesn't expect such a password, they're nearly impossible to defeat.</p>
|
<p>A strategy that's gaining traction lately is that of combining words into a sentence. Some claim it's best for the sentence to make no grammatical sense, others dispute these claims. It's a fact, though, that if your attacker doesn't expect such a password, they're nearly impossible to defeat.</p>
|
||||||
|
<p><iframe width="420" height="315" src="//www.youtube.com/embed/MSyIhapMdI8?start=109" frameborder="0" allowfullscreen></iframe></p>
|
||||||
<p>Let's sum these strategies up in a table, note that this type of comparison is very subjective.</p>
|
<p>Let's sum these strategies up in a table, note that this type of comparison is very subjective.</p>
|
||||||
<table>
|
<table>
|
||||||
<caption>Time to crack a master password</caption>
|
<caption>Time to crack a master password</caption>
|
||||||
|
|||||||
@@ -82,8 +82,7 @@
|
|||||||
<a title="iPhone, iPad, iPod touch" href="https://itunes.apple.com/app/id510296984" onclick="_gaq.push(['_trackPageview', '/outbound/ios']);">iPhone / iPad<img class="popup" src="img/ios.png" /></a> |
|
<a title="iPhone, iPad, iPod touch" href="https://itunes.apple.com/app/id510296984" onclick="_gaq.push(['_trackPageview', '/outbound/ios']);">iPhone / iPad<img class="popup" src="img/ios.png" /></a> |
|
||||||
<a title="Mac (graphical interface)" href="https://itunes.apple.com/app/id662763204" onclick="_gaq.push(['_trackPageview', '/outbound/gui/mac']);">Mac<img class="popup border" src="img/mac-gui.png" /></a> |
|
<a title="Mac (graphical interface)" href="https://itunes.apple.com/app/id662763204" onclick="_gaq.push(['_trackPageview', '/outbound/gui/mac']);">Mac<img class="popup border" src="img/mac-gui.png" /></a> |
|
||||||
<a title="Mac, Linux, UNIX, Windows (graphical interface)" href="https://ssl.masterpasswordapp.com/masterpassword-gui.jar" onclick="_gaq.push(['_trackPageview', '/outbound/gui/java']);">Desktop (Java)<img class="popup" src="img/java-gui.png" /></a> |
|
<a title="Mac, Linux, UNIX, Windows (graphical interface)" href="https://ssl.masterpasswordapp.com/masterpassword-gui.jar" onclick="_gaq.push(['_trackPageview', '/outbound/gui/java']);">Desktop (Java)<img class="popup" src="img/java-gui.png" /></a> |
|
||||||
Terminal (<a title="Mac, Linux, UNIX, Windows (command line interface)" href="https://ssl.masterpasswordapp.com/masterpassword-cli.zip" onclick="_gaq.push(['_trackPageview', '/outbound/cli/java']);">Java<img class="popup" src="img/java-cli.png" /></a> /
|
Terminal (<a title="Mac, Linux, POSIX (command line interface)" href="https://ssl.masterpasswordapp.com/masterpassword-cli.tar.gz" onclick="_gaq.push(['_trackPageview', '/outbound/cli/c']);">Native C<img class="popup" src="img/c-cli.png" /></a>) |
|
||||||
<a title="Mac, Linux, UNIX, Windows (command line interface)" href="https://github.com/Lyndir/MasterPassword/tree/master/MasterPassword/C" onclick="_gaq.push(['_trackPageview', '/outbound/cli/c']);">Native C<img class="popup" src="img/c-cli.png" /></a>) |
|
|
||||||
<a title="Android" href="https://ssl.masterpasswordapp.com/masterpassword-android.apk" onclick="_gaq.push(['_trackPageview', '/outbound/android']);">Android (Beta)<img class="popup" src="img/android.png" /></a> |
|
<a title="Android" href="https://ssl.masterpasswordapp.com/masterpassword-android.apk" onclick="_gaq.push(['_trackPageview', '/outbound/android']);">Android (Beta)<img class="popup" src="img/android.png" /></a> |
|
||||||
<a title="JavaScript" href="https://js.masterpasswordapp.com/" onclick="_gaq.push(['_trackPageview', '/outbound/js']);">Web (Beta)<img class="popup border" src="img/web.png" /></a>
|
<a title="JavaScript" href="https://js.masterpasswordapp.com/" onclick="_gaq.push(['_trackPageview', '/outbound/js']);">Web (Beta)<img class="popup border" src="img/web.png" /></a>
|
||||||
</h4>
|
</h4>
|
||||||
|
|||||||
1
Site/2013-05/masterpassword-cli.tar.gz
Symbolic link
1
Site/2013-05/masterpassword-cli.tar.gz
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
mpw-2.1-cli4-0-g21630e9.tar.gz
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
1fbb6b0754c9ea1ecf733c260dc06200d2eeed6c
|
9d19eaf667de05c7744e8ae1720e1313a3f98774
|
||||||
|
|||||||
Binary file not shown.
1
Site/2013-05/mpw-2.1-cli2-2-g82c96dd.tar.gz
Symbolic link
1
Site/2013-05/mpw-2.1-cli2-2-g82c96dd.tar.gz
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../MasterPassword/C/mpw-2.1-cli2-2-g82c96dd.tar.gz
|
||||||
1
Site/2013-05/mpw-2.1-cli3-0-g438daf2.tar.gz
Symbolic link
1
Site/2013-05/mpw-2.1-cli3-0-g438daf2.tar.gz
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../MasterPassword/C/mpw-2.1-cli3-0-g438daf2.tar.gz
|
||||||
1
Site/2013-05/mpw-2.1-cli4-0-g21630e9.tar.gz
Symbolic link
1
Site/2013-05/mpw-2.1-cli4-0-g21630e9.tar.gz
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../MasterPassword/C/mpw-2.1-cli4-0-g21630e9.tar.gz
|
||||||
@@ -3,4 +3,4 @@ set -e
|
|||||||
|
|
||||||
cd "${BASH_SOURCE[0]%/*}"
|
cd "${BASH_SOURCE[0]%/*}"
|
||||||
s3cmd sync --exclude '.git/**' --delete-removed --follow-symlinks --preserve --acl-public --reduced-redundancy . s3://masterpasswordapp.com/
|
s3cmd sync --exclude '.git/**' --delete-removed --follow-symlinks --preserve --acl-public --reduced-redundancy . s3://masterpasswordapp.com/
|
||||||
rsync -avP --no-group . satura.lyndir.com:/usr/local/www/masterpasswordapp.com/htdocs-secure/
|
rsync -avPL --no-group . satura.lyndir.com:/usr/local/www/masterpasswordapp.com/htdocs-secure/
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
<p>In fact, just stop thinking about passwords at all.</p>
|
<p>In fact, just stop thinking about passwords at all.</p>
|
||||||
<p>Master Password users have no more passwords. They have a password. Their password is their single master key for unlocking all doors.</p>
|
<p>Master Password users have no more passwords. They have a password. Their password is their single master key for unlocking all doors.</p>
|
||||||
|
|
||||||
|
<a name="how"></a>
|
||||||
<h2>One, two, enter.</h2>
|
<h2>One, two, enter.</h2>
|
||||||
<p>As a Master Password user, there are about three steps to entering any site:</p>
|
<p>As a Master Password user, there are about three steps to entering any site:</p>
|
||||||
<ol>
|
<ol>
|
||||||
@@ -118,6 +119,7 @@
|
|||||||
<li>You can stop sharing the keys to your digital life with online password websites that promise all the military grade encryption while being gagged and tapped by a government agency.</li>
|
<li>You can stop sharing the keys to your digital life with online password websites that promise all the military grade encryption while being gagged and tapped by a government agency.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="others"></a>
|
||||||
<h2>I use this other password manager, and it's awesome.</h2>
|
<h2>I use this other password manager, and it's awesome.</h2>
|
||||||
<p>I shall not endeavour to quarrel with the point on the awesome scale of your other password manager. That said, Master Password was designed from the ground up specifically because of the many flaws that existed in all the popular password managers at the time. And the times haven't changed for the better since.</p>
|
<p>I shall not endeavour to quarrel with the point on the awesome scale of your other password manager. That said, Master Password was designed from the ground up specifically because of the many flaws that existed in all the popular password managers at the time. And the times haven't changed for the better since.</p>
|
||||||
<p>I'm going to provide an excessively brief description of the primary flaws other password managers suffer, which Master Password is free from. Please <a href="support.html">contact me</a> if you have something to add, ask or correct.</p>
|
<p>I'm going to provide an excessively brief description of the primary flaws other password managers suffer, which Master Password is free from. Please <a href="support.html">contact me</a> if you have something to add, ask or correct.</p>
|
||||||
@@ -139,6 +141,7 @@
|
|||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="cons"></a>
|
||||||
<h2>What are Master Password's cons? Or is it flawless?</h2>
|
<h2>What are Master Password's cons? Or is it flawless?</h2>
|
||||||
<p>Master Password also has cons. Let's be frank and list the cons that the other solutions generally don't suffer:</p>
|
<p>Master Password also has cons. Let's be frank and list the cons that the other solutions generally don't suffer:</p>
|
||||||
<p><em>Cons:</em> Changing your master password requires you to update all your site passwords. A compromised or forgotten master password requires you to do the same.</p>
|
<p><em>Cons:</em> Changing your master password requires you to update all your site passwords. A compromised or forgotten master password requires you to do the same.</p>
|
||||||
@@ -154,6 +157,7 @@
|
|||||||
<p>Two factor authentication is defined as authenticating yourself with two methods that are so distinct that a single attack cannot compromise both. Many sites claim to use two-factor authentication but actually rely only on an extra password hidden in an app on your phone or computer. If an attacker can steal your master password, he can probably download the hidden password too. Or read in your two-factor response while you're typing it in. On top of that, you're using a password manager: after your "two-factor" authentication, you get a single password to perform another one-factor authentication with a site. As a hacker, I'd go for the weakest link to break your chain.</li>
|
<p>Two factor authentication is defined as authenticating yourself with two methods that are so distinct that a single attack cannot compromise both. Many sites claim to use two-factor authentication but actually rely only on an extra password hidden in an app on your phone or computer. If an attacker can steal your master password, he can probably download the hidden password too. Or read in your two-factor response while you're typing it in. On top of that, you're using a password manager: after your "two-factor" authentication, you get a single password to perform another one-factor authentication with a site. As a hacker, I'd go for the weakest link to break your chain.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="trust"></a>
|
||||||
<h2>You speak of trust, how can I trust you?</h2>
|
<h2>You speak of trust, how can I trust you?</h2>
|
||||||
<p>A very valid question, and arguably the most important one to ask!</p>
|
<p>A very valid question, and arguably the most important one to ask!</p>
|
||||||
<p>Trust is a very difficult thing to guarantee. Powerful entities will solicit your trust by appearing with it and coming well recommended. Trust can also be assured by legalese or contracts. If you have the means and energy to hold an entity responsible for his claims and actions, this might be sufficient for you.</p>
|
<p>Trust is a very difficult thing to guarantee. Powerful entities will solicit your trust by appearing with it and coming well recommended. Trust can also be assured by legalese or contracts. If you have the means and energy to hold an entity responsible for his claims and actions, this might be sufficient for you.</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user