Index: pkgIndex.tcl.in ================================================================== --- pkgIndex.tcl.in +++ pkgIndex.tcl.in @@ -1,6 +1,6 @@ -if {[package vsatisfies [package present Tcl] 8.6-]} { +if {[package vsatisfies [package present Tcl] 8.5-]} { package ifneeded tls @PACKAGE_VERSION@ [list apply {{dir} { if {{@TCLEXT_BUILD@} eq "static"} { load {} Tls } else { load [file join $dir @EXTENSION_TARGET@] Tls @@ -9,6 +9,8 @@ set tlsTclInitScript [file join $dir tls.tcl] if {[file exists $tlsTclInitScript]} { source $tlsTclInitScript } }} $dir] +} elseif {[package vsatisfies [package present Tcl] 8.4]} { + package ifneeded tls @PACKAGE_VERSION@ [list load [file join $dir @EXTENSION_TARGET@] Tls] } Index: tclOpts.h ================================================================== --- tclOpts.h +++ tclOpts.h @@ -24,11 +24,11 @@ var = objv[idx]; \ OPT_POSTLOG() #define OPTSTR(option, var) \ OPT_PROLOG(option) \ - var = Tcl_GetString(objv[idx]);\ + var = Tcl_GetStringFromObj(objv[idx], (Tcl_Size *)NULL);\ OPT_POSTLOG() #define OPTINT(option, var) \ OPT_PROLOG(option) \ if (Tcl_GetIntFromObj(interp, objv[idx], \ Index: tests/all.tcl ================================================================== --- tests/all.tcl +++ tests/all.tcl @@ -14,10 +14,11 @@ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } + set ::tcltest::testSingleFile false set ::tcltest::testsDirectory [file dir [info script]] # We should ensure that the testsDirectory is absolute. Index: tls.c ================================================================== --- tls.c +++ tls.c @@ -23,10 +23,14 @@ #include "tlsInt.h" #include "tclOpts.h" #include +#if TCL_MAJOR_VERSION < 9 + typedef int Tcl_Size; +#endif + /* * External functions */ /* @@ -271,11 +275,11 @@ static int VerifyCallback(int ok, X509_STORE_CTX *ctx) { Tcl_Obj *cmdPtr, *result; char *errStr, *string; - int length; + Tcl_Size length; SSL *ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); X509 *cert = X509_STORE_CTX_get_current_cert(ctx); State *statePtr = (State*)SSL_get_app_data(ssl); int depth = X509_STORE_CTX_get_error_depth(ctx); int err = X509_STORE_CTX_get_error(ctx); Index: tlsIO.c ================================================================== --- tlsIO.c +++ tlsIO.c @@ -21,11 +21,15 @@ /* * Forward declarations */ static int TlsBlockModeProc (ClientData instanceData, int mode); +#if TCL_MAJOR_VERSION < 9 static int TlsCloseProc (ClientData instanceData, Tcl_Interp *interp); +#else +static int TlsClose2Proc (ClientData instanceData, Tcl_Interp *interp, int flags); +#endif static int TlsInputProc (ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); static int TlsOutputProc (ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); static int TlsGetOptionProc (ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *dsPtr); static void TlsWatchProc (ClientData instanceData, int mask); static int TlsGetHandleProc (ClientData instanceData, int direction, ClientData *handlePtr); @@ -86,11 +90,15 @@ * Common elements of the structure (no changes in location or name) * close2Proc, seekProc, setOptionProc stay NULL. */ tlsChannelType->typeName = "tls"; +#if TCL_MAJOR_VERSION < 9 tlsChannelType->closeProc = TlsCloseProc; +#else + tlsChannelType->close2Proc = TlsClose2Proc; +#endif tlsChannelType->inputProc = TlsInputProc; tlsChannelType->outputProc = TlsOutputProc; tlsChannelType->getOptionProc = TlsGetOptionProc; tlsChannelType->watchProc = TlsWatchProc; tlsChannelType->getHandleProc = TlsGetHandleProc; @@ -159,10 +167,27 @@ * Closes the socket of the channel. * *------------------------------------------------------------------- */ static int TlsCloseProc(ClientData instanceData, Tcl_Interp *interp) { + State *statePtr = (State *) instanceData; + + dprintf("TlsCloseProc(%p)", (void *) statePtr); + + Tls_Clean(statePtr); + Tcl_EventuallyFree((ClientData)statePtr, Tls_Free); + + dprintf("Returning TCL_OK"); + + return(TCL_OK); + + /* Interp is unused. */ + interp = interp; +} + +static int TlsClose2Proc(ClientData instanceData, Tcl_Interp *interp, int flags) { + if ((flags & (TCL_CLOSE_READ|TCL_CLOSE_WRITE)) == 0) { State *statePtr = (State *) instanceData; dprintf("TlsCloseProc(%p)", (void *) statePtr); Tls_Clean(statePtr); @@ -169,13 +194,14 @@ Tcl_EventuallyFree((ClientData)statePtr, Tls_Free); dprintf("Returning TCL_OK"); return(TCL_OK); + } - /* Interp is unused. */ - interp = interp; + /* Interp is unused. */ + interp = interp; } /* *------------------------------------------------------* * Index: win/README.txt ================================================================== --- win/README.txt +++ win/README.txt @@ -1,64 +1,49 @@ - Windows DLL Build instructions using nmake build system - 2020-10-15 Harald.Oehlmann@elmicron.de - -Properties: -- 32 bit DLL -- VisualStudio 2015 -Note: Visual C++ 6 does not build OpenSSL (long long syntax error) -- Cygwin32 (temporary helper, please help to replace by tclsh) -- OpenSSL statically linked to TCLTLS DLL. -Note: Dynamic linking also works but results in a DLL dependeny on OPENSSL DLL's - -1) Build OpenSSL static libraries: - -OpenSSL source distribtution unpacked in: -c:\test\tcltls\Openssl_1_1_1h - -- Install Perl from http://strawberryperl.com/download/5.32.0.1/strawberry-perl-5.32.0.1-32bit.msi - to C:\perl - (ActivePerl failed due to missing 32 bit console module) -- Install NASM Assembler: - -https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win32/nasm-2.15.05-installer-x86.exe - to C:\Program Files (x86)\NASM - --> Visual Studio x86 native prompt. - -set Path=%PATH%;C:\Program Files (x86)\NASM;C:\Perl\perl\bin - -perl Configure VC-WIN32 --prefix=c:\test\tcltls\openssl --openssldir=c:\test\tcltls\openssldir no-shared no-filenames threads - -nmake -nmake test -namke install - -2) Build TCLTLS - -Unzip distribution in: -c:\test\tcltls\tcltls-1.8.0 - --> start cygwin bash prompt - -cd /cygdrive/c/test/tcltls/tcltls-1.8.0 -./gen_dh_params > dh_params.h - -od -A n -v -t xC < 'tls.tcl' > tls.tcl.h.new.1 -sed 's@[^0-9A-Fa-f]@@g;s@..@0x&, @g' < tls.tcl.h.new.1 > tls.tcl.h -rm -f tls.tcl.h.new.1 - --> Visual Studio x86 native prompt. - -cd C:\test\tcltls\tcltls-1.8.0\win - -nmake -f makefile.vc TCLDIR=c:\test\tcl8610 SSL_INSTALL_FOLDER=C:\test\tcltls\openssl - -nmake -f makefile.vc install TCLDIR=c:\test\tcl8610 INSTALLDIR=c:\test\tcltls SSL_INSTALL_FOLDER=C:\test\tcltls\openssl - -3) Test - -Start tclsh or wish - -lappend auto_path {C:\test\tcltls\tls1.8.0} -package require tls - -A small "1.8.0" showing up is hopefully the end of this long way... + Windows DLL Build instructions using nmake build system + 2020-10-15 Harald.Oehlmann@elmicron.de + 2023-08-22 Kevin Walzer (kw@codebykevin.com) + +Properties: +- 64 bit DLL +- VisualStudio 2019 +- WSL +- OpenSSL dynamically linked to TCLTLS DLL. We used a freely redistributable build of OpenSSL from https://www.firedaemon.com/firedaemon-openssl. Unzip and install OpenSSL in an accessible place (we used the lib subdirectory of our Tcl installation). + +1. Visual Studio x86 native prompt. Update environmental variables for building Tcltls. Customize the below entries for your setup. + +set PATH=%PATH%;C:\tcl-trunk\lib\openssl-3\x64\bin +set INCLUDE=%INCLUDE%;C:\tcl-trunk\tcl\lib\openssl-3\x64\include\openssl +set LIB=%LIB%;C:\tcl-trunk\tcl\lib\openssl-3\x64\bin + + +2) Build TCLTLS + +-> Unzip distribution on your system. +-> Start WSL. +-> cd /mnt/c/path/to/tcltls + +./gen_dh_params > dh_params.h + +od -A n -v -t xC < 'tls.tcl' > tls.tcl.h.new.1 +sed 's@[^0-9A-Fa-f]@@g;s@..@0x&, @g' < tls.tcl.h.new.1 > tls.tcl.h +rm -f tls.tcl.h.new.1 + +-> Visual Studio x86 native prompt. + +cd C:path\to\tcltls\win + +Run the following commands (modify the flags to your specific installations). + +nmake -f makefile.vc TCLDIR=c:\users\wordt\tcl INSTALLDIR=c:\tcl-trunk\tcl\lib SSL_INSTALL_FOLDER=C:\tcl-trunk\tcl\lib\openssl-3\x64 + +nmake -f makefile.vc TCLDIR=c:\users\wordt\tcl INSTALLDIR=c:\tcl-trunk\tcl\lib SSL_INSTALL_FOLDER=C:\tcl-trunk\tcl\lib\openssl-3\x64 install + +The resulting installation will include both the tcltls package and also have libcrypto.dll and libssl.dll copied into the same directory. + +3) Test + +Start tclsh + +package require tls +package require http +http::register https 443 [list ::tls::socket -autoservername true] +set tok [http::data [http::geturl https://www.tcl-lang.org]] Index: win/makefile.vc ================================================================== --- win/makefile.vc +++ win/makefile.vc @@ -1,24 +1,32 @@ # call nmake with additional parameter SSL_INSTALL_FOLDER= with the # OpenSSL instalation folder following. PROJECT=tls DOTVERSION = 1.8.0 + +PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) +PRJLIB = $(OUT_DIR)\$(PRJLIBNAME) + +!include "rules-ext.vc" PRJ_INCLUDES = -I"$(SSL_INSTALL_FOLDER)\include" PRJ_DEFINES = -D NO_SSL2 -D NO_SSL3 -D _CRT_SECURE_NO_WARNINGS PRJ_LIBS = \ "$(SSL_INSTALL_FOLDER)\lib\libssl.lib" \ "$(SSL_INSTALL_FOLDER)\lib\libcrypto.lib" \ - WS2_32.LIB GDI32.LIB ADVAPI32.LIB CRYPT32.LIB USER32.LIB + WS2_32.LIB GDI32.LIB ADVAPI32.LIB CRYPT32.LIB USER32.LIB + PRJ_OBJS = $(TMP_DIR)\tls.obj \ $(TMP_DIR)\tlsBIO.obj \ $(TMP_DIR)\tlsIO.obj \ $(TMP_DIR)\tlsX509.obj - -!include "rules-ext.vc" + !include "targets.vc" pkgindex: default-pkgindex +install: + copy "$(SSL_INSTALL_FOLDER)\bin\libcrypto-3-x64.dll" "$(INSTALLDIR)\$(PROJECT)$(DOTVERSION)\libcrypto-3-x64.dll" + copy "$(SSL_INSTALL_FOLDER)\bin\libssl-3-x64.dll" "$(INSTALLDIR)\$(PROJECT)$(DOTVERSION)\libssl-3-x64.dll"