NetSurf
sslcert.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.co.uk>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * \file
21  * Implementation of Amiga certificate viewing using core windows.
22  */
23 
24 #include <stdint.h>
25 #include <stdlib.h>
26 
27 #include <proto/intuition.h>
28 
29 #include <classes/window.h>
30 #include <gadgets/button.h>
31 #include <gadgets/layout.h>
32 #include <gadgets/scroller.h>
33 #include <gadgets/space.h>
34 #include <images/label.h>
35 
36 #include <intuition/icclass.h>
37 #include <reaction/reaction_macros.h>
38 
39 #include "utils/log.h"
40 #include "netsurf/keypress.h"
41 #include "netsurf/plotters.h"
42 #include "desktop/sslcert_viewer.h"
43 #include "utils/messages.h"
44 #include "utils/nsoption.h"
45 
46 #include "amiga/corewindow.h"
47 #include "amiga/libs.h"
48 #include "amiga/sslcert.h"
49 #include "amiga/utf8.h"
50 
51 
52 /**
53  * Amiga certificate viewing window context
54  */
55 enum {
59 };
60 
61 #define GID_SSLCERT_SIZE GID_SSLCERT_LAST - GID_CW_LAST
62 
64  /** Amiga core window context */
66 
67  /** Amiga GUI stuff */
68  Object *sslcert_objects[GID_SSLCERT_LAST]; // technically wasting a few bytes here
69 
70  char *sslerr;
71  char *sslaccept;
72  char *sslreject;
73 
74  /** SSL certificate viewer context data */
76 };
77 
78 /**
79  * destroy a previously created certificate view
80  */
81 static nserror
83 {
84  nserror res;
85 
86  res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
87  if (res == NSERROR_OK) {
88  ami_utf8_free(crtvrfy_win->sslerr);
89  ami_utf8_free(crtvrfy_win->sslaccept);
90  ami_utf8_free(crtvrfy_win->sslreject);
91  res = ami_corewindow_fini(&crtvrfy_win->core); /* closes the window for us */
92  }
93  return res;
94 }
95 
96 static void
98 {
99  struct ami_crtvrfy_window *crtvrfy_win;
100  /* technically degenerate container of */
101  crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
102 
103  sslcert_viewer_accept(crtvrfy_win->ssl_data);
104 
105  ami_crtvrfy_destroy(crtvrfy_win);
106 }
107 
108 static void
110 {
111  struct ami_crtvrfy_window *crtvrfy_win;
112  /* technically degenerate container of */
113  crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
114 
115  sslcert_viewer_reject(crtvrfy_win->ssl_data);
116 
117  ami_crtvrfy_destroy(crtvrfy_win);
118 }
119 
120 /**
121  * callback for unknown events on Amiga core window
122  * eg. buttons in the ssl cert window
123  * (result & WMHI_CLASSMASK) gives the class of event (eg. WMHI_GADGETUP)
124  * (result & WMHI_GADGETMASK) gives the gadget ID (eg. GID_SSLCERT_ACCEPT)
125  *
126  * \param ami_cw The Amiga core window structure.
127  * \param result event as returned by RA_HandleInput()
128  * \return TRUE if window closed during event processing
129  */
130 static BOOL
132 {
133  if((result & WMHI_CLASSMASK) == WMHI_GADGETUP) {
134  switch(result & WMHI_GADGETMASK) {
135  case GID_SSLCERT_ACCEPT:
136  ami_crtvrfy_accept(ami_cw);
137  return TRUE;
138  break;
139 
140  case GID_SSLCERT_REJECT:
141  ami_crtvrfy_reject(ami_cw);
142  return TRUE;
143  break;
144  }
145  }
146  return FALSE;
147 }
148 
149 /**
150  * callback for mouse action for certificate verify on core window
151  *
152  * \param ami_cw The Amiga core window structure.
153  * \param mouse_state netsurf mouse state on event
154  * \param x location of event
155  * \param y location of event
156  * \return NSERROR_OK on success otherwise apropriate error code
157  */
158 static nserror
160  browser_mouse_state mouse_state,
161  int x, int y)
162 {
163  struct ami_crtvrfy_window *crtvrfy_win;
164  /* technically degenerate container of */
165  crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
166 
167  sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
168 
169  return NSERROR_OK;
170 }
171 
172 /**
173  * callback for keypress for certificate verify on core window
174  *
175  * \param ami_cw The Amiga core window structure.
176  * \param nskey The netsurf key code
177  * \return NSERROR_OK on success otherwise apropriate error code
178  */
179 static nserror
180 ami_crtvrfy_key(struct ami_corewindow *ami_cw, uint32_t nskey)
181 {
182  struct ami_crtvrfy_window *crtvrfy_win;
183 
184  /* technically degenerate container of */
185  crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
186 
187  if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
188  return NSERROR_OK;
189  }
191 }
192 
193 /**
194  * callback on draw event for certificate verify on core window
195  *
196  * \param ami_cw The Amiga core window structure.
197  * \param x the x coordinate to draw
198  * \param y the y coordinate to draw
199  * \param r The rectangle of the window that needs updating.
200  * \param ctx The drawing context
201  * \return NSERROR_OK on success otherwise apropriate error code
202  */
203 static nserror
204 ami_crtvrfy_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
205 {
206  struct ami_crtvrfy_window *crtvrfy_win;
207 
208  /* technically degenerate container of */
209  crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
210 
211  sslcert_viewer_redraw(crtvrfy_win->ssl_data, x, y, r, ctx);
212 
213  return NSERROR_OK;
214 }
215 
216 static nserror
218 {
219  struct ami_corewindow *ami_cw = (struct ami_corewindow *)&crtvrfy_win->core;
220  ULONG refresh_mode = WA_SmartRefresh;
221  struct Screen *scrn = ami_gui_get_screen();
222 
223  if(nsoption_bool(window_simple_refresh) == true) {
224  refresh_mode = WA_SimpleRefresh;
225  }
226 
227  ami_cw->objects[GID_CW_WIN] = WindowObj,
228  WA_ScreenTitle, ami_gui_get_screen_title(),
229  WA_Title, ami_cw->wintitle,
230  WA_Activate, TRUE,
231  WA_DepthGadget, TRUE,
232  WA_DragBar, TRUE,
233  WA_CloseGadget, FALSE,
234  WA_SizeGadget, TRUE,
235  WA_SizeBBottom, TRUE,
236  WA_Height, scrn->Height / 2,
237  WA_PubScreen, scrn,
238  WA_ReportMouse, TRUE,
239  refresh_mode, TRUE,
240  WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
241  IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
242  IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
243  WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
244  WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE |
245  IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
246  WINDOW_SharedPort, ami_gui_get_shared_msgport(),
247  WINDOW_UserData, crtvrfy_win,
248  /* WINDOW_NewMenu, twin->menu, -> No menu for SSL Cert */
249  WINDOW_IconifyGadget, FALSE,
250  WINDOW_Position, WPOS_CENTERSCREEN,
251  WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
252  LAYOUT_AddImage, LabelObj,
253  LABEL_Text, crtvrfy_win->sslerr,
254  LabelEnd,
255  LAYOUT_AddChild, ami_cw->objects[GID_CW_HSCROLLLAYOUT] = LayoutVObj,
256  LAYOUT_AddChild, ami_cw->objects[GID_CW_VSCROLLLAYOUT] = LayoutHObj,
257  LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
258  GA_ID, GID_CW_DRAW,
259  SPACE_Transparent, TRUE,
260  SPACE_BevelStyle, BVS_DISPLAY,
261  GA_RelVerify, TRUE,
262  SpaceEnd,
263  LAYOUT_AddChild, ami_cw->objects[GID_CW_VSCROLL] = ScrollerObj,
264  GA_ID, GID_CW_VSCROLL,
265  GA_RelVerify, TRUE,
266  ICA_TARGET, ICTARGET_IDCMP,
267  ScrollerEnd,
268  LayoutEnd,
269  LAYOUT_AddChild, ami_cw->objects[GID_CW_HSCROLL] = ScrollerObj,
270  GA_ID, GID_CW_HSCROLL,
271  GA_RelVerify, TRUE,
272  ICA_TARGET, ICTARGET_IDCMP,
273  SCROLLER_Orientation, SORIENT_HORIZ,
274  ScrollerEnd,
275  LayoutEnd,
276  LAYOUT_AddChild, LayoutHObj,
277  LAYOUT_AddChild, crtvrfy_win->sslcert_objects[GID_SSLCERT_ACCEPT] = ButtonObj,
278  GA_ID, GID_SSLCERT_ACCEPT,
279  GA_Text, crtvrfy_win->sslaccept,
280  GA_RelVerify, TRUE,
281  ButtonEnd,
282  LAYOUT_AddChild, crtvrfy_win->sslcert_objects[GID_SSLCERT_REJECT] = ButtonObj,
283  GA_ID, GID_SSLCERT_REJECT,
284  GA_Text, crtvrfy_win->sslreject,
285  GA_RelVerify, TRUE,
286  ButtonEnd,
287  EndGroup,
288  CHILD_WeightedHeight, 0,
289  EndGroup,
290  EndWindow;
291 
292  if(ami_cw->objects[GID_CW_WIN] == NULL) {
293  return NSERROR_NOMEM;
294  }
295 
296  return NSERROR_OK;
297 }
298 
299 /* exported interface documented in amiga/ssl_cert.h */
301  const struct cert_chain *chain,
302  nserror (*cb)(bool proceed, void *pw),
303  void *cbpw)
304 {
305  struct ami_crtvrfy_window *ncwin;
306  nserror res;
307 
308  ncwin = calloc(1, sizeof(struct ami_crtvrfy_window));
309  if (ncwin == NULL) {
310  return NSERROR_NOMEM;
311  }
312 
313  ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("SSLCerts"));
314  ncwin->sslerr = ami_utf8_easy((char *)messages_get("SSLError"));
315  ncwin->sslaccept = ami_utf8_easy((char *)messages_get("SSL_Certificate_Accept"));
316  ncwin->sslreject = ami_utf8_easy((char *)messages_get("SSL_Certificate_Reject"));
317 
318  res = ami_crtvrfy_create_window(ncwin);
319  if (res != NSERROR_OK) {
320  NSLOG(netsurf, INFO, "SSL UI builder init failed");
321  ami_utf8_free(ncwin->core.wintitle);
322  ami_utf8_free(ncwin->sslerr);
323  ami_utf8_free(ncwin->sslaccept);
324  ami_utf8_free(ncwin->sslreject);
325  free(ncwin);
326  return res;
327  }
328 
329  /* initialise Amiga core window */
330  ncwin->core.draw = ami_crtvrfy_draw;
331  ncwin->core.key = ami_crtvrfy_key;
332  ncwin->core.mouse = ami_crtvrfy_mouse;
333  ncwin->core.close = ami_crtvrfy_reject;
334  ncwin->core.event = ami_crtvrfy_event;
335 
336  res = ami_corewindow_init(&ncwin->core);
337  if (res != NSERROR_OK) {
338  ami_utf8_free(ncwin->core.wintitle);
339  ami_utf8_free(ncwin->sslerr);
340  ami_utf8_free(ncwin->sslaccept);
341  ami_utf8_free(ncwin->sslreject);
342  DisposeObject(ncwin->core.objects[GID_CW_WIN]);
343  free(ncwin);
344  return res;
345  }
346 
347  /* initialise certificate viewing interface */
348  res = sslcert_viewer_create_session_data(url, cb, cbpw, chain, &ncwin->ssl_data);
349  if (res != NSERROR_OK) {
350  ami_utf8_free(ncwin->core.wintitle);
351  ami_utf8_free(ncwin->sslerr);
352  ami_utf8_free(ncwin->sslaccept);
353  ami_utf8_free(ncwin->sslreject);
354  DisposeObject(ncwin->core.objects[GID_CW_WIN]);
355  free(ncwin);
356  return res;
357  }
358 
359  res = sslcert_viewer_init(ncwin->core.cb_table,
360  (struct core_window *)ncwin,
361  ncwin->ssl_data);
362  if (res != NSERROR_OK) {
363  ami_utf8_free(ncwin->core.wintitle);
364  ami_utf8_free(ncwin->sslerr);
365  ami_utf8_free(ncwin->sslaccept);
366  ami_utf8_free(ncwin->sslreject);
367  DisposeObject(ncwin->core.objects[GID_CW_WIN]);
368  free(ncwin);
369  return res;
370  }
371 
372  return NSERROR_OK;
373 }
374 
Target independent plotting interface.
nserror sslcert_viewer_create_session_data(struct nsurl *url, nserror(*cb)(bool proceed, void *pw), void *cbpw, const struct cert_chain *chain, struct sslcert_session_data **ssl_d)
Create ssl certificate viewer session data.
char * ami_utf8_easy(const char *string)
Definition: utf8.c:55
#define ButtonObj
Definition: libs.h:54
struct ami_corewindow core
Amiga core window context.
Definition: sslcert.c:65
STATIC char result[100]
Definition: arexx.c:77
struct core_window_callback_table * cb_table
table of callbacks for core window operations
Definition: corewindow.h:86
browser_mouse_state
Mouse state.
Definition: mouse.h:43
Functionality is not implemented.
Definition: errors.h:61
Localised message support (interface).
#define WindowObj
Definition: libs.h:77
nserror sslcert_viewer_accept(struct sslcert_session_data *ssl_d)
Accept a certificate chain.
Memory exhaustion.
Definition: errors.h:32
static struct Screen * scrn
Definition: gui.c:326
#define BVS_DISPLAY
Definition: os3support.h:120
#define IDCMP_EXTENDEDMOUSE
Definition: os3support.h:121
STRPTR ami_gui_get_screen_title(void)
Get the string for NetSurf&#39;s screen titlebar.
Definition: gui.c:974
Object * sslcert_objects[GID_SSLCERT_LAST]
Amiga GUI stuff.
Definition: sslcert.c:68
void(* close)(struct ami_corewindow *ami_cw)
callback to close an Amiga core window
Definition: corewindow.h:165
void sslcert_viewer_redraw(struct sslcert_session_data *ssl_d, int x, int y, struct rect *clip, const struct redraw_context *ctx)
Redraw the ssl certificate viewer.
static void ami_crtvrfy_accept(struct ami_corewindow *ami_cw)
Definition: sslcert.c:97
static nserror ami_crtvrfy_mouse(struct ami_corewindow *ami_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse action for certificate verify on core window
Definition: sslcert.c:159
void ami_utf8_free(char *ptr)
Definition: utf8.c:50
Interface to key press operations.
bool sslcert_viewer_keypress(struct sslcert_session_data *ssl_d, uint32_t key)
Key press handling.
Option reading and saving interface.
struct Screen * ami_gui_get_screen(void)
Get a pointer to the screen NetSurf is running on.
Definition: gui.c:403
nserror sslcert_viewer_init(struct core_window_callback_table *cw_t, void *core_window_handle, struct sslcert_session_data *ssl_d)
Initialise a ssl certificate viewer from session data.
nserror
Enumeration of error codes.
Definition: errors.h:29
nserror(* key)(struct ami_corewindow *ami_cw, uint32_t nskey)
callback for keypress on Amiga core window
Definition: corewindow.h:110
nserror(* draw)(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
callback to draw on drawable area of Amiga core window
Definition: corewindow.h:98
struct Hook idcmp_hook
Definition: corewindow.h:54
nserror ami_corewindow_init(struct ami_corewindow *ami_cw)
initialise elements of Amiga core window.
Definition: corewindow.c:926
No error.
Definition: errors.h:30
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
static nserror ami_crtvrfy_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
callback on draw event for certificate verify on core window
Definition: sslcert.c:204
#define ScrollerObj
Definition: libs.h:73
nserror(* mouse)(struct ami_corewindow *ami_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on Amiga core window
Definition: corewindow.h:121
Amiga core window state.
Definition: corewindow.h:45
SSL Certificate verification UI interface.
#define LabelObj
Definition: libs.h:63
nserror sslcert_viewer_fini(struct sslcert_session_data *ssl_d)
Finalise a ssl certificate viewer.
X509 certificate chain.
Definition: ssl_certs.h:59
static BOOL ami_crtvrfy_event(struct ami_corewindow *ami_cw, ULONG result)
callback for unknown events on Amiga core window eg.
Definition: sslcert.c:131
Redraw context.
Definition: plotters.h:51
char * sslaccept
Definition: sslcert.c:71
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
nserror ami_cert_verify(struct nsurl *url, const struct cert_chain *chain, nserror(*cb)(bool proceed, void *pw), void *cbpw)
Prompt the user to verify a certificate with issues.
Definition: sslcert.c:300
struct sslcert_session_data * ssl_data
SSL certificate viewer context data.
Definition: sslcert.c:75
static nserror ami_crtvrfy_key(struct ami_corewindow *ami_cw, uint32_t nskey)
callback for keypress for certificate verify on core window
Definition: sslcert.c:180
Rectangle coordinates.
Definition: types.h:40
#define LayoutVObj
Definition: libs.h:65
#define LayoutHObj
Definition: libs.h:64
#define SpaceObj
Definition: libs.h:74
static void ami_crtvrfy_reject(struct ami_corewindow *ami_cw)
Definition: sslcert.c:109
nserror sslcert_viewer_reject(struct sslcert_session_data *ssl_d)
Reject a certificate chain.
ssl certificate verification context.
static nserror ami_crtvrfy_create_window(struct ami_crtvrfy_window *crtvrfy_win)
Definition: sslcert.c:217
nserror ami_corewindow_fini(struct ami_corewindow *ami_cw)
finalise elements of Amiga core window.
Definition: corewindow.c:986
Object * objects[GID_CW_LAST]
Definition: corewindow.h:52
void sslcert_viewer_mouse_action(struct sslcert_session_data *ssl_d, browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
char * sslreject
Definition: sslcert.c:72
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
static nserror ami_crtvrfy_destroy(struct ami_crtvrfy_window *crtvrfy_win)
destroy a previously created certificate view
Definition: sslcert.c:82
char * wintitle
window title, must be allocated wth ami_utf8 function
Definition: corewindow.h:76
BOOL(* event)(struct ami_corewindow *ami_cw, ULONG result)
callback for unknown events on Amiga core window eg.
Definition: corewindow.h:133
struct MsgPort * ami_gui_get_shared_msgport(void)
Get shared message port.