commit - f2a22c54e626b8c1ebce3d6df117a35b076e163f
commit + 0b3e475621dfa6b22017095fb285c5087a1a096b
blob - 201fe7f8a5e1dc08ae486163983f69cd28e3a891 (mode 644)
blob + /dev/null
--- src/avatars.c
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#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
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __AVATARS_H__
-#define __AVATARS_H__
-
-#include <glib.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-#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
#include "main.h"
#include "passwordstore.h"
#include "file-utils.h"
-#include "oauth2.h"
typedef struct _IMAPFolder IMAPFolder;
typedef struct _IMAPSession IMAPSession;
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
#include "hooks.h"
#include "logwindow.h"
#include "passwordstore.h"
-#include "oauth2.h"
static GList *inc_dialog_list = NULL;
(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
#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
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ *
*/
#ifndef LOCALFOLDER_H
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
#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"
#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"
prefs_themes_init();
prefs_ext_prog_init();
- prefs_wrapping_init();
prefs_compose_writing_init();
prefs_summaries_init();
prefs_message_init();
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);
claws_register_idle_function(claws_gtk_idle);
- avatars_init();
prefs_toolbar_init();
num_folder_class = g_list_length(folder_get_list());
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
#include "version.h"
#include "statusbar.h"
#include "folder_item_prefs.h"
-#include "avatars.h"
#include "file-utils.h"
#include "addressbook.h"
MessageView *messageview = (MessageView *)data;
MsgInfo *msginfo, *full_msginfo;
gchar *from;
- GdkPixbuf *picture = NULL;
- AvatarRender *avatarr;
if (!messageview->msginfo || !messageview->msginfo->from)
return;
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
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
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "defs.h"
-#include <glib.h>
-#ifdef ENABLE_NLS
-#include <glib/gi18n.h>
-#else
-#define _(a) (a)
-#define N_(a) (a)
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#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
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef _OAUTH2_H_
-#define _OAUTH2_H_
-
-#include <glib.h>
-
-#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
#include "log.h"
#include "hooks.h"
#include "file-utils.h"
-#include "oauth2.h"
#include "defs.h"
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;
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);
}
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
#include "smtp.h"
#include "imap.h"
#include "pop.h"
-#include "oauth2.h"
#include "remotefolder.h"
#include "combobox.h"
#include "setup.h"
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;
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;
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;
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;
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);
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);
{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,
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)
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);
/* 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; */
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;
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;
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];
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();
}
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);
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);
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);
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)
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);
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);
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("<html><head><title>", title,
- "</title><meta charset=\"utf-8\"></head><body><h1>", title,
- "</h1><p>", body, "</p></body></html>", 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
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;
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;
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"));
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;
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),
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
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "defs.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-
-#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
-/*
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#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
#include "inc.h"
#include "log.h"
#include "passwordstore.h"
-#include "oauth2.h"
typedef struct _SendProgressDialog SendProgressDialog;
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
#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
#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
{
MsgInfo *msginfo, *full_msginfo;
gchar *from;
- GdkPixbuf *picture = NULL;
- AvatarRender *avatarr;
msginfo = gtk_cmctree_node_get_row_data(GTK_CMCTREE(summaryview->ctree),
summaryview->selected);
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
#include "manage_window.h"
#include "folder_item_prefs.h"
#include "hooks.h"
-#include "avatars.h"
#include "file-utils.h"
#include "fence.h"
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;
/* 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);
}