2
0

Add support for login names and security answers to C app.

This commit is contained in:
Maarten Billemont 2014-10-19 00:55:26 -04:00
parent 9d926be8ae
commit 49b3fe7913
3 changed files with 37 additions and 10 deletions

View File

@ -59,7 +59,14 @@ void usage() {
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"
" l, login | The username to log in as.\n\n"); " l, login | The username to log in as.\n"
" a, answer | The answer to a security question.\n\n");
fprintf(stderr, " -C context A variant-specific context.\n"
" Defaults to empty.\n"
" p, password | Doesn't currently use a context.\n"
" l, login | Doesn't currently use a context.\n"
" a, answer | Empty for a universal site answer or\n"
" | the most significant word(s) of the question.\n\n");
exit(0); exit(0);
} }
@ -101,26 +108,30 @@ int main(int argc, char *const argv[]) {
const char *siteTypeString = getenv( MP_env_sitetype ); const char *siteTypeString = getenv( MP_env_sitetype );
MPElementVariant siteVariant = MPElementVariantPassword; MPElementVariant siteVariant = MPElementVariantPassword;
const char *siteVariantString = NULL; const char *siteVariantString = 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 );
// Read the options. // Read the options.
for (int opt; (opt = getopt(argc, argv, "u:t:c:v:h")) != -1;) for (int opt; (opt = getopt(argc, argv, "u:t:c:v:C:h")) != -1;)
switch (opt) { switch (opt) {
case 'h':
usage();
break;
case 'u': case 'u':
userName = optarg; userName = optarg;
break; break;
case 't': case 't':
siteTypeString = optarg; siteTypeString = optarg;
break; break;
case 'c':
siteCounterString = optarg;
break;
case 'v': case 'v':
siteVariantString = optarg; siteVariantString = optarg;
break; break;
case 'c': case 'C':
siteCounterString = optarg; siteContextString = optarg;
break;
case 'h':
usage();
break; break;
case '?': case '?':
switch (optopt) { switch (optopt) {
@ -166,6 +177,8 @@ int main(int argc, char *const argv[]) {
trc("siteVariant: %d (%s)\n", siteVariant, siteVariantString); trc("siteVariant: %d (%s)\n", siteVariant, siteVariantString);
if (siteVariant == MPElementVariantLogin) if (siteVariant == MPElementVariantLogin)
siteType = MPElementTypeGeneratedName; siteType = MPElementTypeGeneratedName;
if (siteVariant == MPElementVariantAnswer)
siteType = MPElementTypeGeneratedPhrase;
if (siteTypeString) if (siteTypeString)
siteType = TypeWithName( siteTypeString ); siteType = TypeWithName( siteTypeString );
trc("siteType: %d (%s)\n", siteType, siteTypeString); trc("siteType: %d (%s)\n", siteType, siteTypeString);
@ -230,10 +243,13 @@ int main(int argc, char *const argv[]) {
// Calculate the site seed. // Calculate the site seed.
const char *mpSiteScope = ScopeForVariant(siteVariant); const char *mpSiteScope = ScopeForVariant(siteVariant);
trc("site scope: %s\n", mpSiteScope); trc("site scope: %s, context: %s\n", mpSiteScope, siteContextString == NULL? "<empty>": siteContextString);
const uint32_t n_siteNameLength = htonl(strlen(siteName)); const uint32_t n_siteNameLength = htonl(strlen(siteName));
const uint32_t n_siteCounter = htonl(siteCounter); const uint32_t n_siteCounter = htonl(siteCounter);
const size_t sitePasswordInfoLength = strlen(mpSiteScope) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter); const uint32_t n_siteContextLength = siteContextString == NULL? 0: htonl(strlen(siteContextString));
size_t sitePasswordInfoLength = strlen(mpSiteScope) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
if (siteContextString)
sitePasswordInfoLength += sizeof(n_siteContextLength) + strlen(siteContextString);
char *sitePasswordInfo = (char *)malloc( sitePasswordInfoLength ); char *sitePasswordInfo = (char *)malloc( sitePasswordInfoLength );
if (!sitePasswordInfo) { if (!sitePasswordInfo) {
fprintf(stderr, "Could not allocate site seed: %d\n", errno); fprintf(stderr, "Could not allocate site seed: %d\n", errno);
@ -245,9 +261,13 @@ int main(int argc, char *const argv[]) {
memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength); memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength);
memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName); memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName);
memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter); memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter);
if (siteContextString) {
memcpy(sPI, &n_siteContextLength, sizeof(n_siteContextLength)); sPI += sizeof(n_siteContextLength);
memcpy(sPI, siteContextString, strlen(siteContextString)); sPI += strlen(siteContextString);
}
if (sPI - sitePasswordInfo != sitePasswordInfoLength) if (sPI - sitePasswordInfo != sitePasswordInfoLength)
abort(); abort();
trc("seed from: hmac-sha256(masterKey, %s | %s | %s | %s)\n", mpSiteScope, Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter))); trc("seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n", mpSiteScope, Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter)), Hex(&n_siteContextLength, sizeof(n_siteContextLength)), siteContextString);
trc("sitePasswordInfo ID: %s\n", IDForBuf(sitePasswordInfo, sitePasswordInfoLength)); trc("sitePasswordInfo ID: %s\n", IDForBuf(sitePasswordInfo, sitePasswordInfoLength));
uint8_t sitePasswordSeed[32]; uint8_t sitePasswordSeed[32];

View File

@ -95,6 +95,8 @@ const MPElementVariant VariantWithName(const char *variantName) {
return MPElementVariantPassword; return MPElementVariantPassword;
if (0 == strcmp(lowerVariantName, "l") || 0 == strcmp(lowerVariantName, "login")) if (0 == strcmp(lowerVariantName, "l") || 0 == strcmp(lowerVariantName, "login"))
return MPElementVariantLogin; return MPElementVariantLogin;
if (0 == strcmp(lowerVariantName, "a") || 0 == strcmp(lowerVariantName, "answer"))
return MPElementVariantAnswer;
fprintf(stderr, "Not a variant name: %s", lowerVariantName); fprintf(stderr, "Not a variant name: %s", lowerVariantName);
abort(); abort();
@ -108,6 +110,9 @@ const char *ScopeForVariant(MPElementVariant variant) {
case MPElementVariantLogin: { case MPElementVariantLogin: {
return "com.lyndir.masterpassword.login"; return "com.lyndir.masterpassword.login";
} }
case MPElementVariantAnswer: {
return "com.lyndir.masterpassword.answer";
}
default: { default: {
fprintf(stderr, "Unknown variant: %d", variant); fprintf(stderr, "Unknown variant: %d", variant);
abort(); abort();

View File

@ -11,6 +11,8 @@ typedef enum {
MPElementVariantPassword, MPElementVariantPassword,
/** Generate the login name to log in as. */ /** Generate the login name to log in as. */
MPElementVariantLogin, MPElementVariantLogin,
/** Generate the answer to a security question. */
MPElementVariantAnswer,
} MPElementVariant; } MPElementVariant;
typedef enum { typedef enum {