On 04/05/2019 03:58,
danielre...@gmail.com wrote:
> I'm looking for some help in regards to protecting a TCL file from
> being copied.
Files can be copied. It's pretty much impossible to prevent that; it's a
fundamental feature of operating systems. :-)
But that's not to say there's nothing that can be done.
> We are using TCL files to run macros/scripts in Surpac (Mining
> software), currently when viewed as a text file they are in the
> native code. We would however like to make it so that they cannot be
> read.
>
> They would however still need to be executed by Surpac.
Are you packaging the Tcl files with the software that reads them? If
so, you can use things like the TDK compiler (if you can find a working
version) to generate shrouded bytecode files that can be executed by any
Tcl interpreter that has the tbcload package (which you statically build
into the reading software).
Alternatively in 8.7 onwards, you can package all your Tcl code as an
attached encrypted ZIP archive. It's a way to build applications where
the Tcl code is locked down.
Neither technique is designed to prevent an actually determined
attacker. (ZIP encryption is famously weak, and the .tbc format is
merely very weird and very horrible, not *actually* deeply encrypted.)
The only method that stands a reasonable chance there is to run the code
on a server you control and make sure that users can't ever get access
to the code at all (standard client-server stuff). You probably don't
want to do that in your case.
But it wouldn't be too hard to do a custom code reading command that
decrypts (based on an algoithm like RC4, for which there are both Tcl
and C implementations, and using a key you compile into your program)
code before running it. You could even do something like this:
package require rc4; # See Tcllib package
set key "MYSECRET"; # Not the right format for an RC4 key! Get
your own
proc decryptingSource {interpreter filename} {
# Read the file as RAW BYTES
set f [open $filename rb]
set data [read $f]
close $f
# Decrypt if encrypted
if {[file extension $filname] eq ".encTcl"} {
global key
set data [rc4::rc4 -key $key $data]
}
# Convert to text (important!)
set sourceCode [encoding convertfrom [encoding systm] $dat]
# Evaluate in the child interp
$interpreter eval $sourceCode
}
interp create shroudedEnvironment
interp alias shroudedEnvironment source \
{} decryptingSource shroudedEnvironment
shroudedEnvironment eval {source main.encTcl}
There's a few extra nuances, but that sort of thing (where you perhaps
implement the decryption engine in C to shroud the key better) is the
core of how to do moderately strong protection.
Donal.
--
Donal Fellows — Tcl user, Tcl maintainer, TIP editor.