Skip to content

Commit

Permalink
Merge pull request #679 from lastpass/ff-url-encryption
Browse files Browse the repository at this point in the history
Write encrypted URL with FF
  • Loading branch information
juliocavalin-lp authored Apr 11, 2024
2 parents b56bf8e + 10f4cf9 commit ee4bfc3
Show file tree
Hide file tree
Showing 17 changed files with 254 additions and 93 deletions.
54 changes: 39 additions & 15 deletions blob.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* encrypted vault parsing
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -368,7 +368,7 @@ static struct account *account_parse(struct chunk *chunk, const unsigned char ke
if (check_next_entry_encrypted(chunk))
entry_crypt(url);
else
entry_hex(url);
entry_hex(url);
entry_crypt(note);
entry_boolean(fav);
skip(sharedfromaid);
Expand Down Expand Up @@ -800,7 +800,7 @@ static void write_app_chunk(struct buffer *buffer, struct account *account)
}
}

static void write_account_chunk(struct buffer *buffer, struct account *account)
static void write_account_chunk(struct buffer *buffer, struct account *account, const struct feature_flag *feature_flag)
{
struct buffer accbuf, fieldbuf;
struct field *field;
Expand All @@ -814,7 +814,14 @@ static void write_account_chunk(struct buffer *buffer, struct account *account)
write_plain_string(&accbuf, account->id);
write_crypt_string(&accbuf, account->name_encrypted);
write_crypt_string(&accbuf, account->group_encrypted);
write_hex_string(&accbuf, account->url);
if (feature_flag && feature_flag->url_encryption_enabled) {
if (account->url_encrypted != NULL)
write_crypt_string(&accbuf, account->url_encrypted);
else
write_hex_string(&accbuf, account->url);
} else {
write_hex_string(&accbuf, account->url);
}
write_crypt_string(&accbuf, account->note_encrypted);
write_plain_string(&accbuf, "skipped");
write_plain_string(&accbuf, "skipped");
Expand Down Expand Up @@ -868,7 +875,7 @@ static void write_share_chunk(struct buffer *buffer, struct share *share)
write_chunk(buffer, &sharebuf, "SHAR");
}

size_t blob_write(const struct blob *blob, const unsigned char key[KDF_HASH_LEN], char **out)
size_t blob_write(const struct blob *blob, const unsigned char key[KDF_HASH_LEN], char **out, const struct feature_flag *feature_flag)
{
struct buffer buffer;
struct share *last_share = NULL;
Expand All @@ -885,7 +892,7 @@ size_t blob_write(const struct blob *blob, const unsigned char key[KDF_HASH_LEN]

list_for_each_entry(account, &blob->account_head, list) {
if (!account->share)
write_account_chunk(&buffer, account);
write_account_chunk(&buffer, account, feature_flag);
}
list_for_each_entry(account, &blob->account_head, list) {
if (!account->share)
Expand All @@ -894,7 +901,7 @@ size_t blob_write(const struct blob *blob, const unsigned char key[KDF_HASH_LEN]
write_share_chunk(&buffer, account->share);
last_share = account->share;
}
write_account_chunk(&buffer, account);
write_account_chunk(&buffer, account, feature_flag);
}

*out = buffer.bytes;
Expand Down Expand Up @@ -964,12 +971,12 @@ struct blob *blob_load(enum blobsync sync, struct session *session, const unsign
return blob_get_latest(session, key);
}

void blob_save(const struct blob *blob, const unsigned char key[KDF_HASH_LEN])
void blob_save(const struct blob *blob, const unsigned char key[KDF_HASH_LEN], const struct feature_flag *feature_flag)
{
_cleanup_free_ char *bluffer = NULL;
size_t len;

len = blob_write(blob, key, &bluffer);
len = blob_write(blob, key, &bluffer, feature_flag);
if (!len)
die("Could not write blob.");

Expand Down Expand Up @@ -1012,10 +1019,24 @@ void account_set_note(struct account *account, char *note, unsigned const char k
{
set_encrypted_field(account, note);
}
void account_set_url(struct account *account, char *url, unsigned const char key[KDF_HASH_LEN])
void account_set_url(struct account *account, char *url, unsigned const char key[KDF_HASH_LEN], const struct feature_flag *feature_flag)
{
UNUSED(key);
set_field(account, url);
if (url != NULL && strstr(url, "://") == NULL) {
char *url_with_prefix;
if ((url_with_prefix = malloc(strlen(url) + strlen("http://") + 1)) != NULL) {
strcpy(url_with_prefix, "http://");
strcat(url_with_prefix, url);
free(url);
url = url_with_prefix;
}
}

if (feature_flag && feature_flag->url_encryption_enabled) {
set_encrypted_field(account, url);
} else {
UNUSED(key);
set_field(account, url);
}
}
void account_set_appname(struct account *account, char *appname, unsigned const char key[KDF_HASH_LEN])
{
Expand All @@ -1040,12 +1061,15 @@ static bool is_shared_folder_name(const char *fullname)
return !strncmp(fullname, "Shared-", 7) && strchr(fullname, '/');
}

void account_reencrypt(struct account *account, const unsigned char key[KDF_HASH_LEN])
void account_reencrypt(struct account *account, const unsigned char key[KDF_HASH_LEN], const struct feature_flag *feature_flag)
{
struct field *field;

reencrypt_field(account, name);
reencrypt_field(account, group);
if (feature_flag && feature_flag->url_encryption_enabled) {
reencrypt_field(account, url);
}
reencrypt_field(account, username);
reencrypt_field(account, password);
reencrypt_field(account, note);
Expand Down Expand Up @@ -1110,7 +1134,7 @@ struct share *find_unique_share(struct blob *blob, const char *name)
* same folder is not available.
*/
void account_assign_share(struct blob *blob, struct account *account,
unsigned const char key[KDF_HASH_LEN])
unsigned const char key[KDF_HASH_LEN], const struct feature_flag *feature_flag)
{
struct share *share, *old_share;
_cleanup_free_ char *shared_name = NULL;
Expand Down Expand Up @@ -1143,7 +1167,7 @@ void account_assign_share(struct blob *blob, struct account *account,

reencrypt:
if (old_share != account->share)
account_reencrypt(account, key);
account_reencrypt(account, key, feature_flag);
}

struct account *notes_expand(struct account *acc)
Expand Down
11 changes: 6 additions & 5 deletions blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "session.h"
#include "list.h"
#include "notes.h"
#include "feature-flag.h"
#include <stdbool.h>
#include <stddef.h>

Expand Down Expand Up @@ -152,9 +153,9 @@ enum blobsync { BLOB_SYNC_AUTO, BLOB_SYNC_YES, BLOB_SYNC_NO };

struct blob *blob_parse(const unsigned char *blob, size_t len, const unsigned char key[KDF_HASH_LEN], const struct private_key *private_key);
void blob_free(struct blob *blob);
size_t blob_write(const struct blob *blob, const unsigned char key[KDF_HASH_LEN], char **out);
size_t blob_write(const struct blob *blob, const unsigned char key[KDF_HASH_LEN], char **out, const struct feature_flag *feature_flag);
struct blob *blob_load(enum blobsync sync, struct session *session, const unsigned char key[KDF_HASH_LEN]);
void blob_save(const struct blob *blob, const unsigned char key[KDF_HASH_LEN]);
void blob_save(const struct blob *blob, const unsigned char key[KDF_HASH_LEN], const struct feature_flag *feature_flag);
void field_free(struct field *field);
struct app *account_to_app(const struct account *account);
struct app *new_app();
Expand All @@ -165,11 +166,11 @@ void account_set_password(struct account *account, char *password, unsigned cons
void account_set_group(struct account *account, char *group, unsigned const char key[KDF_HASH_LEN]);
void account_set_name(struct account *account, char *name, unsigned const char key[KDF_HASH_LEN]);
void account_set_fullname(struct account *account, char *fullname, unsigned const char key[KDF_HASH_LEN]);
void account_set_url(struct account *account, char *url, unsigned const char key[KDF_HASH_LEN]);
void account_set_url(struct account *account, char *url, unsigned const char key[KDF_HASH_LEN], const struct feature_flag *feature_flag);
void account_set_note(struct account *account, char *note, unsigned const char key[KDF_HASH_LEN]);
void account_set_appname(struct account *account, char *appname, unsigned const char key[KDF_HASH_LEN]);
void account_assign_share(struct blob *blob, struct account *account, unsigned const char key[KDF_HASH_LEN]);
void account_reencrypt(struct account *account, const unsigned char key[KDF_HASH_LEN]);
void account_assign_share(struct blob *blob, struct account *account, unsigned const char key[KDF_HASH_LEN], const struct feature_flag *feature_flag);
void account_reencrypt(struct account *account, const unsigned char key[KDF_HASH_LEN], const struct feature_flag *feature_flag);
bool account_is_group(struct account *account);
void field_set_value(struct account *account, struct field *field, char *value, unsigned const char key[KDF_HASH_LEN]);
struct account *notes_expand(struct account *acc);
Expand Down
6 changes: 3 additions & 3 deletions cmd-duplicate.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* command for making copies of vault entries
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -95,7 +95,7 @@ int cmd_duplicate(int argc, char **argv)
account_set_password(new, xstrdup(found->password), key);
account_set_note(new, xstrdup(found->note), key);
new->fullname = xstrdup(found->fullname);
new->url = xstrdup(found->url);
account_set_url(new, xstrdup(found->url), key, &session->feature_flag);
new->pwprotect = found->pwprotect;

list_for_each_entry(field, &found->field_head, list) {
Expand All @@ -110,7 +110,7 @@ int cmd_duplicate(int argc, char **argv)
list_add(&new->list, &blob->account_head);

lastpass_update_account(sync, key, session, new, blob);
blob_save(blob, key);
blob_save(blob, key, &session->feature_flag);

session_free(session);
blob_free(blob);
Expand Down
11 changes: 5 additions & 6 deletions cmd-generate.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* command for generating passwords
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -123,8 +123,7 @@ int cmd_generate(int argc, char **argv)
if (username)
account_set_username(found, username, key);
if (url) {
free(found->url);
found->url = url;
account_set_url(found, xstrdup(url), key, &session->feature_flag);
}
if (notes_expansion && notes_collapsed) {
found = notes_collapsed;
Expand All @@ -140,14 +139,14 @@ int cmd_generate(int argc, char **argv)
account_set_fullname(new, xstrdup(name), key);
account_set_username(new, username ? username : xstrdup(""), key);
account_set_note(new, xstrdup(""), key);
new->url = url ? url : xstrdup("");
account_assign_share(blob, new, key);
account_set_url(new, url ? url : xstrdup(""), key, &session->feature_flag);
account_assign_share(blob, new, key, &session->feature_flag);

list_add(&new->list, &blob->account_head);
}

lastpass_update_account(sync, key, session, found ? found : new, blob);
blob_save(blob, key);
blob_save(blob, key, &session->feature_flag);

if (clip)
clipboard_open();
Expand Down
22 changes: 15 additions & 7 deletions cmd-import.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* command for importing vault entries from CSV file into the vault
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -191,11 +191,11 @@ static void csv_parse(FILE *fp, struct list_head *list)
free(record);
}

static struct account *new_import_account(unsigned char key[KDF_HASH_LEN])
static struct account *new_import_account(unsigned char key[KDF_HASH_LEN], const struct feature_flag *feature_flag)
{
struct account *account = new_account();

account_set_url(account, xstrdup(""), key);
account_set_url(account, xstrdup(""), key, feature_flag);
account_set_username(account, xstrdup(""), key);
account_set_password(account, xstrdup(""), key);
account_set_note(account, xstrdup(""), key);
Expand All @@ -206,7 +206,7 @@ static struct account *new_import_account(unsigned char key[KDF_HASH_LEN])
}

static int csv_parse_accounts(FILE *fp, struct list_head *account_list,
unsigned char key[KDF_HASH_LEN])
unsigned char key[KDF_HASH_LEN], const struct feature_flag *feature_flag)
{
struct list_head items;
struct csv_record *record, *tmp_record, *first;
Expand Down Expand Up @@ -243,6 +243,14 @@ static int csv_parse_accounts(FILE *fp, struct list_head *account_list,
} \
} while (0)

#define set_field_ff(x, fieldname, feature_flag) \
do { \
if (i == x ## _index) { \
account_set_ ## fieldname (account, field->value, key, feature_flag); \
set = true; \
} \
} while (0)

/*
* first line should tell us the field matrix; if
* it doesn't reveal anything useful then we won't
Expand Down Expand Up @@ -274,11 +282,11 @@ static int csv_parse_accounts(FILE *fp, struct list_head *account_list,
if (record == first)
continue;

account = new_import_account(key);
account = new_import_account(key, feature_flag);
i = 0;
list_for_each_entry(field, &record->field_head, list) {
bool set = false;
set_field(url, url);
set_field_ff(url, url, feature_flag);
set_field(username, username);
set_field(password, password);
set_field(name, name);
Expand Down Expand Up @@ -387,7 +395,7 @@ int cmd_import(int argc, char **argv)
init_all(sync, key, &session, &blob);

INIT_LIST_HEAD(&accounts);
count = csv_parse_accounts(fp, &accounts, key);
count = csv_parse_accounts(fp, &accounts, key, &session->feature_flag);

printf("Parsed %d accounts\n", count);

Expand Down
4 changes: 2 additions & 2 deletions cmd-ls.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* command for listing the vault
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -319,7 +319,7 @@ int cmd_ls(int argc, char **argv)
account->id = share->id;
account_set_name(account, xstrdup(""), key);
account_set_fullname(account, tmpname, key);
account_set_url(account, "http://group", key);
account_set_url(account, "http://group", key, &session->feature_flag);
account_array[i++] = account;
}
qsort(account_array, num_accounts, sizeof(struct account *),
Expand Down
6 changes: 3 additions & 3 deletions cmd-mv.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* command for moving vault entries
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -97,7 +97,7 @@ int cmd_mv(int argc, char **argv)
old_share = account->share;

account_set_fullname(account, new_fullname, key);
account_assign_share(blob, account, key);
account_assign_share(blob, account, key, &session->feature_flag);
if (account->share && account->share->readonly) {
die("You do not have access to move %s into %s",
account->name, account->share->name);
Expand All @@ -117,7 +117,7 @@ int cmd_mv(int argc, char **argv)
/* standard case: account just changing group name */
lastpass_update_account(sync, key, session, account, blob);
}
blob_save(blob, key);
blob_save(blob, key, &session->feature_flag);

session_free(session);
blob_free(blob);
Expand Down
4 changes: 2 additions & 2 deletions cmd-rm.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* command for removing vault entries
*
* Copyright (C) 2014-2018 LastPass.
* Copyright (C) 2014-2024 LastPass.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -89,7 +89,7 @@ int cmd_rm(int argc, char **argv)
list_del(&found->list);

lastpass_remove_account(sync, key, session, found, blob);
blob_save(blob, key);
blob_save(blob, key, &session->feature_flag);
account_free(found);

session_free(session);
Expand Down
Loading

0 comments on commit ee4bfc3

Please sign in to comment.