User Tools

Site Tools


fetching_20a_20secure_20web_20page

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
fetching_20a_20secure_20web_20page [2018/03/31 13:19] – external edit 127.0.0.1fetching_20a_20secure_20web_20page [2025/03/23 15:13] (current) richardrussell
Line 1: Line 1:
 =====Fetching a secure web page===== =====Fetching a secure web page=====
  
-//by Richard Russell, July 2009//\\ \\  The procedure listed below fetches the contents of a secure (**https:**) web page to a specified file; it uses the [[http://www.openssl.org/|OpenSSL]] library and requires the files **libssl32.dll** and **libeay32.dll** to be available. They can be downloaded in this [[http://downloads.sourceforge.net/gnuwin32/openssl-0.9.8h-1-bin.zip|Zip file]], from which they should be extracted and copied to a location where they will be found by **LoadLibrary**, i.e. one of:\\ +//by Richard Russell, July 2009, updated July 2018 and March 2025//
  
-  * The directory from which the application will be loaded (@dir$). +The procedure listed below fetches the contents of a web resource to a specified file; it uses the code listed in the //BBC BASIC for Windows// [[https://www.bbcbasic.co.uk/bbcwin/manual/bbcwine.html#urlmon|manual]] (it also runs in //BBC BASIC for SDL 2.0// but in **Windows** only):
-  * The 'current' directory. +
-  * The system directory (e.g. **C:\Windows\System32\**). +
-  * The Windows directory (e.g. **C:\Windows\**). +
-  * One of the directories listed in the PATH environment variable. +
-\\  If you want to distribute **libssl32.dll** and **libeay32.dll** with your application then store them in **@dir$** and embed them in the executable. Alternatively you can put them in **@lib$** (or sub-directory) but in that case you will need to amend the procedure below to load them explicitly from that location.\\ \\  The procedure should be called in the following context:\\ \\  +
-        port$ = "443" : REM https +
-        host$ = "www.fortify.net" +
-        page$ = "/sslcheck.html+
-        file$ = @tmp$ + "sslcheck.html" +
-        PROCsslfetch(port$, host$, page$, file$) +
-This fetches the page https://www.fortify.net/sslcheck.html to the file **sslcheck.html**.\\ \\  Here is the procedure:\\ \\  +
-        DEF PROCsslfetch(port$, host$, page$, file$) +
-        LOCAL libssl%, libeay%, meth%, ctx%, sock%, temp%, res%, ssl%, sbio%, file% +
-        LOCAL req$, buf&()+
  
-        FIONBIO &8004667E +<code bb4w> 
-        BIO_NOCLOSE = 0 +      url$ "https://www.fortify.net/sslcheck.html" 
-        BUFSIZ = 256+      file$ @tmp$ + "sslcheck.html" 
 +      SYS "LoadLibraryA", "URLMON.DLL" TO urlmon% 
 +      SYS "GetProcAddress", urlmon%, "URLDownloadToFileA" TO `URLDownloadToFile` 
 +      SYS `URLDownloadToFile`, FALSE, url$, file$, 0, FALSE TO fail% 
 +      IF fail% ERROR 100, "File download failed" 
 +      OSCLI "RUN notepad """ + file$ + """" 
 +</code>
  
-        ON ERROR LOCAL RESTORE ERROR : INSTALL @lib$+"SOCKLIB" +If you find this code doesn't work, you can instead try the routine below which uses the  
-        PROC_initsockets+ [[http://www.openssl.org/|OpenSSL]] library and requires the files **libssl-3.dll** and **libcrypto-3.dll** to be available. They can be obtained from  [[https://slproweb.com/products/Win32OpenSSL.html|this page]]; download and install **Win32OpenSSL_Light-3_4_1.exe** from there.  You should normally choose the option of installing the DLLs in the Windows system directory.
  
-        SYS "LoadLibrary", "libssl32.dll" TO libssl% +If you want to distribute **libssl-3.dll** and **libcrypto-3.dll** with your application then store them in **@dir$** and embed them in the executable. Alternatively you can put them in **@lib$** (or a sub-directory) but in that case you will need to amend the procedure below to load them explicitly from that location.
-        IF libssl% = 0 PROCsslcleanup : ERROR 100, "Cannot load LIBSSL32.DLL" +
-        SYS "GetProcAddress", libssl%, "SSL_library_init" TO `SSL_library_init` +
-        SYS "GetProcAddress", libssl%, "SSLv23_method"    TO `SSLv23_method` +
-        SYS "GetProcAddress", libssl%, "SSL_CTX_new"      TO `SSL_CTX_new` +
-        SYS "GetProcAddress", libssl%, "SSL_new"          TO `SSL_new` +
-        SYS "GetProcAddress", libssl%, "SSL_set_bio"      TO `SSL_set_bio` +
-        SYS "GetProcAddress", libssl%, "SSL_connect"      TO `SSL_connect` +
-        SYS "GetProcAddress", libssl%, "SSL_write"        TO `SSL_write` +
-        SYS "GetProcAddress", libssl%, "SSL_read"         TO `SSL_read` +
-        SYS "GetProcAddress", libssl%, "SSL_CTX_free"     TO `SSL_CTX_free`+
  
-        SYS "LoadLibrary", "libeay32.dll" TO libeay% +The procedure should be called in the following context:
-        IF libeay% = 0 PROCsslcleanup ERROR 100, "Cannot load LIBEAY32.DLL" +
-        SYS "GetProcAddress", libeay%, "BIO_new_socket"   TO `BIO_new_socket`+
  
-        REM Global system initialisation+<code bb4w> 
-        SYS `SSL_library_init`+      port$ = "443" REM https 
 +      host$ = "www.fortify.net" 
 +      page$ = "/sslcheck.html" 
 +      file$ = @tmp$ + "sslcheck.html" 
 +      PROCsslfetch(port$, host$, page$, file$) 
 +</code>
  
-        REM Create SSL context: +This fetches the page https://www.fortify.net/sslcheck.html to the file **sslcheck.html**.
-        SYS `SSLv23_method` TO meth% +
-        SYS `SSL_CTX_new`, meth% TO ctx% +
-        IF ctx% = 0 PROCsslcleanup : ERROR 100, "SSL_CTX_new failed"+
  
-        REM Connect the TCP socket: +Here is the procedure:
-        sock% = FN_tcpconnect(host$, port$) +
-        IF sock% < 0 PROCsslcleanup : ERROR 100, "Cannot connect to " + host$+
  
-        temp% = 0 +<code bb4w> 
-        SYS `ioctlsocket`sock%, FIONBIO^temp% TO res% +      DEF PROCsslfetch(port$host$, page$, file$) 
-        IF resPROCsslcleanup : ERROR 105"Cannot set socket to blocking"+      LOCAL libssl%, libeay%, meth%, ctx%, sock%, temp%res%, ssl%, sbio%, file% 
 +      LOCAL req$, buf&()
  
-        REM Connect the SSL socket: +      FIONBIO = &8004667E 
-        SYS `SSL_new`, ctx% TO ssl% +      BIO_NOCLOSE = 0 
-        SYS `BIO_new_socket`, sock%, BIO_NOCLOSE TO sbio% +      BUFSIZ = 256
-        SYS `SSL_set_bio`, ssl%, sbio%, sbio%+
  
-        SYS `SSL_connect`, ssl% TO res% +      ON ERROR LOCAL RESTORE ERROR : INSTALL @lib$+"SOCKLIB" 
-        IF res% <= 0 PROCsslcleanup : ERROR 100, "SSL connect failed" + STR$res%+      PROC_initsockets
  
-        REM Request the page: +      SYS "LoadLibrary""libcrypto-3.dllTO libeay% 
-        req$  = "GET + page$ + HTTP/1.0+ CHR$13 + CHR$10 +      IF libeay% 0 PROCsslcleanup : ERROR 100, "Cannot load libcrypto-3.dll
-        req$ += "User-Agent: BB4W+ CHR$13 + CHR$10 +      SYS "GetProcAddress", libeay%, "BIO_new_socket  TO `BIO_new_socket`
-        req$ += "Host: + host$ + ":+ port$ + CHR$13 + CHR$10 +
-        req$ += CHR$13 + CHR$10+
  
-        SYS `SSL_write`, ssl%, req$LEN(req$) TO res+      SYS "LoadLibrary", "libssl-3.dll" TO libssl% 
-        IF res<> LEN(req$) PROCsslcleanup : ERROR 100, "SSL write failed: + STR$res%+      IF libssl% = 0 PROCsslcleanup : ERROR 100, "Cannot load libssl-3.dll" 
 +      SYS "GetProcAddress", libssl%, "TLSv1_2_method"   TO `TLSv1_2_method` 
 +      SYS "GetProcAddress"libssl%, "SSL_CTX_new"      TO `SSL_CTX_new` 
 +      SYS "GetProcAddress"libssl%, "SSL_new"          TO `SSL_new` 
 +      SYS "GetProcAddress", libssl%, "SSL_set_bio"      TO `SSL_set_bio` 
 +      SYS "GetProcAddress", libssl%, "SSL_connect"      TO `SSL_connect` 
 +      SYS "GetProcAddress", libssl%, "SSL_write"        TO `SSL_write` 
 +      SYS "GetProcAddress", libssl%, "SSL_read        TO `SSL_read` 
 +      SYS "GetProcAddress", libssl%, "SSL_CTX_free"     TO `SSL_CTX_free`
  
-        REM Copy the requested page to a file+      REM Create SSL context
-        DIM buf&(BUFSIZ-1)+      SYS `TLSv1_2_method` TO meth% 
 +      SYS `SSL_CTX_new`, meth% TO ctx% 
 +      IF ctx% = 0 PROCsslcleanup : ERROR 100, "SSL_CTX_new failed"
  
-        file% = OPENOUT(file$+      REM Connect the TCP socket: 
-        REPEAT +      sock% = FN_tcpconnect(host$, port$
-          SYS `SSL_read`ssl%, ^buf&(0), BUFSIZ TO res% +      IF sock% < 0 PROCsslcleanup : ERROR 100, "Cannot connect to " + host$
-          IF res% > 0 SYS "WriteFile", @hfile%(file%), ^buf&(0), res%, ^temp%, 0 +
-        UNTIL res% <0 +
-        CLOSE #file% +
-        IF res% PROCsslcleanup : ERROR 100, "SSL read failed: " + STR$res%+
  
-        REM Tidy up before exit: +      temp% = 0 
-        PROCsslcleanup +      SYS `ioctlsocket`, sock%, FIONBIO, ^temp% TO res% 
-        ENDPROC+      IF res% PROCsslcleanup : ERROR 105, "Cannot set socket to blocking"
  
-        DEF PROCsslcleanup +      REM Connect the SSL socket: 
-        sock% += 0 : IF sock% PROC_closesocket(sock%) : sock% = 0 +      SYS `SSL_new`, ctx% TO ssl% 
-        ctx% += 0 :  IF ctx% SYS `SSL_CTX_free`, ctx% : ctx% = 0 +      SYS `BIO_new_socket`, sock%, BIO_NOCLOSE TO sbio% 
-        libssl% += 0 : IF libssl% SYS "FreeLibrary", libssl% : libssl% = 0 +      SYS `SSL_set_bio`, ssl%, sbio%, sbio% 
-        libeay% += 0 : IF libeay% SYS "FreeLibrary", libeay% : libeay% = 0 + 
-        PROC_exitsockets +      SYS `SSL_connect`, ssl% TO res% 
-        ENDPROC+      IF res% <= 0 PROCsslcleanup : ERROR 100, "SSL connect failed: " + STR$res% 
 + 
 +      REM Request the page: 
 +      req$  = "GET " + page$ + " HTTP/1.0" + CHR$13 + CHR$10 
 +      req$ += "User-Agent: BB4W" + CHR$13 + CHR$10 
 +      req$ += "Host: " + host$ + ":" + port$ + CHR$13 + CHR$10 
 +      req$ += CHR$13 + CHR$10 
 + 
 +      SYS `SSL_write`, ssl%, req$, LEN(req$) TO res% 
 +      IF res% <> LEN(req$) PROCsslcleanup : ERROR 100, "SSL write failed: " + STR$res% 
 + 
 +      REM Copy the requested page to a file: 
 +      DIM buf&(BUFSIZ-1) 
 + 
 +      file% = OPENOUT(file$) 
 +      REPEAT 
 +        SYS `SSL_read`, ssl%, ^buf&(0), BUFSIZ TO res% 
 +        IF res% > 0 SYS "WriteFile", @hfile%(file%), ^buf&(0), res%, ^temp%, 0 
 +      UNTIL res% <= 0 
 +      CLOSE #file% 
 +      IF res% PROCsslcleanup : ERROR 100, "SSL read failed: " + STR$res% 
 + 
 +      REM Tidy up before exit: 
 +      PROCsslcleanup 
 +      ENDPROC 
 + 
 +      DEF PROCsslcleanup 
 +      sock% += 0 : IF sock% PROC_closesocket(sock%) : sock% = 0 
 +      ctx% += 0 :  IF ctx% SYS `SSL_CTX_free`, ctx% : ctx% = 0 
 +      libssl% += 0 : IF libssl% SYS "FreeLibrary", libssl% : libssl% = 0 
 +      libeay% += 0 : IF libeay% SYS "FreeLibrary", libeay% : libeay% = 0 
 +      PROC_exitsockets 
 +      ENDPROC 
 +</code>
fetching_20a_20secure_20web_20page.1522502359.txt.gz · Last modified: 2024/01/05 00:17 (external edit)