Commit 83512cdbe6eabfe2ffb163b11e6288426325bb11

Authored by David RENÉ
1 parent 0eadd7a3

update the read (according to current xlib and remove unneeded read (http_server…

….anubis, html.anubis)
Showing 1 changed file with 390 additions and 390 deletions   Show diff stats
web/CXM_https_get.anubis
1 -  
2 - *Project* The Anubis Project  
3 -  
4 - *Title* Getting a document from the secured Web.  
5 -  
6 - *Copyright* Copyright (c) Alain Prouté 2001.  
7 -  
8 -  
9 - *Author* Alain Prouté  
10 -  
11 -  
12 - *Overview*  
13 - This file defines the function 'https_get' which retrieve a document from the world  
14 - wide web in secured mode (HTTPS). The function is analogous to 'http_get', to be found  
15 - in 'web/http_get.anubis'.  
16 -  
17 - The function simulates the behavior of a browser, at least just what is needed to  
18 - retrieve the document. It does not display the document, but returns it (if found) in  
19 - the form of a string.  
20 -  
21 - The function 'https_get' takes the following operands:  
22 -  
23 - - the name of the server to which the request is to be sent,  
24 - - the name (including the path) of the document on this server,  
25 - - a list of headers to be added to mandatory standard headers,  
26 - - a list of 'arguments' to be sent as the body of the request (web arguments).  
27 - - an accept policy function (see below), for accepting X.509 certificates in case of  
28 - a problem.  
29 -  
30 - The result returned by 'https_get' has the following type, which defines the problems  
31 - which may happen:  
32 -  
33 -  
34 -read tools/basis.anubis  
35 -read system/string.anubis  
36 -read html.anubis  
37 -read http_get_common.anubis  
38 -read http_server.anubis  
39 -read common.anubis  
40 -  
41 -  
42 -public type HTTPS_GET_Result:  
43 - cannot_resolve_server_name(DNS_Result),  
44 - ssl_connect_error(SSLConnectError),  
45 - transmission_problem,  
46 - request_refused_by_server,  
47 - ok(String response,  
48 - List(HTTP_header) headers,  
49 - String document).  
50 -  
51 - Cookies are among headers. See 'web/cookies.anubis' for cookies handling.  
52 -  
53 -  
54 - Note: The types 'DNS_Result' and 'SSLConnectError' are defined in 'predefined.anubis'.  
55 -  
56 -public define HTTPS_GET_Result  
57 - https_get  
58 - (  
59 - String server_name,  
60 - String document_name,  
61 - List(HTTP_header) headers,  
62 - List(HTTP_argument) arguments,  
63 - (Maybe(X509)) -> Bool accept_policy  
64 - ).  
65 -  
66 - The same one without the 'headers' argument:  
67 -  
68 -public define HTTPS_GET_Result  
69 - https_get  
70 - (  
71 - String server_name,  
72 - String document_name,  
73 - List(HTTP_argument) arguments,  
74 - (Maybe(X509)) -> Bool accept_policy  
75 - ) = https_get(server_name,document_name,[],arguments,accept_policy).  
76 -  
77 - The main difference with 'http_get' is the presence of the 'accept_policy'  
78 - argument. 'accept_policy' is the function which determines your personal policy for  
79 - accepting a server certificate, if it is the case that either this certificate is  
80 - invalid (or missing), or if its common name does not match the server name, that is to  
81 - say if 'open_SSL_connection' (defined in 'predefined.anubis') did not already accept  
82 - it.  
83 -  
84 - 'X509' is an 'opaque' type defined in 'predefined.anubis'. It is 'opaque' in the sens  
85 - that no alternative of this type is directly accessible to you (despite the fact that  
86 - the type is public).  
87 -  
88 - An accept policy function takes (maybe) an X.509 certificate as its unique argument, so  
89 - that the decision may be taken with the suspect certificate at hand. It must return  
90 - 'true' for accepting, and 'false' for refusing.  
91 -  
92 - You may use the following default accept policy function:  
93 -  
94 -public define Bool  
95 - default_accept_policy  
96 - (  
97 - Maybe(X509) suspect_certificate  
98 - ) = false.  
99 -  
100 - That is, never accept a certificate which cannot be successfully verified by  
101 - 'open_SSL_connection'. Notice that this is not a paranoid behavior, but a normal  
102 - behavior. Nevertheless, you still have the possibility to weaken this behavior by  
103 - using another accept policy function. Be very careful when writing this function,  
104 - because this may weaken your security. This function may for example show the  
105 - certificate and ask for user input for accepting it. It may also check the certificate  
106 - fingerprint against a data base, etc...  
107 -  
108 - Another accept policy function is defined in this file:  
109 -  
110 -public define Bool  
111 - command_line_accept_policy  
112 - (  
113 - Maybe(X509) suspect_certificate  
114 - ).  
115 -  
116 - It is used by the command line module 'https_get.adm'. If the certificate is not  
117 - accepted by 'open_SSL_connection', this function prints the certificate on the screen,  
118 - and ask the user for acceptation. It also asks the user for accepting the certificate  
119 - for ever.  
120 -  
121 - It is likely that you will need an accept policy function of your own. See the  
122 - definition of 'command_line_accept_policy' below for information and  
123 - 'predefined.anubis' for the tools enabling the manipulation of X.509 certificates.  
124 - Certificates that you trust are stored into the directory declared under the symbol  
125 - 'ca' (for 'Certificate Authorities') in your configuration file. Any certificate  
126 - present in this directory is trusted without any condition.  
127 -  
128 - This file defines the module 'https_get' to be used directly from the command line. To  
129 - learn about the syntax, just type 'https_get' at the system prompt, or have a look at  
130 - the end of this file.  
131 -  
132 -  
133 -  
134 -  
135 - --- That's all for public definitions. ------------------------------------------------  
136 -  
137 -  
138 -  
139 -  
140 -  
141 -  
142 -  
143 -  
144 -define Maybe(String)  
145 - receive_text_chunk  
146 - (  
147 - SSL_Connection conn  
148 - ) =  
149 - read(conn,100,1000).  
150 -  
151 -  
152 -  
153 -  
154 -define HTTPS_GET_Result  
155 - receive  
156 - (  
157 - SSL_Connection conn,  
158 - String headers,  
159 - String text_so_far,  
160 - Bool double_crlf_seen  
161 - ) =  
162 - if receive_text_chunk(conn) is  
163 - {  
164 - failure then if separate_headers(headers) is  
165 - {  
166 - [ ] then ok("",[],text_so_far),  
167 - [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far)  
168 - },  
169 -  
170 - success(s) then  
171 - if s = ""  
172 - then if separate_headers(headers) is  
173 - {  
174 - [ ] then ok("",[],text_so_far),  
175 - [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far)  
176 - }  
177 - else with new_s = text_so_far+s,  
178 - if double_crlf_seen  
179 - then receive(conn,headers,new_s,true)  
180 - else if has_double_crlf(new_s) is  
181 - {  
182 - failure then receive(conn,headers,new_s,false),  
183 - success(n) then  
184 - if sub_string(new_s,n+4,length(new_s)-n-4) is  
185 - {  
186 - failure then alert,  
187 - success(s1) then  
188 - if sub_string(new_s,0,n) is  
189 - {  
190 - failure then alert,  
191 - success(h) then receive(conn,h,s1,true)  
192 - }  
193 - }  
194 - }  
195 - }.  
196 -  
197 -  
198 -  
199 - The next function has a valid SSL connection to the server, and tries to retrieve the  
200 - document.  
201 -  
202 -define HTTPS_GET_Result  
203 - https_get  
204 - (  
205 - Bool print_all,  
206 - SSL_Connection conn,  
207 - String server_name,  
208 - String document_name,  
209 - List(HTTP_header) headers,  
210 - List(HTTP_argument) arguments  
211 - ) =  
212 - //  
213 - // Send the HTTP request, and receive the answer:  
214 - //  
215 - with body = format_http_args(arguments),  
216 - with request = (if arguments = [] then "GET " else "POST ")  
217 - + document_name + " HTTP/1.0" + crlf +  
218 - "Host: " + server_name + crlf +  
219 - "Accept-Charset: iso-8859-1,*,utf-8" + crlf +  
220 - (if arguments = [] then ""  
221 - else "Content-type: application/x-www-form-urlencoded" + crlf +  
222 - "Content-length: " + to_decimal(length(body))+ crlf) +  
223 - format_headers(headers) +  
224 - crlf +  
225 - body,  
226 - (if print_all then  
227 - (  
228 - print("Sending request:\n");  
229 - print(request);  
230 - print("\n")  
231 - ) else unique);  
232 - if write(conn,request) is  
233 - {  
234 - failure then transmission_problem,  
235 - success(_) then receive(conn,"","",false)  
236 - }.  
237 -  
238 -  
239 - The next function retrieves the document using the numerical (resolved) server address.  
240 -  
241 -define HTTPS_GET_Result  
242 - https_get  
243 - (  
244 - Bool print_all,  
245 - Word32 server_addr,  
246 - Word32 server_port,  
247 - String server_name,  
248 - String document_name,  
249 - List(HTTP_header) headers,  
250 - List(HTTP_argument) arguments,  
251 - (Maybe(X509)) -> Bool accept_policy  
252 - ) =  
253 - if open_SSL_connection(server_name,server_addr,server_port,accept_policy) is  
254 - {  
255 - error(msg) then ssl_connect_error(msg),  
256 - ok(conn) then https_get(print_all,conn,server_name,document_name,headers,arguments)  
257 - }.  
258 -  
259 -  
260 -  
261 -define HTTPS_GET_Result  
262 - https_get  
263 - (  
264 - Bool print_all,  
265 - String server_name,  
266 - String document_name,  
267 - List(HTTP_header) headers,  
268 - List(HTTP_argument) arguments,  
269 - (Maybe(X509)) -> Bool accept_policy  
270 - ) =  
271 - if separate_name_port(server_name,443) is (name,port) then  
272 - //  
273 - // resolve server name and call 'https_get' with numeric server address:  
274 - //  
275 - with a = dns(name),  
276 - if a is ok(addr)  
277 - then https_get(print_all,addr,port,name,document_name,headers,arguments,accept_policy)  
278 - else cannot_resolve_server_name(a).  
279 -  
280 -  
281 -  
282 - Now, here is our public tool:  
283 -  
284 -public define HTTPS_GET_Result  
285 - https_get  
286 - (  
287 - String server_name,  
288 - String document_name,  
289 - List(HTTP_header) headers,  
290 - List(HTTP_argument) arguments,  
291 - (Maybe(X509)) -> Bool accept_policy  
292 - ) = https_get(false,server_name,document_name,headers,arguments,accept_policy).  
293 -  
294 -  
295 -  
296 -  
297 -  
298 - Finally, we construct the command line executable module 'https_get.adm':  
299 -  
300 -define One  
301 - syntax_https_get =  
302 - print("\nUsage: https_get <server> <document> [options] =<header> <value> ... <arg> <value> ...\n");  
303 - print(" Options are:\n");  
304 - print(" -print_all print request, response line, headers and document\n");  
305 - print(" (default is to print only the document)\n").  
306 -  
307 -  
308 -  
309 -  
310 - Below is our accept policy function for the command line module. This function may  
311 - serve as a model for your own accept policy function.  
312 -  
313 -public define Bool  
314 - command_line_accept_policy  
315 - (  
316 - Maybe(X509) mbcert  
317 - ) =  
318 - if mbcert is  
319 - {  
320 - failure then  
321 - print("No server certificate or invalid server certificate.\n");  
322 - print("Do you want to trust this site anyway ? [Y/N]\n");  
323 - yes, // this is the same as 'if yes then true else false'  
324 -  
325 - success(cert) then  
326 - print(to_string(cert));  
327 - print("\nDo you want to accept the above certificate ? [Y/N]\n");  
328 - if yes  
329 - then (  
330 - print("Do you want to accept this certificate for ever ? [Y/N]\n");  
331 - if yes  
332 - then (if trust_for_ever(cert) is  
333 - {  
334 - ca_directory_not_found then print("'ca' directory not found.\n"),  
335 - cannot_create_file then print("cannot create file.\n"),  
336 - cannot_create_symbolic_link then print("cannot create symbolic link.\n"),  
337 - write_error then print("write error.\n"),  
338 - ok then unique  
339 - }; true)  
340 - else true  
341 - )  
342 - else false  
343 - }.  
344 -  
345 -  
346 -global define One  
347 - https_get  
348 - (  
349 - List(String) args  
350 - ) =  
351 - if args is  
352 - {  
353 - [ ] then syntax_https_get,  
354 - [server . t] then if t is  
355 - {  
356 - [ ] then syntax_https_get,  
357 - [document . rest] then  
358 - with print_all = member(rest,"-print_all"),  
359 - headers = get_headers(rest),  
360 - arguments = get_arguments(rest),  
361 - if https_get(print_all,server,document,headers,arguments,command_line_accept_policy) is  
362 - {  
363 - cannot_resolve_server_name(dns_error) then  
364 - print("Cannot resolve server name: " + format(dns_error) + ".\n"),  
365 -  
366 - ssl_connect_error(connect_error) then  
367 - print("SSL connect error: " + format(connect_error) + ".\n"),  
368 -  
369 - transmission_problem then  
370 - print("Transmission problem.\n"),  
371 -  
372 - request_refused_by_server then  
373 - print("The request has been refused by server: " + server + ".\n"),  
374 -  
375 - ok(response,headers1,document1) then  
376 - (  
377 - if print_all  
378 - then (  
379 - print("\n----- response ----\n");  
380 - print(response);  
381 - print("\n----- headers -----\n");  
382 - print_headers(headers1);  
383 - print("----- document ----\n")  
384 - ) else unique  
385 - );  
386 - print(document1) // on the screen (use a redirection to get it in a file)  
387 - }  
388 - }  
389 - }.  
390 - 1 +
  2 + *Project* The Anubis Project
  3 +
  4 + *Title* Getting a document from the secured Web.
  5 +
  6 + *Copyright* Copyright (c) Alain Prouté 2001.
  7 +
  8 +
  9 + *Author* Alain Prouté
  10 +
  11 +
  12 + *Overview*
  13 + This file defines the function 'https_get' which retrieve a document from the world
  14 + wide web in secured mode (HTTPS). The function is analogous to 'http_get', to be found
  15 + in 'web/http_get.anubis'.
  16 +
  17 + The function simulates the behavior of a browser, at least just what is needed to
  18 + retrieve the document. It does not display the document, but returns it (if found) in
  19 + the form of a string.
  20 +
  21 + The function 'https_get' takes the following operands:
  22 +
  23 + - the name of the server to which the request is to be sent,
  24 + - the name (including the path) of the document on this server,
  25 + - a list of headers to be added to mandatory standard headers,
  26 + - a list of 'arguments' to be sent as the body of the request (web arguments).
  27 + - an accept policy function (see below), for accepting X.509 certificates in case of
  28 + a problem.
  29 +
  30 + The result returned by 'https_get' has the following type, which defines the problems
  31 + which may happen:
  32 +
  33 +
  34 +read tools/basis.anubis
  35 +read system/string.anubis
  36 +//read html.anubis
  37 +read CXM_http_get_common.anubis
  38 +//read http_server.anubis
  39 +read CXM_common.anubis
  40 +
  41 +
  42 +public type HTTPS_GET_Result:
  43 + cannot_resolve_server_name(DNS_Result),
  44 + ssl_connect_error(SSLConnectError),
  45 + transmission_problem,
  46 + request_refused_by_server,
  47 + ok(String response,
  48 + List(HTTP_header) headers,
  49 + String document).
  50 +
  51 + Cookies are among headers. See 'web/cookies.anubis' for cookies handling.
  52 +
  53 +
  54 + Note: The types 'DNS_Result' and 'SSLConnectError' are defined in 'predefined.anubis'.
  55 +
  56 +public define HTTPS_GET_Result
  57 + https_get
  58 + (
  59 + String server_name,
  60 + String document_name,
  61 + List(HTTP_header) headers,
  62 + List(HTTP_argument) arguments,
  63 + (Maybe(X509)) -> Bool accept_policy
  64 + ).
  65 +
  66 + The same one without the 'headers' argument:
  67 +
  68 +public define HTTPS_GET_Result
  69 + https_get
  70 + (
  71 + String server_name,
  72 + String document_name,
  73 + List(HTTP_argument) arguments,
  74 + (Maybe(X509)) -> Bool accept_policy
  75 + ) = https_get(server_name,document_name,[],arguments,accept_policy).
  76 +
  77 + The main difference with 'http_get' is the presence of the 'accept_policy'
  78 + argument. 'accept_policy' is the function which determines your personal policy for
  79 + accepting a server certificate, if it is the case that either this certificate is
  80 + invalid (or missing), or if its common name does not match the server name, that is to
  81 + say if 'open_SSL_connection' (defined in 'predefined.anubis') did not already accept
  82 + it.
  83 +
  84 + 'X509' is an 'opaque' type defined in 'predefined.anubis'. It is 'opaque' in the sens
  85 + that no alternative of this type is directly accessible to you (despite the fact that
  86 + the type is public).
  87 +
  88 + An accept policy function takes (maybe) an X.509 certificate as its unique argument, so
  89 + that the decision may be taken with the suspect certificate at hand. It must return
  90 + 'true' for accepting, and 'false' for refusing.
  91 +
  92 + You may use the following default accept policy function:
  93 +
  94 +public define Bool
  95 + default_accept_policy
  96 + (
  97 + Maybe(X509) suspect_certificate
  98 + ) = false.
  99 +
  100 + That is, never accept a certificate which cannot be successfully verified by
  101 + 'open_SSL_connection'. Notice that this is not a paranoid behavior, but a normal
  102 + behavior. Nevertheless, you still have the possibility to weaken this behavior by
  103 + using another accept policy function. Be very careful when writing this function,
  104 + because this may weaken your security. This function may for example show the
  105 + certificate and ask for user input for accepting it. It may also check the certificate
  106 + fingerprint against a data base, etc...
  107 +
  108 + Another accept policy function is defined in this file:
  109 +
  110 +public define Bool
  111 + command_line_accept_policy
  112 + (
  113 + Maybe(X509) suspect_certificate
  114 + ).
  115 +
  116 + It is used by the command line module 'https_get.adm'. If the certificate is not
  117 + accepted by 'open_SSL_connection', this function prints the certificate on the screen,
  118 + and ask the user for acceptation. It also asks the user for accepting the certificate
  119 + for ever.
  120 +
  121 + It is likely that you will need an accept policy function of your own. See the
  122 + definition of 'command_line_accept_policy' below for information and
  123 + 'predefined.anubis' for the tools enabling the manipulation of X.509 certificates.
  124 + Certificates that you trust are stored into the directory declared under the symbol
  125 + 'ca' (for 'Certificate Authorities') in your configuration file. Any certificate
  126 + present in this directory is trusted without any condition.
  127 +
  128 + This file defines the module 'https_get' to be used directly from the command line. To
  129 + learn about the syntax, just type 'https_get' at the system prompt, or have a look at
  130 + the end of this file.
  131 +
  132 +
  133 +
  134 +
  135 + --- That's all for public definitions. ------------------------------------------------
  136 +
  137 +
  138 +
  139 +
  140 +
  141 +
  142 +
  143 +
  144 +define Maybe(String)
  145 + receive_text_chunk
  146 + (
  147 + SSL_Connection conn
  148 + ) =
  149 + read(conn,100,1000).
  150 +
  151 +
  152 +
  153 +
  154 +define HTTPS_GET_Result
  155 + receive
  156 + (
  157 + SSL_Connection conn,
  158 + String headers,
  159 + String text_so_far,
  160 + Bool double_crlf_seen
  161 + ) =
  162 + if receive_text_chunk(conn) is
  163 + {
  164 + failure then if separate_headers(headers) is
  165 + {
  166 + [ ] then ok("",[],text_so_far),
  167 + [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far)
  168 + },
  169 +
  170 + success(s) then
  171 + if s = ""
  172 + then if separate_headers(headers) is
  173 + {
  174 + [ ] then ok("",[],text_so_far),
  175 + [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far)
  176 + }
  177 + else with new_s = text_so_far+s,
  178 + if double_crlf_seen
  179 + then receive(conn,headers,new_s,true)
  180 + else if has_double_crlf(new_s) is
  181 + {
  182 + failure then receive(conn,headers,new_s,false),
  183 + success(n) then
  184 + if sub_string(new_s,n+4,length(new_s)-n-4) is
  185 + {
  186 + failure then alert,
  187 + success(s1) then
  188 + if sub_string(new_s,0,n) is
  189 + {
  190 + failure then alert,
  191 + success(h) then receive(conn,h,s1,true)
  192 + }
  193 + }
  194 + }
  195 + }.
  196 +
  197 +
  198 +
  199 + The next function has a valid SSL connection to the server, and tries to retrieve the
  200 + document.
  201 +
  202 +define HTTPS_GET_Result
  203 + https_get
  204 + (
  205 + Bool print_all,
  206 + SSL_Connection conn,
  207 + String server_name,
  208 + String document_name,
  209 + List(HTTP_header) headers,
  210 + List(HTTP_argument) arguments
  211 + ) =
  212 + //
  213 + // Send the HTTP request, and receive the answer:
  214 + //
  215 + with body = format_http_args(arguments),
  216 + with request = (if arguments = [] then "GET " else "POST ")
  217 + + document_name + " HTTP/1.0" + crlf +
  218 + "Host: " + server_name + crlf +
  219 + "Accept-Charset: iso-8859-1,*,utf-8" + crlf +
  220 + (if arguments = [] then ""
  221 + else "Content-type: application/x-www-form-urlencoded" + crlf +
  222 + "Content-length: " + to_decimal(length(body))+ crlf) +
  223 + format_headers(headers) +
  224 + crlf +
  225 + body,
  226 + (if print_all then
  227 + (
  228 + print("Sending request:\n");
  229 + print(request);
  230 + print("\n")
  231 + ) else unique);
  232 + if write(conn,request) is
  233 + {
  234 + failure then transmission_problem,
  235 + success(_) then receive(conn,"","",false)
  236 + }.
  237 +
  238 +
  239 + The next function retrieves the document using the numerical (resolved) server address.
  240 +
  241 +define HTTPS_GET_Result
  242 + https_get
  243 + (
  244 + Bool print_all,
  245 + Word32 server_addr,
  246 + Word32 server_port,
  247 + String server_name,
  248 + String document_name,
  249 + List(HTTP_header) headers,
  250 + List(HTTP_argument) arguments,
  251 + (Maybe(X509)) -> Bool accept_policy
  252 + ) =
  253 + if open_SSL_connection(server_name,server_addr,server_port,accept_policy) is
  254 + {
  255 + error(msg) then ssl_connect_error(msg),
  256 + ok(conn) then https_get(print_all,conn,server_name,document_name,headers,arguments)
  257 + }.
  258 +
  259 +
  260 +
  261 +define HTTPS_GET_Result
  262 + https_get
  263 + (
  264 + Bool print_all,
  265 + String server_name,
  266 + String document_name,
  267 + List(HTTP_header) headers,
  268 + List(HTTP_argument) arguments,
  269 + (Maybe(X509)) -> Bool accept_policy
  270 + ) =
  271 + if separate_name_port(server_name,443) is (name,port) then
  272 + //
  273 + // resolve server name and call 'https_get' with numeric server address:
  274 + //
  275 + with a = dns(name),
  276 + if a is ok(addr)
  277 + then https_get(print_all,addr,port,name,document_name,headers,arguments,accept_policy)
  278 + else cannot_resolve_server_name(a).
  279 +
  280 +
  281 +
  282 + Now, here is our public tool:
  283 +
  284 +public define HTTPS_GET_Result
  285 + https_get
  286 + (
  287 + String server_name,
  288 + String document_name,
  289 + List(HTTP_header) headers,
  290 + List(HTTP_argument) arguments,
  291 + (Maybe(X509)) -> Bool accept_policy
  292 + ) = https_get(false,server_name,document_name,headers,arguments,accept_policy).
  293 +
  294 +
  295 +
  296 +
  297 +
  298 + Finally, we construct the command line executable module 'https_get.adm':
  299 +
  300 +define One
  301 + syntax_https_get =
  302 + print("\nUsage: https_get <server> <document> [options] =<header> <value> ... <arg> <value> ...\n");
  303 + print(" Options are:\n");
  304 + print(" -print_all print request, response line, headers and document\n");
  305 + print(" (default is to print only the document)\n").
  306 +
  307 +
  308 +
  309 +
  310 + Below is our accept policy function for the command line module. This function may
  311 + serve as a model for your own accept policy function.
  312 +
  313 +public define Bool
  314 + command_line_accept_policy
  315 + (
  316 + Maybe(X509) mbcert
  317 + ) =
  318 + if mbcert is
  319 + {
  320 + failure then
  321 + print("No server certificate or invalid server certificate.\n");
  322 + print("Do you want to trust this site anyway ? [Y/N]\n");
  323 + yes, // this is the same as 'if yes then true else false'
  324 +
  325 + success(cert) then
  326 + print(to_string(cert));
  327 + print("\nDo you want to accept the above certificate ? [Y/N]\n");
  328 + if yes
  329 + then (
  330 + print("Do you want to accept this certificate for ever ? [Y/N]\n");
  331 + if yes
  332 + then (if trust_for_ever(cert) is
  333 + {
  334 + ca_directory_not_found then print("'ca' directory not found.\n"),
  335 + cannot_create_file then print("cannot create file.\n"),
  336 + cannot_create_symbolic_link then print("cannot create symbolic link.\n"),
  337 + write_error then print("write error.\n"),
  338 + ok then unique
  339 + }; true)
  340 + else true
  341 + )
  342 + else false
  343 + }.
  344 +
  345 +
  346 +global define One
  347 + https_get
  348 + (
  349 + List(String) args
  350 + ) =
  351 + if args is
  352 + {
  353 + [ ] then syntax_https_get,
  354 + [server . t] then if t is
  355 + {
  356 + [ ] then syntax_https_get,
  357 + [document . rest] then
  358 + with print_all = member(rest,"-print_all"),
  359 + headers = get_headers(rest),
  360 + arguments = get_arguments(rest),
  361 + if https_get(print_all,server,document,headers,arguments,command_line_accept_policy) is
  362 + {
  363 + cannot_resolve_server_name(dns_error) then
  364 + print("Cannot resolve server name: " + format(dns_error) + ".\n"),
  365 +
  366 + ssl_connect_error(connect_error) then
  367 + print("SSL connect error: " + format(connect_error) + ".\n"),
  368 +
  369 + transmission_problem then
  370 + print("Transmission problem.\n"),
  371 +
  372 + request_refused_by_server then
  373 + print("The request has been refused by server: " + server + ".\n"),
  374 +
  375 + ok(response,headers1,document1) then
  376 + (
  377 + if print_all
  378 + then (
  379 + print("\n----- response ----\n");
  380 + print(response);
  381 + print("\n----- headers -----\n");
  382 + print_headers(headers1);
  383 + print("----- document ----\n")
  384 + ) else unique
  385 + );
  386 + print(document1) // on the screen (use a redirection to get it in a file)
  387 + }
  388 + }
  389 + }.
  390 +