Skip to content

Commit

Permalink
Create compatibility aliases in ::tls namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
chpock committed May 27, 2024
1 parent 0b47a99 commit cb43829
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 5 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2024-05-27 Konstantin Kushnir <chpock@gmail.com>
* Create compatibility aliases in ::tls namespace by default

2024-05-12 Konstantin Kushnir <chpock@gmail.com>
* Fix an issue with untrusted certificates with TLS1.3 protocol
* Add test cases from https://github.com/wbond/badtls.io
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ Typically one would use the [socket](README\.html\#::mtls::socket) command which
compatibility with the native Tcl [socket](https://www.tcl.tk/man/tcl8.6/TclCmd/socket.htm)
command. In such cases [import](README\.html\#::mtls::import) should not be used directly.

Please note, to ensure seamless use of both the classic tcltls package
and this package, command aliases are created in the `::tls` namespace
when loading mtls. This allows the same code base to be used when using
different packages to support SSL/TLS connections. However, aliases
will not be created if the `::tls` namespace already exists at the time
the mtls package is loaded. This in turn allows both the tcltls and
mtls packages to be loaded at the same time. But the tcltls package
must be loaded first.

## <a name='::mtls-HTTPS_examples'></a>HTTPS examples

### <a name='::mtls-client_example'></a>client example
Expand All @@ -142,7 +151,7 @@ command. In such cases [import](README\.html\#::mtls::import) should not be used
package require http
package require mtls
http::register https 443 ::tls::socket
http::register https 443 ::mtls::socket
set tok [http::geturl https://www.tcl.tk/]
Expand Down
11 changes: 10 additions & 1 deletion doc/doc.ruff
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ namespace eval mtls {
compatibility with the native Tcl [socket](https://www.tcl.tk/man/tcl8.6/TclCmd/socket.htm)
command. In such cases [import] should not be used directly.

Please note, to ensure seamless use of both the classic tcltls package
and this package, command aliases are created in the `::tls` namespace
when loading mtls. This allows the same code base to be used when using
different packages to support SSL/TLS connections. However, aliases
will not be created if the `::tls` namespace already exists at the time
the mtls package is loaded. This in turn allows both the tcltls and
mtls packages to be loaded at the same time. But the tcltls package
must be loaded first.

## HTTPS examples

### client example
Expand All @@ -153,7 +162,7 @@ namespace eval mtls {
package require http
package require mtls

http::register https 443 ::tls::socket
http::register https 443 ::mtls::socket

set tok [http::geturl https://www.tcl.tk/]

Expand Down
3 changes: 2 additions & 1 deletion doc/mtls.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ <h2 class='ruff'><a name='::mtls-Description'></a>Description<span class='ruff-u
<div style='clear:both;'></div>
<p class='ruff'>This Tcl package provides an extension which implements Transport Layer Security (TLS) over Transmission Control Protocol (TCP) network communication channels.</p>
<p class='ruff'>Typically one would use the <a href="mtls.html#::mtls::socket" title="socket" class='ruff_cmd'>socket</a> command which provides compatibility with the native Tcl <a href="https://www.tcl.tk/man/tcl8.6/TclCmd/socket.htm" >socket</a> command. In such cases <a href="mtls.html#::mtls::import" title="import" class='ruff_cmd'>import</a> should not be used directly.</p>
<p class='ruff'>Please note, to ensure seamless use of both the classic tcltls package and this package, command aliases are created in the <code>::tls</code> namespace when loading mtls. This allows the same code base to be used when using different packages to support SSL/TLS connections. However, aliases will not be created if the <code>::tls</code> namespace already exists at the time the mtls package is loaded. This in turn allows both the tcltls and mtls packages to be loaded at the same time. But the tcltls package must be loaded first.</p>
<h2 class='ruff'><a name='::mtls-HTTPS examples'></a>HTTPS examples<span class='ruff-uplink'><a href='mtls.html#::mtls'>mtls</a>, <a href='#top'>Top</a></span></h2>
<div style='clear:both;'></div>
<h3 class='ruff'><a name='::mtls-client example'></a>client example<span class='ruff-uplink'><a href='mtls.html#::mtls'>mtls</a>, <a href='#top'>Top</a></span></h3>
Expand All @@ -111,7 +112,7 @@ <h3 class='ruff'><a name='::mtls-client example'></a>client example<span class='
package require http
package require mtls

http::register https 443 ::tls::socket
http::register https 443 ::mtls::socket

set tok [http::geturl https://www.tcl.tk/]

Expand Down
11 changes: 10 additions & 1 deletion doc/mtls.n
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ network communication channels\&.
Typically one would use the \fIsocket\fP command which provides
compatibility with the native Tcl \fIsocket\fP [URL: https://www\&.tcl\&.tk/man/tcl8\&.6/TclCmd/socket\&.htm]
command\&. In such cases \fIimport\fP should not be used directly\&.
.PP
Please note, to ensure seamless use of both the classic tcltls package
and this package, command aliases are created in the ::tls namespace
when loading mtls\&. This allows the same code base to be used when using
different packages to support SSL/TLS connections\&. However, aliases
will not be created if the ::tls namespace already exists at the time
the mtls package is loaded\&. This in turn allows both the tcltls and
mtls packages to be loaded at the same time\&. But the tcltls package
must be loaded first\&.
.SH "HTTPS EXAMPLES"
.SS "CLIENT EXAMPLE"
.PP
Expand All @@ -46,7 +55,7 @@ command\&. In such cases \fIimport\fP should not be used directly\&.
package require http
package require mtls

http::register https 443 ::tls::socket
http::register https 443 ::mtls::socket

set tok [http::geturl https://www\&.tcl\&.tk/]

Expand Down
64 changes: 64 additions & 0 deletions generic/tclmtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1514,27 +1514,91 @@ DLLEXPORT int Mtls_Init(Tcl_Interp* interp) {
RETURN(ERROR);
}

int createAliases;
if (Tcl_FindNamespace(interp, "::tls", NULL, TCL_GLOBAL_ONLY)
== NULL)
{
DBG("create aliases in ::tls");
Tcl_CreateNamespace(interp, "::tls", NULL, NULL);
createAliases = 1;
} else {
DBG("do not create aliases in ::tls");
createAliases = 0;
}


Tcl_CreateObjCommand(interp, "::mtls::socket",
(Tcl_ObjCmdProc *)mtls_cmd_socket, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::socket", interp,
"::mtls::socket", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::init",
(Tcl_ObjCmdProc *)mtls_cmd_init, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::init", interp,
"::mtls::init", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::import",
(Tcl_ObjCmdProc *)mtls_cmd_import, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::import", interp,
"::mtls::import", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::handshake",
(Tcl_ObjCmdProc *)mtls_cmd_handshake, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::handshake", interp,
"::mtls::handshake", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::debug",
(Tcl_ObjCmdProc *)mtls_cmd_debug, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::debug", interp,
"::mtls::debug", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::ciphers",
(Tcl_ObjCmdProc *)mtls_cmd_ciphers, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::ciphers", interp,
"::mtls::ciphers", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::protocols",
(Tcl_ObjCmdProc *)mtls_cmd_protocols, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::protocols", interp,
"::mtls::protocols", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::version",
(Tcl_ObjCmdProc *)mtls_cmd_version, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::version", interp,
"::mtls::version", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::unimport",
(Tcl_ObjCmdProc *)mtls_cmd_unimport, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::unimport", interp,
"::mtls::unimport", 0, NULL);
}

Tcl_CreateObjCommand(interp, "::mtls::status",
(Tcl_ObjCmdProc *)mtls_cmd_status, conf, NULL);
if (createAliases) {
Tcl_CreateAlias(interp, "::tls::status", interp,
"::mtls::status", 0, NULL);
}


DBG("initialization: done");
RETURN(OK);
}
#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion manifest.uuid
Original file line number Diff line number Diff line change
@@ -1 +1 @@
git-0c70f9d9f7e6858e29681d6ffb1306213021841e
git-0b47a998647230ead5190bb285a0ab248ce9420c
33 changes: 33 additions & 0 deletions tests/basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,39 @@ test mtls-basic-1.2 { check that mtls::import preserves options } -constraints c
unset -nocomplain s1 s2 opts1 opts2 res opt
}

test mtls-basic-2.1 { check that ::tls aliases are created } -setup {
set script [makeFile {
package require mtls
puts [lsort [info commands ::tls::*]]
} script]
} -body {
set s [open "|[interpreter] $script" r]
set res [gets $s]
close $s
set res
} -cleanup {
catch { close $s }
file delete -force $script
unset -nocomplain script s res
} -result {::tls::ciphers ::tls::debug ::tls::handshake ::tls::import ::tls::init ::tls::protocols ::tls::socket ::tls::status ::tls::unimport ::tls::version}

test mtls-basic-2.2 { check that ::tls aliases are not created when namespace exists } -setup {
set script [makeFile {
namespace eval ::tls {}
package require mtls
puts [lsort [info commands ::tls::*]]
} script]
} -body {
set s [open "|[interpreter] $script" r]
set res [gets $s]
close $s
set res
} -cleanup {
catch { close $s }
file delete -force $script
unset -nocomplain script s res
} -result {}

# cleanup
cleanupTests
return

0 comments on commit cb43829

Please sign in to comment.