commit 0b3e475621dfa6b22017095fb285c5087a1a096b from: Oliver Lowe date: Fri Nov 21 10:10:48 2025 UTC delete stuff commit - f2a22c54e626b8c1ebce3d6df117a35b076e163f commit + 0b3e475621dfa6b22017095fb285c5087a1a096b blob - 201fe7f8a5e1dc08ae486163983f69cd28e3a891 (mode 644) blob + /dev/null --- src/avatars.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2014-2016 Ricardo Mones and the Claws Mail team - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "defs.h" -#include "hooks.h" -#include "gtkutils.h" -#include "procmsg.h" -#include "prefs_common.h" -#include "avatars.h" - -static gulong avatar_render_hook_id = HOOK_NONE; - -AvatarRender *avatars_avatarrender_new(MsgInfo *msginfo) -{ - AvatarRender *ar = g_new0(AvatarRender, 1); - ar->full_msginfo = msginfo; - ar->image = NULL; - ar->type = 0; - - return ar; -} - -void avatars_avatarrender_free(AvatarRender *avrender) -{ - if (avrender == NULL) - return; - - if (avrender->image != NULL) { - gtk_widget_destroy(avrender->image); - } - g_free(avrender); -} - -gboolean avatars_internal_rendering_hook(gpointer source, gpointer data) -{ - AvatarRender *avatarr = (AvatarRender *)source; - gchar *aface; - - if (!(prefs_common.enable_avatars & AVATARS_ENABLE_RENDER)) { - debug_print("Internal rendering of avatars is disabled\n"); - return FALSE; - } - - if (avatarr == NULL) { - g_warning("internal rendering invoked with NULL argument"); - return FALSE; - } - - if (avatarr->image != NULL) { - g_warning("memory leak: image widget not destroyed"); - } - - aface = procmsg_msginfo_get_avatar(avatarr->full_msginfo, AVATAR_FACE); - if (aface) { - avatarr->image = face_get_from_header(aface); - avatarr->type = AVATAR_FACE; - } - return FALSE; -} - -void avatars_init(void) -{ - if (avatar_render_hook_id != HOOK_NONE) { - g_warning("internal avatars rendering already initialized"); - return; - } - avatar_render_hook_id = hooks_register_hook(AVATAR_IMAGE_RENDER_HOOKLIST, avatars_internal_rendering_hook, NULL); - if (avatar_render_hook_id == HOOK_NONE) { - g_warning("failed to register avatars internal rendering hook"); - } -} - -void avatars_done(void) -{ - if (avatar_render_hook_id != HOOK_NONE) { - hooks_unregister_hook(AVATAR_IMAGE_RENDER_HOOKLIST, avatar_render_hook_id); - avatar_render_hook_id = HOOK_NONE; - } -} blob - 3b34acfa74c2c3920bd1dd37ab2214cc2febeea1 (mode 644) blob + /dev/null --- src/avatars.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2014 Ricardo Mones and the Claws Mail team - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __AVATARS_H__ -#define __AVATARS_H__ - -#include -#include -#include - -#include "proctypes.h" - -#define AVATAR_IMAGE_RENDER_HOOKLIST "avatar_image_render" - -typedef struct _AvatarRender AvatarRender; - -struct _AvatarRender -{ - MsgInfo *full_msginfo; - GtkWidget *image; - gint type; -}; - -AvatarRender *avatars_avatarrender_new (MsgInfo *msginfo); -void avatars_avatarrender_free (AvatarRender *avrender); - -gboolean avatars_internal_rendering_hook (gpointer source, - gpointer data); - -void avatars_init (void); -void avatars_done (void); - -#endif blob - 448757c17b224c61c5a0e824acfebf25d89005ef blob + 85baa8232686d4520f03569e38563c5b9e21d852 --- src/imap.c +++ src/imap.c @@ -58,7 +58,6 @@ #include "main.h" #include "passwordstore.h" #include "file-utils.h" -#include "oauth2.h" typedef struct _IMAPFolder IMAPFolder; typedef struct _IMAPSession IMAPSession; @@ -1246,8 +1245,6 @@ static gint imap_session_authenticate(IMAPSession *ses gboolean failed = FALSE; gint ok = MAILIMAP_NO_ERROR; g_return_val_if_fail(account->userid != NULL, MAILIMAP_ERROR_BAD_STATE); - if(account->imap_auth_type == IMAP_AUTH_OAUTH2) - oauth2_check_passwds (account); if (!password_get(account->userid, account->recv_server, "imap", SESSION(session)->port, &acc_pass)) { acc_pass = passwd_store_get_account(account->account_id, blob - a1a261c9a8a46d0a00bf384a93626cea4eb142c9 blob + 54f8d8687cfbd93354262b954e202faef73eba85 --- src/inc.c +++ src/inc.c @@ -55,7 +55,6 @@ #include "hooks.h" #include "logwindow.h" #include "passwordstore.h" -#include "oauth2.h" static GList *inc_dialog_list = NULL; @@ -572,10 +571,6 @@ static gint inc_start(IncProgressDialog *inc_dialog) (inc_dialog->dialog->window, NULL, NULL); - if(pop3_session->ac_prefs->use_pop_auth && - pop3_session->ac_prefs->pop_auth_type == POPAUTH_OAUTH2) - oauth2_check_passwds (pop3_session->ac_prefs); - if (password_get(pop3_session->user, pop3_session->ac_prefs->recv_server, "pop3", pop3_get_port(pop3_session), blob - d538b199d205852908403d3cf40e813f56727c99 blob + 1d6a4c6db7ee7ed9af2943386373b66b1db5d039 --- src/localfolder.c +++ src/localfolder.c @@ -24,20 +24,6 @@ #include "xml.h" #include "utils.h" -void folder_local_folder_init(Folder *folder, const gchar *name, - const gchar *path) -{ - folder_init(folder, name); - LOCAL_FOLDER(folder)->rootpath = g_strdup(path); -} - -void folder_local_folder_destroy(LocalFolder *lfolder) -{ - cm_return_if_fail(lfolder != NULL); - - g_free(lfolder->rootpath); -} - void folder_local_set_xml(Folder *_folder, XMLTag *tag) { LocalFolder *folder = LOCAL_FOLDER(_folder); blob - 128dad5b7904e4fdaa2fc6a9af318e7bb9014ad4 blob + adc285e6df52337e0dc3009dffd50709ec1052cc --- src/localfolder.h +++ src/localfolder.h @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ #ifndef LOCALFOLDER_H @@ -35,10 +35,6 @@ struct _LocalFolder gchar *rootpath; }; -void folder_local_folder_init (Folder *folder, - const gchar *name, - const gchar *path); -void folder_local_folder_destroy (LocalFolder *lfolder); void folder_local_set_xml (Folder *folder, XMLTag *tag); XMLTag *folder_local_get_xml (Folder *folder); blob - 3816e9a1c19c654e198635729fe4b9aaa0cf9384 blob + 9ad3b0199907a48b70d59fcf5071976c35c3d876 --- src/main.c +++ src/main.c @@ -55,7 +55,6 @@ #include "prefs_themes.h" #include "prefs_other.h" #include "prefs_send.h" -#include "prefs_wrapping.h" #include "prefs_compose_writing.h" #include "prefs_display_header.h" #include "account.h" @@ -82,10 +81,8 @@ #include "matcher.h" #include "hooks.h" #include "menu.h" -#include "avatars.h" #include "passwordstore.h" #include "file-utils.h" -#include "oauth2.h" #include "etpan/imap-thread.h" #include "stock_pixmap.h" @@ -454,7 +451,6 @@ int main(int argc, char *argv[]) prefs_themes_init(); prefs_ext_prog_init(); - prefs_wrapping_init(); prefs_compose_writing_init(); prefs_summaries_init(); prefs_message_init(); @@ -496,7 +492,6 @@ int main(int argc, char *argv[]) prefs_account_init(); account_read_config_all(); - account_read_oauth2_all(); imap_main_init(prefs_common.skip_ssl_cert_check); imap_main_set_timeout(prefs_common.io_timeout_secs); @@ -560,7 +555,6 @@ int main(int argc, char *argv[]) claws_register_idle_function(claws_gtk_idle); - avatars_init(); prefs_toolbar_init(); num_folder_class = g_list_length(folder_get_list()); @@ -736,12 +730,10 @@ static void exit_claws(MainWindow *mainwin) main_window_destroy_all(); prefs_toolbar_done(); - avatars_done(); addressbook_destroy(); prefs_themes_done(); prefs_ext_prog_done(); - prefs_wrapping_done(); prefs_compose_writing_done(); prefs_summaries_done(); prefs_message_done(); blob - 72d2996dc7b4d7a8afa8ed25919041868a97c139 blob + e07bfdd6458ceb82827970c0240c65921ae75d3a --- src/messageview.c +++ src/messageview.c @@ -60,7 +60,6 @@ #include "version.h" #include "statusbar.h" #include "folder_item_prefs.h" -#include "avatars.h" #include "file-utils.h" #include "addressbook.h" @@ -1990,8 +1989,6 @@ static void add_address_cb(GtkAction *action, gpointer MessageView *messageview = (MessageView *)data; MsgInfo *msginfo, *full_msginfo; gchar *from; - GdkPixbuf *picture = NULL; - AvatarRender *avatarr; if (!messageview->msginfo || !messageview->msginfo->from) return; @@ -2003,16 +2000,9 @@ static void add_address_cb(GtkAction *action, gpointer full_msginfo = procmsg_msginfo_get_full_info(msginfo); - avatarr = avatars_avatarrender_new(full_msginfo); - hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr); - procmsg_msginfo_free(&full_msginfo); - if (avatarr->image != NULL) - picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image)); - - addressbook_add_contact(msginfo->fromname, from, NULL, picture); - avatars_avatarrender_free(avatarr); + addressbook_add_contact(msginfo->fromname, from, NULL, NULL); } static gboolean messageview_update_msg(gpointer source, gpointer data) blob - c6be54eaae6995c2627355ee6e8c88d948d733df blob + 42dc750da793ef3455105dea820790be8f17abd0 --- src/mh.c +++ src/mh.c @@ -178,13 +178,13 @@ static Folder *mh_folder_new(const gchar *name, const static void mh_folder_destroy(Folder *folder) { - folder_local_folder_destroy(LOCAL_FOLDER(folder)); + free(LOCAL_FOLDER(folder)->rootpath); } static void mh_folder_init(Folder *folder, const gchar *name, const gchar *path) { - folder_local_folder_init(folder, name, path); - + folder_init(folder, name); + LOCAL_FOLDER(folder)->rootpath = strdup(path); } gboolean mh_scan_required(Folder *folder, FolderItem *item) blob - 84e74ad5074abebf7d6591b1b2a1aa3d0a410f87 (mode 644) blob + /dev/null --- src/oauth2.c +++ /dev/null @@ -1,896 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2021-2023 the Claws Mail team - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "defs.h" -#include -#ifdef ENABLE_NLS -#include -#else -#define _(a) (a) -#define N_(a) (a) -#endif -#include -#include -#include - -#include "imap.h" -#include "oauth2.h" -#include "utils.h" -#include "log.h" -#include "time.h" -#include "common/version.h" -#include "file-utils.h" -#include "prefs_common.h" - -#define GNUTLS_PRIORITY "NORMAL:!VERS-SSL3.0:!VERS-TLS1.0:!VERS-TLS1.1" -//Yahoo requires token requests to send POST header Authorization: Basic -//where the password is Base64 encoding of client_id:client_secret - -static gint oauth2_post_request (gchar *buf, gchar *host, gchar *resource, gchar *header, gchar *body); -static gint oauth2_filter_refresh (gchar *json, gchar *refresh_token); -static gint oauth2_filter_access (gchar *json, gchar *access_token, gint *expiry); -static GList *oauth2_providers_list = NULL; -static Oauth2Info tmp_oa2_info; - -static PrefParam oauth2_info[] = { - {"oa2_name", NULL, &tmp_oa2_info.oa2_name, P_STRING, NULL, NULL, NULL}, - {"oa2_base_url", NULL, &tmp_oa2_info.oa2_base_url, P_STRING, NULL, NULL, NULL}, - {"oa2_client_id", NULL, &tmp_oa2_info.oa2_client_id, P_STRING, NULL, NULL, NULL}, - {"oa2_client_secret", NULL, &tmp_oa2_info.oa2_client_secret, P_STRING, NULL, NULL, NULL}, - {"oa2_redirect_uri", NULL, &tmp_oa2_info.oa2_redirect_uri, P_STRING, NULL, NULL, NULL}, - {"oa2_auth_resource", NULL, &tmp_oa2_info.oa2_auth_resource, P_STRING, NULL, NULL, NULL}, - {"oa2_access_resource", NULL, &tmp_oa2_info.oa2_access_resource, P_STRING, NULL, NULL, NULL}, - {"oa2_refresh_resource", NULL, &tmp_oa2_info.oa2_refresh_resource, P_STRING, NULL, NULL, NULL}, - {"oa2_response_type", NULL, &tmp_oa2_info.oa2_response_type, P_STRING, NULL, NULL, NULL}, - {"oa2_scope_for_auth", NULL, &tmp_oa2_info.oa2_scope_for_auth, P_STRING, NULL, NULL, NULL}, - {"oa2_grant_type_access", NULL, &tmp_oa2_info.oa2_grant_type_access, P_STRING, NULL, NULL, NULL}, - {"oa2_grant_type_refresh", NULL, &tmp_oa2_info.oa2_grant_type_refresh, P_STRING, NULL, NULL, NULL}, - {"oa2_tenant", NULL, &tmp_oa2_info.oa2_tenant, P_STRING, NULL, NULL, NULL}, - {"oa2_state", NULL, &tmp_oa2_info.oa2_state, P_STRING, NULL, NULL, NULL}, - {"oa2_access_type", NULL, &tmp_oa2_info.oa2_access_type, P_STRING, NULL, NULL, NULL}, - {"oa2_scope_for_access", NULL, &tmp_oa2_info.oa2_scope_for_access, P_STRING, NULL, NULL, NULL}, - {"oa2_response_mode", NULL, &tmp_oa2_info.oa2_response_mode, P_STRING, NULL, NULL, NULL}, - {"oa2_header_auth_basic", NULL, &tmp_oa2_info.oa2_header_auth_basic, P_STRING, NULL, NULL, NULL}, - {"oa2_two_stage_pop", NULL, &tmp_oa2_info.oa2_two_stage_pop, P_INT, NULL, NULL, NULL}, - {"oa2_codemarker_start", NULL, &tmp_oa2_info.oa2_codemarker_start, P_STRING, NULL, NULL, NULL}, - {"oa2_codemarker_stop", NULL, &tmp_oa2_info.oa2_codemarker_stop, P_STRING, NULL, NULL, NULL}, - {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} -}; - -static gchar *oauth2_tmpl = - "protected=0\n\n" - "[Oauth2: 1]\n" - "oa2_name=Google\n" - "oa2_base_url=accounts.google.com\n" - "oa2_client_id=\n" - "oa2_client_secret=.\n" - "oa2_redirect_uri=http://127.0.0.1:8888\n" - "oa2_auth_resource=/o/oauth2/auth\n" - "oa2_access_resource=/o/oauth2/token\n" - "oa2_refresh_resource=/o/oauth2/token\n" - "oa2_response_type=code\n" - "oa2_scope_for_auth=https://mail.google.com\n" - "oa2_grant_type_access=authorization_code\n" - "oa2_grant_type_refresh=refresh_token\n" - "oa2_tenant=\n" - "oa2_state=\n" - "oa2_access_type=\n" - "oa2_scope_for_access=\n" - "oa2_response_mode=\n" - "oa2_header_auth_basic=\n" - "oa2_two_stage_pop=0\n" - "oa2_codemarker_start=code=\n" - "oa2_codemarker_stop=&scope=\n\n" - "[Oauth2: 2]\n" - "oa2_name=Outlook\n" - "oa2_base_url=login.microsoftonline.com\n" - "oa2_client_id=\n" - "oa2_client_secret=\n" - "oa2_redirect_uri=http://127.0.0.1:8888\n" - "oa2_auth_resource=/common/oauth2/v2.0/authorize\n" - "oa2_access_resource=/common/oauth2/v2.0/token\n" - "oa2_refresh_resource=/common/oauth2/v2.0/token\n" - "oa2_response_type=code\n" - "oa2_scope_for_auth=offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send\n" - "oa2_grant_type_access=authorization_code\n" - "oa2_grant_type_refresh=refresh_token\n" - "oa2_tenant=common\n" - "oa2_state=\n" - "oa2_access_type=offline\n" - "oa2_scope_for_access=offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send\n" - "oa2_response_mode=query\n" - "oa2_header_auth_basic=\n" - "oa2_two_stage_pop=1\n" - "oa2_codemarker_start=code=\n" - "oa2_codemarker_stop= HTTP\n\n" - "[Oauth2: 3]\n" - "oa2_name=Exchange\n" - "oa2_base_url=login.microsoftonline.com\n" - "oa2_client_id=\n" - "oa2_client_secret=\n" - "oa2_redirect_uri=http://127.0.0.1:8888\n" - "oa2_auth_resource=/common/oauth2/v2.0/authorize\n" - "oa2_access_resource=/common/oauth2/v2.0/token\n" - "oa2_refresh_resource=/common/oauth2/v2.0/token\n" - "oa2_response_type=code\n" - "oa2_scope_for_auth=offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send\n" - "oa2_grant_type_access=authorization_code\n" - "oa2_grant_type_refresh=refresh_token\n" - "oa2_tenant=common\n" - "oa2_state=\n" - "oa2_access_type=offline\n" - "oa2_scope_for_access=offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send\n" - "oa2_response_mode=query\n" - "oa2_header_auth_basic=\n" - "oa2_two_stage_pop=1\n" - "oa2_codemarker_start=code=\n" - "oa2_codemarker_stop=&session_state=\n\n" - "[Oauth2: 4]\n" - "oa2_name=Microsoft_gcchigh\n" - "oa2_base_url=login.microsoftonline.us\n" - "oa2_client_id=\n" - "oa2_client_secret=\n" - "oa2_redirect_uri=http://127.0.0.1:8888\n" - "oa2_auth_resource=/common/oauth2/v2.0/authorize\n" - "oa2_access_resource=/common/oauth2/v2.0/token\n" - "oa2_refresh_resource=/common/oauth2/v2.0/token\n" - "oa2_response_type=code\n" - "oa2_scope_for_auth=offline_access https://outlook.office365.us/IMAP.AccessAsUser.All https://outlook.office365.us/POP.AccessAsUser.All https://outlook.office365.us/SMTP.Send\n" - "oa2_grant_type_access=authorization_code\n" - "oa2_grant_type_refresh=refresh_token\n" - "oa2_tenant=common\n" - "oa2_state=\n" - "oa2_access_type=offline\n" - "oa2_scope_for_access=offline_access https://outlook.office365.us/IMAP.AccessAsUser.All https://outlook.office365.us/POP.AccessAsUser.All https://outlook.office365.us/SMTP.Send\n" - "oa2_response_mode=query\n" - "oa2_header_auth_basic=\n" - "oa2_two_stage_pop=1\n" - "oa2_codemarker_start=code=\n" - "oa2_codemarker_stop=&session_state=\n\n" - "[Oauth2: 5]\n" - "oa2_name=Yahoo\n" - "oa2_base_url=api.login.yahoo.com\n" - "oa2_client_id=\n" - "oa2_client_secret=.\n" - "oa2_redirect_uri=oob\n" - "oa2_auth_resource=/oauth2/request_auth\n" - "oa2_access_resource=/oauth2/get_token\n" - "oa2_refresh_resource=/oauth2/get_token\n" - "oa2_response_type=code\n" - "oa2_scope_for_auth=\n" - "oa2_grant_type_access=authorization_code\n" - "oa2_grant_type_refresh=refresh_token\n" - "oa2_tenant=\n" - "oa2_state=\n" - "oa2_access_type=\n" - "oa2_scope_for_access=\n" - "oa2_response_mode=\n" - "oa2_header_auth_basic=1\n" - "oa2_two_stage_pop=0\n" - "oa2_codemarker_start=\n" - "oa2_codemarker_stop=\n" - ; - -static Oauth2Info *oauth2_new_from_config(const gchar *label) -{ - gchar *rcpath; - Oauth2Info *oa2_info; - - cm_return_val_if_fail(label != NULL, NULL); - - oa2_info = g_new0(Oauth2Info, 1); - - /* Load default values to tmp_oa2_info first, ... */ - memset(&tmp_oa2_info, 0, sizeof(Oauth2Info)); - prefs_set_default(oauth2_info); - - /* ... overriding them with values from stored config file. */ - rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, OAUTH2_RC, NULL); - prefs_read_config(oauth2_info, label, rcpath, NULL); - g_free(rcpath); - - *oa2_info = tmp_oa2_info; - - return oa2_info; -} - -void account_read_oauth2_all(void) -{ - GSList *oauth2_label_list = NULL, *cur; - Oauth2Info *oauth2_prefs; - gchar *rcpath; - gchar *oauth2_text, *version_text; - FILE *fp; - gchar buf[PREFSBUFSIZE]; - gint protected = 1; - gint matchedversion = 0; - - debug_print("Reading oauth2rc file\n"); - - rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, OAUTH2_RC, NULL); - if ((fp = g_fopen(rcpath, "rb")) == NULL) { - //No oauth2rc file exists - oauth2_text = g_strconcat("[Version: ", VERSION, "]\n", oauth2_tmpl, NULL); - str_write_to_file(oauth2_text, rcpath, TRUE); - g_free(oauth2_text); - debug_print("No oauth2rc file found, new one created\n"); - - if ((fp = g_fopen(rcpath, "rb")) == NULL) { - if (ENOENT != errno) FILE_OP_ERROR(rcpath, "g_fopen"); - g_free(rcpath); - return; - } - }else{ - //oauth2rc file exists. Check version and whether protected from update - version_text = g_strconcat("[Version: ", VERSION, "]\n", NULL); - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (!strncmp(buf, "protected=0", 11)) { - protected = 0; - debug_print("oauth2rc file is unprotected from updates\n"); - } - - if (!strcmp(buf, version_text)) { - matchedversion = 1; - debug_print("oauth2rc file matches Claws version\n"); - } - } - g_free(version_text); - rewind(fp); - - if(!protected && !matchedversion){ - //oauth2rc not protected from updates and does not match this version of Claws - //Update it to the latest template version. - fclose(fp); - oauth2_text = g_strconcat("[Version: ", VERSION, "]\n", oauth2_tmpl, NULL); - str_write_to_file(oauth2_text, rcpath, TRUE); - g_free(oauth2_text); - debug_print("Replacement oauth2rc file created to match this Claws version\n"); - - if ((fp = g_fopen(rcpath, "rb")) == NULL) { - if (ENOENT != errno) FILE_OP_ERROR(rcpath, "g_fopen"); - g_free(rcpath); - return; - } - } - } - g_free(rcpath); - - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (!strncmp(buf, "[Oauth2: ", 9)) { - strretchomp(buf); - memmove(buf, buf + 1, sizeof(buf) - 1); - buf[strlen(buf) - 1] = '\0'; - debug_print("Found configuration: %s\n", buf); - oauth2_label_list = g_slist_append(oauth2_label_list, - g_strdup(buf)); - } - } - fclose(fp); - - /* read config data from file */ - for (cur = oauth2_label_list; cur != NULL; cur = cur->next) { - debug_print("Extracting oauth2 data\n"); - oauth2_prefs = oauth2_new_from_config((gchar *)cur->data); - oauth2_providers_list = g_list_append(oauth2_providers_list, oauth2_prefs); - } - - while (oauth2_label_list) { - g_free(oauth2_label_list->data); - oauth2_label_list = g_slist_remove(oauth2_label_list, - oauth2_label_list->data); - } -} - -GList *oauth2_providers_get_list(void) -{ - return oauth2_providers_list; -} - -static gint oauth2_post_request (gchar *buf, gchar *host, gchar *resource, gchar *header, gchar *body) -{ - gint len; - - debug_print("Complete body: %s\n", body); - len = strlen(body); - if (header[0]) - return snprintf(buf, OAUTH2BUFSIZE, "POST %s HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: text/html,application/json\r\nContent-Length: %i\r\nHost: %s\r\nConnection: close\r\nUser-Agent: ClawsMail\r\n%s\r\n\r\n%s", resource, len, host, header, body); - else - return snprintf(buf, OAUTH2BUFSIZE, "POST %s HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: text/html,application/json\r\nContent-Length: %i\r\nHost: %s\r\nConnection: close\r\nUser-Agent: ClawsMail\r\n\r\n%s", resource, len, host, body); -} - -static gint oauth2_filter_access (gchar *json, gchar *access_token, gint *expiry) -{ - GMatchInfo *matchInfo; - GRegex *regex; - - regex = g_regex_new ("\"access_token\": ?\"(.*?)\",?", G_REGEX_RAW, 0, NULL); - g_regex_match (regex, json, 0, &matchInfo); - if (g_match_info_matches (matchInfo)) - g_stpcpy (access_token,g_match_info_fetch (matchInfo, 1)); - else{ - g_match_info_free (matchInfo); - return (-1); - } - - g_match_info_free (matchInfo); - - regex = g_regex_new ("\"expires_in\": ?([0-9]*),?", G_REGEX_RAW, 0, NULL); - g_regex_match (regex, json, 0, &matchInfo); - if (g_match_info_matches (matchInfo)){ - // Reduce available token life to avoid attempting connections with (near) expired tokens - *expiry = (g_get_real_time () / G_USEC_PER_SEC) + atoi(g_match_info_fetch (matchInfo, 1)) - 120; - }else{ - g_match_info_free (matchInfo); - return (-2); - } - - g_match_info_free (matchInfo); - - return(0); -} - -static gint oauth2_filter_refresh (gchar *json, gchar *refresh_token) -{ - GMatchInfo *matchInfo; - GRegex *regex; - - regex = g_regex_new ("\"refresh_token\": ?\"(.*?)\",?", G_REGEX_RAW, 0, NULL); - g_regex_match (regex, json, 0, &matchInfo); - if (g_match_info_matches (matchInfo)) - g_stpcpy (refresh_token,g_match_info_fetch (matchInfo, 1)); - else{ - g_match_info_free (matchInfo); - return (-1); - } - - g_match_info_free (matchInfo); - - return(0); -} - -static gchar* oauth2_get_token_from_response(Oauth2Service provider, const gchar* response) { - gchar* token = NULL; - gint i; - Oauth2Info *oa2; - - //Retrieve oauth2 configuration information - if(provider > g_list_length(oauth2_providers_list)){ - debug_print("Configured OAUTH2 provider is not present in the oauth2rc config file\n"); - return NULL; - } - - i = (int)provider - 1; - - oa2 = g_list_nth_data (oauth2_providers_list, i); - - debug_print("Auth response: %s\n", response); - if (!oa2->oa2_codemarker_start || !oa2->oa2_codemarker_stop || - !oa2->oa2_codemarker_start[0] || !oa2->oa2_codemarker_stop[0]) { - /* Providers which display auth token in browser for users to copy */ - token = g_strdup(response); - } else { - gchar* start = g_strstr_len(response, strlen(response), oa2->oa2_codemarker_start); - if (start == NULL) - return NULL; - start += strlen(oa2->oa2_codemarker_start); - gchar* stop = g_strstr_len(response, strlen(response), oa2->oa2_codemarker_stop); - if (stop == NULL) - return NULL; - token = g_strndup(start, stop - start); - } - - return token; -} - -static gchar *oauth2_contact_server(SockInfo *sock, const gchar *request) -{ - gboolean got_some_error, timeout; - gint ret; - char buf[1024]; - GString *response = g_string_sized_new(sizeof(buf)); - time_t end_time = time(NULL); - - end_time += prefs_common_get_prefs()->io_timeout_secs; - - if (!response) - return NULL; - - if (sock_write(sock, request, strlen(request)) < 0) { - log_message(LOG_PROTOCOL, _("OAuth2 socket write error\n")); - g_string_free(response, TRUE); - return NULL; - } - - do { - ret = sock_read(sock, buf, sizeof(buf) - 1); - got_some_error = ret < 0; - timeout = time(NULL) > end_time; - - if (timeout) - break; - - if (ret < 0 && errno == EAGAIN) - continue; - - if (got_some_error) - break; - - if (ret) { - buf[ret] = '\0'; - g_string_append_len(response, buf, ret); - } - } while (ret); - - if (timeout) - log_message(LOG_PROTOCOL, _("OAuth2 socket timeout error\n")); - - return g_string_free(response, got_some_error || timeout); -} - -int oauth2_obtain_tokens (Oauth2Service provider, OAUTH2Data *OAUTH2Data, const gchar *authcode) -{ - gchar *request; - gchar *response; - gchar *body; - gchar *uri; - gchar *header; - gchar *tmp_hd, *tmp_hd_encoded; - gchar *access_token; - gchar *refresh_token; - gint expiry = 0; - gint ret; - SockInfo *sock; - gchar *client_id; - gchar *client_secret; - gchar *token = NULL; - gchar *tmp; - gint i; - Oauth2Info *oa2; - - //Retrieve oauth2 configuration information - if(provider > g_list_length(oauth2_providers_list)){ - debug_print("Configured OAUTH2 provider is not present in the oauth2rc config file\n"); - return (1); - } - - i = (int)provider - 1; - oa2 = g_list_nth_data (oauth2_providers_list, i); - - token = oauth2_get_token_from_response(provider, authcode); - debug_print("Auth token: %s\n", token); - if (token == NULL) { - log_message(LOG_PROTOCOL, _("OAuth2 missing authorization code\n")); - return (1); - } - debug_print("Connect: %s:443\n", oa2->oa2_base_url); - sock = sock_connect(oa2->oa2_base_url, 443); - if (sock == NULL) { - log_message(LOG_PROTOCOL, _("OAuth2 connection error\n")); - g_free(token); - return (1); - } - sock->ssl_cert_auto_accept = TRUE; - sock->use_tls_sni = TRUE; - sock_set_nonblocking_mode(sock, FALSE); - gint timeout_secs = prefs_common_get_prefs()->io_timeout_secs; - debug_print("Socket timeout: %i sec(s)\n", timeout_secs); - sock_set_io_timeout(timeout_secs); - sock->gnutls_priority = GNUTLS_PRIORITY; - if (ssl_init_socket(sock) == FALSE) { - log_message(LOG_PROTOCOL, _("OAuth2 TLS connection error\n")); - g_free(token); - return (1); - } - - refresh_token = g_malloc(OAUTH2BUFSIZE+1); - access_token = g_malloc(OAUTH2BUFSIZE+1); - request = g_malloc(OAUTH2BUFSIZE+1); - - if(OAUTH2Data->custom_client_id[0]) - client_id = g_strdup(OAUTH2Data->custom_client_id); - else - client_id = g_strdup(oa2->oa2_client_id); - - body = g_strconcat ("client_id=", client_id, "&code=", token, NULL); - debug_print("Body: %s\n", body); - g_free(token); - - if(oa2->oa2_client_secret[0]){ - //Only allow custom client secret if the service provider would usually expect a client secret - if(OAUTH2Data->custom_client_secret[0]) - client_secret = g_strdup(OAUTH2Data->custom_client_secret); - else - client_secret = g_strdup(oa2->oa2_client_secret); - uri = g_uri_escape_string (client_secret, NULL, FALSE); - tmp = g_strconcat (body, "&client_secret=", uri, NULL); - g_free(body); - g_free(uri); - body = tmp; - }else{ - client_secret = g_strconcat ("", NULL); - } - - if(oa2->oa2_redirect_uri[0]) { - tmp = g_strconcat(body, "&redirect_uri=", oa2->oa2_redirect_uri, NULL); - g_free(body); - body = tmp; - } - if(oa2->oa2_grant_type_access[0]) { - tmp = g_strconcat(body, "&grant_type=", oa2->oa2_grant_type_access, NULL); - g_free(body); - body = tmp; - } - if(oa2->oa2_tenant[0]) { - tmp = g_strconcat(body, "&tenant=", oa2->oa2_tenant, NULL); - g_free(body); - body = tmp; - } - if(oa2->oa2_scope_for_access[0]) { - tmp = g_strconcat(body, "&scope=", oa2->oa2_scope_for_access, NULL); - g_free(body); - body = tmp; - } - if(oa2->oa2_state[0]) { - tmp = g_strconcat(body, "&state=", oa2->oa2_state, NULL); - g_free(body); - body = tmp; - } - - if(oa2->oa2_header_auth_basic[0]){ - tmp_hd = g_strconcat(client_id, ":", client_secret, NULL); - tmp_hd_encoded = g_base64_encode (tmp_hd, strlen(tmp_hd)); - header = g_strconcat ("Authorization: Basic ", tmp_hd_encoded, NULL); - g_free(tmp_hd_encoded); - g_free(tmp_hd); - }else{ - header = g_strconcat ("", NULL); - } - - oauth2_post_request (request, oa2->oa2_base_url, oa2->oa2_access_resource, header, body); - response = oauth2_contact_server (sock, request); - debug_print("Response from server: %s\n", response); - - if(response && oauth2_filter_access (response, access_token, &expiry) == 0){ - OAUTH2Data->access_token = g_strdup(access_token); - OAUTH2Data->expiry = expiry; - OAUTH2Data->expiry_str = g_strdup_printf ("%i", expiry); - ret = 0; - log_message(LOG_PROTOCOL, _("OAuth2 access token obtained\n")); - }else{ - log_message(LOG_PROTOCOL, _("OAuth2 access token not obtained\n")); - debug_print("OAuth2 - request: %s\n Response: %s", request, response); - ret = 1; - } - - if(response && oauth2_filter_refresh (response, refresh_token) == 0){ - OAUTH2Data->refresh_token = g_strdup(refresh_token); - log_message(LOG_PROTOCOL, _("OAuth2 refresh token obtained\n")); - }else{ - log_message(LOG_PROTOCOL, _("OAuth2 refresh token not obtained\n")); - } - - sock_close(sock, TRUE); - g_free(body); - g_free(header); - g_free(request); - g_free(response); - g_free(client_id); - g_free(client_secret); - g_free(access_token); - g_free(refresh_token); - - return (ret); -} - -gint oauth2_use_refresh_token (Oauth2Service provider, OAUTH2Data *OAUTH2Data) -{ - - gchar *request; - gchar *response; - gchar *body; - gchar *uri; - gchar *header; - gchar *tmp_hd, *tmp_hd_encoded; - gchar *access_token; - gchar *refresh_token; - gint expiry = 0; - gint ret; - SockInfo *sock; - gchar *client_id; - gchar *client_secret; - gchar *tmp; - gint i; - Oauth2Info *oa2; - - //Retrieve oauth2 configuration information - if(provider > g_list_length(oauth2_providers_list)){ - debug_print("Configured OAUTH2 provider is not present in the oauth2rc config file\n"); - return (1); - } - - i = (int)provider - 1; - oa2 = g_list_nth_data (oauth2_providers_list, i); - - sock = sock_connect(oa2->oa2_base_url, 443); - if (sock == NULL) { - log_message(LOG_PROTOCOL, _("OAuth2 connection error\n")); - return (1); - } - sock->ssl_cert_auto_accept = TRUE; - sock->use_tls_sni = TRUE; - sock_set_nonblocking_mode(sock, FALSE); - gint timeout_secs = prefs_common_get_prefs()->io_timeout_secs; - debug_print("Socket timeout: %i sec(s)\n", timeout_secs); - sock_set_io_timeout(timeout_secs); - sock->gnutls_priority = GNUTLS_PRIORITY; - if (ssl_init_socket(sock) == FALSE) { - log_message(LOG_PROTOCOL, _("OAuth2 TLS connection error\n")); - return (1); - } - - access_token = g_malloc(OAUTH2BUFSIZE+1); - refresh_token = g_malloc(OAUTH2BUFSIZE+1); - request = g_malloc(OAUTH2BUFSIZE+1); - - if(OAUTH2Data->custom_client_id[0]) - client_id = g_strdup(OAUTH2Data->custom_client_id); - else - client_id = g_strdup(oa2->oa2_client_id); - - uri = g_uri_escape_string (client_id, NULL, FALSE); - body = g_strconcat ("client_id=", uri, "&refresh_token=", OAUTH2Data->refresh_token, NULL); - g_free(uri); - - if(oa2->oa2_client_secret[0]){ - //Only allow custom client secret if the service provider would usually expect a client secret - if(OAUTH2Data->custom_client_secret[0]) - client_secret = g_strdup(OAUTH2Data->custom_client_secret); - else - client_secret = g_strdup(oa2->oa2_client_secret); - uri = g_uri_escape_string (client_secret, NULL, FALSE); - tmp = g_strconcat (body, "&client_secret=", uri, NULL); - g_free(body); - g_free(uri); - body = tmp; - }else{ - client_secret = g_strconcat ("", NULL); - } - - if(oa2->oa2_grant_type_refresh[0]) { - uri = g_uri_escape_string (oa2->oa2_grant_type_refresh, NULL, FALSE); - tmp = g_strconcat (body, "&grant_type=", uri, NULL); - g_free(body); - g_free(uri); - body = tmp; - } - if(oa2->oa2_scope_for_access[0]) { - uri = g_uri_escape_string (oa2->oa2_scope_for_access, NULL, FALSE); - tmp = g_strconcat (body, "&scope=", uri, NULL); - g_free(body); - g_free(uri); - body = tmp; - } - if(oa2->oa2_state[0]) { - uri = g_uri_escape_string (oa2->oa2_state, NULL, FALSE); - tmp = g_strconcat (body, "&state=", uri, NULL); - g_free(body); - g_free(uri); - body = tmp; - } - - if(oa2->oa2_header_auth_basic[0]){ - tmp_hd = g_strconcat(client_id, ":", client_secret, NULL); - tmp_hd_encoded = g_base64_encode (tmp_hd, strlen(tmp_hd)); - header = g_strconcat ("Authorization: Basic ", tmp_hd_encoded, NULL); - g_free(tmp_hd_encoded); - g_free(tmp_hd); - }else{ - header = g_strconcat ("", NULL); - } - - oauth2_post_request (request, oa2->oa2_base_url, oa2->oa2_refresh_resource, header, body); - debug_print("Request: %s\n", request); - response = oauth2_contact_server (sock, request); - debug_print("Response from server: %s\n", response); - - - if(response && oauth2_filter_access (response, access_token, &expiry) == 0){ - OAUTH2Data->access_token = g_strdup(access_token); - OAUTH2Data->expiry = expiry; - OAUTH2Data->expiry_str = g_strdup_printf ("%i", expiry); - ret = 0; - log_message(LOG_PROTOCOL, _("OAuth2 access token obtained\n")); - }else{ - log_message(LOG_PROTOCOL, _("OAuth2 access token not obtained\n")); - debug_print("OAuth2 - request: %s\n Response: %s", request, response); - ret = 1; - } - - if (response && oauth2_filter_refresh (response, refresh_token) == 0) { - OAUTH2Data->refresh_token = g_strdup(refresh_token); - log_message(LOG_PROTOCOL, _("OAuth2 replacement refresh token provided\n")); - } else - log_message(LOG_PROTOCOL, _("OAuth2 replacement refresh token not provided\n")); - - debug_print("OAuth2 - access token: %s\n", access_token); - debug_print("OAuth2 - access token expiry: %i\n", expiry); - - sock_close(sock, TRUE); - g_free(body); - g_free(header); - g_free(request); - g_free(response); - g_free(client_id); - g_free(client_secret); - g_free(access_token); - g_free(refresh_token); - - return (ret); -} - -gint oauth2_authorisation_url (Oauth2Service provider, gchar **url, const gchar *custom_client_id) -{ - gint i; - gchar *client_id = NULL; - gchar *tmp; - gchar *uri; - Oauth2Info *oa2; - - //Retrieve oauth2 configuration information - if(provider > g_list_length(oauth2_providers_list)){ - debug_print("Configured OAUTH2 provider is not present in the oauth2rc config file\n"); - return (1); - } - - i = (int)provider - 1; - oa2 = g_list_nth_data (oauth2_providers_list, i); - - debug_print("FROM OAUTH2.C Oauth2 name: %s\n", oa2->oa2_name); - debug_print("FROM OAUTH2.C Oauth2 URL: %s\n", oa2->oa2_redirect_uri); - - if(!custom_client_id[0]) - client_id = g_strdup(oa2->oa2_client_id); - - uri = g_uri_escape_string (custom_client_id[0] ? custom_client_id : client_id, NULL, FALSE); - *url = g_strconcat ("https://", oa2->oa2_base_url, oa2->oa2_auth_resource, "?client_id=", - uri, NULL); - g_free(uri); - if (client_id) - g_free(client_id); - - if(oa2->oa2_redirect_uri[0]) { - uri = g_uri_escape_string (oa2->oa2_redirect_uri, NULL, FALSE); - tmp = g_strconcat (*url, "&redirect_uri=", uri, NULL); - g_free(*url); - *url = tmp; - g_free(uri); - - } - if(oa2->oa2_response_type[0]) { - uri = g_uri_escape_string (oa2->oa2_response_type, NULL, FALSE); - tmp = g_strconcat (*url, "&response_type=", uri, NULL); - g_free(*url); - *url = tmp; - g_free(uri); - } - if(oa2->oa2_scope_for_auth[0]) { - uri = g_uri_escape_string (oa2->oa2_scope_for_auth, NULL, FALSE); - tmp = g_strconcat (*url, "&scope=", uri, NULL); - g_free(*url); - *url = tmp; - g_free(uri); - } - if(oa2->oa2_tenant[0]) { - uri = g_uri_escape_string (oa2->oa2_tenant, NULL, FALSE); - tmp = g_strconcat (*url, "&tenant=", uri, NULL); - g_free(*url); - *url = tmp; - g_free(uri); - } - if(oa2->oa2_response_mode[0]) { - uri = g_uri_escape_string (oa2->oa2_response_mode, NULL, FALSE); - tmp = g_strconcat (*url, "&response_mode=", uri, NULL); - g_free(*url); - *url = tmp; - g_free(uri); - } - if(oa2->oa2_state[0]) { - uri = g_uri_escape_string (oa2->oa2_state, NULL, FALSE); - tmp = g_strconcat (*url, "&state=", uri, NULL); - g_free(*url); - *url = tmp; - g_free(uri); - } - - return (0); -} - -gint oauth2_check_passwds (PrefsAccount *ac_prefs) -{ - gchar *uid = g_strdup_printf("%d", ac_prefs->account_id); - gint expiry; - OAUTH2Data *OAUTH2Data = g_malloc(sizeof(* OAUTH2Data)); - gint ret; - gchar *acc; - - oauth2_init (OAUTH2Data); - - OAUTH2Data->custom_client_id = ac_prefs->oauth2_client_id; - OAUTH2Data->custom_client_secret = ac_prefs->oauth2_client_secret; - - if (passwd_store_has_password(PWS_ACCOUNT, uid, PWS_ACCOUNT_OAUTH2_EXPIRY)) { - acc = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_OAUTH2_EXPIRY); - expiry = atoi(acc); - g_free(acc); - if (expiry > (g_get_real_time () / G_USEC_PER_SEC)) { - g_free(OAUTH2Data); - log_message(LOG_PROTOCOL, _("OAuth2 access token still fresh\n")); - g_free(uid); - return (0); - } - } - - if (passwd_store_has_password(PWS_ACCOUNT, uid, PWS_ACCOUNT_OAUTH2_REFRESH)) { - log_message(LOG_PROTOCOL, _("OAuth2 obtaining access token using refresh token\n")); - OAUTH2Data->refresh_token = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_OAUTH2_REFRESH); - ret = oauth2_use_refresh_token (ac_prefs->oauth2_provider, OAUTH2Data); - } else if (passwd_store_has_password(PWS_ACCOUNT, uid, PWS_ACCOUNT_OAUTH2_AUTH)) { - log_message(LOG_PROTOCOL, _("OAuth2 trying for fresh access token with authorization code\n")); - acc = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_OAUTH2_AUTH); - ret = oauth2_obtain_tokens (ac_prefs->oauth2_provider, OAUTH2Data, acc); - g_free(acc); - } else - ret = 1; - - if (ret) - log_message(LOG_PROTOCOL, _("OAuth2 access token not obtained\n")); - else { - if (ac_prefs->imap_auth_type == IMAP_AUTH_OAUTH2 || - (ac_prefs->use_pop_auth && ac_prefs->pop_auth_type == POPAUTH_OAUTH2)) - passwd_store_set_account(ac_prefs->account_id, PWS_ACCOUNT_RECV, OAUTH2Data->access_token, FALSE); - if (ac_prefs->use_smtp_auth && ac_prefs->smtp_auth_type == SMTPAUTH_OAUTH2) - passwd_store_set_account(ac_prefs->account_id, PWS_ACCOUNT_SEND, OAUTH2Data->access_token, FALSE); - passwd_store_set_account(ac_prefs->account_id, PWS_ACCOUNT_OAUTH2_EXPIRY, OAUTH2Data->expiry_str, FALSE); - //Some providers issue replacement refresh tokens with each access token. Re-store whether replaced or not. - if (OAUTH2Data->refresh_token != NULL) - passwd_store_set_account(ac_prefs->account_id, PWS_ACCOUNT_OAUTH2_REFRESH, OAUTH2Data->refresh_token, FALSE); - passwd_store_write_config(); - log_message(LOG_PROTOCOL, _("OAuth2 access and refresh token updated\n")); - } - if (OAUTH2Data->refresh_token) { - memset(OAUTH2Data->refresh_token, 0, strlen(OAUTH2Data->refresh_token)); - } - g_free(OAUTH2Data->refresh_token); - g_free(OAUTH2Data); - g_free(uid); - - return (ret); -} - -gint oauth2_init (OAUTH2Data *OAUTH2Data) -{ - OAUTH2Data->refresh_token = NULL; - OAUTH2Data->access_token = NULL; - OAUTH2Data->expiry_str = NULL; - OAUTH2Data->expiry = 0; - OAUTH2Data->custom_client_id = NULL; - OAUTH2Data->custom_client_secret = NULL; - - return (0); -} blob - 487a0f84251e2b54ebcf2d2ead7cea60c54f42d6 (mode 644) blob + /dev/null --- src/oauth2.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2020-2022 the Claws Mail team - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef _OAUTH2_H_ -#define _OAUTH2_H_ - -#include - -#include "socket.h" -#include "passwordstore.h" -#include "smtp.h" -#include "prefs_account.h" -#include "prefs_gtk.h" - -#define OAUTH2BUFSIZE 8192 -#define OAUTH2AUTH_NONE 0 - -GList *oauth2_providers_get_list (void); - -typedef int Oauth2Service; - -typedef struct _OAUTH2Data OAUTH2Data; - -struct _OAUTH2Data -{ - gchar *refresh_token; - gchar *access_token; - gint expiry; - gchar *expiry_str; - gchar *custom_client_id; - gchar *custom_client_secret; -}; - -gint oauth2_init (OAUTH2Data *OAUTH2Data); -gint oauth2_check_passwds (PrefsAccount *ac_prefs); -gint oauth2_obtain_tokens (Oauth2Service provider, OAUTH2Data *OAUTH2Data, const gchar *authcode); -gint oauth2_authorisation_url (Oauth2Service provider, gchar **url, const gchar *custom_client_id); -gint oauth2_use_refresh_token (Oauth2Service provider, OAUTH2Data *OAUTH2Data); - -struct _Oauth2Info -{ - gchar *oa2_name; - gchar *oa2_base_url; - gchar *oa2_client_id; - gchar *oa2_client_secret; - gchar *oa2_redirect_uri; - gchar *oa2_auth_resource; - gchar *oa2_access_resource; - gchar *oa2_refresh_resource; - gchar *oa2_response_type; - gchar *oa2_scope_for_auth; - gchar *oa2_grant_type_access; - gchar *oa2_grant_type_refresh; - gchar *oa2_tenant; - gchar *oa2_state; - gchar *oa2_access_type; - gchar *oa2_scope_for_access; - gchar *oa2_response_mode; - gchar *oa2_header_auth_basic; - gint oa2_two_stage_pop; - gchar *oa2_codemarker_start; - gchar *oa2_codemarker_stop; -}; - -typedef struct _Oauth2Info Oauth2Info; - -void account_read_oauth2_all (void); - -#endif /* _OAUTH2_H_ */ blob - c73cdf5cd0cc1b329a99f9f306c8a87edb1b253c blob + 2361a57f7dafb1d85d3f648f0349441697f72cab --- src/pop.c +++ src/pop.c @@ -32,7 +32,6 @@ #include "log.h" #include "hooks.h" #include "file-utils.h" -#include "oauth2.h" #include "defs.h" @@ -133,77 +132,6 @@ static gint pop3_getauth_pass_send(Pop3Session *sessio return PS_SUCCESS; } -static gint pop3_getauth_oauth2_send_generic(Pop3Session *session) -{ - gchar buf[MESSAGEBUFSIZE], *b64buf, *out; - gint len; - - cm_return_val_if_fail(session->user != NULL, -1); - cm_return_val_if_fail(session->pass != NULL, -1); - - session->state = POP3_GETAUTH_OAUTH2; - memset(buf, 0, sizeof buf); - - /* "user=" {User} "^Aauth=Bearer " {Access Token} "^A^A" */ - /* session->pass contains the OAUTH2 Access Token */ - len = sprintf(buf, "user=%s\1auth=Bearer %s\1\1", session->user, session->pass); - b64buf = g_base64_encode(buf, len); - out = g_strconcat("AUTH XOAUTH2 ", b64buf, NULL); - g_free(b64buf); - - pop3_gen_send(session, "%s", out); - /* Any error response contains base64({JSON-Body}) containing three values: status, schemes, and scope */ - /* This could be dealt with but is currently written to the log in a fairly graceful fail - not crucial */ - g_free(out); - return PS_SUCCESS; -} - -/* Microsoft requires authentication to be split in two lines */ -static gint pop3_getauth_oauth2_send_microsoft_1(Pop3Session *session) -{ - cm_return_val_if_fail(session->user != NULL, -1); - cm_return_val_if_fail(session->pass != NULL, -1); - - session->state = POP3_GETAUTH_USER_PHASE2; - - pop3_gen_send(session, "AUTH XOAUTH2"); - - return PS_SUCCESS; -} - -static gint pop3_getauth_oauth2_send_microsoft_2(Pop3Session *session) -{ - gchar buf[MESSAGEBUFSIZE], *b64buf; - gint len; - - cm_return_val_if_fail(session->user != NULL, -1); - cm_return_val_if_fail(session->pass != NULL, -1); - - session->state = POP3_GETAUTH_OAUTH2; - memset(buf, 0, sizeof buf); - - /* "user=" {User} "^Aauth=Bearer " {Access Token} "^A^A"*/ - /* session->pass contains the OAUTH2 Access Token*/ - len = sprintf(buf, "user=%s\1auth=Bearer %s\1\1", session->user, session->pass); - b64buf = g_base64_encode(buf, len); - - pop3_gen_send(session, "%s", b64buf); - - g_free(b64buf); - /* Any error response contains base64({JSON-Body}) containing three values: status, schemes, and scope */ - /* This could be dealt with but is currently written to the log in a fairly graceful fail - not crucial */ - return PS_SUCCESS; -} - -static gint pop3_getauth_oauth2_send(Pop3Session *session) -{ - gint two_stage_pop = session->two_stage_pop; - return ( two_stage_pop ? - pop3_getauth_oauth2_send_microsoft_1(session) - : pop3_getauth_oauth2_send_generic(session) - ); -} - static gint pop3_getrange_stat_send(Pop3Session *session) { session->state = POP3_GETRANGE_STAT; @@ -545,17 +473,6 @@ Session *pop3_session_new(PrefsAccount *account) session->current_time = time(NULL); session->error_val = PS_SUCCESS; session->error_msg = NULL; - - if(session->ac_prefs->use_pop_auth && session->ac_prefs->pop_auth_type == POPAUTH_OAUTH2){ - //Set up for two stage sessions - link provider selected in ac_prefs to the config file - GList *oauth2_providers_list = oauth2_providers_get_list(); - Oauth2Info *oa2; - - oa2 = g_list_nth_data (oauth2_providers_list, session->ac_prefs->oauth2_provider - 1); - debug_print("POP - Oauth2 name: %s Two stage POP: %i\n", oa2->oa2_name, oa2->oa2_two_stage_pop); - session->two_stage_pop = oa2->oa2_two_stage_pop; - } - return SESSION(session); } @@ -946,27 +863,17 @@ static gint pop3_session_recv_msg(Session *session, co if (pop3_session->ac_prefs->ssl_pop == SSL_STARTTLS) val = pop3_stls_send(pop3_session); else - if (pop3_session->ac_prefs->use_pop_auth && pop3_session->ac_prefs->pop_auth_type == POPAUTH_OAUTH2) - val = pop3_getauth_oauth2_send(pop3_session); - else val = pop3_getauth_user_send(pop3_session); break; case POP3_STLS: if (pop3_stls_recv(pop3_session) != PS_SUCCESS) return -1; - else if (pop3_session->ac_prefs->use_pop_auth && pop3_session->ac_prefs->pop_auth_type == POPAUTH_OAUTH2) - val = pop3_getauth_oauth2_send(pop3_session); - else - val = pop3_getauth_user_send(pop3_session); + val = pop3_getauth_user_send(pop3_session); break; case POP3_GETAUTH_USER: val = pop3_getauth_pass_send(pop3_session); break; - case POP3_GETAUTH_USER_PHASE2: - val = pop3_getauth_oauth2_send_microsoft_2(pop3_session); - break; case POP3_GETAUTH_PASS: - case POP3_GETAUTH_OAUTH2: if (!pop3_session->pop_before_smtp) val = pop3_getrange_stat_send(pop3_session); else blob - df67a3fb609f90a5b65d53bfb334750b0ebc00f1 blob + 152f0f4c9a009d3f22c7425a1d68751eb6e533e4 --- src/prefs_account.c +++ src/prefs_account.c @@ -51,7 +51,6 @@ #include "smtp.h" #include "imap.h" #include "pop.h" -#include "oauth2.h" #include "remotefolder.h" #include "combobox.h" #include "setup.h" @@ -87,10 +86,6 @@ struct AutocheckWidgets { static GSList *prefs_pages = NULL; -static GTask *oauth2_listener_task; -static int oauth2_listener_cancel = 0; -static int oauth2_listener_closed = 0; - typedef struct BasicPage { PrefsPage page; @@ -182,24 +177,6 @@ typedef struct SendPage GtkWidget *pop_auth_minutes_lbl; } SendPage; -typedef struct Oauth2Page -{ - PrefsPage page; - - GtkWidget *vbox; - GtkWidget *oauth2_sensitive; - - GtkWidget *oauth2_authorise_btn; - GtkWidget *oauth2_deauthorise_btn; - GtkWidget *oauth2_authcode_entry; - GtkWidget *oauth2_auth_optmenu; - GtkWidget *oauth2_link_button; - GtkWidget *oauth2_link_copy_button; - gpointer *protocol_optmenu; - GtkWidget *oauth2_client_id_entry; - GtkWidget *oauth2_client_secret_entry; -} Oauth2Page; - typedef struct { gchar *auth_uri; @@ -220,21 +197,6 @@ typedef struct ComposePage GtkWidget *autoreplyto_entry; } ComposePage; -typedef struct TemplatesPage -{ - PrefsPage page; - - GtkWidget *vbox; - - GtkWidget *checkbtn_compose_with_format; - GtkWidget *compose_subject_format; - GtkWidget *compose_body_format; - GtkWidget *checkbtn_reply_with_format; - GtkWidget *reply_body_format; - GtkWidget *checkbtn_forward_with_format; - GtkWidget *forward_body_format; -} TemplatesPage; - typedef struct PrivacyPage { PrefsPage page; @@ -312,7 +274,6 @@ typedef struct AdvancedPage static BasicPage basic_page; static ReceivePage receive_page; static SendPage send_page; -static Oauth2Page oauth2_page; static ComposePage compose_page; static PrivacyPage privacy_page; static SSLPage ssl_page; @@ -333,13 +294,6 @@ static char *protocol_names[] = { N_("None (SMTP only)") }; -struct Oauth2Listener { - int success; - Oauth2Service service; - OAUTH2Data *OAUTH2Data; - gchar *trim_text; -}; - static void prefs_account_protocol_set_data_from_optmenu(PrefParam *pparam); static void prefs_account_protocol_set_optmenu (PrefParam *pparam); static void prefs_account_protocol_changed (GtkComboBox *combobox, gpointer data); @@ -354,16 +308,6 @@ static void prefs_account_smtp_auth_type_set_optmenu ( static void prefs_account_pop_auth_type_set_data_from_optmenu (PrefParam *pparam); static void prefs_account_pop_auth_type_set_optmenu (PrefParam *pparam); -static void prefs_account_oauth2_provider_set_data_from_optmenu (PrefParam *pparam); -static void prefs_account_oauth2_provider_set_optmenu (PrefParam *pparam); -static void prefs_account_oauth2_copy_url (GtkButton *button, gpointer data); -static void prefs_account_oauth2_listener(GTask *task, gpointer source, gpointer task_data, GCancellable *cancellable); -static void prefs_account_oauth2_callback(GObject *source, GAsyncResult *res, gpointer user_data); -static int prefs_account_oauth2_get_line(int sock, char *buf, int size); -static void prefs_account_oauth2_set_sensitivity(void); -static void prefs_account_oauth2_set_auth_sensitivity(void); -static void prefs_account_oauth2_obtain_tokens(GtkButton *button, gpointer data); - static void prefs_account_set_autochk_interval_from_widgets(PrefParam *pparam); static void prefs_account_set_autochk_interval_to_widgets(PrefParam *pparam); @@ -532,27 +476,6 @@ static PrefParam send_param[] = { {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} }; -static PrefParam oauth2_param[] = { - {"oauth2_auth_provider", "0", &tmp_ac_prefs.oauth2_provider, P_ENUM, - &oauth2_page.oauth2_auth_optmenu, - prefs_account_oauth2_provider_set_data_from_optmenu, - prefs_account_oauth2_provider_set_optmenu}, - - {"oauth2_date", 0, &tmp_ac_prefs.oauth2_date, P_INT, - NULL, NULL, NULL}, - - {"oauth2_authcode", NULL, &tmp_ac_prefs.oauth2_authcode, P_PASSWORD, - NULL, NULL, NULL}, - - {"oauth2_client_id", NULL, &tmp_ac_prefs.oauth2_client_id, P_STRING, - &oauth2_page.oauth2_client_id_entry, prefs_set_data_from_entry, prefs_set_entry}, - - {"oauth2_client_secret", NULL, &tmp_ac_prefs.oauth2_client_secret, P_STRING, - &oauth2_page.oauth2_client_secret_entry, prefs_set_data_from_entry, prefs_set_entry}, - - {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} -}; - static PrefParam compose_param[] = { {"set_autocc", "FALSE", &tmp_ac_prefs.set_autocc, P_BOOL, &compose_page.autocc_checkbtn, @@ -1708,222 +1631,6 @@ static void send_create_widget_func(PrefsPage * _page, page->page.widget = vbox1; } -static void oauth2_create_widget_func(PrefsPage * _page, - GtkWindow * window, - gpointer data) -{ - Oauth2Page *page = (Oauth2Page *) _page; - PrefsAccount *ac_prefs = (PrefsAccount *) data; - - GtkWidget *vbox1, *vbox2, *vbox3; - GtkWidget *hbox; - GtkWidget *hbox_spc; - GtkWidget *oauth2_authorise_btn; - GtkWidget *auth_vbox, *auth_frame; - GtkWidget *label; - GtkWidget *oauth2_authcode_entry; - GtkWidget *oauth2_auth_optmenu; - GtkWidget *oauth2_link_button; - GtkWidget *oauth2_link_copy_button; - GtkWidget *oauth2_client_id_entry; - GtkWidget *oauth2_client_secret_entry; - GtkWidget *table1; - GtkListStore *menu; - GtkTreeIter iter; - char *buf; - struct BasicProtocol *protocol_optmenu; - - vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); - gtk_widget_show (vbox1); - gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER); - - auth_vbox = gtkut_get_options_frame(vbox1, &auth_frame, - _("Authorization")); - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (auth_vbox), hbox, FALSE, FALSE, 0); - - hbox_spc = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show (hbox_spc); - gtk_widget_set_size_request (hbox_spc, 12, -1); - gtk_box_pack_start (GTK_BOX (hbox), hbox_spc, FALSE, FALSE, 0); - - /* Email service provider */ - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (auth_vbox), hbox, FALSE, FALSE, 0); - - label = gtk_label_new (_("Select OAuth2 Email Service Provider")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - oauth2_auth_optmenu = gtkut_sc_combobox_create(NULL, FALSE); - menu = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(oauth2_auth_optmenu))); - gtk_widget_show (oauth2_auth_optmenu); - gtk_box_pack_start (GTK_BOX (hbox), oauth2_auth_optmenu, FALSE, FALSE, 0); - - COMBOBOX_ADD (menu, _("Select"), NULL); - COMBOBOX_ADD (menu, NULL, 0); - - gint j = 1; - GList *oauth2_providers_list = oauth2_providers_get_list(); - GList *cur; - Oauth2Info *oa2; - for (cur = oauth2_providers_list; cur != NULL; cur = cur->next) { - oa2 = (Oauth2Info *)cur->data; - COMBOBOX_ADD (menu, oa2->oa2_name, j); - j++; - } - - protocol_optmenu = g_new(struct BasicProtocol, 1); - protocol_optmenu->combobox = oauth2_auth_optmenu; - protocol_optmenu->label = label; - protocol_optmenu->descrlabel = label; - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (auth_vbox), hbox, FALSE, FALSE, 0); - - vbox3 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_widget_show (vbox3); - gtk_box_pack_start (GTK_BOX (auth_vbox), vbox3, FALSE, FALSE, 0); - - vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_widget_show (vbox2); - gtk_box_pack_start (GTK_BOX (vbox3), vbox2, FALSE, FALSE, 0); - - table1 = gtk_grid_new(); - gtk_widget_show (table1); - gtk_container_add (GTK_CONTAINER (vbox2), table1); - gtk_container_set_border_width (GTK_CONTAINER (table1), 8); - gtk_grid_set_row_spacing(GTK_GRID(table1), VSPACING_NARROW); - gtk_grid_set_column_spacing(GTK_GRID(table1), 8); - - label = gtk_label_new (_("Client ID")); - gtk_widget_show (label); - gtk_label_set_xalign(GTK_LABEL (label), 1.0); - gtk_grid_attach(GTK_GRID(table1), label, 0, 0, 1, 1); - - oauth2_client_id_entry = gtk_entry_new(); - gtk_widget_show (oauth2_client_id_entry); - gtk_grid_attach(GTK_GRID(table1), oauth2_client_id_entry, 1, 0, 1, 1); - gtk_widget_set_hexpand(oauth2_client_id_entry, TRUE); - gtk_widget_set_halign(oauth2_client_id_entry, GTK_ALIGN_FILL); - - label = gtk_label_new (_("Client secret")); - gtk_widget_show (label); - gtk_label_set_xalign(GTK_LABEL (label), 1.0); - gtk_grid_attach(GTK_GRID(table1), label, 0, 1, 1, 1); - - oauth2_client_secret_entry = gtk_entry_new (); - gtk_widget_show (oauth2_client_secret_entry); - gtk_grid_attach(GTK_GRID(table1), oauth2_client_secret_entry, 1, 1, 1, 1); - gtk_widget_set_hexpand(oauth2_client_secret_entry, TRUE); - gtk_widget_set_halign(oauth2_client_secret_entry, GTK_ALIGN_FILL); - - hbox_spc = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show (hbox_spc); - gtk_box_pack_start (GTK_BOX (hbox), hbox_spc, FALSE, FALSE, 0); - //gtk_widget_set_size_request (hbox_spc, 12, -1); - - hbox_spc = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show (hbox_spc); - gtk_box_pack_start (GTK_BOX (vbox2), hbox_spc, FALSE, FALSE, 0); - //gtk_widget_set_size_request (hbox_spc, 12, 10); - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (vbox3), hbox, FALSE, FALSE, 0); - - label = gtk_label_new (_("Obtain authorization code")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - oauth2_link_button = gtk_button_new_with_label(_("Open default browser with request")); - g_signal_connect(G_OBJECT(oauth2_link_button), "clicked", G_CALLBACK(prefs_account_oauth2_copy_url), NULL); - gtk_widget_set_sensitive(oauth2_link_button, TRUE); - gtk_widget_set_margin_bottom(oauth2_link_button, 8); - gtk_widget_show (oauth2_link_button); - gtk_box_pack_start (GTK_BOX (hbox), oauth2_link_button, FALSE, FALSE, 0); - - oauth2_link_copy_button = gtk_button_new_with_label(_("Copy link")); - g_signal_connect(G_OBJECT(oauth2_link_copy_button), "clicked", G_CALLBACK(prefs_account_oauth2_copy_url), NULL); - gtk_widget_set_sensitive(oauth2_link_copy_button, TRUE); - gtk_widget_set_margin_bottom(oauth2_link_copy_button, 8); - gtk_widget_show (oauth2_link_copy_button); - gtk_box_pack_start (GTK_BOX (hbox), oauth2_link_copy_button, FALSE, FALSE, 0); - - /* Authorisation code */ - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (vbox3), hbox, FALSE, FALSE, 0); - //gtk_widget_set_size_request (hbox, -1, 50); - - label = gtk_label_new ("Authorization code"); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - oauth2_authcode_entry = gtk_entry_new (); - gtk_widget_show (oauth2_authcode_entry); - gtk_widget_set_margin_bottom(oauth2_authcode_entry, 8); - gtk_widget_set_tooltip_text(oauth2_authcode_entry, - _("Paste complete URL from browser or the provided authorization token")); - gtk_box_pack_start (GTK_BOX (hbox), oauth2_authcode_entry, TRUE, TRUE, 0); - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (vbox3), hbox, FALSE, FALSE, 0); - - label = gtk_label_new (_("Complete authorization")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - oauth2_authorise_btn = gtk_button_new_with_label(_("Authorize")); - gtk_box_pack_start(GTK_BOX(hbox), oauth2_authorise_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(oauth2_authorise_btn), "clicked", - G_CALLBACK(prefs_account_oauth2_obtain_tokens), NULL); - gtk_widget_show(oauth2_authorise_btn); - - /* Add items to page struct */ - - page->oauth2_link_button = oauth2_link_button; - page->oauth2_link_copy_button = oauth2_link_copy_button; - page->oauth2_authcode_entry = oauth2_authcode_entry; - page->oauth2_auth_optmenu = oauth2_auth_optmenu; - page->protocol_optmenu = (gpointer)protocol_optmenu; - page->oauth2_authorise_btn = oauth2_authorise_btn; - page->oauth2_client_id_entry = oauth2_client_id_entry; - page->oauth2_client_secret_entry = oauth2_client_secret_entry; - page->vbox = vbox1; - page->page.widget = vbox1; - page->oauth2_sensitive = vbox3; - - tmp_ac_prefs = *ac_prefs; - - g_signal_connect(G_OBJECT(oauth2_auth_optmenu), "changed", - G_CALLBACK(prefs_account_oauth2_set_sensitivity), NULL); - g_signal_connect(G_OBJECT(oauth2_authcode_entry), "changed", - G_CALLBACK(prefs_account_oauth2_set_auth_sensitivity), NULL); - prefs_account_oauth2_set_auth_sensitivity(); - - if (new_account) { - prefs_set_dialog_to_default(oauth2_param); - } else { - prefs_set_dialog(oauth2_param); - - /* Passwords are handled outside of PrefParams. */ - buf = passwd_store_get_account(ac_prefs->account_id, - PWS_ACCOUNT_OAUTH2_AUTH); - gtk_entry_set_text(GTK_ENTRY(page->oauth2_authcode_entry), buf != NULL ? buf : ""); - if (buf != NULL) { - memset(buf, 0, strlen(buf)); - g_free(buf); - } - } -} - static void compose_create_widget_func(PrefsPage * _page, GtkWindow * window, gpointer data) @@ -2756,19 +2463,6 @@ static gint prefs_send_apply(void) return 0; } -static gint prefs_oauth2_apply(void) -{ - prefs_set_data_from_dialog(oauth2_param); - - /* Passwords are stored outside of PrefParams. */ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_OAUTH2_AUTH, - gtk_entry_get_text(GTK_ENTRY(oauth2_page.oauth2_authcode_entry)), - FALSE); - - return 0; -} - static gint prefs_compose_apply(void) { prefs_set_data_from_dialog(compose_param); @@ -2845,16 +2539,6 @@ static void send_destroy_widget_func(PrefsPage *_page) /* SendPage *page = (SendPage *) _page; */ } -static void oauth2_destroy_widget_func(PrefsPage *_page) -{ - /* Oauth2Page *page = (Oauth2Page *) _page; */ - - if(oauth2_listener_task){ - debug_print("Closing oauth2 listener task\n"); - oauth2_listener_cancel = 1; - } -} - static void compose_destroy_widget_func(PrefsPage *_page) { /* ComposePage *page = (ComposePage *) _page; */ @@ -2905,16 +2589,6 @@ static gboolean send_can_close_func(PrefsPage *_page) return prefs_send_apply() >= 0; } -static gboolean oauth2_can_close_func(PrefsPage *_page) -{ - Oauth2Page *page = (Oauth2Page *) _page; - - if (!page->page.page_open) - return TRUE; - - return prefs_oauth2_apply() >= 0; -} - static gboolean compose_can_close_func(PrefsPage *_page) { ComposePage *page = (ComposePage *) _page; @@ -2988,17 +2662,6 @@ static void send_save_func(PrefsPage *_page) cancelled = FALSE; } -static void oauth2_save_func(PrefsPage *_page) -{ - Oauth2Page *page = (Oauth2Page *) _page; - - if (!page->page.page_open) - return; - - if (prefs_oauth2_apply() >= 0) - cancelled = FALSE; -} - static void compose_save_func(PrefsPage *_page) { ComposePage *page = (ComposePage *) _page; @@ -3097,24 +2760,6 @@ static void register_send_page(void) prefs_account_register_page((PrefsPage *) &send_page); } -static void register_oauth2_page(void) -{ - static gchar *path[3]; - - path[0] = _("Account"); - path[1] = _("OAuth2"); - path[2] = NULL; - - oauth2_page.page.path = path; - oauth2_page.page.weight = 1000.0; - oauth2_page.page.create_widget = oauth2_create_widget_func; - oauth2_page.page.destroy_widget = oauth2_destroy_widget_func; - oauth2_page.page.save_page = oauth2_save_func; - oauth2_page.page.can_close = oauth2_can_close_func; - - prefs_account_register_page((PrefsPage *) &oauth2_page); -} - static void register_compose_page(void) { static gchar *path[3]; @@ -3261,7 +2906,6 @@ void prefs_account_init() register_ssl_page(); hooks_register_hook(SSLCERT_GET_CLIENT_CERT_HOOKLIST, sslcert_get_client_cert_hook, NULL); hooks_register_hook(SSL_CERT_GET_PASSWORD, sslcert_get_password, NULL); - register_oauth2_page(); register_advanced_page(); } @@ -3274,7 +2918,6 @@ PrefsAccount *prefs_account_new(void) prefs_set_default(basic_param); prefs_set_default(receive_param); prefs_set_default(send_param); - prefs_set_default(oauth2_param); prefs_set_default(compose_param); prefs_set_default(privacy_param); prefs_set_default(ssl_param); @@ -3305,7 +2948,6 @@ PrefsAccount *prefs_account_new_from_config(const gcha prefs_set_default(basic_param); prefs_set_default(receive_param); prefs_set_default(send_param); - prefs_set_default(oauth2_param); prefs_set_default(compose_param); prefs_set_default(privacy_param); prefs_set_default(ssl_param); @@ -3316,7 +2958,6 @@ PrefsAccount *prefs_account_new_from_config(const gcha prefs_read_config(basic_param, label, rcpath, NULL); prefs_read_config(receive_param, label, rcpath, NULL); prefs_read_config(send_param, label, rcpath, NULL); - prefs_read_config(oauth2_param, label, rcpath, NULL); prefs_read_config(compose_param, label, rcpath, NULL); prefs_read_config(privacy_param, label, rcpath, NULL); prefs_read_config(ssl_param, label, rcpath, NULL); @@ -3453,7 +3094,6 @@ void prefs_account_write_config_all(GList *account_lis WRITE_PARAM(basic_param) WRITE_PARAM(receive_param) WRITE_PARAM(send_param) - WRITE_PARAM(oauth2_param) WRITE_PARAM(compose_param) WRITE_PARAM(privacy_param) WRITE_PARAM(ssl_param) @@ -3498,7 +3138,6 @@ void prefs_account_free(PrefsAccount *ac_prefs) prefs_free(basic_param); prefs_free(receive_param); prefs_free(send_param); - prefs_free(oauth2_param); prefs_free(compose_param); prefs_free(privacy_param); prefs_free(ssl_param); @@ -3957,163 +3596,6 @@ static void prefs_account_pop_auth_type_set_optmenu(Pr combobox_select_by_data(optmenu, type); } -static void prefs_account_oauth2_provider_set_data_from_optmenu(PrefParam *pparam) -{ - *((Oauth2Service *)pparam->data) = - combobox_get_active_data(GTK_COMBO_BOX(*pparam->widget)); -} - -static void prefs_account_oauth2_provider_set_optmenu(PrefParam *pparam) -{ - Oauth2Service type = *((Oauth2Service *)pparam->data); - GtkComboBox *optmenu = GTK_COMBO_BOX(*pparam->widget); - - combobox_select_by_data(optmenu, type); -} - -static void prefs_account_oauth2_set_auth_sensitivity(void) -{ - const gchar *authcode = gtk_entry_get_text((GtkEntry *)oauth2_page.oauth2_authcode_entry); - gchar *trim_text = g_strdup(authcode); - g_strstrip(trim_text); - gtk_widget_set_sensitive(oauth2_page.oauth2_authorise_btn, (*trim_text != 0)); - g_free(trim_text); -} - -static void prefs_account_oauth2_set_sensitivity(void) -{ - struct BasicProtocol *protocol_optmenu = (struct BasicProtocol *)oauth2_page.protocol_optmenu; - GtkWidget *optmenu = protocol_optmenu->combobox; - Oauth2Service service; - - service = combobox_get_active_data(GTK_COMBO_BOX(optmenu)); - - if(service == OAUTH2AUTH_NONE) - gtk_widget_set_sensitive(oauth2_page.oauth2_sensitive, FALSE); - else - gtk_widget_set_sensitive(oauth2_page.oauth2_sensitive, TRUE); -} - -static void prefs_account_oauth2_copy_url(GtkButton *button, gpointer data) -{ - struct BasicProtocol *protocol_optmenu = (struct BasicProtocol *)oauth2_page.protocol_optmenu; - - GtkWidget *optmenu = protocol_optmenu->combobox; - - GtkWidget *win; - GtkClipboard *clip, *clip2; - gint len; - gchar *url; - url = g_malloc(OAUTH2BUFSIZE+1); - Oauth2Service service; - const gchar * custom_client_id = NULL; - struct Oauth2Listener *oauth2_listener_data; - - service = combobox_get_active_data(GTK_COMBO_BOX(optmenu)); - custom_client_id = gtk_entry_get_text((GtkEntry *)oauth2_page.oauth2_client_id_entry); - - oauth2_authorisation_url(service, &url, custom_client_id); - - win = gtk_widget_get_toplevel (optmenu); - len = strlen(url); - - clip = gtk_widget_get_clipboard (win, GDK_SELECTION_PRIMARY); - clip2 = gtk_widget_get_clipboard (win, GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text (clip, url, len); - gtk_clipboard_set_text (clip2, url, len); - - if (strcmp(gtk_button_get_label(button), "Copy link") != 0) - open_uri(url, prefs_common_get_uri_cmd()); - - g_free(url); - - //Start listener task for authorisation reply using a separate task - //Avoids hanging while we wait, and to allow cancellation of the process - //If task already exists gracefully close it - if(oauth2_listener_task){ - debug_print("Closing oauth2 listener task\n"); - oauth2_listener_cancel = 1; - while (oauth2_listener_closed == 0) - gtk_main_iteration(); - } - - debug_print("Starting oauth2 listener task\n"); - - oauth2_listener_data = g_new(struct Oauth2Listener, 1); - oauth2_listener_data->success = FALSE; - oauth2_listener_data->trim_text = NULL; - oauth2_listener_data->service = combobox_get_active_data(GTK_COMBO_BOX(optmenu)); - oauth2_listener_data->OAUTH2Data = g_malloc(sizeof(* oauth2_listener_data->OAUTH2Data)); - oauth2_init (oauth2_listener_data->OAUTH2Data); - oauth2_listener_data->OAUTH2Data->custom_client_secret = - g_strdup(gtk_entry_get_text((GtkEntry *)oauth2_page.oauth2_client_secret_entry)); - oauth2_listener_data->OAUTH2Data->custom_client_id = - g_strdup(gtk_entry_get_text((GtkEntry *)oauth2_page.oauth2_client_id_entry)); - - oauth2_listener_cancel = 0; - oauth2_listener_closed = 0; - - oauth2_listener_task = g_task_new(NULL, NULL, prefs_account_oauth2_callback, oauth2_listener_data); - g_task_set_task_data(oauth2_listener_task, oauth2_listener_data, NULL); - g_task_run_in_thread(oauth2_listener_task, prefs_account_oauth2_listener); -} - -static void prefs_account_oauth2_obtain_tokens(GtkButton *button, gpointer data) -{ - struct BasicProtocol *protocol_optmenu = (struct BasicProtocol *)oauth2_page.protocol_optmenu; - - GtkWidget *optmenu = protocol_optmenu->combobox; - Oauth2Service service; - OAUTH2Data *OAUTH2Data = g_malloc(sizeof(* OAUTH2Data)); - const gchar *authcode = gtk_entry_get_text ((GtkEntry *)oauth2_page.oauth2_authcode_entry); - gchar *trim_text = g_strdup(authcode); - g_strstrip(trim_text); - gint ret; - - oauth2_init (OAUTH2Data); - - - OAUTH2Data->custom_client_secret = - g_strdup(gtk_entry_get_text((GtkEntry *)oauth2_page.oauth2_client_secret_entry)); - OAUTH2Data->custom_client_id = - g_strdup(gtk_entry_get_text((GtkEntry *)oauth2_page.oauth2_client_id_entry)); - - - service = combobox_get_active_data(GTK_COMBO_BOX(optmenu)); - ret = oauth2_obtain_tokens (service, OAUTH2Data, trim_text); - - if(!ret){ - if(OAUTH2Data->refresh_token != NULL){ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_OAUTH2_REFRESH, OAUTH2Data->refresh_token, FALSE); - log_message(LOG_PROTOCOL, "OAuth2 refresh token stored\n"); - } - - if(OAUTH2Data->access_token != NULL){ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_RECV, OAUTH2Data->access_token, FALSE); - gtk_entry_set_text(GTK_ENTRY(basic_page.pass_entry), OAUTH2Data->access_token); - - if (tmp_ac_prefs.use_smtp_auth && tmp_ac_prefs.smtp_auth_type == SMTPAUTH_OAUTH2) { - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_SEND, OAUTH2Data->access_token, FALSE); - gtk_entry_set_text(GTK_ENTRY(send_page.smtp_pass_entry), OAUTH2Data->access_token); - } - log_message(LOG_PROTOCOL, "OAuth2 access token stored\n"); - } - - if(OAUTH2Data->expiry_str != NULL){ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_OAUTH2_EXPIRY, OAUTH2Data->expiry_str, FALSE); - log_message(LOG_PROTOCOL, "OAuth2 access token expiry stored\n"); - } - - tmp_ac_prefs.oauth2_date = g_get_real_time () / G_USEC_PER_SEC; - } - g_free(trim_text); - g_free(OAUTH2Data); -} - static void prefs_account_set_autochk_interval_to_widgets(PrefParam *pparam) { gint val = *((gint *)pparam->data); @@ -4602,194 +4084,3 @@ static void prefs_account_receive_itv_spinbutton_value PREFS_RECV_AUTOCHECK_MIN_INTERVAL); } } - -//Automation of the oauth2 authorisation process to receive loopback callback generated by redirect in browser -static void prefs_account_oauth2_listener(GTask *task, gpointer source, gpointer task_data, GCancellable *cancellable) -{ - struct Oauth2Listener *oauth2_listener_data = (struct Oauth2Listener *)task_data; - unsigned int socket_desc; - int client_sock, c; - struct sockaddr_in server , client; - char client_message[2000]; - char *reply; - char *reply_message; - char *title; - char *body; - fd_set rfds; - gint ret = 1; - struct timeval timeout; - - debug_print("oauth2 listener task running\n"); - - //Create socket - socket_desc = socket(AF_INET , SOCK_STREAM , 0); - if (socket_desc == -1) - { - debug_print("oauth2 listener could not create socket\n"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); - return; - } - debug_print("oauth2 listener socket created\n"); - - //Prepare the sockaddr_in structure - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; - server.sin_port = htons( 8888 ); - - //Bind - if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) - { - close(socket_desc); - debug_print("oauth2 listener bind failed\n"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); - return; - } - debug_print("oauth2 listener bind done\n"); - - listen(socket_desc , 1); - - //Accept and incoming connection - debug_print("oauth2 listener waiting for incoming connections...\n"); - c = sizeof(struct sockaddr_in); - - do{ - FD_ZERO(&rfds); - FD_SET(socket_desc, &rfds); - timeout.tv_sec = 1; - timeout.tv_usec = 0; - - select(socket_desc+1, &rfds, NULL, NULL, &timeout); - - //select woke up, maybe accept connection from an incoming client - if(FD_ISSET(socket_desc, &rfds)){ - client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); - if (client_sock < 0){ - debug_print("oauth2 listener accept failed\n"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); - return; - } - debug_print("oauth2 listener connection accepted\n"); - - //Receive message sent to the loopback address by the authorisation page - prefs_account_oauth2_get_line(client_sock, client_message, sizeof(client_message)); - oauth2_listener_data->trim_text = g_strdup(client_message); - g_strstrip(oauth2_listener_data->trim_text); - - ret = oauth2_obtain_tokens (oauth2_listener_data->service, oauth2_listener_data->OAUTH2Data, oauth2_listener_data->trim_text); - - if(!ret){ - oauth2_listener_data->success = TRUE; - title = _("Authorisation complete"); - body = _("Your OAuth2 authorisation code has been received by Claws Mail"); - }else{ - //Something went wrong - title = _("Authorisation NOT completed"); - body = _("Your OAuth2 authorisation code was not received by Claws Mail"); - log_message(LOG_PROTOCOL, "OAuth2 authorisation code not received\n"); - } - reply_message = g_strconcat("", title, - "

", title, - "

", body, "

", NULL); - reply = g_strdup_printf( - "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", - strlen(reply_message), reply_message); - g_free(reply_message); - write(client_sock, reply, strlen(reply)); - g_free(reply); - close(client_sock); - } - }while(ret && !oauth2_listener_cancel); - - close(socket_desc); - debug_print("oauth2 closing task\n"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void prefs_account_oauth2_callback(GObject *source, GAsyncResult *res, gpointer user_data) -{ - struct Oauth2Listener *oauth2_listener_data = (struct Oauth2Listener *)user_data; - - if(oauth2_listener_data->success){ - debug_print("oauth2 listener callback storing data and updating GUI\n"); - - if(oauth2_listener_data->OAUTH2Data->refresh_token != NULL){ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_OAUTH2_REFRESH, - oauth2_listener_data->OAUTH2Data->refresh_token, - FALSE); - log_message(LOG_PROTOCOL, "OAuth2 refresh token stored\n"); - } - - if(oauth2_listener_data->OAUTH2Data->access_token != NULL){ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_RECV, - oauth2_listener_data->OAUTH2Data->access_token, - FALSE); - if (tmp_ac_prefs.use_smtp_auth && tmp_ac_prefs.smtp_auth_type == SMTPAUTH_OAUTH2) - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_SEND, - oauth2_listener_data->OAUTH2Data->access_token, - FALSE); - log_message(LOG_PROTOCOL, "OAuth2 access token stored\n"); - } - - if(oauth2_listener_data->OAUTH2Data->expiry_str != NULL){ - passwd_store_set_account(tmp_ac_prefs.account_id, - PWS_ACCOUNT_OAUTH2_EXPIRY, - oauth2_listener_data->OAUTH2Data->expiry_str, - FALSE); - log_message(LOG_PROTOCOL, "OAuth2 access token expiry stored\n"); - } - - tmp_ac_prefs.oauth2_date = g_get_real_time () / G_USEC_PER_SEC; - - gtk_entry_set_text(GTK_ENTRY(oauth2_page.oauth2_authcode_entry), oauth2_listener_data->trim_text != NULL ? oauth2_listener_data->trim_text : ""); - gtk_widget_set_sensitive(oauth2_page.oauth2_authcode_entry, FALSE); - gtk_widget_set_sensitive(oauth2_page.oauth2_authorise_btn, FALSE); - gtk_entry_set_text(GTK_ENTRY(basic_page.pass_entry), oauth2_listener_data->OAUTH2Data->access_token); - gtk_entry_set_text(GTK_ENTRY(send_page.smtp_pass_entry), oauth2_listener_data->OAUTH2Data->access_token); - } - - debug_print("oauth2 listener callback freeing resources\n"); - g_free(oauth2_listener_data->trim_text); - g_free(oauth2_listener_data->OAUTH2Data); - g_free(oauth2_listener_data); - oauth2_listener_cancel = 0; - oauth2_listener_closed = 1; -} - -static int prefs_account_oauth2_get_line(int sock, char *buf, int size) -{ - int i = 0; - char c = '\0'; - int n; - - while ((i < size - 1) && (c != '\n')) { - n = recv(sock, &c, 1, 0); - //printf("%02X\n", c); - if (n > 0) { - if (c == '\r') { - n = recv(sock, &c, 1, MSG_PEEK); - //printf("%02X\n", c); - if ((n > 0) && (c == '\n')) { - n = recv(sock, &c, 1, 0); - if (n < 0) - log_message(LOG_PROTOCOL, "Receiving from pipe failed\n"); - } - else - c = '\n'; - } - buf[i] = c; - i++; - } - else - c = '\n'; - } - buf[i] = '\0'; - - return (i); -} blob - 0bfe0ea807f256522d90d92a773afb356b73d9d3 blob + 52ebb26dbbe2dbee304169e32f0fa5570379fb89 --- src/prefs_compose_writing.c +++ src/prefs_compose_writing.c @@ -45,9 +45,6 @@ typedef struct _WritingPage GtkWidget *window; GtkWidget *checkbtn_autoextedit; - GtkWidget *checkbtn_reply_account_autosel; - GtkWidget *checkbtn_forward_account_autosel; - GtkWidget *checkbtn_reedit_account_autosel; GtkWidget *spinbtn_undolevel; GtkWidget *checkbtn_reply_with_quote; GtkWidget *checkbtn_default_reply_list; @@ -71,10 +68,6 @@ static void prefs_compose_writing_create_widget(PrefsP GtkWidget *vbox2; GtkWidget *checkbtn_autoextedit; GtkWidget *frame; - GtkWidget *hbox_autosel; - GtkWidget *checkbtn_reply_account_autosel; - GtkWidget *checkbtn_forward_account_autosel; - GtkWidget *checkbtn_reedit_account_autosel; GtkWidget *hbox_undolevel; GtkWidget *label_undolevel; @@ -114,21 +107,6 @@ static void prefs_compose_writing_create_widget(PrefsP gtk_widget_show (vbox1); gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER); - /* Account autoselection */ - PACK_FRAME(vbox1, frame, _("Automatic account selection")); - - hbox_autosel = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, VSPACING_NARROW); - gtk_widget_show (hbox_autosel); - gtk_container_add (GTK_CONTAINER (frame), hbox_autosel); - gtk_container_set_border_width (GTK_CONTAINER (hbox_autosel), 8); - - PACK_CHECK_BUTTON (hbox_autosel, checkbtn_reply_account_autosel, - _("when replying")); - PACK_CHECK_BUTTON (hbox_autosel, checkbtn_forward_account_autosel, - _("when forwarding")); - PACK_CHECK_BUTTON (hbox_autosel, checkbtn_reedit_account_autosel, - _("when re-editing")); - /* Editing */ vbox2 = gtkut_get_options_frame(vbox1, &frame, _("Editing")); @@ -243,9 +221,6 @@ static void prefs_compose_writing_create_widget(PrefsP SET_TOGGLE_SENSITIVITY (checkbtn_warn_large_insert, label_warn_large_insert_size); prefs_writing->checkbtn_autoextedit = checkbtn_autoextedit; - prefs_writing->checkbtn_reply_account_autosel = checkbtn_reply_account_autosel; - prefs_writing->checkbtn_forward_account_autosel = checkbtn_forward_account_autosel; - prefs_writing->checkbtn_reedit_account_autosel = checkbtn_reedit_account_autosel; prefs_writing->spinbtn_undolevel = spinbtn_undolevel; @@ -284,12 +259,6 @@ static void prefs_compose_writing_create_widget(PrefsP prefs_common.warn_large_insert); gtk_spin_button_set_value(GTK_SPIN_BUTTON(prefs_writing->spinbtn_warn_large_insert_size), prefs_common.warn_large_insert_size); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_reply_account_autosel), - prefs_common.reply_account_autosel); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_forward_account_autosel), - prefs_common.forward_account_autosel); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_reedit_account_autosel), - prefs_common.reedit_account_autosel); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_reply_with_quote), prefs_common.reply_with_quote); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_writing->checkbtn_warn_pasted_attachments), @@ -325,12 +294,10 @@ static void prefs_compose_writing_save(PrefsPage *_pag prefs_common.warn_large_insert_size = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page->spinbtn_warn_large_insert_size)); - prefs_common.reply_account_autosel = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_reply_account_autosel)); - prefs_common.forward_account_autosel = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_forward_account_autosel)); - prefs_common.reedit_account_autosel = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_reedit_account_autosel)); + prefs_common.reply_account_autosel = TRUE; + prefs_common.forward_account_autosel = TRUE; + prefs_common.reedit_account_autosel = TRUE; + prefs_common.reply_with_quote = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(page->checkbtn_reply_with_quote)); prefs_common.default_reply_list = blob - c2a1af87f4e01ea466df824a2397993a4373cd05 (mode 644) blob + /dev/null --- src/prefs_wrapping.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2004-2025 The Claws Mail Team and Hiroyuki Yamamoto - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "defs.h" - -#include -#include - -#include -#include -#include -#include - -#include "prefs_common.h" -#include "prefs_gtk.h" - -#include "gtk/gtkutils.h" -#include "gtk/prefswindow.h" - -#include "manage_window.h" - -typedef struct _WrappingPage -{ - PrefsPage page; - - GtkWidget *window; - - GtkWidget *spinbtn_linewrap; - GtkWidget *checkbtn_wrapquote; - GtkWidget *checkbtn_autowrap; - GtkWidget *checkbtn_autoindent; -} WrappingPage; - -static void prefs_wrapping_create_widget(PrefsPage *_page, GtkWindow *window, - gpointer data) -{ - WrappingPage *prefs_wrapping = (WrappingPage *) _page; - - GtkWidget *vbox1; - GtkWidget *vbox2; - GtkWidget *label_linewrap; - GtkAdjustment *spinbtn_linewrap_adj; - GtkWidget *spinbtn_linewrap; - GtkWidget *checkbtn_wrapquote; - GtkWidget *checkbtn_autowrap; - GtkWidget *checkbtn_autoindent; - GtkWidget *hbox1; - - vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); - gtk_widget_show (vbox1); - gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER); - - vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_widget_show (vbox2); - gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0); - - PACK_CHECK_BUTTON (vbox2, checkbtn_autowrap, _("Auto wrapping")); - PACK_CHECK_BUTTON (vbox2, checkbtn_wrapquote, _("Wrap quotation")); - PACK_CHECK_BUTTON (vbox2, checkbtn_autoindent, _("Auto indent")); - - hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (hbox1); - gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0); - - label_linewrap = gtk_label_new (_("Wrap text at")); - gtk_widget_show (label_linewrap); - gtk_box_pack_start (GTK_BOX (hbox1), label_linewrap, FALSE, FALSE, 4); - - spinbtn_linewrap_adj = GTK_ADJUSTMENT(gtk_adjustment_new (72, 20, 1024, 1, 10, 0)); - spinbtn_linewrap = gtk_spin_button_new - (GTK_ADJUSTMENT (spinbtn_linewrap_adj), 1, 0); - gtk_widget_show (spinbtn_linewrap); - gtk_box_pack_start (GTK_BOX (hbox1), spinbtn_linewrap, FALSE, FALSE, 0); - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_linewrap), TRUE); - - label_linewrap = gtk_label_new (_("characters")); - gtk_widget_show (label_linewrap); - gtk_box_pack_start (GTK_BOX (hbox1), label_linewrap, FALSE, FALSE, 0); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_autowrap), - prefs_common.autowrap); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_wrapquote), - prefs_common.linewrap_quote); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_autoindent), - prefs_common.auto_indent); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbtn_linewrap), - prefs_common.linewrap_len); - - prefs_wrapping->window = GTK_WIDGET(window); - prefs_wrapping->spinbtn_linewrap = spinbtn_linewrap; - prefs_wrapping->checkbtn_wrapquote = checkbtn_wrapquote; - prefs_wrapping->checkbtn_autowrap = checkbtn_autowrap; - prefs_wrapping->checkbtn_autoindent = checkbtn_autoindent; - - prefs_wrapping->page.widget = vbox1; -} - -static void prefs_wrapping_save(PrefsPage *_page) -{ - WrappingPage *page = (WrappingPage *) _page; - - prefs_common.linewrap_len = - gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page->spinbtn_linewrap)); - prefs_common.linewrap_quote = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_wrapquote)); - prefs_common.autowrap = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_autowrap)); - prefs_common.auto_indent = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_autoindent)); -} - -static void prefs_wrapping_destroy_widget(PrefsPage *_page) -{ -} - -WrappingPage *prefs_wrapping; - -void prefs_wrapping_init(void) -{ - WrappingPage *page; - static gchar *path[3]; - - path[0] = _("Write"); - path[1] = _("Wrapping"); - path[2] = NULL; - - page = g_new0(WrappingPage, 1); - page->page.path = path; - page->page.create_widget = prefs_wrapping_create_widget; - page->page.destroy_widget = prefs_wrapping_destroy_widget; - page->page.save_page = prefs_wrapping_save; - page->page.weight = 182.0; - prefs_gtk_register_page((PrefsPage *) page); - prefs_wrapping = page; -} - -void prefs_wrapping_done(void) -{ - prefs_gtk_unregister_page((PrefsPage *) prefs_wrapping); - g_free(prefs_wrapping); -} blob - 3e2ed6c063a3983c47d7af695d998bf8dbd38fd9 (mode 644) blob + /dev/null --- src/prefs_wrapping.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2004-2012 Hiroyuki Yamamoto and the Claws Mail team - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef PREFS_WRAPPING_H -#define PREFS_WRAPPING_H - -void prefs_wrapping_init (void); -void prefs_wrapping_done (void); - -#endif /* PREFS_WRAPPING_H */ blob - ea7b2468f9cf561e0cd864ad6c13dea7974cee4b blob + c8742172672cc7a1204853b927bed3eef2bb900b --- src/send_message.c +++ src/send_message.c @@ -48,7 +48,6 @@ #include "inc.h" #include "log.h" #include "passwordstore.h" -#include "oauth2.h" typedef struct _SendProgressDialog SendProgressDialog; @@ -265,8 +264,6 @@ gint send_message_smtp_full(PrefsAccount *ac_prefs, GS strlen(ac_prefs->gnutls_priority)) session->gnutls_priority = g_strdup(ac_prefs->gnutls_priority); session->use_tls_sni = ac_prefs->use_tls_sni; - if (ac_prefs->use_smtp_auth && ac_prefs->smtp_auth_type == SMTPAUTH_OAUTH2) - oauth2_check_passwds(ac_prefs); if (ac_prefs->use_smtp_auth) { smtp_session->forced_auth_type = ac_prefs->smtp_auth_type; blob - c4a1e95c0975217900c16372e2825e5e5c4319d6 blob + 0aeae07d33c950a4977833b9f0894721ff00cdef --- src/setup.c +++ src/setup.c @@ -26,7 +26,6 @@ #include "mainwindow.h" #include "gtkutils.h" #include "mh.h" -#define SETUP_DIALOG_WIDTH 540 static void scan_tree_func(Folder *folder, FolderItem *item, gpointer data); blob - e5cee45cd72f92bcc60010a9142408060c4211bd blob + 2f01028c53307cdf4da3d7caa297a61d91450baf --- src/summaryview.c +++ src/summaryview.c @@ -67,7 +67,6 @@ #include "log.h" #include "manual.h" #include "manage_window.h" -#include "avatars.h" #define SUMMARY_COL_MARK_WIDTH 10 #define SUMMARY_COL_STATUS_WIDTH 13 @@ -4087,8 +4086,6 @@ void summary_add_address(SummaryView *summaryview) { MsgInfo *msginfo, *full_msginfo; gchar *from; - GdkPixbuf *picture = NULL; - AvatarRender *avatarr; msginfo = gtk_cmctree_node_get_row_data(GTK_CMCTREE(summaryview->ctree), summaryview->selected); @@ -4101,16 +4098,9 @@ void summary_add_address(SummaryView *summaryview) full_msginfo = procmsg_msginfo_get_full_info(msginfo); - avatarr = avatars_avatarrender_new(full_msginfo); - hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr); - procmsg_msginfo_free(&full_msginfo); - if (avatarr->image) - picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image)); - - addressbook_add_contact(msginfo->fromname, from, NULL, picture); - avatars_avatarrender_free(avatarr); + addressbook_add_contact(msginfo->fromname, from, NULL, NULL); } void summary_select_all(SummaryView *summaryview) blob - 0db9c31d8ceeb838d59a7b5672c45d0752a798ee blob + 701ad99e21e797b69271e888ad4526f641ead88f --- src/textview.c +++ src/textview.c @@ -53,7 +53,6 @@ #include "manage_window.h" #include "folder_item_prefs.h" #include "hooks.h" -#include "avatars.h" #include "file-utils.h" #include "fence.h" @@ -2335,9 +2334,6 @@ static void add_uri_to_addrbook_cb (GtkAction *action, gchar *fromname, *fromaddress; ClickableText *uri = g_object_get_data(G_OBJECT(textview->mail_popup_menu), "menu_button"); - AvatarRender *avatarr = NULL; - GdkPixbuf *picture = NULL; - gboolean use_picture = FALSE; if (uri == NULL) return; @@ -2345,27 +2341,11 @@ static void add_uri_to_addrbook_cb (GtkAction *action, /* extract url */ fromaddress = g_strdup(uri->uri + 7); - if (textview->messageview->msginfo && - !g_strcmp0(fromaddress, textview->messageview->msginfo->from)) - use_picture = TRUE; - fromname = procheader_get_fromname(fromaddress); extract_address(fromaddress); - if (use_picture) { - avatarr = avatars_avatarrender_new(textview->messageview->msginfo); - hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr); - } + addressbook_add_contact( fromname, fromaddress, NULL, NULL); - if (avatarr && avatarr->image) { - picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image)); - } - if (avatarr) { - avatars_avatarrender_free(avatarr); - } - - addressbook_add_contact( fromname, fromaddress, NULL, picture); - g_free(fromaddress); g_free(fromname); }