1 /**
2  * @file
3  * Certificate Verification Dialog
4  *
5  * @authors
6  * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /**
24  * @page conn_gui Certificate Verification Dialog
25  *
26  * The Certificate Verification Dialog lets the user check the details of a
27  * certificate.
28  *
29  * This is a @ref gui_simple
30  *
31  * ## Windows
32  *
33  * | Name                            | Type               | See Also                 |
34  * | :------------------------------ | :----------------- | :----------------------- |
35  * | Certificate Verification Dialog | WT_DLG_CERTIFICATE | dlg_verify_certificate() |
36  *
37  * **Parent**
38  * - @ref gui_dialog
39  *
40  * **Children**
41  * - See: @ref gui_simple
42  *
43  * ## Data
44  *
45  * None.
46  *
47  * ## Events
48  *
49  * None.  Once constructed, the events are handled by the Menu
50  * (part of the @ref gui_simple).
51  */
52 
53 #include "config.h"
54 #include <stdbool.h>
55 #include <stdio.h>
56 #include "mutt/lib.h"
57 #include "gui/lib.h"
58 #include "menu/lib.h"
59 #include "opcodes.h"
60 #include "options.h"
61 #include "ssl.h"
62 
63 #ifdef USE_SSL
64 /// Help Bar for the Certificate Verification dialog
65 static const struct Mapping VerifyHelp[] = {
66   // clang-format off
67   { N_("Exit"), OP_EXIT },
68   { N_("Help"), OP_HELP },
69   { NULL, 0 },
70   // clang-format on
71 };
72 #endif
73 
74 #ifdef USE_SSL
75 /**
76  * dlg_verify_certificate - Ask the user to validate the certificate
77  * @param title        Menu title
78  * @param list         Certificate text to display
79  * @param allow_always If true, allow the user to always accept the certificate
80  * @param allow_skip   If true, allow the user to skip the verification
81  * @retval 1 Reject certificate (or menu aborted)
82  * @retval 2 Accept certificate once
83  * @retval 3 Accept certificate always/skip (see notes)
84  * @retval 4 Accept certificate skip
85  *
86  * The possible retvals will depend on the parameters.
87  * The options are given in the order: Reject, Once, Always, Skip.
88  * The retval represents the chosen option.
89  */
dlg_verify_certificate(const char * title,struct ListHead * list,bool allow_always,bool allow_skip)90 int dlg_verify_certificate(const char *title, struct ListHead *list,
91                            bool allow_always, bool allow_skip)
92 {
93   struct MuttWindow *dlg = simple_dialog_new(MENU_GENERIC, WT_DLG_CERTIFICATE, VerifyHelp);
94 
95   struct Menu *menu = dlg->wdata;
96 
97   struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
98   sbar_set_title(sbar, title);
99 
100   struct ListNode *np = NULL;
101   STAILQ_FOREACH(np, list, entries)
102   {
103     menu_add_dialog_row(menu, NONULL(np->data));
104   }
105 
106   if (allow_always)
107   {
108     if (allow_skip)
109     {
110       menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always, (s)kip");
111       /* L10N: The letters correspond to the choices in the string:
112          "(r)eject, accept (o)nce, (a)ccept always, (s)kip"
113          This is an interactive certificate confirmation prompt for an SSL connection. */
114       menu->keys = _("roas");
115     }
116     else
117     {
118       menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always");
119       /* L10N: The letters correspond to the choices in the string:
120          "(r)eject, accept (o)nce, (a)ccept always"
121          This is an interactive certificate confirmation prompt for an SSL connection. */
122       menu->keys = _("roa");
123     }
124   }
125   else
126   {
127     if (allow_skip)
128     {
129       menu->prompt = _("(r)eject, accept (o)nce, (s)kip");
130       /* L10N: The letters correspond to the choices in the string:
131          "(r)eject, accept (o)nce, (s)kip"
132          This is an interactive certificate confirmation prompt for an SSL connection. */
133       menu->keys = _("ros");
134     }
135     else
136     {
137       menu->prompt = _("(r)eject, accept (o)nce");
138       /* L10N: The letters correspond to the choices in the string:
139          "(r)eject, accept (o)nce"
140          This is an interactive certificate confirmation prompt for an SSL connection. */
141       menu->keys = _("ro");
142     }
143   }
144 
145   bool old_ime = OptIgnoreMacroEvents;
146   OptIgnoreMacroEvents = true;
147 
148   int rc = 0;
149   while (rc == 0)
150   {
151     switch (menu_loop(menu))
152     {
153       case -1:         // Abort: Ctrl-G
154       case OP_EXIT:    // Q)uit
155       case OP_MAX + 1: // R)eject
156         rc = 1;
157         break;
158       case OP_MAX + 2: // O)nce
159         rc = 2;
160         break;
161       case OP_MAX + 3: // A)lways / S)kip
162         rc = 3;
163         break;
164       case OP_MAX + 4: // S)kip
165         rc = 4;
166         break;
167     }
168   }
169   OptIgnoreMacroEvents = old_ime;
170 
171   simple_dialog_free(&dlg);
172 
173   return rc;
174 }
175 #endif
176