Skip to content

Commit e139323

Browse files
committed
Added MQSCO structure for better TLS controls
1 parent a20b130 commit e139323

File tree

6 files changed

+245
-103
lines changed

6 files changed

+245
-103
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,9 @@ See the [README](cmd/mq_json/README.md) for more details.
170170
* Removed xxx_CURRENT_LENGTH definitions from cmqc
171171

172172
10 Jan 2017
173-
* Added support for the MQCD structure to allow programmable client
174-
connectivity, without requiring a CCDT. See the clienttest program
175-
for an example of using it.
173+
* Added support for the MQCD and MQSCO structures to allow programmable client
174+
connectivity, without requiring a CCDT. See the clientconn sample program
175+
for an example of using the MQCD.
176176
* Moved sample programs into subdirectory
177177

178178
## Health Warning

cmd/samples/clientconn/clientconn.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
This is a short sample to show how to connect to a remote
3+
queue manager in a Go program without requiring external
4+
client configuration such as a CCDT. Only the basic
5+
parameters are needed here - channel name and connection information -
6+
along with the queue manager name.
7+
8+
For example, run as
9+
clientconn QMGR1 "SYSTEM.DEF.SVRCONN" "myhost.example.com(1414)"
10+
11+
If the MQSAMP_USER_ID environment variable is set, then a userid/password
12+
flow is also made to authenticate to the queue manager.
13+
14+
There is no attempt in this sample to configure advanced security features
15+
such TLS.
16+
17+
If an error occurs, the error is reported.
18+
*/
19+
package main
20+
21+
/*
22+
Copyright (c) IBM Corporation 2017
23+
24+
Licensed under the Apache License, Version 2.0 (the "License");
25+
you may not use this file except in compliance with the License.
26+
You may obtain a copy of the License at
27+
28+
http://www.apache.org/licenses/LICENSE-2.0
29+
30+
Unless required by applicable law or agreed to in writing, software
31+
distributed under the License is distributed on an "AS IS" BASIS,
32+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33+
See the License for the specific
34+
35+
Contributors:
36+
Mark Taylor - Initial Contribution
37+
*/
38+
39+
import (
40+
"bufio"
41+
"fmt"
42+
"ibmmq"
43+
"os"
44+
"time"
45+
)
46+
47+
func main() {
48+
var qMgrName string
49+
var err error
50+
var qMgr ibmmq.MQQueueManager
51+
52+
if len(os.Args) != 4 {
53+
fmt.Println("clientconn <qmgrname> <channelname> <conname>")
54+
fmt.Println("")
55+
fmt.Println("For example")
56+
fmt.Println(" clientconn QMGR1 \"SYSTEM.DEF.SVRCONN\" \"myhost.example.com(1414)\"")
57+
fmt.Println("All parameters are required.")
58+
os.Exit(1)
59+
}
60+
61+
// Which queue manager do we want to connect to
62+
qMgrName = os.Args[1]
63+
64+
// Allocate the MQCNO and MQCD structures needed for the
65+
// MQCONNX call.
66+
cno := ibmmq.NewMQCNO()
67+
cd := ibmmq.NewMQCD()
68+
69+
// Fill in the required fields in the
70+
// MQCD channel definition structure
71+
cd.ChannelName = os.Args[2]
72+
cd.ConnectionName = os.Args[3]
73+
74+
// Reference the CD structure from the CNO
75+
// and indicate that we want to use the client
76+
// connection method.
77+
cno.ClientConn = cd
78+
cno.Options = ibmmq.MQCNO_CLIENT_BINDING
79+
80+
// Also fill in the userid and password if the MQSAMP_USER_ID
81+
// environment variable is set. This is the same as the C
82+
// sample programs such as amqsput.
83+
userId := os.Getenv("MQSAMP_USER_ID")
84+
if userId != "" {
85+
scanner := bufio.NewScanner(os.Stdin)
86+
csp := ibmmq.NewMQCSP()
87+
csp.AuthenticationType = ibmmq.MQCSP_AUTH_USER_ID_AND_PWD
88+
csp.UserId = userId
89+
90+
fmt.Println("Enter password : ")
91+
scanner.Scan()
92+
csp.Password = scanner.Text()
93+
94+
// And make the CNO refer to the CSP structure
95+
cno.SecurityParms = csp
96+
}
97+
98+
// And connect. Wait a short time before
99+
// disconnecting.
100+
qMgr, mqreturn, err := ibmmq.Connx(qMgrName, cno)
101+
if err == nil {
102+
fmt.Printf("Connection to %s succeeded.\n", qMgrName)
103+
d, _ := time.ParseDuration("5s")
104+
time.Sleep(d)
105+
qMgr.Disc()
106+
} else {
107+
fmt.Printf("Connection to %s failed.\n", qMgrName)
108+
fmt.Println(err)
109+
}
110+
111+
fmt.Println("Done.")
112+
os.Exit((int)(mqreturn.MQCC))
113+
114+
}

cmd/samples/clienttest/clienttest.go

Lines changed: 0 additions & 89 deletions
This file was deleted.

ibmmq/mqiMQCD.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ MQ_CLIENT_CONN_DEFAULT structure for consistency.
9797
func copyCDtoC(mqcd *C.MQCD, gocd *MQCD) {
9898

9999
setMQIString((*C.char)(&mqcd.ChannelName[0]), gocd.ChannelName, C.MQ_CHANNEL_NAME_LENGTH)
100-
mqcd.Version = C.MQCD_VERSION_11
100+
mqcd.Version = C.MQCD_VERSION_11 // The version this is written to match
101101
mqcd.ChannelType = C.MQCHT_CLNTCONN
102102
mqcd.TransportType = C.MQXPT_TCP
103103
setMQIString((*C.char)(&mqcd.Desc[0]), "", C.MQ_CHANNEL_DESC_LENGTH)
@@ -139,7 +139,7 @@ func copyCDtoC(mqcd *C.MQCD, gocd *MQCD) {
139139
mqcd.HeartbeatInterval = 1
140140
mqcd.BatchInterval = 0
141141
mqcd.NonPersistentMsgSpeed = C.MQNPMS_FAST
142-
mqcd.StrucLength = C.MQCD_CURRENT_LENGTH
142+
mqcd.StrucLength = C.MQCD_LENGTH_11
143143
mqcd.ExitNameLength = C.MQ_EXIT_NAME_LENGTH
144144
mqcd.ExitDataLength = C.MQ_EXIT_DATA_LENGTH
145145
mqcd.MsgExitsDefined = 0

ibmmq/mqiMQCNO.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type MQCNO struct {
4040
SecurityParms *MQCSP
4141
CCDTUrl string
4242
ClientConn *MQCD
43+
SSLConfig *MQSCO
4344
}
4445

4546
/*
@@ -82,41 +83,52 @@ func copyCNOtoC(mqcno *C.MQCNO, gocno *MQCNO) {
8283
var i int
8384
var mqcsp C.PMQCSP
8485
var mqcd C.PMQCD
86+
var mqsco C.PMQSCO
8587

8688
setMQIString((*C.char)(&mqcno.StrucId[0]), "CNO ", 4)
8789
mqcno.Version = C.MQLONG(gocno.Version)
8890
mqcno.Options = C.MQLONG(gocno.Options)
8991

90-
mqcno.ClientConnOffset = 0
91-
mqcno.ClientConnPtr = nil
92-
9392
for i = 0; i < C.MQ_CONN_TAG_LENGTH; i++ {
9493
mqcno.ConnTag[i] = 0
9594
}
9695
for i = 0; i < C.MQ_CONNECTION_ID_LENGTH; i++ {
9796
mqcno.ConnectionId[i] = 0
9897
}
9998

100-
mqcno.SSLConfigOffset = 0
101-
mqcno.SSLConfigPtr = nil
102-
99+
mqcno.ClientConnOffset = 0
103100
if gocno.ClientConn != nil {
104101
gocd := gocno.ClientConn
105-
mqcd = C.PMQCD(C.malloc(C.MQCD_CURRENT_LENGTH))
102+
mqcd = C.PMQCD(C.malloc(C.MQCD_LENGTH_11))
106103
copyCDtoC(mqcd, gocd)
107104
mqcno.ClientConnPtr = C.MQPTR(mqcd)
108105
if gocno.Version < 2 {
109106
mqcno.Version = C.MQCNO_VERSION_2
110107
}
108+
} else {
109+
mqcno.ClientConnPtr = nil
110+
}
111+
112+
mqcno.SSLConfigOffset = 0
113+
if gocno.SSLConfig != nil {
114+
gosco := gocno.SSLConfig
115+
mqsco = C.PMQSCO(C.malloc(C.MQSCO_LENGTH_5))
116+
copySCOtoC(mqsco, gosco)
117+
mqcno.SSLConfigPtr = C.PMQSCO(mqsco)
118+
if gocno.Version < 4 {
119+
mqcno.Version = C.MQCNO_VERSION_4
120+
}
121+
} else {
122+
mqcno.SSLConfigPtr = nil
111123
}
112124

113125
mqcno.SecurityParmsOffset = 0
114126
if gocno.SecurityParms != nil {
115127
gocsp := gocno.SecurityParms
116128

117-
mqcsp = C.PMQCSP(C.malloc(C.MQCSP_CURRENT_LENGTH))
129+
mqcsp = C.PMQCSP(C.malloc(C.MQCSP_LENGTH_1))
118130
setMQIString((*C.char)(&mqcsp.StrucId[0]), "CSP ", 4)
119-
mqcsp.Version = C.MQCSP_CURRENT_VERSION
131+
mqcsp.Version = C.MQCSP_VERSION_1
120132
mqcsp.AuthenticationType = C.MQLONG(gocsp.AuthenticationType)
121133
mqcsp.CSPUserIdOffset = 0
122134
mqcsp.CSPPasswordOffset = 0
@@ -166,6 +178,11 @@ func copyCNOfromC(mqcno *C.MQCNO, gocno *MQCNO) {
166178
C.free(unsafe.Pointer(mqcno.ClientConnPtr))
167179
}
168180

181+
if mqcno.SSLConfigPtr != nil {
182+
copySCOfromC(C.PMQSCO(mqcno.SSLConfigPtr), gocno.SSLConfig)
183+
C.free(unsafe.Pointer(mqcno.SSLConfigPtr))
184+
}
185+
169186
if mqcno.CCDTUrlPtr != nil {
170187
C.free(unsafe.Pointer(mqcno.CCDTUrlPtr))
171188
}

0 commit comments

Comments
 (0)