[epiphany/wip/sync-rebase: 22/86] ephy-sync: Implement the Fetch Sync Keys act
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/sync-rebase: 22/86] ephy-sync: Implement the Fetch Sync Keys act
- Date: Fri, 7 Oct 2016 22:50:34 +0000 (UTC)
commit df02268552c7342b8ad842686cc41f343a4a4d99
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Fri Jul 8 17:51:49 2016 +0300
ephy-sync: Implement the Fetch Sync Keys act
src/ephy-sync-crypto.c | 444 ++++++++++++++++++++++++++++++++++++++---------
src/ephy-sync-crypto.h | 91 ++++++----
src/ephy-sync-secret.c | 6 +-
src/ephy-sync-secret.h | 4 +-
src/ephy-sync-service.c | 347 ++++++++++++++++++++-----------------
src/ephy-sync-service.h | 11 +-
src/ephy-sync-utils.c | 35 +++--
src/ephy-sync-utils.h | 10 +-
src/prefs-dialog.c | 17 ++-
9 files changed, 652 insertions(+), 313 deletions(-)
---
diff --git a/src/ephy-sync-crypto.c b/src/ephy-sync-crypto.c
index 64e560d..01e9b27 100644
--- a/src/ephy-sync-crypto.c
+++ b/src/ephy-sync-crypto.c
@@ -17,6 +17,7 @@
*/
#include "ephy-sync-crypto.h"
+#include "ephy-sync-utils.h"
#include <libsoup/soup.h>
#include <nettle/hmac.h>
@@ -26,17 +27,31 @@
#define HAWK_VERSION 1
-static EphySyncCryptoHawkHeader *
-ephy_sync_crypto_hawk_header_new (gchar *header,
- EphySyncCryptoHawkArtifacts *artifacts)
+EphySyncCryptoHawkOptions *
+ephy_sync_crypto_hawk_options_new (gchar *app,
+ gchar *dlg,
+ gchar *ext,
+ gchar *content_type,
+ gchar *hash,
+ gchar *local_time_offset,
+ gchar *nonce,
+ gchar *payload,
+ gchar *timestamp)
{
- EphySyncCryptoHawkHeader *hawk_header;
+ EphySyncCryptoHawkOptions *hawk_options;
- hawk_header = g_slice_new (EphySyncCryptoHawkHeader);
- hawk_header->header = header;
- hawk_header->artifacts = artifacts;
+ hawk_options = g_slice_new (EphySyncCryptoHawkOptions);
+ hawk_options->app = app;
+ hawk_options->dlg = dlg;
+ hawk_options->ext = ext;
+ hawk_options->content_type = content_type;
+ hawk_options->hash = hash;
+ hawk_options->local_time_offset = local_time_offset;
+ hawk_options->nonce = nonce;
+ hawk_options->payload = payload;
+ hawk_options->timestamp = timestamp;
- return hawk_header;
+ return hawk_options;
}
static EphySyncCryptoHawkArtifacts *
@@ -68,9 +83,89 @@ ephy_sync_crypto_hawk_artifacts_new (gchar *app,
return hawk_artifacts;
}
+static EphySyncCryptoHawkHeader *
+ephy_sync_crypto_hawk_header_new (gchar *header,
+ EphySyncCryptoHawkArtifacts *artifacts)
+{
+ EphySyncCryptoHawkHeader *hawk_header;
+
+ hawk_header = g_slice_new (EphySyncCryptoHawkHeader);
+ hawk_header->header = header;
+ hawk_header->artifacts = artifacts;
+
+ return hawk_header;
+}
+
+static EphySyncCryptoStretchedCredentials *
+ephy_sync_crypto_stretched_credentials_new (guint8 *quickStretchedPW,
+ guint8 *authPW,
+ guint8 *unwrapBKey)
+{
+ EphySyncCryptoStretchedCredentials *stretched_credentials;
+
+ stretched_credentials = g_slice_new (EphySyncCryptoStretchedCredentials);
+ stretched_credentials->quickStretchedPW = quickStretchedPW;
+ stretched_credentials->authPW = authPW;
+ stretched_credentials->unwrapBKey = unwrapBKey;
+
+ return stretched_credentials;
+}
+
+static EphySyncCryptoProcessedKFT *
+ephy_sync_crypto_processed_kft_new (guint8 *tokenID,
+ guint8 *reqHMACkey,
+ guint8 *respHMACkey,
+ guint8 *respXORkey)
+{
+ EphySyncCryptoProcessedKFT *processed_kft;
+
+ processed_kft = g_slice_new (EphySyncCryptoProcessedKFT);
+ processed_kft->tokenID = tokenID;
+ processed_kft->reqHMACkey = reqHMACkey;
+ processed_kft->respHMACkey = respHMACkey;
+ processed_kft->respXORkey = respXORkey;
+
+ return processed_kft;
+}
+
+static EphySyncCryptoSyncKeys *
+ephy_sync_crypto_sync_keys_new (guint8 *kA,
+ guint8 *kB,
+ guint8 *wrapKB)
+{
+ EphySyncCryptoSyncKeys *sync_keys;
+
+ sync_keys = g_slice_new (EphySyncCryptoSyncKeys);
+ sync_keys->kA = kA;
+ sync_keys->kB = kB;
+ sync_keys->wrapKB = wrapKB;
+
+ return sync_keys;
+}
+
+void
+ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *hawk_options)
+{
+ g_return_if_fail (hawk_options != NULL);
+
+ g_free (hawk_options->app);
+ g_free (hawk_options->dlg);
+ g_free (hawk_options->ext);
+ g_free (hawk_options->content_type);
+ g_free (hawk_options->hash);
+ g_free (hawk_options->local_time_offset);
+ g_free (hawk_options->nonce);
+ g_free (hawk_options->payload);
+ g_free (hawk_options->timestamp);
+
+ g_slice_free (EphySyncCryptoHawkOptions, hawk_options);
+}
+
static void
ephy_sync_crypto_hawk_artifacts_free (EphySyncCryptoHawkArtifacts *hawk_artifacts)
{
+ g_return_if_fail (hawk_artifacts != NULL);
+
g_free (hawk_artifacts->app);
g_free (hawk_artifacts->dlg);
g_free (hawk_artifacts->ext);
@@ -85,6 +180,104 @@ ephy_sync_crypto_hawk_artifacts_free (EphySyncCryptoHawkArtifacts *hawk_artifact
g_slice_free (EphySyncCryptoHawkArtifacts, hawk_artifacts);
}
+void
+ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *hawk_header)
+{
+ g_return_if_fail (hawk_header != NULL);
+
+ g_free (hawk_header->header);
+ ephy_sync_crypto_hawk_artifacts_free (hawk_header->artifacts);
+
+ g_slice_free (EphySyncCryptoHawkHeader, hawk_header);
+}
+
+void
+ephy_sync_crypto_stretched_credentials_free (EphySyncCryptoStretchedCredentials *stretched_credentials)
+{
+ g_return_if_fail (stretched_credentials != NULL);
+
+ g_free (stretched_credentials->quickStretchedPW);
+ g_free (stretched_credentials->authPW);
+ g_free (stretched_credentials->unwrapBKey);
+
+ g_slice_free (EphySyncCryptoStretchedCredentials, stretched_credentials);
+}
+
+void
+ephy_sync_crypto_processed_kft_free (EphySyncCryptoProcessedKFT *processed_kft)
+{
+ g_return_if_fail (processed_kft != NULL);
+
+ g_free (processed_kft->tokenID);
+ g_free (processed_kft->reqHMACkey);
+ g_free (processed_kft->respHMACkey);
+ g_free (processed_kft->respXORkey);
+
+ g_slice_free (EphySyncCryptoProcessedKFT, processed_kft);
+}
+
+void
+ephy_sync_crypto_sync_keys_free (EphySyncCryptoSyncKeys *sync_keys)
+{
+ g_return_if_fail (sync_keys != NULL);
+
+ g_free (sync_keys->kA);
+ g_free (sync_keys->kB);
+ g_free (sync_keys->wrapKB);
+
+ g_slice_free (EphySyncCryptoSyncKeys, sync_keys);
+}
+
+static guint8 *
+xor (guint8 *a,
+ guint8 *b,
+ gsize length)
+{
+ guint8 *xored;
+
+ xored = g_malloc (length);
+ for (gsize i = 0; i < length; i++)
+ xored[i] = a[i] ^ b[i];
+
+ return xored;
+}
+
+static gboolean
+are_equal (guint8 *a,
+ guint8 *b)
+{
+ gchar *a_hex;
+ gchar *b_hex;
+ gboolean retval;
+
+ a_hex = ephy_sync_utils_encode_hex (a, 0);
+ b_hex = ephy_sync_utils_encode_hex (b, 0);
+ retval = g_str_equal (a_hex, b_hex);
+
+ g_free (a_hex);
+ g_free (b_hex);
+
+ return retval;
+}
+
+static guint8 *
+sha256_hmac (guint8 *data,
+ gsize data_length,
+ guint8 *key,
+ gsize key_length)
+{
+ struct hmac_sha256_ctx ctx;
+ guint8 *digest;
+
+ digest = g_malloc (SHA256_DIGEST_SIZE);
+
+ hmac_sha256_set_key (&ctx, key_length, key);
+ hmac_sha256_update (&ctx, data_length, data);
+ hmac_sha256_digest (&ctx, SHA256_DIGEST_SIZE, digest);
+
+ return digest;
+}
+
static gchar *
generate_random_string (gsize length)
{
@@ -237,7 +430,6 @@ calculate_mac (const gchar *mac_type,
gsize key_length,
EphySyncCryptoHawkArtifacts *artifacts)
{
- struct hmac_sha256_ctx ctx;
guint8 *digest;
gchar *normalized;
gchar *mac;
@@ -247,11 +439,8 @@ calculate_mac (const gchar *mac_type,
g_return_val_if_fail (artifacts, NULL);
normalized = normalize_string (mac_type, artifacts);
- digest = g_malloc (SHA256_DIGEST_SIZE);
-
- hmac_sha256_set_key (&ctx, key_length, key);
- hmac_sha256_update (&ctx, strlen (normalized), (guint8 *) normalized);
- hmac_sha256_digest (&ctx, SHA256_DIGEST_SIZE, digest);
+ digest = sha256_hmac ((guint8 *) normalized, strlen (normalized),
+ key, key_length);
mac = g_base64_encode (digest, SHA256_DIGEST_SIZE);
g_free (normalized);
@@ -278,69 +467,17 @@ append_token_to_header (gchar *header,
return new_header;
}
-EphySyncCryptoHawkOptions *
-ephy_sync_crypto_hawk_options_new (gchar *app,
- gchar *dlg,
- gchar *ext,
- gchar *content_type,
- gchar *hash,
- gchar *local_time_offset,
- gchar *nonce,
- gchar *payload,
- gchar *timestamp)
-{
- EphySyncCryptoHawkOptions *hawk_options;
-
- hawk_options = g_slice_new (EphySyncCryptoHawkOptions);
- hawk_options->app = app;
- hawk_options->dlg = dlg;
- hawk_options->ext = ext;
- hawk_options->content_type = content_type;
- hawk_options->hash = hash;
- hawk_options->local_time_offset = local_time_offset;
- hawk_options->nonce = nonce;
- hawk_options->payload = payload;
- hawk_options->timestamp = timestamp;
-
- return hawk_options;
-}
-
-void
-ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *hawk_options)
-{
- g_free (hawk_options->app);
- g_free (hawk_options->dlg);
- g_free (hawk_options->ext);
- g_free (hawk_options->content_type);
- g_free (hawk_options->hash);
- g_free (hawk_options->local_time_offset);
- g_free (hawk_options->nonce);
- g_free (hawk_options->payload);
- g_free (hawk_options->timestamp);
-
- g_slice_free (EphySyncCryptoHawkOptions, hawk_options);
-}
-
-void
-ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *hawk_header)
-{
- g_free (hawk_header->header);
- ephy_sync_crypto_hawk_artifacts_free (hawk_header->artifacts);
-
- g_slice_free (EphySyncCryptoHawkHeader, hawk_header);
-}
-
/*
* Runs 1000 iterations of PBKDF2.
* Uses sha256 as hash function.
*/
-void
-ephy_sync_crypto_pbkdf2_1k (guint8 *key,
- gsize key_length,
- guint8 *salt,
- gsize salt_length,
- guint8 *out,
- gsize out_length)
+static void
+pbkdf2_1k (guint8 *key,
+ gsize key_length,
+ guint8 *salt,
+ gsize salt_length,
+ guint8 *out,
+ gsize out_length)
{
pbkdf2_hmac_sha256 (key_length, key, 1000, salt_length, salt, out_length, out);
}
@@ -350,15 +487,15 @@ ephy_sync_crypto_pbkdf2_1k (guint8 *key,
* Uses sha256 as hash function.
* https://tools.ietf.org/html/rfc5869
*/
-void
-ephy_sync_crypto_hkdf (guint8 *in,
- gsize in_length,
- guint8 *salt,
- gsize salt_length,
- guint8 *info,
- gsize info_length,
- guint8 *out,
- gsize out_length)
+static void
+hkdf (guint8 *in,
+ gsize in_length,
+ guint8 *salt,
+ gsize salt_length,
+ guint8 *info,
+ gsize info_length,
+ guint8 *out,
+ gsize out_length)
{
struct hmac_sha256_ctx ctx;
const gsize hash_length = 32;
@@ -403,6 +540,149 @@ ephy_sync_crypto_hkdf (guint8 *in,
g_free (prk);
}
+EphySyncCryptoStretchedCredentials *
+ephy_sync_crypto_stretch (const gchar *emailUTF8,
+ const gchar *passwordUTF8)
+{
+ gchar *salt_stretch;
+ gchar *info_auth;
+ gchar *info_unwrap;
+ guint8 *quickStretchedPW;
+ guint8 *authPW;
+ guint8 *unwrapBKey;
+
+ salt_stretch = ephy_sync_utils_kwe ("quickStretch", emailUTF8);
+ quickStretchedPW = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ pbkdf2_1k ((guint8 *) passwordUTF8, strlen (passwordUTF8),
+ (guint8 *) salt_stretch, strlen (salt_stretch),
+ quickStretchedPW, EPHY_SYNC_TOKEN_LENGTH);
+
+ info_auth = ephy_sync_utils_kw ("authPW");
+ authPW = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ hkdf (quickStretchedPW, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info_auth, strlen (info_auth),
+ authPW, EPHY_SYNC_TOKEN_LENGTH);
+
+ info_unwrap = ephy_sync_utils_kw ("unwrapBkey");
+ unwrapBKey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ hkdf (quickStretchedPW, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info_unwrap, strlen (info_unwrap),
+ unwrapBKey, EPHY_SYNC_TOKEN_LENGTH);
+
+ g_free (salt_stretch);
+ g_free (info_unwrap);
+ g_free (info_auth);
+
+ return ephy_sync_crypto_stretched_credentials_new (quickStretchedPW,
+ authPW,
+ unwrapBKey);
+}
+
+EphySyncCryptoProcessedKFT *
+ephy_sync_crypto_process_key_fetch_token (const gchar *keyFetchToken)
+{
+ guint8 *kft;
+ guint8 *out1;
+ guint8 *out2;
+ guint8 *tokenID;
+ guint8 *reqHMACkey;
+ guint8 *respHMACkey;
+ guint8 *respXORkey;
+ guint8 *keyRequestKey;
+ gchar *info_kft;
+ gchar *info_keys;
+
+ kft = ephy_sync_utils_decode_hex (keyFetchToken);
+ info_kft = ephy_sync_utils_kw ("keyFetchToken");
+ info_keys = ephy_sync_utils_kw ("account/keys");
+ out1 = g_malloc (3 * EPHY_SYNC_TOKEN_LENGTH);
+ out2 = g_malloc (3 * EPHY_SYNC_TOKEN_LENGTH);
+
+ hkdf (kft, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info_kft, strlen (info_kft),
+ out1, 3 * EPHY_SYNC_TOKEN_LENGTH);
+
+ tokenID = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ keyRequestKey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (tokenID, out1, EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (reqHMACkey, out1 + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (keyRequestKey, out1 + 2 * EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+
+ hkdf (keyRequestKey, EPHY_SYNC_TOKEN_LENGTH,
+ NULL, 0,
+ (guint8 *) info_keys, strlen (info_keys),
+ out2, 3 * EPHY_SYNC_TOKEN_LENGTH);
+
+ respHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ respXORkey = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (respHMACkey, out2, EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (respXORkey, out2 + EPHY_SYNC_TOKEN_LENGTH, 2 * EPHY_SYNC_TOKEN_LENGTH);
+
+ g_free (kft);
+ g_free (out1);
+ g_free (out2);
+ g_free (info_kft);
+ g_free (info_keys);
+ g_free (keyRequestKey);
+
+ return ephy_sync_crypto_processed_kft_new (tokenID,
+ reqHMACkey,
+ respHMACkey,
+ respXORkey);
+}
+
+EphySyncCryptoSyncKeys *
+ephy_sync_crypto_retrieve_sync_keys (const gchar *bundle,
+ guint8 *respHMACkey,
+ guint8 *respXORkey,
+ guint8 *unwrapBKey)
+{
+ guint8 *bdl;
+ guint8 *ciphertext;
+ guint8 *respMAC;
+ guint8 *respMAC2;
+ guint8 *xored;
+ guint8 *wrapKB;
+ guint8 *kA;
+ guint8 *kB;
+ EphySyncCryptoSyncKeys *retval = NULL;
+
+ bdl = ephy_sync_utils_decode_hex (bundle);
+ ciphertext = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
+ respMAC = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ wrapKB = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+ kA = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+
+ memcpy (ciphertext, bdl, 2 * EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (respMAC, bdl + 2 * EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+ respMAC2 = sha256_hmac (ciphertext, 2 * EPHY_SYNC_TOKEN_LENGTH,
+ respHMACkey, EPHY_SYNC_TOKEN_LENGTH);
+
+ if (are_equal (respMAC, respMAC2) == FALSE) {
+ g_warning ("respMAC and respMAC2 differ");
+ goto out;
+ }
+
+ xored = xor (ciphertext, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (kA, xored, EPHY_SYNC_TOKEN_LENGTH);
+ memcpy (wrapKB, xored + EPHY_SYNC_TOKEN_LENGTH, EPHY_SYNC_TOKEN_LENGTH);
+ kB = xor (unwrapBKey, wrapKB, EPHY_SYNC_TOKEN_LENGTH);
+ retval = ephy_sync_crypto_sync_keys_new (kA, kB, wrapKB);
+
+out:
+ g_free (bdl);
+ g_free (ciphertext);
+ g_free (respMAC);
+ g_free (respMAC2);
+ g_free (xored);
+
+ return retval;
+}
+
EphySyncCryptoHawkHeader *
ephy_sync_crypto_compute_hawk_header (const gchar *url,
const gchar *method,
diff --git a/src/ephy-sync-crypto.h b/src/ephy-sync-crypto.h
index 7afb73d..2e3c789 100644
--- a/src/ephy-sync-crypto.h
+++ b/src/ephy-sync-crypto.h
@@ -53,42 +53,61 @@ typedef struct {
EphySyncCryptoHawkArtifacts *artifacts;
} EphySyncCryptoHawkHeader;
-void ephy_sync_crypto_pbkdf2_1k (guint8 *key,
- gsize key_length,
- guint8 *salt,
- gsize salt_length,
- guint8 *out,
- gsize out_length);
-
-void ephy_sync_crypto_hkdf (guint8 *in,
- gsize in_length,
- guint8 *salt,
- gsize salt_length,
- guint8 *info,
- gsize info_length,
- guint8 *out,
- gsize out_length);
-
-EphySyncCryptoHawkHeader *ephy_sync_crypto_compute_hawk_header (const gchar *url,
- const gchar *method,
- const gchar *id,
- guint8 *key,
- gsize key_length,
- EphySyncCryptoHawkOptions *options);
-
-EphySyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (gchar *app,
- gchar *dlg,
- gchar *ext,
- gchar *content_type,
- gchar *hash,
- gchar *local_time_offset,
- gchar *nonce,
- gchar *payload,
- gchar *timestamp);
-
-void ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions *hawk_options);
-
-void ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader *hawk_header);
+typedef struct {
+ guint8 *quickStretchedPW;
+ guint8 *authPW;
+ guint8 *unwrapBKey;
+} EphySyncCryptoStretchedCredentials;
+
+typedef struct {
+ guint8 *tokenID;
+ guint8 *reqHMACkey;
+ guint8 *respHMACkey;
+ guint8 *respXORkey;
+} EphySyncCryptoProcessedKFT;
+
+typedef struct {
+ guint8 *kA;
+ guint8 *kB;
+ guint8 *wrapKB;
+} EphySyncCryptoSyncKeys;
+
+EphySyncCryptoHawkOptions *ephy_sync_crypto_hawk_options_new (gchar *app,
+ gchar *dlg,
+ gchar *ext,
+ gchar *content_type,
+ gchar *hash,
+ gchar *local_time_offset,
+ gchar *nonce,
+ gchar *payload,
+ gchar *timestamp);
+
+void ephy_sync_crypto_hawk_options_free (EphySyncCryptoHawkOptions
*hawk_options);
+
+void ephy_sync_crypto_hawk_header_free (EphySyncCryptoHawkHeader
*hawk_header);
+
+void ephy_sync_crypto_stretched_credentials_free
(EphySyncCryptoStretchedCredentials *stretched_credentials);
+
+void ephy_sync_crypto_processed_kft_free (EphySyncCryptoProcessedKFT
*processed_kft);
+
+void ephy_sync_crypto_sync_keys_free (EphySyncCryptoSyncKeys
*sync_keys);
+
+EphySyncCryptoStretchedCredentials *ephy_sync_crypto_stretch (const gchar *emailUTF8,
+ const gchar *passwordUTF8);
+
+EphySyncCryptoProcessedKFT *ephy_sync_crypto_process_key_fetch_token (const gchar
*keyFetchToken);
+
+EphySyncCryptoSyncKeys *ephy_sync_crypto_retrieve_sync_keys (const gchar *bundle,
+ guint8 *respHMACkey,
+ guint8 *respXORkey,
+ guint8 *unwrapBKey);
+
+EphySyncCryptoHawkHeader *ephy_sync_crypto_compute_hawk_header (const gchar
*url,
+ const gchar
*method,
+ const gchar
*id,
+ guint8
*key,
+ gsize
key_length,
+ EphySyncCryptoHawkOptions
*options);
G_END_DECLS
diff --git a/src/ephy-sync-secret.c b/src/ephy-sync-secret.c
index 4b430dd..29ca050 100644
--- a/src/ephy-sync-secret.c
+++ b/src/ephy-sync-secret.c
@@ -123,7 +123,7 @@ ephy_sync_secret_load_tokens (EphySyncService *sync_service)
if (g_strcmp0 (emailUTF8, user_email))
continue;
- ephy_sync_service_save_token (sync_service, token_type, g_strdup (token_value));
+ ephy_sync_service_save_token (sync_service, g_strdup (token_value), token_type);
LOG ("[%d] Loaded token %s with value %s for email %s", __LINE__, token_name, token_value, emailUTF8);
g_hash_table_unref (attributes);
@@ -134,8 +134,8 @@ LOG ("[%d] Loaded token %s with value %s for email %s", __LINE__, token_name, to
void
ephy_sync_secret_store_token (const gchar *emailUTF8,
- EphySyncTokenType token_type,
- gchar *token_value)
+ gchar *token_value,
+ EphySyncTokenType token_type)
{
SecretValue *secret_value;
GHashTable *attributes;
diff --git a/src/ephy-sync-secret.h b/src/ephy-sync-secret.h
index 5885f77..b5826b5 100644
--- a/src/ephy-sync-secret.h
+++ b/src/ephy-sync-secret.h
@@ -39,8 +39,8 @@ void ephy_sync_secret_forget_all_tokens (void);
void ephy_sync_secret_load_tokens (EphySyncService *sync_service);
void ephy_sync_secret_store_token (const gchar *emailUTF8,
- EphySyncTokenType token_type,
- gchar *token_value);
+ gchar *token_value,
+ EphySyncTokenType token_type);
G_END_DECLS
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index 04910e1..aa4f4f3 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -24,17 +24,20 @@
#include "ephy-sync-service.h"
#include "ephy-sync-utils.h"
+#include <glib/gi18n.h>
#include <json-glib/json-glib.h>
#include <libsoup/soup.h>
#include <string.h>
#define FXA_BASEURL "https://api.accounts.firefox.com/"
#define FXA_VERSION "v1/"
+#define STATUS_OK 200
struct _EphySyncService {
GObject parent_instance;
SoupSession *soup_session;
+ JsonParser *parser;
gchar *user_email;
GHashTable *tokens;
@@ -43,15 +46,23 @@ struct _EphySyncService {
G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
-static SoupMessage *
-synchronous_hawk_get_request (EphySyncService *self,
- const gchar *endpoint,
- const gchar *id,
- guint8 *key,
- gsize key_length)
+static void
+save_and_store_tokens (EphySyncService *self,
+ gchar *token_value,
+ EphySyncTokenType token_type,
+ ...) G_GNUC_NULL_TERMINATED;
+
+static guint
+synchronous_hawk_get_request (EphySyncService *self,
+ const gchar *endpoint,
+ const gchar *id,
+ guint8 *key,
+ gsize key_length,
+ JsonObject **jobject)
{
EphySyncCryptoHawkHeader *hawk_header;
SoupMessage *message;
+ JsonNode *root;
gchar *url;
url = g_strdup_printf ("%s%s%s", FXA_BASEURL, FXA_VERSION, endpoint);
@@ -64,24 +75,34 @@ synchronous_hawk_get_request (EphySyncService *self,
"authorization", hawk_header->header);
LOG ("[%d] Sending synchronous HAWK GET request to %s endpoint", __LINE__, endpoint);
soup_session_send_message (self->soup_session, message);
+LOG ("[%d] Got response from server: %u", __LINE__, message->status_code);
+
+ json_parser_load_from_data (self->parser,
+ message->response_body->data,
+ -1, NULL);
+ root = json_parser_get_root (self->parser);
+ g_assert (JSON_NODE_HOLDS_OBJECT (root));
+ *jobject = json_node_get_object (root);
g_free (url);
ephy_sync_crypto_hawk_header_free (hawk_header);
- return message;
+ return message->status_code;
}
-static SoupMessage *
-synchronous_hawk_post_request (EphySyncService *self,
- const gchar *endpoint,
- const gchar *id,
- guint8 *key,
- gsize key_length,
- gchar *request_body)
+static guint
+synchronous_hawk_post_request (EphySyncService *self,
+ const gchar *endpoint,
+ const gchar *id,
+ guint8 *key,
+ gsize key_length,
+ gchar *request_body,
+ JsonObject **jobject)
{
EphySyncCryptoHawkHeader *hawk_header;
EphySyncCryptoHawkOptions *hawk_options;
SoupMessage *message;
+ JsonNode *root;
gchar *url;
url = g_strdup_printf ("%s%s%s", FXA_BASEURL, FXA_VERSION, endpoint);
@@ -106,20 +127,30 @@ synchronous_hawk_post_request (EphySyncService *self,
"content-type", "application/json");
LOG ("[%d] Sending synchronous HAWK POST request to %s endpoint", __LINE__, endpoint);
soup_session_send_message (self->soup_session, message);
+LOG ("[%d] Got response from server: %u", __LINE__, message->status_code);
+
+ json_parser_load_from_data (self->parser,
+ message->response_body->data,
+ -1, NULL);
+ root = json_parser_get_root (self->parser);
+ g_assert (JSON_NODE_HOLDS_OBJECT (root));
+ *jobject = json_node_get_object (root);
g_free (url);
ephy_sync_crypto_hawk_options_free (hawk_options);
ephy_sync_crypto_hawk_header_free (hawk_header);
- return message;
+ return message->status_code;
}
-static SoupMessage *
-synchronous_fxa_post_request (EphySyncService *self,
- const gchar *endpoint,
- gchar *request_body)
+static guint
+synchronous_fxa_post_request (EphySyncService *self,
+ const gchar *endpoint,
+ gchar *request_body,
+ JsonObject **jobject)
{
SoupMessage *message;
+ JsonNode *root;
gchar *url;
url = g_strdup_printf ("%s%s%s", FXA_BASEURL, FXA_VERSION, endpoint);
@@ -131,10 +162,40 @@ synchronous_fxa_post_request (EphySyncService *self,
strlen (request_body));
LOG ("[%d] Sending synchronous POST request to %s endpoint", __LINE__, endpoint);
soup_session_send_message (self->soup_session, message);
+LOG ("[%d] Got response from server: %u", __LINE__, message->status_code);
+
+ json_parser_load_from_data (self->parser,
+ message->response_body->data,
+ -1, NULL);
+ root = json_parser_get_root (self->parser);
+ g_assert (JSON_NODE_HOLDS_OBJECT (root));
+ *jobject = json_node_get_object (root);
g_free (url);
- return message;
+ return message->status_code;
+}
+
+static void
+save_and_store_tokens (EphySyncService *self,
+ gchar *token_value,
+ EphySyncTokenType token_type,
+ ...)
+{
+ EphySyncTokenType type;
+ gchar *value;
+ va_list args;
+
+ ephy_sync_service_save_token (self, token_value, token_type);
+ ephy_sync_secret_store_token (self->user_email, token_value, token_type);
+
+ va_start (args, token_type);
+ while ((value = va_arg (args, gchar *)) != NULL) {
+ type = va_arg (args, EphySyncTokenType);
+ ephy_sync_service_save_token (self, value, type);
+ ephy_sync_secret_store_token (self->user_email, value, type);
+ }
+ va_end (args);
}
static void
@@ -145,6 +206,7 @@ ephy_sync_service_finalize (GObject *object)
g_free (self->user_email);
g_hash_table_destroy (self->tokens);
g_clear_object (&self->soup_session);
+ g_clear_object (&self->parser);
G_OBJECT_CLASS (ephy_sync_service_parent_class)->finalize (object);
}
@@ -165,6 +227,7 @@ ephy_sync_service_init (EphySyncService *self)
self->tokens = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, g_free);
self->soup_session = soup_session_new ();
+ self->parser = json_parser_new ();
sync_user = g_settings_get_string (EPHY_SETTINGS_MAIN,
EPHY_PREFS_SYNC_USER);
@@ -215,8 +278,8 @@ LOG ("[%d] Returning token %s with value %s", __LINE__, token_name, token_value)
void
ephy_sync_service_save_token (EphySyncService *self,
- EphySyncTokenType token_type,
- gchar *token_value)
+ gchar *token_value,
+ EphySyncTokenType token_type)
{
const gchar *token_name;
@@ -251,154 +314,114 @@ LOG ("[%d] Deleted all tokens", __LINE__);
gboolean
ephy_sync_service_login (EphySyncService *self,
- guint *error_code,
+ const gchar *emailUTF8,
+ const gchar *passwordUTF8,
gchar **error_message)
{
- SoupMessage *message;
- JsonParser *parser;
- JsonNode *root;
- JsonObject *object;
+ EphySyncCryptoStretchedCredentials *stretched_credentials = NULL;
+ EphySyncCryptoProcessedKFT *processed_kft = NULL;
+ EphySyncCryptoSyncKeys *sync_keys = NULL;
+ JsonObject *jobject;
gchar *request_body;
- gchar *quickStretchedPW;
- gchar *authPW;
- gchar *unwrapBKey;
- gchar *uid;
- gchar *sessionToken;
- gchar *keyFetchToken;
-
- authPW = ephy_sync_service_get_token (self, EPHY_SYNC_TOKEN_AUTHPW);
- g_return_val_if_fail (authPW, FALSE);
-
+ gchar *tokenID = NULL;
+ gchar *authPW = NULL;
+ gchar *unwrapBKey = NULL;
+ gchar *uid = NULL;
+ gchar *sessionToken = NULL;
+ gchar *keyFetchToken = NULL;
+ gchar *kA = NULL;
+ gchar *kB = NULL;
+ gchar *wrapKB = NULL;
+ guint status_code;
+ gboolean retval = FALSE;
+
+ stretched_credentials = ephy_sync_crypto_stretch (emailUTF8, passwordUTF8);
+ authPW = ephy_sync_utils_encode_hex (stretched_credentials->authPW, 0);
request_body = ephy_sync_utils_build_json_string ("authPW", authPW,
- "email", self->user_email,
+ "email", emailUTF8,
NULL);
- message = synchronous_fxa_post_request (self,
- "account/login?keys=true",
- request_body);
-LOG ("[%d] status code: %u", __LINE__, message->status_code);
-
- parser = json_parser_new ();
- json_parser_load_from_data (parser, message->response_body->data, -1, NULL);
- root = json_parser_get_root (parser);
- g_assert (JSON_NODE_HOLDS_OBJECT (root));
- object = json_node_get_object (root);
-
- if (message->status_code != 200) {
- *error_message = g_strdup (json_object_get_string_member (object, "message"));
- *error_code = json_object_get_int_member (object, "errno");
-
-LOG ("[%d] errno: %u, errmsg: %s", __LINE__, *error_code, *error_message);
-
- ephy_sync_service_delete_all_tokens (self);
- ephy_sync_service_set_user_email (self, NULL);
-
- return FALSE;
+ status_code = synchronous_fxa_post_request (self,
+ "account/login?keys=true",
+ request_body,
+ &jobject);
+ if (status_code != STATUS_OK) {
+ g_warning ("FxA server errno: %ld, errmsg: %s",
+ json_object_get_int_member (jobject, "errno"),
+ json_object_get_string_member (jobject, "message"));
+ *error_message = g_strdup_printf ("%s.",
+ json_object_get_string_member (jobject, "message"));
+ g_free (authPW);
+ goto out;
+ } else if (json_object_get_boolean_member (jobject, "verified") == FALSE) {
+ g_warning ("Firefox Account not verified");
+ *error_message = g_strdup (_("Account not verified!"));
+ g_free (authPW);
+ goto out;
}
- /* Extract uid, sesionToken, keyFetchToken */
- uid = g_strdup (json_object_get_string_member (object, "uid"));
- sessionToken = g_strdup (json_object_get_string_member (object, "sessionToken"));
- keyFetchToken = g_strdup (json_object_get_string_member (object, "keyFetchToken"));
-
- /* Save tokens in memory */
- ephy_sync_service_save_token (self,
- EPHY_SYNC_TOKEN_UID,
- uid);
- ephy_sync_service_save_token (self,
- EPHY_SYNC_TOKEN_SESSIONTOKEN,
- sessionToken);
- ephy_sync_service_save_token (self,
- EPHY_SYNC_TOKEN_KEYFETCHTOKEN,
- keyFetchToken);
-
- /* Store tokens on disk */
- quickStretchedPW = ephy_sync_service_get_token (self, EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW);
- unwrapBKey = ephy_sync_service_get_token (self, EPHY_SYNC_TOKEN_UNWRAPBKEY);
- ephy_sync_secret_store_token (self->user_email,
- EPHY_SYNC_TOKEN_AUTHPW,
- authPW);
- ephy_sync_secret_store_token (self->user_email,
- EPHY_SYNC_TOKEN_KEYFETCHTOKEN,
- keyFetchToken);
- ephy_sync_secret_store_token (self->user_email,
- EPHY_SYNC_TOKEN_SESSIONTOKEN,
- sessionToken);
- ephy_sync_secret_store_token (self->user_email,
- EPHY_SYNC_TOKEN_UID,
- uid);
- ephy_sync_secret_store_token (self->user_email,
- EPHY_SYNC_TOKEN_UNWRAPBKEY,
- unwrapBKey);
- ephy_sync_secret_store_token (self->user_email,
- EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW,
- quickStretchedPW);
-
- return TRUE;
-}
+ uid = g_strdup (json_object_get_string_member (jobject, "uid"));
+ sessionToken = g_strdup (json_object_get_string_member (jobject, "sessionToken"));
+ keyFetchToken = g_strdup (json_object_get_string_member (jobject, "keyFetchToken"));
+
+ /* Proceed with key fetching */
+ processed_kft = ephy_sync_crypto_process_key_fetch_token (keyFetchToken);
+ tokenID = ephy_sync_utils_encode_hex (processed_kft->tokenID, 0);
+ status_code = synchronous_hawk_get_request (self,
+ "account/keys",
+ tokenID,
+ processed_kft->reqHMACkey,
+ EPHY_SYNC_TOKEN_LENGTH,
+ &jobject);
+ if (status_code != STATUS_OK) {
+ g_warning ("FxA server errno: %ld, errmsg: %s",
+ json_object_get_int_member (jobject, "errno"),
+ json_object_get_string_member (jobject, "message"));
+ /* Translators: the %s refers to the error message. */
+ *error_message = g_strdup_printf (_("Failed to retrieve keys: %s. Please try again."),
+ json_object_get_string_member (jobject, "message"));
+ g_free (authPW);
+ g_free (uid);
+ g_free (sessionToken);
+ g_free (keyFetchToken);
+ goto out;
+ }
-void
-ephy_sync_service_stretch (EphySyncService *self,
- const gchar *emailUTF8,
- const gchar *passwordUTF8)
-{
- gchar *salt_stretch;
- gchar *info_auth;
- gchar *info_unwrap;
- guint8 *quickStretchedPW;
- guint8 *authPW;
- guint8 *unwrapBKey;
-
- salt_stretch = ephy_sync_utils_kwe ("quickStretch", emailUTF8);
- quickStretchedPW = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
- ephy_sync_crypto_pbkdf2_1k ((guint8 *) passwordUTF8,
- strlen (passwordUTF8),
- (guint8 *) salt_stretch,
- strlen (salt_stretch),
- quickStretchedPW,
- EPHY_SYNC_TOKEN_LENGTH);
-
-ephy_sync_utils_display_hex ("quickStretchedPW", quickStretchedPW, EPHY_SYNC_TOKEN_LENGTH);
-
- info_auth = ephy_sync_utils_kw ("authPW");
- authPW = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
- ephy_sync_crypto_hkdf (quickStretchedPW,
- EPHY_SYNC_TOKEN_LENGTH,
- NULL, 0,
- (guint8 *) info_auth,
- strlen (info_auth),
- authPW,
- EPHY_SYNC_TOKEN_LENGTH);
-
- info_unwrap = ephy_sync_utils_kw ("unwrapBkey");
- unwrapBKey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
- ephy_sync_crypto_hkdf (quickStretchedPW,
- EPHY_SYNC_TOKEN_LENGTH,
- NULL, 0,
- (guint8 *) info_unwrap,
- strlen (info_unwrap),
- unwrapBKey,
- EPHY_SYNC_TOKEN_LENGTH);
-
-LOG ("[%d] Stretching done", __LINE__);
+ sync_keys = ephy_sync_crypto_retrieve_sync_keys (json_object_get_string_member (jobject, "bundle"),
+ processed_kft->respHMACkey,
+ processed_kft->respXORkey,
+ stretched_credentials->unwrapBKey);
+ if (sync_keys == NULL) {
+ *error_message = g_strdup (_("Something went wrong, please try again."));
+ g_free (authPW);
+ g_free (uid);
+ g_free (sessionToken);
+ g_free (keyFetchToken);
+ goto out;
+ }
+ /* Everything okay, save and store tokens */
ephy_sync_service_set_user_email (self, emailUTF8);
- ephy_sync_service_save_token (self,
- EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW,
- ephy_sync_utils_encode_hex (quickStretchedPW,
- EPHY_SYNC_TOKEN_LENGTH));
- ephy_sync_service_save_token (self,
- EPHY_SYNC_TOKEN_AUTHPW,
- ephy_sync_utils_encode_hex (authPW,
- EPHY_SYNC_TOKEN_LENGTH));
- ephy_sync_service_save_token (self,
- EPHY_SYNC_TOKEN_UNWRAPBKEY,
- ephy_sync_utils_encode_hex (unwrapBKey,
- EPHY_SYNC_TOKEN_LENGTH));
-
- g_free (salt_stretch);
- g_free (info_unwrap);
- g_free (info_auth);
- g_free (quickStretchedPW);
- g_free (authPW);
- g_free (unwrapBKey);
+ unwrapBKey = ephy_sync_utils_encode_hex (stretched_credentials->unwrapBKey, 0);
+ kA = ephy_sync_utils_encode_hex (sync_keys->kA, 0);
+ kB = ephy_sync_utils_encode_hex (sync_keys->kB, 0);
+ wrapKB = ephy_sync_utils_encode_hex (sync_keys->wrapKB, 0);
+ save_and_store_tokens (self,
+ authPW, EPHY_SYNC_TOKEN_AUTHPW,
+ unwrapBKey, EPHY_SYNC_TOKEN_UNWRAPBKEY,
+ uid, EPHY_SYNC_TOKEN_UID,
+ sessionToken, EPHY_SYNC_TOKEN_SESSIONTOKEN,
+ keyFetchToken, EPHY_SYNC_TOKEN_KEYFETCHTOKEN,
+ kA, EPHY_SYNC_TOKEN_KA,
+ kB, EPHY_SYNC_TOKEN_KB,
+ wrapKB, EPHY_SYNC_TOKEN_WRAPKB,
+ NULL);
+ retval = TRUE;
+
+out:
+ ephy_sync_crypto_stretched_credentials_free (stretched_credentials);
+ ephy_sync_crypto_processed_kft_free (processed_kft);
+ ephy_sync_crypto_sync_keys_free (sync_keys);
+ g_free (tokenID);
+
+ return retval;
}
diff --git a/src/ephy-sync-service.h b/src/ephy-sync-service.h
index 2631971..ffe63eb 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -40,20 +40,17 @@ gchar *ephy_sync_service_get_token (EphySyncService *self,
EphySyncTokenType token_type);
void ephy_sync_service_save_token (EphySyncService *self,
- EphySyncTokenType token_type,
- gchar *token_value);
+ gchar *token_value,
+ EphySyncTokenType token_type);
void ephy_sync_service_delete_token (EphySyncService *self,
EphySyncTokenType token_type);
void ephy_sync_service_delete_all_tokens (EphySyncService *self);
-void ephy_sync_service_stretch (EphySyncService *self,
- const gchar *emailUTF8,
- const gchar *passwordUTF8);
-
gboolean ephy_sync_service_login (EphySyncService *self,
- guint *error_code,
+ const gchar *emailUTF8,
+ const gchar *passwordUTF8,
gchar **error_message);
G_END_DECLS
diff --git a/src/ephy-sync-utils.c b/src/ephy-sync-utils.c
index c307b0b..784b78e 100644
--- a/src/ephy-sync-utils.c
+++ b/src/ephy-sync-utils.c
@@ -41,16 +41,20 @@ gchar *
ephy_sync_utils_encode_hex (guint8 *data,
gsize data_length)
{
- gchar *retval = g_malloc (data_length * 2 + 1);
+ gchar *retval;
+ gsize length;
- for (gsize i = 0; i < data_length; i++) {
+ length = data_length == 0 ? EPHY_SYNC_TOKEN_LENGTH : data_length;
+ retval = g_malloc (length * 2 + 1);
+
+ for (gsize i = 0; i < length; i++) {
guint8 byte = data[i];
retval[2 * i] = hex_digits[byte >> 4];
retval[2 * i + 1] = hex_digits[byte & 0xf];
}
- retval[data_length * 2] = 0;
+ retval[length * 2] = 0;
return retval;
}
@@ -59,8 +63,9 @@ guint8 *
ephy_sync_utils_decode_hex (const gchar *hex_string)
{
guint8 *retval;
- gsize hex_length = strlen (hex_string);
+ gsize hex_length;
+ hex_length = strlen (hex_string);
g_return_val_if_fail (hex_length % 2 == 0, NULL);
retval = g_malloc (hex_length / 2);
@@ -77,17 +82,21 @@ ephy_sync_utils_token_name_from_type (EphySyncTokenType token_type)
{
switch (token_type) {
case EPHY_SYNC_TOKEN_AUTHPW:
- return "authPw";
- case EPHY_SYNC_TOKEN_KEYFETCHTOKEN:
- return "keyFetchToken";
- case EPHY_SYNC_TOKEN_SESSIONTOKEN:
- return "sessionToken";
- case EPHY_SYNC_TOKEN_UID:
- return "uid";
+ return "authPW";
case EPHY_SYNC_TOKEN_UNWRAPBKEY:
return "unwrapBKey";
- case EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW:
- return "quickStretchedPW";
+ case EPHY_SYNC_TOKEN_UID:
+ return "uid";
+ case EPHY_SYNC_TOKEN_SESSIONTOKEN:
+ return "sessionToken";
+ case EPHY_SYNC_TOKEN_KEYFETCHTOKEN:
+ return "keyFetchToken";
+ case EPHY_SYNC_TOKEN_KA:
+ return "kA";
+ case EPHY_SYNC_TOKEN_KB:
+ return "kB";
+ case EPHY_SYNC_TOKEN_WRAPKB:
+ return "wrapKB";
default:
g_assert_not_reached ();
}
diff --git a/src/ephy-sync-utils.h b/src/ephy-sync-utils.h
index 9e33850..a0ee2ec 100644
--- a/src/ephy-sync-utils.h
+++ b/src/ephy-sync-utils.h
@@ -27,11 +27,13 @@ G_BEGIN_DECLS
typedef enum {
EPHY_SYNC_TOKEN_AUTHPW,
- EPHY_SYNC_TOKEN_KEYFETCHTOKEN,
- EPHY_SYNC_TOKEN_SESSIONTOKEN,
- EPHY_SYNC_TOKEN_UID,
EPHY_SYNC_TOKEN_UNWRAPBKEY,
- EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW
+ EPHY_SYNC_TOKEN_UID,
+ EPHY_SYNC_TOKEN_SESSIONTOKEN,
+ EPHY_SYNC_TOKEN_KEYFETCHTOKEN,
+ EPHY_SYNC_TOKEN_KA,
+ EPHY_SYNC_TOKEN_KB,
+ EPHY_SYNC_TOKEN_WRAPKB
} EphySyncTokenType;
gchar *ephy_sync_utils_kw (const gchar *name);
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index ae830fb..633e809 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -34,6 +34,7 @@
#include "ephy-session.h"
#include "ephy-settings.h"
#include "ephy-shell.h"
+#include "ephy-sync-secret.h"
#include "ephy-sync-service.h"
#include "clear-data-dialog.h"
#include "cookies-dialog.h"
@@ -173,7 +174,6 @@ on_sync_login_button_clicked (GtkWidget *button,
const gchar *emailUTF8;
const gchar *passwordUTF8;
gboolean login_ok;
- guint error_code = 0;
gchar *error_message = NULL;
gtk_label_set_markup (GTK_LABEL (dialog->sync_email_details_label), "");
@@ -199,8 +199,10 @@ LOG ("[%d] email: %s", __LINE__, emailUTF8);
LOG ("[%d] password: %s", __LINE__, passwordUTF8);
sync_service = ephy_shell_get_global_sync_service ();
- ephy_sync_service_stretch (sync_service, emailUTF8, passwordUTF8);
- login_ok = ephy_sync_service_login (sync_service, &error_code, &error_message);
+ login_ok = ephy_sync_service_login (sync_service,
+ emailUTF8,
+ passwordUTF8,
+ &error_message);
if (login_ok == FALSE) {
/* Translators: the %s refers to the error message. */
@@ -229,10 +231,17 @@ static void
on_sync_logout_button_clicked (GtkWidget *button,
PrefsDialog *dialog)
{
+ EphySyncService *sync_service;
+
+ sync_service = ephy_shell_get_global_sync_service ();
+
gtk_entry_set_text (GTK_ENTRY (dialog->sync_email_entry), "");
gtk_entry_set_text (GTK_ENTRY (dialog->sync_password_entry), "");
- /* TODO: Call /session/destroy endpoint and forget tokens */
+ /* TODO: Call session/destroy endpoint */
+
+ ephy_sync_service_delete_all_tokens (sync_service);
+ ephy_sync_secret_forget_all_tokens ();
g_settings_set_string (EPHY_SETTINGS_MAIN,
EPHY_PREFS_SYNC_USER,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]