comparison Tests/CheckDicomTls.py @ 375:08fac54c8555 Orthanc-1.9.0

CheckDicomTls.py
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 28 Jan 2021 15:52:41 +0100
parents
children f454fe86061b
comparison
equal deleted inserted replaced
374:78bef07c4118 375:08fac54c8555
1 #!/usr/bin/python
2
3 # Orthanc - A Lightweight, RESTful DICOM Store
4 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
5 # Department, University Hospital of Liege, Belgium
6 # Copyright (C) 2017-2021 Osimis S.A., Belgium
7 #
8 # This program is free software: you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation, either version 3 of the
11 # License, or (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21
22
23 import argparse
24 import os
25 import pprint
26 import re
27 import sys
28 import subprocess
29 import unittest
30
31 from Toolbox import *
32
33
34 ##
35 ## Parse the command-line arguments
36 ##
37
38 parser = argparse.ArgumentParser(description = 'Run the integration tests for DICOM TLS in Orthanc.')
39
40 parser.add_argument('--server',
41 default = 'localhost',
42 help = 'Address of the Orthanc server to test')
43 parser.add_argument('--aet',
44 default = 'ORTHANC',
45 help = 'AET of the Orthanc instance to test')
46 parser.add_argument('--dicom',
47 type = int,
48 default = 4242,
49 help = 'DICOM port of the Orthanc instance to test')
50 parser.add_argument('--rest',
51 type = int,
52 default = 8042,
53 help = 'Port to the REST API')
54 parser.add_argument('--username',
55 default = 'alice',
56 help = 'Username to the REST API')
57 parser.add_argument('--password',
58 default = 'orthanctest',
59 help = 'Password to the REST API')
60 parser.add_argument('--force', help = 'Do not warn the user',
61 action = 'store_true')
62 parser.add_argument('--config', help = 'Create the configuration files for this test in the current folder',
63 action = 'store_true')
64 parser.add_argument('options', metavar = 'N', nargs = '*',
65 help='Arguments to Python unittest')
66
67 args = parser.parse_args()
68
69
70 ##
71 ## Configure the testing context
72 ##
73
74
75 if args.config:
76 def CreateCertificate(name):
77 subprocess.check_call([ 'openssl', 'req', '-x509', '-nodes', '-days', '365', '-newkey', 'rsa:2048',
78 '-keyout', '%s.key' % name,
79 '-out', '%s.crt' % name,
80 '-subj', '/C=BE/CN=localhost' ])
81
82 print('Writing configuration to folder: %s' % args.config)
83 CreateCertificate('dicom-tls-a')
84 CreateCertificate('dicom-tls-b')
85 CreateCertificate('dicom-tls-c') # Not trusted by Orthanc
86
87 with open('dicom-tls-trusted.crt', 'w') as f:
88 for i in [ 'dicom-tls-a.crt', 'dicom-tls-b.crt' ]:
89 with open(i, 'r') as g:
90 f.write(g.read())
91
92 with open('dicom-tls.json', 'w') as f:
93 f.write(json.dumps({
94 'DicomTlsEnabled' : True,
95 'DicomTlsCertificate' : 'dicom-tls-a.crt',
96 'DicomTlsPrivateKey' : 'dicom-tls-a.key',
97 'DicomTlsTrustedCertificates' : 'dicom-tls-trusted.crt',
98 'ExecuteLuaEnabled' : True,
99 'RemoteAccessAllowed' : True,
100 'RegisteredUsers' : {
101 'alice' : 'orthanctest'
102 },
103 }))
104
105 exit(0)
106
107
108 if not args.force:
109 print("""
110 WARNING: This test will remove all the content of your
111 Orthanc instance running on %s!
112
113 Are you sure ["yes" to go on]?""" % args.server)
114
115 if sys.stdin.readline().strip() != 'yes':
116 print('Aborting...')
117 exit(0)
118
119
120 ORTHANC = DefineOrthanc(server = args.server,
121 username = args.username,
122 password = args.password,
123 restPort = args.rest,
124 aet = args.aet,
125 dicomPort = args.dicom)
126
127
128 ##
129 ## The tests
130 ##
131
132
133 FNULL = open(os.devnull, 'w') # Emulates "subprocess.DEVNULL" on Python 2.7
134
135
136 class Orthanc(unittest.TestCase):
137 def setUp(self):
138 if (sys.version_info >= (3, 0)):
139 # Remove annoying warnings about unclosed socket in Python 3
140 import warnings
141 warnings.simplefilter('ignore', ResourceWarning)
142
143 DropOrthanc(ORTHANC)
144
145
146 def test_incoming(self):
147 # No certificate
148 self.assertRaises(Exception, lambda: subprocess.check_call([
149 FindExecutable('echoscu'),
150 ORTHANC['Server'],
151 str(ORTHANC['DicomPort']),
152 '-aec', 'ORTHANC',
153 ], stderr = FNULL))
154
155 subprocess.check_call([
156 FindExecutable('echoscu'),
157 ORTHANC['Server'],
158 str(ORTHANC['DicomPort']),
159 '-aec', 'ORTHANC',
160 '+tls', 'dicom-tls-b.key', 'dicom-tls-b.crt',
161 '+cf', 'dicom-tls-a.crt',
162 ], stderr = FNULL)
163
164 self.assertRaises(Exception, lambda: subprocess.check_call([
165 FindExecutable('echoscu'),
166 ORTHANC['Server'],
167 str(ORTHANC['DicomPort']),
168 '-aec', 'ORTHANC',
169 '+tls', 'dicom-tls-c.key', 'dicom-tls-c.crt', # Not trusted by Orthanc
170 '+cf', 'dicom-tls-a.crt',
171 ], stderr = FNULL))
172
173 self.assertRaises(Exception, lambda: subprocess.check_call([
174 FindExecutable('echoscu'),
175 ORTHANC['Server'],
176 str(ORTHANC['DicomPort']),
177 '-aec', 'ORTHANC',
178 '+tls', 'dicom-tls-b.key', 'dicom-tls-b.crt',
179 '+cf', 'dicom-tls-b.crt', # Not the certificate of Orthanc
180 ], stderr = FNULL))
181
182
183 def test_outgoing_to_self(self):
184 u = UploadInstance(ORTHANC, 'DummyCT.dcm') ['ID']
185
186 # Error, as DICOM TLS is not enabled
187 DoPut(ORTHANC, '/modalities/self', {
188 'AET' : 'ORTHANC',
189 'Host' : ORTHANC['Server'],
190 'Port' : ORTHANC['DicomPort'],
191 })
192
193 self.assertRaises(Exception, lambda: DoPost(ORTHANC, '/modalities/self/store', u))
194
195 # Retry using DICOM TLS
196 DoPut(ORTHANC, '/modalities/self', {
197 'AET' : 'ORTHANC',
198 'Host' : ORTHANC['Server'],
199 'Port' : ORTHANC['DicomPort'],
200 'UseDicomTls' : True,
201 })
202
203 self.assertEqual(1, DoPost(ORTHANC, '/modalities/self/store', u) ['InstancesCount'])
204
205
206 try:
207 print('\nStarting the tests...')
208 unittest.main(argv = [ sys.argv[0] ] + args.options)
209
210 finally:
211 print('\nDone')