A scripted update to formats of log messages:
[stompngo_examples.git] / tlsexamps / tlsuc2 / tlsuc2.go
blob7ee186ad4830378d22bb4319c5288f8e7cbd0da8
1 //
2 // Copyright © 2013-2016 Guy M. Allard
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 Connect and Disconnect from a STOMP broker with a TLS connection, use case 2.
20 TLS Use Case 2 - client *does* authenticate broker.
22 Subcase 2.A - Message broker configuration does *not* require client authentication
24 - Expect connection success because the client did authenticate the
25 broker's certificate.
27 Subcase 2.B - Message broker configuration *does* require client authentication
29 - Expect connection failure (broker must be sent a valid client certificate)
31 Example use might be:
33 go build
34 ./tlsuc2 -srvCAFile=/ad3/gma/sslwork/2013/TestCA.crt # PEM format file
37 package main
39 import (
40 "crypto/tls"
41 "crypto/x509"
42 "encoding/pem"
43 "flag"
44 "io/ioutil"
45 "log"
46 "net"
47 "os"
49 "github.com/gmallard/stompngo"
50 // senv methods could be used in general by stompngo clients.
51 "github.com/gmallard/stompngo/senv"
52 // sngecomm methods are used specifically for these example clients.
53 "github.com/gmallard/stompngo_examples/sngecomm"
56 var (
57 exampid = "tlsuc2:"
58 tc *tls.Config
59 srvCAFile string // Name of file with broker's CA certificate, PEM format
61 ll = log.New(os.Stdout, "TLSU2 ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
64 func init() {
65 flag.StringVar(&srvCAFile, "srvCAFile", "DUMMY", "Name of file with broker CA certificate")
68 // Connect to a STOMP broker using TLS and disconnect.
69 func main() {
70 ll.Printf("%s starts\n", exampid)
72 flag.Parse() // Parse flags
73 ll.Printf("%s using srvCAFile srvCAFile:%s\n",
74 exampid, srvCAFile)
76 // TLS Configuration.
77 tc = new(tls.Config)
78 tc.InsecureSkipVerify = false // *Do* check the broker's certificate
80 // Get host and port
81 h, p := senv.HostAndPort()
82 ll.Printf("%s host_and_port host:%s port:%s\n", exampid, h, p)
84 // Be polite, allow SNI (Server Virtual Hosting)
85 tc.ServerName = h
87 // Finish TLS Config initialization, so client can authenticate broker.
88 b, e := ioutil.ReadFile(srvCAFile) // Read broker's CA cert (PEM)
89 if e != nil {
90 ll.Fatalf("%s %s\n", exampid, e.Error())
92 k, _ := pem.Decode(b) // Decode PEM format (*pem.Block)
93 if k == nil {
94 ll.Fatalf("%s %s\n", exampid, e.Error())
96 c, e := x509.ParseCertificate(k.Bytes) // Create *x509.Certificate
97 if e != nil {
98 ll.Fatalf("%s %s\n", exampid, e.Error())
101 tc.RootCAs = x509.NewCertPool() // Create a cert "pool"
102 tc.RootCAs.AddCert(c) // Add the CA cert to the pool
104 // Connect logic: use net.Dial and tls.Client
105 hap := net.JoinHostPort(h, p)
106 t, e := net.Dial("tcp", hap)
107 if e != nil {
108 ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ......
110 ll.Printf("%s dial_complete\n", exampid)
112 nc := tls.Client(t, tc)
113 e = nc.Handshake()
114 if e != nil {
115 if e.Error() == "EOF" {
116 ll.Printf("%s handshake EOF, Is the broker port TLS enabled? port:%s\n",
117 exampid, p)
119 ll.Fatalf("%s v1:%v v2:%v\n", exampid, "netHandshake", e) // Handle this .....
121 ll.Printf("%s handshake_complete\n", exampid)
123 sngecomm.DumpTLSConfig(exampid, tc, nc)
125 // stompngo Connect Headers
126 ch := sngecomm.ConnectHeaders()
127 // Get a stomp connection. Parameters are:
128 // a) the opened net connection
129 // b) the connect Headers
130 conn, e := stompngo.Connect(nc, ch)
131 if e != nil {
132 ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ......
134 ll.Printf("%s connsess:%s stomp_connect_complete\n",
135 exampid, conn.Session())
137 // *NOTE* your application functionaltiy goes here!
139 // Polite Stomp disconnects are not required, but highly recommended.
140 // Empty headers here.
141 e = conn.Disconnect(stompngo.Headers{})
142 if e != nil {
143 ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ......
145 ll.Printf("%s connsess:%s stomp_disconnect_complete\n",
146 exampid, conn.Session())
148 // Close the net connection.
149 e = nc.Close()
150 if e != nil {
151 ll.Fatalf("%s %s\n", exampid, e.Error()) // Handle this ......
153 ll.Printf("%s connsess:%s net_close_complete\n",
154 exampid, conn.Session())
156 ll.Printf("%s ends\n", exampid)