[evolution-data-server] Change how OAuth2 credentials are stored in the code



commit 7554d3b95124486ac98d9a5052e069e46242a216
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 8 08:51:51 2022 +0200

    Change how OAuth2 credentials are stored in the code
    
    At least do not store them in the clear form.

 CMakeLists.txt                               |   8 +-
 src/libedataserver/CMakeLists.txt            |  28 +++++
 src/libedataserver/e-oauth2-service-google.c |   6 +-
 src/libedataserver/e-oauth2-service-yahoo.c  |   6 +-
 src/libedataserver/e-oauth2-service.c        | 159 +++++++++++++++++++++++++++
 src/libedataserver/e-oauth2-service.h        |   3 +
 6 files changed, 202 insertions(+), 8 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1e53162e8..f84bcb455 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -410,11 +410,11 @@ add_printable_variable(WITH_GOOGLE_CLIENT_ID "Google OAuth 2.0 client id" "")
 add_printable_variable(WITH_GOOGLE_CLIENT_SECRET "Google OAuth 2.0 client secret" "")
 
 if(WITH_GOOGLE_CLIENT_ID STREQUAL "")
-       set(WITH_GOOGLE_CLIENT_ID "590402290962-2i0b7rqma8b9nmtfrcp7fa06g6cf7g74.apps.googleusercontent.com")
+       set(WITH_GOOGLE_CLIENT_ID 
"|7uLr7+vp6eLr4u3p9umy67nsqaq2uuO54rW2r72puKvsvbrr7bztuL3svOzv9bqrq6j1vLS0vLe+rqi+qbi0ta++ta/1uLS22w==|")
 endif(WITH_GOOGLE_CLIENT_ID STREQUAL "")
 
 if(WITH_GOOGLE_CLIENT_SECRET STREQUAL "")
-       set(WITH_GOOGLE_CLIENT_SECRET "mtfUe5W8Aal9DcgVipOY1T9G")
+       set(WITH_GOOGLE_CLIENT_SECRET "|UUhaaVkJawR9XVAFeF9balVMc2UNaAV7PA==|")
 endif(WITH_GOOGLE_CLIENT_SECRET STREQUAL "")
 
 add_printable_variable(WITH_OUTLOOK_CLIENT_ID "Outlook.com OAuth 2.0 client id" "")
@@ -433,11 +433,11 @@ add_printable_variable(WITH_YAHOO_CLIENT_ID "Yahoo! OAuth 2.0 client id" "")
 add_printable_variable(WITH_YAHOO_CLIENT_SECRET "Yahoo! OAuth 2.0 client secret" "")
 
 if(WITH_YAHOO_CLIENT_ID STREQUAL "")
-       set(WITH_YAHOO_CLIENT_ID 
"dj0yJmk9RHNlMGFKTXdkYzRXJmQ9WVdrOVNUUXpUWGhzWjJzbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PWNi")
+       set(WITH_YAHOO_CLIENT_ID 
"|Q00XXm1KTB51b2lLamBhbHN/Q0x+XXV/bUp2HnBxQ1VocWlycn9XcnBgT11wTW1dRXBpb0VdS2l2cxcebUlqHn4VHlJEFHFTfX9tXX1waV59f3ZKRBR+HmpkfRN3cGlOJw==|")
 endif(WITH_YAHOO_CLIENT_ID STREQUAL "")
 
 if(WITH_YAHOO_CLIENT_SECRET STREQUAL "")
-       set(WITH_YAHOO_CLIENT_SECRET "35f49f199dd754ec5e86d3c7cd576a1341c9bc0b")
+       set(WITH_YAHOO_CLIENT_SECRET "|c3UmdHkmcXl5JCR3dXQlI3UleHYkcyN3IyR1d3YhcXN0cSN5IiNwIkA=|")
 endif(WITH_YAHOO_CLIENT_SECRET STREQUAL "")
 
 # ******************************************
diff --git a/src/libedataserver/CMakeLists.txt b/src/libedataserver/CMakeLists.txt
index aa535055f..32fcb543a 100644
--- a/src/libedataserver/CMakeLists.txt
+++ b/src/libedataserver/CMakeLists.txt
@@ -331,3 +331,31 @@ gir_add_introspection_simple(
        gir_deps
        gir_sources
 )
+
+if(ENABLE_MAINTAINER_MODE)
+       add_executable(oauth2-value-helper
+               e-oauth2-service.c
+       )
+
+       add_dependencies(oauth2-value-helper
+               ${DEPENDENCIES}
+       )
+
+       target_compile_definitions(oauth2-value-helper PRIVATE
+               -DG_LOG_DOMAIN=\"oauth2-value-helper\"
+               -DBUILDING_VALUE_HELPER=1
+       )
+
+       target_compile_options(oauth2-value-helper PUBLIC
+               ${DATA_SERVER_CFLAGS}
+       )
+
+       target_include_directories(oauth2-value-helper PUBLIC
+               ${CMAKE_BINARY_DIR}
+               ${DATA_SERVER_INCLUDE_DIRS}
+       )
+
+       target_link_libraries(oauth2-value-helper
+               ${DATA_SERVER_LDFLAGS}
+       )
+endif(ENABLE_MAINTAINER_MODE)
diff --git a/src/libedataserver/e-oauth2-service-google.c b/src/libedataserver/e-oauth2-service-google.c
index f0c6f2cbf..4d262d32f 100644
--- a/src/libedataserver/e-oauth2-service-google.c
+++ b/src/libedataserver/e-oauth2-service-google.c
@@ -92,6 +92,7 @@ static const gchar *
 eos_google_get_client_id (EOAuth2Service *service,
                          ESource *source)
 {
+       static gchar glob_buff[128] = {0, };
        const gchar *client_id;
 
        client_id = eos_google_read_settings (service, "oauth2-google-client-id");
@@ -99,13 +100,14 @@ eos_google_get_client_id (EOAuth2Service *service,
        if (client_id && *client_id)
                return client_id;
 
-       return GOOGLE_CLIENT_ID;
+       return e_oauth2_service_util_compile_value (GOOGLE_CLIENT_ID, glob_buff, sizeof (glob_buff));
 }
 
 static const gchar *
 eos_google_get_client_secret (EOAuth2Service *service,
                              ESource *source)
 {
+       static gchar glob_buff[128] = {0, };
        const gchar *client_secret;
 
        client_secret = eos_google_read_settings (service, "oauth2-google-client-secret");
@@ -113,7 +115,7 @@ eos_google_get_client_secret (EOAuth2Service *service,
        if (client_secret && *client_secret)
                return client_secret;
 
-       return GOOGLE_CLIENT_SECRET;
+       return e_oauth2_service_util_compile_value (GOOGLE_CLIENT_SECRET, glob_buff, sizeof (glob_buff));
 }
 
 static const gchar *
diff --git a/src/libedataserver/e-oauth2-service-yahoo.c b/src/libedataserver/e-oauth2-service-yahoo.c
index 329a38c41..b16e6b18a 100644
--- a/src/libedataserver/e-oauth2-service-yahoo.c
+++ b/src/libedataserver/e-oauth2-service-yahoo.c
@@ -89,6 +89,7 @@ static const gchar *
 eos_yahoo_get_client_id (EOAuth2Service *service,
                         ESource *source)
 {
+       static gchar glob_buff[128] = {0, };
        const gchar *client_id;
 
        client_id = eos_yahoo_read_settings (service, "oauth2-yahoo-client-id");
@@ -96,13 +97,14 @@ eos_yahoo_get_client_id (EOAuth2Service *service,
        if (client_id && *client_id)
                return client_id;
 
-       return YAHOO_CLIENT_ID;
+       return e_oauth2_service_util_compile_value (YAHOO_CLIENT_ID, glob_buff, sizeof (glob_buff));
 }
 
 static const gchar *
 eos_yahoo_get_client_secret (EOAuth2Service *service,
                             ESource *source)
 {
+       static gchar glob_buff[128] = {0, };
        const gchar *client_secret;
 
        client_secret = eos_yahoo_read_settings (service, "oauth2-yahoo-client-secret");
@@ -110,7 +112,7 @@ eos_yahoo_get_client_secret (EOAuth2Service *service,
        if (client_secret && *client_secret)
                return client_secret;
 
-       return YAHOO_CLIENT_SECRET;
+       return e_oauth2_service_util_compile_value (YAHOO_CLIENT_SECRET, glob_buff, sizeof (glob_buff));
 }
 
 static const gchar *
diff --git a/src/libedataserver/e-oauth2-service.c b/src/libedataserver/e-oauth2-service.c
index ce970b8bf..25c8483cf 100644
--- a/src/libedataserver/e-oauth2-service.c
+++ b/src/libedataserver/e-oauth2-service.c
@@ -30,6 +30,8 @@
 
 #include <string.h>
 #include <glib/gi18n-lib.h>
+
+#ifndef BUILDING_VALUE_HELPER
 #include <json-glib/json-glib.h>
 
 #include "e-secret-store.h"
@@ -1590,3 +1592,160 @@ e_oauth2_service_util_take_to_form (GHashTable *form,
        else
                g_hash_table_remove (form, name);
 }
+
+/**
+ * e_oauth2_service_util_compile_value:
+ * @compile_value: a value provided in the compile time
+ * @out_glob_buff: (out caller-allocates): a global buffer to store the processed value to
+ * @out_glob_buff_size: size of the @out_glob_buff
+ *
+ * Processes the @compile_value and returns the result, which is stored
+ * into the @out_glob_buff. The @out_glob_buff should be large enough to hold
+ * the processed value and it should be a global memory buffer (usually
+ * statically allocated) initialized to 0, which is used to short-circuit
+ * the call, because the processing is done only if the first element
+ * of the @out_glob_buff is 0, in all other cases the function
+ * immediately returns the @out_glob_buff.
+ *
+ * Returns: processed @compile_value, saved into *out_glob_buff
+ *
+ * Since: 3.46
+ **/
+#else  /* !BUILDING_VALUE_HELPER */
+static /* to not claim missing prototype */
+#endif /* !BUILDING_VALUE_HELPER */
+const gchar *
+e_oauth2_service_util_compile_value (const gchar *compile_value,
+                                    gchar *out_glob_buff,
+                                    gsize out_glob_buff_size)
+{
+       G_LOCK_DEFINE_STATIC (lock);
+
+       g_return_val_if_fail (out_glob_buff != NULL, NULL);
+       g_return_val_if_fail (out_glob_buff_size > 0, NULL);
+
+       if (!compile_value || !*compile_value) {
+               out_glob_buff[0] = '\0';
+               return out_glob_buff;
+       }
+
+       G_LOCK (lock);
+
+       if (!*out_glob_buff) {
+               if (g_str_has_prefix (compile_value, "|") &&
+                   g_str_has_suffix (compile_value, "|") && compile_value[1]) {
+                       gchar *tmp = g_strndup (compile_value + 1, strlen (compile_value) - 2);
+                       guchar *data;
+                       gsize data_len = 0;
+
+                       data = g_base64_decode (tmp, &data_len);
+                       if (!data) {
+                               g_warning ("Failed to decode base64 data");
+                       } else if (!data_len) {
+                               /* Nothing to decode */
+                       } else if (out_glob_buff_size < data_len) {
+                               g_warning ("global buffer size (%" G_GSIZE_FORMAT ") is not large enough, 
requires at least %" G_GSIZE_FORMAT " bytes",
+                                       out_glob_buff_size, (gsize) data_len);
+                       } else {
+                               guchar rval = data[data_len - 1];
+                               guint ii;
+
+                               for (ii = 0; ii < data_len; ii++) {
+                                       out_glob_buff[ii] = data[ii] ^ rval;
+                               }
+                       }
+                       g_free (data);
+                       g_free (tmp);
+               } else if (out_glob_buff_size < strlen (compile_value) + 1) {
+                       g_warning ("global buffer size (%" G_GSIZE_FORMAT ") is not large enough, requires at 
least %" G_GSIZE_FORMAT " bytes",
+                               out_glob_buff_size, (gsize) (strlen (compile_value) + 1));
+               } else {
+                       strcpy (out_glob_buff, compile_value);
+               }
+       }
+
+       G_UNLOCK (lock);
+
+       return out_glob_buff;
+}
+
+#ifdef BUILDING_VALUE_HELPER
+#include <stdio.h>
+
+gint
+main (void)
+{
+       gchar chr;
+       GString *str;
+
+       str = g_string_new ("");
+
+       g_random_set_seed ((gint) (g_get_monotonic_time () + g_get_real_time ()));
+
+       while (chr = fgetc (stdin), !feof (stdin) || str->len) {
+               if (chr == '\n' || feof (stdin)) {
+                       if (str->len) {
+                               GByteArray *array;
+                               const gchar *processed;
+                               gchar *b64, *res, *test_buff;
+                               gsize test_buff_size;
+                               guchar rval;
+                               guint ii;
+
+                               while (rval = g_random_int_range (1, 255), !rval) {
+                                       ;
+                               }
+
+                               array = g_byte_array_new ();
+
+                               for (ii = 0; ii < str->len; ii++) {
+                                       guchar val = (guchar) str->str[ii];
+                                       val = val ^ rval;
+                                       g_byte_array_append (array, &val, 1);
+                               }
+
+                               g_byte_array_append (array, &rval, 1);
+
+                               b64 = g_base64_encode (array->data, array->len);
+                               res = g_strconcat ("|", b64, "|", NULL);
+
+                               g_byte_array_unref (array);
+                               g_free (b64);
+
+                               test_buff_size = strlen (res) + 1;
+                               test_buff = g_malloc0 (sizeof (gchar) * test_buff_size);
+
+                               processed = e_oauth2_service_util_compile_value (res, test_buff, 
test_buff_size);
+                               if (g_strcmp0 (processed, str->str) != 0) {
+                                       g_warning ("Failed to de-process '%s', stopping", str->str);
+                                       g_free (test_buff);
+                                       g_free (res);
+                                       break;
+                               }
+
+                               processed = e_oauth2_service_util_compile_value (res, test_buff, 
test_buff_size);
+                               if (g_strcmp0 (processed, str->str) != 0) {
+                                       g_warning ("Failed to de-process '%s' for the second call, stopping", 
str->str);
+                                       g_free (test_buff);
+                                       g_free (res);
+                                       break;
+                               }
+
+                               printf ("%s ~> %s\n", str->str, res);
+
+                               g_free (test_buff);
+                               g_free (res);
+
+                               g_string_truncate (str, 0);
+                       }
+               } else if (chr != '\t' && chr != '\r' && chr != ' ') {
+                       g_string_append_c (str, chr);
+               }
+       }
+
+       g_string_free (str, TRUE);
+
+       return 0;
+}
+
+#endif /* BUILDING_VALUE_HELPER */
diff --git a/src/libedataserver/e-oauth2-service.h b/src/libedataserver/e-oauth2-service.h
index e97778e68..5eac007be 100644
--- a/src/libedataserver/e-oauth2-service.h
+++ b/src/libedataserver/e-oauth2-service.h
@@ -249,6 +249,9 @@ void                e_oauth2_service_util_set_to_form       (GHashTable *form,
 void           e_oauth2_service_util_take_to_form      (GHashTable *form,
                                                         const gchar *name,
                                                         gchar *value);
+const gchar *  e_oauth2_service_util_compile_value     (const gchar *compile_value,
+                                                        gchar *out_glob_buff,
+                                                        gsize out_glob_buff_size);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]