TCL TLS

  • Creator
    Topic
  • #55335
    Dave Scoggins
    Participant

    I found myself in need of trying to create a TCL script using the TLS package. I will be using this TCL script for submission of immunization records to our state registry. I don’t see that we have TLS package installed though I do see that I can download it from the sourceforege.net website.

    When I download the .gz file and extract the files, where in my TCL directory do I want to place the files? Do they need to go in the tcllib1.14 directory or in their own directory? The file structure on the Cloverleaf server is as follows: cis6.0/integrator/tcl/lib/tcllib1.14

    Also, does anybody have a TCL script they’d be willing to share that will create a secure connection using TLSv1.2 to a vendor? I just need to get a sense of what code I need for establishing the connection and sending the VXU messages.

    Thank you for any assistance you may be able to provide.

Viewing 1 reply thread
  • Author
    Replies
    • #85002
      David Barr
      Participant

      Here’s some code that we use.

      Code:

      #!/usr/bin/env tcl

      proc socketcmd { listenport sock ip_addr port } {
         echo [clock format [clock seconds]]: socket connected on $listenport
         set pd $::portdata($listenport)
         keylget pd USERID userid
         keylget pd PASSWORD password
         keylget pd URL url
         keylget pd RCPT rcpt

         fconfigure $sock -blocking 0 -translation binary
         fileevent $sock readable [list iocmd $listenport $sock $ip_addr $port $userid $password $url $rcpt]
      }

      proc iocmd { listenport sock ip_addr port userid password url rcpt } {
         set data “”
         echo iocmd $listenport $sock $ip_addr $port $userid $password $url $rcpt
         while { 1 } {
             if { [eof $sock] } {
                 echo [clock format [clock seconds]]: socket closed
                 return [close $sock]
             }
             append data [read $sock]
             #echo data = “{$data}”
             if { [regexp {^.*x0b([^x0b]*)x1cx0d$} $data -> msg] } {
                 #echo msg = $msg
                 echo [clock format [clock seconds]]: received message from Cloverleaf on $listenport
                 set replymsg [postmsg $msg $url $userid $password $rcpt]
                 set data “”
                 puts -nonewline $sock “x0b$replymsgx1cx0d”
                 flush $sock
                 return
             } else {
                 # incomplete msg
                 after 1000
             }
         }
         close $sock
      }

      proc postmsg { msg url userid password rcpt } {
         package require http
         package require tls
         package require hl7
         ::http::register https 443 ::tls::socket

         ::tls::init -tls1 1

         set disp CONTINUE
         set errdisp ERROR

      #     puts “Message:n[join [split $msg r] n]”
      #     puts “End of messagen”

         set qry [::http::formatQuery USERID $userid PASSWORD $password MESSAGEDATA $msg]

         set result [catch {::http::geturl $url -query $qry -timeout 50000} token]
         echo http::geturl = $result
         flush stdout

         if { $result } {
             return [myack $msg $token]
         } else {
             upvar #0 $token state
             if { [::http::status $token] ne “ok” } {
                 # geturl returned success, but status is not ok.
                 # this usually happens when the web server closes the
                 # connection before responding.
                 return [myack $msg “http::status = [::http::status $token]”]
             } elseif { [::http::ncode $token] / 100 != 2 } {
                 # unsuccessful HTTP response code
                 parray state
                 return [myack $msg “http::code = [::http::code $token]”]
             } else {
                 set replymsg [::http::data $token]
                 echo replymsg = [split $replymsg n]
                 set replymsg “[join [lsearch -inline -all -exact -not [split $replymsg n] {}] r]r”
                 set hl7 [hl7::parse_msg $replymsg]
                 if { [hl7::get_field hl7 MSA.1] eq “AE” } {
                     if { [regexp {^Not logged in:} [hl7::get_field hl7 MSA.3]] } {
                         # retry on temporary failures
                         hl7::set_field hl7 MSA.1 “AR”
                         set replymsg [hl7::join_msg hl7]
                         echo ‘received temporary error; changed to AR’
                         echo sleeping for 30 seconds
                         after 30000
                         echo done sleeping
                     } else {
                         hl7::set_field hl7 MSA.1 “AA” ;# send AA to Cloverleaf
                         set replymsg [hl7::join_msg hl7]
                         send_mail $msg $hl7 $rcpt
                     }
                 } elseif { [hl7::get_field hl7 MSA.1] eq “AR” } {
                     if { [regexp {^Processing error prevented the completion of this request:} [hl7::get_field hl7 ERR.8]] } {
                         hl7::set_field hl7 MSA.1 “AA” ;# send AA to Cloverleaf
                         send_mail $msg $hl7 $rcpt
                         hl7::delete_seg hl7 ERR
                         set replymsg [hl7::join_msg hl7]
                     }
                 }
                 echo forwarding reply from child
                 return $replymsg
             }
         }
      }

      proc myack { msg errmsg } {
         echo creating nak message: $errmsg
         set mh [msgcreate $msg]
         keylset args2 MODE run
         keylset args2 MSGID $mh
         keylset args2 CONTEXT sms_ib_data
         set replymsg “”
         foreach dispItem [eval “hl7Raw_ack_vmc $args2″] {
             lassign $dispItem disp newmh
             if { $disp eq “OVER” } {
                 set replymsg [msgget $newmh]
             }
             msgdestroy $newmh
         }
         #echo replymsg = $replymsg
         set hl7 [hl7::parse_msg $replymsg]
         hl7::set_field hl7 MSA.1 “AR”
         hl7::set_field hl7 MSA.3 “proxy error: $errmsg”
         echo sleeping for 30 seconds
         after 30000
         echo done sleeping
         return [hl7::join_msg hl7]
      }

      proc send_mail { hl7msg hl7ack rcpt } {
         package require mime
         package require smtp

         set hl7 [hl7::parse_msg $hl7msg]
         set body “nPatient MRN: [hl7::get_field hl7 PID.3.1]”
         append body “nPatient Name: [hl7::get_field hl7 PID.5]”
         append body “nAdministration date: [hl7::get_field hl7 RXA.4]”
         append body “nAdministered code: [hl7::get_field hl7 RXA.5]”
         append body “nError message: [hl7::get_field hl7ack ERR.8]”
         append body “nMessage ID: [hl7::get_field hl7 MSH.10]”

         append body “nn[string map { r n } $hl7msg]”

         #set body [string map { r n } $hl7]
         #append body [string map { r n } [hl7::join_msg hl7ack]]

         # rxa 4 admin date
         # rxa 5 admin code

         set textT [mime::initialize -canonical text/plain -string $body]

         # create a multipart containing both, and a timestamp
         set multiT [mime::initialize -canonical multipart/mixed
                         -parts [list $textT]]

         # call Sendmail to deliver the message
         #set rcpt “David_Barr@valleymed.org”
         set rcpt2 [join $rcpt ” “]
         set fp [open “|/usr/sbin/sendmail $rcpt2” w]
         puts $fp “To: [join $rcpt ,]”
         puts $fp “From: “VMC.QDX Integrator production mode.” ”
         puts $fp “Subject: child profile error”
         #Date: Wed, 02 Mar 2008 16:34:00 -0700
         puts $fp [::mime::buildmessage $multiT]
         close $fp
      }

      set HciConnName dummy

      foreach { what port data } [read_file $HciRoot/scripts/child-proxy.cfg] {
         socket -server “socketcmd $port” $port
         set ::portdata($port) $data
      }

      vwait forever

    • #85003
      Dave Scoggins
      Participant

      Thank you David. I’ll work with it tomorrow. Hopefully it’ll work for our needs.

Viewing 1 reply thread
  • The forum ‘Cloverleaf’ is closed to new topics and replies.

Forum Statistics

Registered Users
5,129
Forums
28
Topics
9,301
Replies
34,447
Topic Tags
288
Empty Topic Tags
10