TclHttpd: The .tml File

The .tml file is a good place to put variables and small procedures that are commonly used in your TclHttpd application (note that you don't want to put a lot of procedures here, they're probably best put in custom libraries). For those of you who have worked with ColdFusion, the .tml file is similar to the application.cfm (the .tml is more powerful though, since it's a Tcl script).

Once the .tml has been 'sourced', the variables are available everywhere in the application, not just the directory in which the .tml resides.

Typical Uses

  • The email of the webmaster (using Doc_Webmaster)
  • URLs of the client/server error pages (using Doc_NotFoundPage and Doc_ErrorPage)
  • Cookie and session handling
  • I also typically create a variable called errors_to_browser which, when set to 1, shows the error output on the template defined in Doc_ErrorPage. The Doc_ErrorPage template contains a simple conditional that checks the value of errors_to_browser and acts accordingly.

Example Code

 # Application navigation links
 set navigation {    
     Home /tcl/index.tml {Return to the home page}
     {Log Off} /tcl/logout.tml {Quit the application}
 }
 
 set secondary_navigation {
     {Contact} /tcl/contact.tml {Contact a representative}
     {Search} /tcl/search.tml {Search the site}
     {Help} /tcl/help.tml {Assistance using this site}
 }
 
 # If this is set to 1, error messages will be shown in the error
 # template. This should be set to 0 in a production environment
 set errors_to_browser 0
 
 # Some basic application variables
 Doc_Webmaster [email protected]
 Doc_NotFoundPage /tcl/notfound.tml
 Doc_ErrorPage /tcl/error.tml
 
 # Security and session management
 if {[ncgi::value login] == "Login"} {
         
     # The user is trying to login, check to see if their username/password
     # combination is valid
         
     # Delete an existing session cookie, if it exists
     catch {[Doc_SetCookie -name app_session -value {} -expires \
     [clock format [clock seconds] -format {%A, %d-%b-%Y %H:%M:%S GMT} -gmt 1]]}    
         
     # Make sure user entered values for username and password
     if {[ncgi::value username] != "" && [ncgi::value password] != ""} {
         
         # Values entered for both username and password
         # Values entered for both username and password
         # Code that validates the user's credentials goes here
 
         if {$user_id != 0} {
                 
             # The user entered valid login information, so set session
             # variables and cookie containing session ID
             set session_id [Session_Create app_session]
             Session_Variable $session_id userid $user_id
             Doc_SetCookie -name app_session -value $session_id
              
         } else {
              
             # The user entered invalid login information, redirect them
             # to the invalid user template
             Doc_Redirect /invalid-user.html
         }
         
     } else {
         
         # Username or password was left empty
         Doc_Redirect /invalid-user.html
     }
     
 } elseif {[catch {Doc_Cookie app_session}] > 0} {
         
     # There's no session cookie, send the user to the login
     # template
     Doc_Redirect /
 } else {
     
     # Well, the user has a valid cookie, so do nothing for now
 }

CMcC This code is good, and very interesting, but you should be aware that it will only trigger when templates are being processed, so if there's a cached dynamic page, the .tml files won't be sourced and evaluated, so the processing won't occur. I think this might be better if called in or around the Auth processing.


LV Has anyone played with invoking Java objects from a .tml file? Someone stopped by this morning talking to me about ColdFusion vs Java servlets vs Tcl on the desktop, and they indicated that they were not considering Tcl on the back-end. They need to be able to interact with their business logic which is in EJB beans. I won't be able to convince them otherwise, but I just thought I would check to see what people had tried along these lines.

schlenk As you can use any Tcl extension inside a .tml file, you could package require tclblend and use it to access the Java side. The tclsh running the server would have to be threaded for tclblend, but thats about it.

TV Mind that when you are on the internet, and have allowed file uploading, it's possible to upload a .tml file, which can then be invoked, and execute any tcl command... The latest tchhttpd seems to exec in a safe interpreter, but it's worth checking out.

WJR Huh? What does this have to do with the .tml file, or with TclHttpd? If you've allowed arbitrary file uploading, this would apply to pretty much any application server (e.g. upload a coldfusion template that uses CFEXECUTE to delete files or perform other malicious activities).

TV That if anyone has tclhttpd running, and allows both uploading and the use of .tml files (the standard config, I think), he or she is in danger of what I warned for. "Application server" I don't see me refering to; I'm just refering to the general tclhttpd webserver, and I didn't mention (nor know about) coldfusion either.

WJR My point is that if you've created an interface that enables file uploads, and exposed this interface to an arbitrary set of users, then your concerns would apply to any application server, not just to TclHttpd.

TV Well, as you maybe refer to, one could allow uploads to end up only outside the document file hierarchy, then the possibility of executing the uploaded script containing page is prevented.

WJR perhaps TV's point is that most people won't think of tclhttpd as an application server, but just a means to put up some personal web pages.

CMcC I think TV is mistaken in asserting that Tclhttpd ships with a facility to upload .tml files into the htdoc hierarchy. If I am correct, then there is no exploit. If I am mistaken, then there would be an exploit, and I would be happy to fix it if someone shows me where it is.

Merely stating that it is possible to configure the server so it's possible to upload *.tml files which could then be evaluated, while true, does not imply that Tclhttpd is insecure, rather that it is quite powerful.


See also