Index of /tcl/ftparchive/sorted/net/demo

      Name                   Last modified     Size  Description

[DIR] Parent Directory 29-Jan-99 12:29 - [   ] README 18-Jan-98 19:14 12k [DIR] demoCA/ 29-Jan-99 12:29 -

 	Demonstrations of how to use SSLtcl
	Peter Antman

  SSLtcl main program is a loadable module SSLtcl.so which can be loaded
  by tclsh or wish at any time. It then gives the programmer access to
  an extended version of tcl sockets. If you already know how to use the
  socket command then read the manual page and get on with it.

  If you feel unsure how to use sockets under tcl then have a look in
  demo.  There you find six example programs that utilize sockets with
  SSL. They show different ways of configuring the socket under tcl.

  The tcl socket command is among the most easiest ways to create
  applications that can communicate over tcp/ip. Its most fundamental
  aspect is that it either creates a client socket that directly tries
  to connect to a server. Or it creates a server socket that listens on
  the specified port and then creates additional sockets for each client
  that connect so that is can service more than one client at a time.

  To get tcl sockets to work in this nice way you have to have it in an
  event loop and you have to configure the channel the socket is wrapped
  in so that the program can take back command when it has started
  serving a client.

  The scripts in the demo directory contain different solutions to this
  problem.

  The scripts tstCli.tcl and tstSrv.tcl is two simple scripts that
  utilize sockets and SSL in an easy way; but with the negative
  sideffect that the server only will service one client at  time.

  Lets take a look at tstCli.tcl

           9   set shouldbe [exec cat tstCli.tcl]
           10  load ../SSLtcl.so SSLtcl
           11
           ...
           16  set s [socket -ssl -verify 1 -ciphers RC4-MD5 -cert demoCA/newcert.pem -key \

           17  demoCA/newkey.pem -CAfile demoCA/cacert.pem localhost 443]

           18
           19  puts $s ''GET /''
           20  puts ''Req complete''
           21  flush $s
           22  set got ''''
           23  while { [gets $s l ] >= 0 } {
           24          if { $got == '''' } {
           25                  set got $l
           26          } else {
           27                  set got ''$got\n$l''
           28          }
           29          # puts ''RECV($l)''
           30  }
           31  close $s
           32  puts ''Client done''
           33  if { $got == $shouldbe } {
           34          puts ''Client successful!!!''
           35  } else {
           36          puts ''Bummer!!!  Client did not rec what it should have!''

           37          exit -1;
           38  }
           39

  As you see it loads in SSLtcl.so in line 10. SSLtcl.so is not as is
  common under C based applications loaded from the best found location.
  Therefore you have to specify the full path. For example

  load /usr/local/lib/SSLtcl.so SSLtcl

  tstCli.tcl is a string fall through application. On line 16 it opens a
  socket and sets certain characteristics of it. Here we make it a
  client socket which uses SSL. All possible options is used in this
  example. The application will have its own certificate and will also
  have a file which contain certificate from Certificate Authorities it
  trusts. It also tells that it will only tolerate use of a special
  cipher.

  The socket command returns a channel identifier which we now can use
  to read from and write to.

  On line 19-21 the application writes to the socket and flushed the
  channel so that it really sends something. Because we are using SSL
  the communication with the server will take place over a cryptated
  tunnel.

  We then go in a loop and wait for something to read on the channel on
  lone 23-29. When we get something we immediately closes the cannel, as
  on line 31.

  This could be the basis of a webbrowser fetching webpages. That is,
  for a connectionless protocol.

  The server tstSrv.tcl is not that useful for real life problems,
  because it blocks while servicing clients. But is fairly easy to
  understand.

            9  set data [exec cat tstCli.tcl]
           10
           11  # This is the callback procedure that has to be part of the socket call

           12  proc getit { s ip port args } {
           13          global data
           14          puts $args
           15          puts ''Server socket ($s $ip $port)''
           16          set req [gets $s];
           17          puts ''RECV($req)''
           18          if { $req == ''GET /'' } {
           19                  puts $s $data
           20          } else {
           21                  puts ''UNKNOWN request''
           22                  puts $s ''UNKNOWN request''
           23          }
           24          close $s
           25  }
           26
           27  # load the module, with full path to it
           28  load ../SSLtcl.so SSLtcl
           29  set s [socket -server getit -ssl -Verify 1 -cert \
           30  demoCA/newcert.pem -key demoCA/newkey.pem \
           31  -CAfile demoCA/cacert.pem 443]
           32  puts $s
           33  set tst 0
           34  puts ''Server waiting connection on $s''
           35
           36  # Go into the eventloop
        37     vwait tst

  The main different between the client socket and a server socket is
  that the application have to enter an event loop. A server program is
  therefore not as straight a client program. Every server socket has to
  have a command to call back when a request arrives.

  At line 29 the channel is created. As we see we have to tell tcl that
  wee want a server socket with the switch -server. This option have a
  necessary argument, namely a callback command.

  This is created on line 12-25. When a client connects this client will
  be handed over to the callback command, in this case a procedure. The
  procedure is rather straightforward. It read from the channel with
  gets (line 16). Observe that this is not the same channel as that
  returned by the socket command, but is a new channel given as a
  argument to the procedure. It then writes back to the channel with
  puts $channelid something.

  At line 36 we went into an event loop. Nothing would have happen on
  the socket channel before we did go into that loop because tcl would
  not know how to handle the callback but would be busy doing other
  things.

  A connections is closed by closing the connection socket. The server
  socket is closed first when you close the channel you got back from
  the socket command.

  To do something more useful one would like at least the server to be
  able to respond to more than one client at a time. tstSrvReal is an
  example of such a client. It is basically build on two callback. One
  for the server socket to call, and one for every connections socket to
  call. To get a callback from every socket when it need attention wee
  have to configure it for that. This is done with the command filevent.
  At line 36 you can see how it is used in this example.

          9       # server writing back to client
      10  proc getit_fork {s l} {
      11          puts $s $l
      12          flush $s
      13  }
      14
      15  # the callback from filevent
      16  proc getit_hand {s} {
      17          puts filevent
      18            set l [gets $s]    ;# get the client packet
      19          puts ''got $l''
      20          if {[eof $s]} {    ;# client gone or finished
      21                  close $s        ;# release the servers client channel

      22          } elseif {$l == ''Q''} {
      23                  close $s
      24                  exit
      25          } elseif {$l == ''q''} {
      26                  close $s
      27                  return
      28          } else {
      29                  getit_fork $s $l
      30          }
      31  }
      32
      33  # The connection callback, called from ssl
      34  proc getit { s ip port args } {
      35          puts ''in getit''
      36          fileevent $s readable [list getit_hand $s]
      37
      38
      39          fconfigure $s -buffering line -blocking 0
      40          return
      41
      42  }
      43
      44  # load the module
      45  load ../SSLtcl.so SSLtcl
      46
      47  # create socket, with ssl
      48  set s [socket -server getit -ssl -Verify 1 -cert \
      49  demoCA/newcert.pem -key demoCA/newkey.pem \
      50  -CAfile /home/peter/ssl/demoCA/cacert.pem 443]
      51  puts ''Server waiting connection on $s''
      52
      53  # Go into the eventloop
    54    vwait events

  The main part of the program is rather short. On line 45 to 54 we load
  the module, creates the socket and goes into the event loop.

  But in the callback procedure we give to the -server option we behave
  differently. There we instead gives a new callback, configures the new
  channel and returns so that the main program can continue on.

  The filevent command is used to get tcl to call a procedure when there
  is something happening on the cannel. In our case we want is to call
  the procedure getit_hand when the channel is readable. And we send the
  new channel as an argument.

  We also configure the cannel. Especially useful is to configure it for
  non blocking mode. If we do not do that the server will not be able to
  service new client until the first connected has at least send
  something, which means that a client could easily freeze the whole
  server.

  In the new callback we read in what's in the socket and examine its
  connect. Useful is to check for End Of File, which is done on line 20
  so that we know if the client has disappeared.

  The stsCliReal.tcl is based on the same principles that tstSrvReal,
  that is, we implement an event loop and a callback even in the client.
  This is particularly good for connections that will be durable.

          9       load ../SSLtcl.so SSLtcl
      10
      11  #  I'm repeating this a few times to check for
      12  #  problems that may accumulate like file descriptor not being

      13  #  closed.
      14  proc read_sock {sock} {
      15    set l [gets $sock]
      16          if {[eof $sock]} {
      17                  close $sock
      18                  set eventLoop ''done''
      19          }
      20    puts stdout ''ServerReply:$l''
      21  }
      22
      23  # Read a line of text from stdin and send it to the echoserver socket,

      24  # on eof stdin closedown the echoserver client socket connection

      25  # this implements sending a message to the Server.
      26  proc read_stdin {wsock} {
      27          global  eventLoop
      28          set l [gets stdin]
      29          puts ''l: $l''
      30          if {[eof stdin]} {
      31                  close $wsock             ;# close the socket client connection

      32                  set eventLoop ''done''     ;# terminate the vwait (eventloop)

      33          } elseif {$l == ''Q''} {
      34                  puts $wsock $l
      35                  close $wsock
      36                  exit
      37          } elseif {$l == ''q''} {
      38                  puts $wsock $l
      39                  close $wsock
      40                  exit
      41          } else {
      42                  puts $wsock $l           ;# send the data to the server

      43    }
      44  }
      45
      46  # Create the socket and ssl enables it
      47  set s [socket -ssl -verify 1 -ciphers RC4-MD5 -cert demoCA/newcert.pem -key \

      48  demoCA/newkey.pem -CAfile demoCA/cacert.pem localhost 443]

      49
      50  puts $s
      51  fileevent $s readable [list read_sock $s]
      52  fconfigure $s -buffering line
      53  fileevent stdin readable [list read_stdin $s]
      54  vwait eventLoop
      55  puts ''Finished''

  In this we create the socket and then a callback for that socket with
  filevent on lines 47 and 51. We also creates a callback for
  standardin. This means that we can type something on the screen at it
  will be sent to the server. If something is on standardin we read it
  and sends it to the server.  If something is on the socket, we reads
  it and prints it to the terminal. On line 54 we go into an eventloop
  by waiting on an event on the variable eventLoop.

  The two scripts tstSrvRealNoSSL.tcl and tstCliRealNoSSL.tcl is exactly
  the same as the above scripts, except that they do not configure the
  socket for SSL (but it uses the socket command provided by SSLtcl.)