1''' 2''' 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, software 14# distributed under the License is distributed on an "AS IS" BASIS, 15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16# See the License for the specific language governing permissions and 17# limitations under the License. 18 19import hashlib 20import hmac 21 22Test.Summary = ''' 23Test url_sig plugin 24''' 25 26Test.ContinueOnFail = True 27 28# Skip if plugins not present. 29Test.SkipUnless(Condition.PluginExists('url_sig.so')) 30 31# Set up to check the output after the tests have run. 32# 33url_sig_log_id = Test.Disk.File("url_sig_short.log") 34url_sig_log_id.Content = "url_sig.gold" 35 36server = Test.MakeOriginServer("server") 37 38request_header = { 39 "headers": "GET /foo/abcde/qrstuvwxyz HTTP/1.1\r\nHost: just.any.thing\r\n\r\n", "timestamp": "1469733493.993", "body": "" 40} 41# expected response from the origin server 42response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 43# add response to the server dictionary 44server.addResponse("sessionfile.log", request_header, response_header) 45 46# Define default ATS. Disable the cache to make sure each request is forwarded 47# to the origin server. 48ts = Test.MakeATSProcess("ts", select_ports=True, enable_tls=True, enable_cache=False) 49 50ts.addDefaultSSLFiles() 51 52ts.Disk.records_config.update({ 53 # 'proxy.config.diags.debug.enabled': 1, 54 # 'proxy.config.diags.debug.tags': 'http|url_sig', 55 'proxy.config.proxy_name': 'Poxy_Proxy', # This will be the server name. 56 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir), 57 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir), 58}) 59 60ts.Disk.ssl_multicert_config.AddLine( 61 'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key' 62) 63 64# Use unchanged incoming URL. 65# 66ts.Disk.remap_config.AddLine( 67 'map http://one.two.three/ http://127.0.0.1:{}/'.format(server.Variables.Port) + 68 ' @plugin=url_sig.so @pparam={}/url_sig.config'.format(Test.TestDirectory) 69) 70 71# Use unchanged incoming HTTPS URL. 72# 73ts.Disk.remap_config.AddLine( 74 'map https://one.two.three/ http://127.0.0.1:{}/'.format(server.Variables.Port) + 75 ' @plugin=url_sig.so @pparam={}/url_sig.config'.format(Test.TestDirectory) 76) 77 78# Use pristine URL, incoming URL unchanged. 79# 80ts.Disk.remap_config.AddLine( 81 'map http://four.five.six/ http://127.0.0.1:{}/'.format(server.Variables.Port) + 82 ' @plugin=url_sig.so @pparam={}/url_sig.config @pparam=pristineurl'.format(Test.TestDirectory) 83) 84 85# Use pristine URL, incoming URL changed. 86# 87ts.Disk.remap_config.AddLine( 88 'map http://seven.eight.nine/ http://127.0.0.1:{}'.format(server.Variables.Port) + 89 ' @plugin=url_sig.so @pparam={}/url_sig.config @pparam=PristineUrl'.format(Test.TestDirectory) 90) 91 92# Validation failure tests. 93 94LogTee = " 2>&1 | grep '^<' | tee -a {}/url_sig_long.log".format(Test.RunDirectory) 95 96# Bad client / MD5 / P=101 / URL pristine / URL altered. 97# 98tr = Test.AddTestRun() 99tr.Processes.Default.StartBefore(ts) 100tr.Processes.Default.StartBefore(server, ready=When.PortOpen(server.Variables.Port)) 101tr.Processes.Default.ReturnCode = 0 102tr.Processes.Default.Command = ( 103 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 104 "foo/abcde/qrstuvwxyz?C=127.0.0.2&E=33046620008&A=2&K=13&P=101&S=d1f352d4f1d931ad2f441013402d93f8'" + 105 LogTee 106) 107 108# With client / MD5 / P=010 / URL pristine / URL altered -- Expired. 109# 110tr = Test.AddTestRun() 111tr.Processes.Default.ReturnCode = 0 112tr.Processes.Default.Command = ( 113 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 114 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=1&A=2&K=13&P=010&S=f237aad1fa010234d7bf8108a0e36387'" + 115 LogTee 116) 117 118# With client / No algorithm / P=101 / URL pristine / URL altered. 119# 120tr = Test.AddTestRun() 121tr.Processes.Default.ReturnCode = 0 122tr.Processes.Default.Command = ( 123 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 124 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&K=13&P=101&S=d1f352d4f1d931ad2f441013402d93f8'" + 125 LogTee 126) 127 128# With client / Bad algorithm / P=101 / URL pristine / URL altered. 129# 130tr = Test.AddTestRun() 131tr.Processes.Default.ReturnCode = 0 132tr.Processes.Default.Command = ( 133 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 134 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=3&K=13&P=101&S=d1f352d4f1d931ad2f441013402d93f8'" + 135 LogTee 136) 137 138# With client / MD5 / No parts / URL pristine / URL altered. 139# 140tr = Test.AddTestRun() 141tr.Processes.Default.ReturnCode = 0 142tr.Processes.Default.Command = ( 143 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 144 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=2&K=13&S=d1f352d4f1d931ad2f441013402d93f8'" + 145 LogTee 146) 147 148# With client / MD5 / P=10 (bad) / URL pristine / URL altered. 149# 150tr = Test.AddTestRun() 151tr.Processes.Default.ReturnCode = 0 152tr.Processes.Default.Command = ( 153 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 154 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=2&K=13&P=10&S=d1f352d4f1d931ad2f441013402d93f8'" + 155 LogTee 156) 157 158# With client / MD5 / P=101 / URL pristine / URL altered -- No signature. 159# 160tr = Test.AddTestRun() 161tr.Processes.Default.ReturnCode = 0 162tr.Processes.Default.Command = ( 163 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 164 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=2&K=13&P=101'" + 165 LogTee 166) 167 168# With client / MD5 / P=101 / URL pristine / URL altered -- Bad signature. 169# 170tr = Test.AddTestRun() 171tr.Processes.Default.ReturnCode = 0 172tr.Processes.Default.Command = ( 173 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 174 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=2&K=13&P=101&S=d1f452d4f1d931ad2f441013402d93f8'" + 175 LogTee 176) 177 178# With client / MD5 / P=101 / URL pristine / URL altered -- Spurious &. 179# 180tr = Test.AddTestRun() 181tr.Processes.Default.ReturnCode = 0 182tr.Processes.Default.Command = ( 183 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 184 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=2&&K=13&P=101&S=d1f352d4f1d931ad2f441013402d93f8#'" + 185 LogTee 186) 187 188# Success tests. 189 190# With client / SHA1 / P=1 / URL pristine / URL not altered. 191# 192tr = Test.AddTestRun() 193tr.Processes.Default.ReturnCode = 0 194tr.Processes.Default.Command = ( 195 "curl --verbose --proxy http://127.0.0.1:{} 'http://four.five.six/".format(ts.Variables.port) + 196 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046618556&A=1&K=15&P=1&S=f4103561a23adab7723a89b9831d77e0afb61d92'" + 197 LogTee 198) 199 200# No client / MD5 / P=1 / URL pristine / URL altered. 201# 202tr = Test.AddTestRun() 203tr.Processes.Default.ReturnCode = 0 204tr.Processes.Default.Command = ( 205 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 206 "foo/abcde/qrstuvwxyz?E=33046618586&A=2&K=0&P=1&S=0364efa28afe345544596705b92d20ac'" + 207 LogTee 208) 209 210# With client / MD5 / P=010 / URL pristine / URL altered. 211# 212tr = Test.AddTestRun() 213tr.Processes.Default.ReturnCode = 0 214tr.Processes.Default.Command = ( 215 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 216 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046619717&A=2&K=13&P=010&S=f237aad1fa010234d7bf8108a0e36387'" + 217 LogTee 218) 219 220# With client / MD5 / P=101 / URL pristine / URL altered. 221# 222tr = Test.AddTestRun() 223tr.Processes.Default.ReturnCode = 0 224tr.Processes.Default.Command = ( 225 "curl --verbose --proxy http://127.0.0.1:{} 'http://seven.eight.nine/".format(ts.Variables.port) + 226 "foo/abcde/qrstuvwxyz?C=127.0.0.1&E=33046620008&A=2&K=13&P=101&S=d1f352d4f1d931ad2f441013402d93f8'" + 227 LogTee 228) 229 230 231def sign(payload, key): 232 secret = bytes(key, 'utf-8') 233 data = bytes(payload, 'utf-8') 234 md = bytes(hmac.new(secret, data, digestmod=hashlib.sha1).digest().hex(), 'utf-8') 235 return md.decode("utf-8") 236 237 238# No client / SHA1 / P=1 / URL not pristine / URL not altered. 239# 240path = "foo/abcde/qrstuvwxyz?E=33046618506&A=1&K=7&P=1&S=" 241to_sign = "127.0.0.1:{}/".format(server.Variables.Port) + path 242url = "http://one.two.three/" + path + sign(to_sign, "dqsgopTSM_doT6iAysasQVUKaPykyb6e") 243 244tr = Test.AddTestRun() 245tr.Processes.Default.ReturnCode = 0 246tr.Processes.Default.Command = ( 247 "curl --verbose --proxy http://127.0.0.1:{} '{}'".format(ts.Variables.port, url) + LogTee 248) 249 250# No client / SHA1 / P=1 / URL not pristine / URL not altered -- HTTPS. 251# 252path = "foo/abcde/qrstuvwxyz?E=33046618506&A=1&K=7&P=1&S=" 253to_sign = "127.0.0.1:{}/".format(server.Variables.Port) + path 254url = "https://127.0.0.1:{}/".format(ts.Variables.ssl_port) + path + sign(to_sign, "dqsgopTSM_doT6iAysasQVUKaPykyb6e") 255 256tr = Test.AddTestRun() 257tr.Processes.Default.ReturnCode = 0 258tr.Processes.Default.Command = ( 259 "curl --verbose --http1.1 --insecure --header 'Host: one.two.three' '{}'".format(url) + 260 LogTee + " ; grep -F -e '< HTTP' -e Authorization {0}/url_sig_long.log > {0}/url_sig_short.log ".format(ts.RunDirectory) 261) 262 263# Overriding the built in ERROR check since we expect some ERROR messages 264ts.Disk.diags_log.Content = Testers.ContainsExpression("ERROR", "Some tests are failure tests") 265ts.Disk.diags_log.Content += Testers.ExcludesExpression("Error parsing", "Verify that we can accept long comment lines") 266