Review Board 1.7.16


Testsuite: For httpd server, need option to define server name for security purposes

Review Request #4377 - Created Jan. 26, 2015 and submitted

Ashley Sanders
testsuite
ASTERISK-24316
Reviewers
asterisk-dev
testsuite
Currently, all responses from the Asterisk HTTP server contain a [Server] header that identifies Asterisk and its version (e.g. "Server:Asterisk/<version>", where <version> is the currently running version of Asterisk). The preferred behavior is to allow the user to configure an alternate name to use for the value returned in the [Server] header for HTTP responses (e.g. "Server:SomeSuperAwesomeServerName").

This patch to the Asterisk source provides a new configuration property, [servername], in http.conf, that gives users the ability to modify the value that Asterisk uses when identifying itself. 

This test verifies that the HTTP server correctly reports the expected name through the [Server] header field in all HTTP responses. It uses three instances of Asterisk to test the three possible logic paths:
1) No configuration was provided
2) A non-empty/non-null value was provided through the new configuration property [servername]
3) An empty/null value was provided through the new configuration property [servername]

For clarity, consider this example for the possible outcomes as described above, respectively:
1) There was nothing configured for [servername].
2) The user configured a non-empty value for [servername] (e.g. servername="JohnMcClane")
3) The user configured an empty/null value for [servername] (e.g. servername="")

The HTTP server is expected to create the [Server] header field as follows, respectively:
1) Server: Asterisk/<version>
2) Server: JohnMcClane
3) 

In case #3, the [Server] header field will be omitted from HTTP response headers.

***Note*** This is the test. It is only the test. You can find the review for the Asterisk source at: https://reviewboard.asterisk.org/r/4374/

 

Changes between revision 1 and 2

1 2
1 2

  1. ./asterisk/trunk/tests/http_server/servername/run-test: Loading...
./asterisk/trunk/tests/http_server/servername/run-test
Diff Revision 1 Diff Revision 2
1
#!/usr/bin/env python
1
#!/usr/bin/env python
2
"""
2
"""
3
Copyright (C) 2015, Digium, Inc.
3
Copyright (C) 2015, Digium, Inc.
4
Ashley Sanders <asanders@digium.com>
4
Ashley Sanders <asanders@digium.com>
5

    
   
5

   
6
This program is free software, distributed under the terms of
6
This program is free software, distributed under the terms of
7
the GNU General Public License Version 2.
7
the GNU General Public License Version 2.
8
"""
8
"""
9

    
   
9

   
10

    
   
10

   
11
import logging
11
import logging
12
import requests
12
import requests
13
import sys
13
import sys
14

    
   
14

   
15
sys.path.append("lib/python")
15
sys.path.append("lib/python")
16

    
   
16

   
17
from twisted.internet import reactor
17
from twisted.internet import reactor
18
from asterisk.asterisk import Asterisk
18
from asterisk.asterisk import Asterisk
19
from asterisk.version import AsteriskVersion
19
from asterisk.version import AsteriskVersion
20
from asterisk.test_case import TestCase
20
from asterisk.test_case import TestCase
21

    
   
21

   
22
LOGGER = logging.getLogger(__name__)
22
LOGGER = logging.getLogger(__name__)
23

    
   
23

   
24
EXPECTED_NAMES = ["Peabody", "Asterisk/<version>", ""]
24
EXPECTED_NAMES = ["Peabody", "Asterisk/<version>", None]
25

    
   
25

   
26
BASE_URL = "http://127.0.0.%d:8088/httpstatus"
26
BASE_URL = "http://127.0.0.%d:8088/httpstatus"
27

    
   
27

   
28
class HttpClientTest(TestCase):
28
class HttpClientTest(TestCase):
29
    """Responsible for making a request to the http-server and then parsing
29
    """Responsible for making a request to the http-server and then parsing
30
    response headers to verify that the value returned for 'Server' matches
30
    response headers to verify that the value returned for 'Server' matches
31
    the expected value."""
31
    the expected value."""
32

    
   
32

   
33
    def __init__(self):
33
    def __init__(self):
34
        """Constructor."""
34
        """Constructor."""
35

    
   
35

   
36
        TestCase.__init__(self)
36
        TestCase.__init__(self)
37
        self.create_asterisk(3)
37
        self.create_asterisk(3)
38

    
   
38

   
39
    def run(self):
39
    def run(self):
40
        """Runs the test."""
40
        """Runs the test."""
41

    
   
41

   
42
        TestCase.run(self)
42
        TestCase.run(self)
43

    
   
43

   
44
        for i in range(0, 3):
44
        for i in range(0, 3):
45
            name = EXPECTED_NAMES[i].replace("<version>",
45
            name = EXPECTED_NAMES[i]

    
   
46
            if name is not None:

    
   
47
                name = name.replace("<version>",
46
                            str(AsteriskVersion()).rstrip('\n'))
48
                                str(AsteriskVersion()).rstrip('\n'))

    
   
49

   
47
            url = BASE_URL % (i+1)
50
            url = BASE_URL % (i+1)
48

    
   
51

   
49
            self.run_scenario(url, name)
52
            self.run_scenario(url, name)
50
            if self.passed == False:
53
            if self.passed == False:
51
                break
54
                break
52

    
   
55

   
53
        LOGGER.debug("Stopping reactor...")
56
        LOGGER.debug("Stopping reactor...")
54
        self.stop_reactor()
57
        self.stop_reactor()
55

    
   
58

   
56
    def run_scenario(self, url, expected_name):
59
    def run_scenario(self, url, expected_name):
57
        """Runs an individual test scenario.
60
        """Runs an individual test scenario.
58

    
   
61

   
59
        Keyword Arguments:
62
        Keyword Arguments:
60
        url             --  The url to use for making the server request
63
        url             --  The url to use for making the server request
61
        expected_name   --  The name that the server is expected to return
64
        expected_name   --  The name that the server is expected to return
62
                            in its response headers
65
                            in its response headers
63
        """
66
        """
64

    
   
67

   
65
        LOGGER.debug("Running %s", self)
68
        LOGGER.debug("Running %s", self)
66

    
   
69

   
67
        LOGGER.debug("[url]: [%s]", url)
70
        LOGGER.debug("[url]: [%s]", url)
68
        LOGGER.debug("[expected_name]: [%s]", expected_name)
71
        LOGGER.debug("[expected_name]: [%s]", expected_name)
69

    
   
72

   
70
        resp = requests.get(url)
73
        resp = requests.get(url)
71
        LOGGER.debug("[resp]: [%r]", resp)
74
        LOGGER.debug("[resp]: [%r]", resp)
72

    
   
75

   
73
        server = resp.headers.get('Server')
76
        server = resp.headers.get('Server')
74
        LOGGER.debug("[server]: [%s]", server)
77
        LOGGER.debug("[server]: [%s]", server)
75

    
   
78

   
76
        if server != expected_name:
79
        if server != expected_name:
77
            LOGGER.debug("[%s] != [%s]", server, expected_name)
80
            LOGGER.debug("[%s] != [%s]", server, expected_name)
78
            self.set_passed(False)
81
            self.set_passed(False)
79
            return
82
            return
80

    
   
83

   
81
        self.set_passed(True)
84
        self.set_passed(True)
82
        return
85
        return
83

    
   
86

   
84
def main():
87
def main():
85
    """Main entry-point for the test."""
88
    """Main entry-point for the test."""
86

    
   
89

   
87
    test = HttpClientTest()
90
    test = HttpClientTest()
88
    reactor.run()
91
    reactor.run()
89

    
   
92

   
90
    if test.passed:
93
    if test.passed:
91
        return 0
94
        return 0
92
    return 1
95
    return 1
93

    
   
96

   
94
if __name__ == "__main__":
97
if __name__ == "__main__":
95
    sys.exit(main() or 0)
98
    sys.exit(main() or 0)
  1. ./asterisk/trunk/tests/http_server/servername/run-test: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.