Passed
Pull Request — master (#111)
by
unknown
01:50
created

ospd.parser   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 119
dl 0
loc 194
rs 10
c 0
b 0
f 0
wmc 10

2 Functions

Rating   Name   Duplication   Size   Complexity  
A get_common_args() 0 42 1
C create_args_parser() 0 115 9
1
# Copyright (C) 2019 Greenbone Networks GmbH
2
#
3
# SPDX-License-Identifier: GPL-2.0-or-later
4
#
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; either version 2
8
# of the License, or (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
19
import argparse
20
import logging
21
import os
22
import ssl
23
import time
24
25
# Default file locations as used by a OpenVAS default installation
26
DEFAULT_KEY_FILE = "/usr/var/lib/gvm/private/CA/serverkey.pem"
27
DEFAULT_CERT_FILE = "/usr/var/lib/gvm/CA/servercert.pem"
28
DEFAULT_CA_FILE = "/usr/var/lib/gvm/CA/cacert.pem"
29
30
DEFAULT_PORT = 1234
31
DEFAULT_ADDRESS = "0.0.0.0"
32
DEFAULT_NICENESS = 10
33
34
35
def create_args_parser(description):
36
    """ Create a command-line arguments parser for OSPD. """
37
38
    parser = argparse.ArgumentParser(description=description)
39
40
    def network_port(string):
41
        """ Check if provided string is a valid network port. """
42
43
        value = int(string)
44
        if not 0 < value <= 65535:
45
            raise argparse.ArgumentTypeError(
46
                'port must be in ]0,65535] interval'
47
            )
48
        return value
49
50
    def cacert_file(cacert):
51
        """ Check if provided file is a valid CA Certificate """
52
        try:
53
            context = ssl.create_default_context(cafile=cacert)
54
        except AttributeError:
55
            # Python version < 2.7.9
56
            return cacert
57
        except IOError:
58
            raise argparse.ArgumentTypeError('CA Certificate not found')
59
        try:
60
            not_after = context.get_ca_certs()[0]['notAfter']
61
            not_after = ssl.cert_time_to_seconds(not_after)
62
            not_before = context.get_ca_certs()[0]['notBefore']
63
            not_before = ssl.cert_time_to_seconds(not_before)
64
        except (KeyError, IndexError):
65
            raise argparse.ArgumentTypeError('CA Certificate is erroneous')
66
        if not_after < int(time.time()):
67
            raise argparse.ArgumentTypeError('CA Certificate expired')
68
        if not_before > int(time.time()):
69
            raise argparse.ArgumentTypeError('CA Certificate not active yet')
70
        return cacert
71
72
    def log_level(string):
73
        """ Check if provided string is a valid log level. """
74
75
        value = getattr(logging, string.upper(), None)
76
        if not isinstance(value, int):
77
            raise argparse.ArgumentTypeError(
78
                'log level must be one of {debug,info,warning,error,critical}'
79
            )
80
        return value
81
82
    def filename(string):
83
        """ Check if provided string is a valid file path. """
84
85
        if not os.path.isfile(string):
86
            raise argparse.ArgumentTypeError(
87
                '%s is not a valid file path' % string
88
            )
89
        return string
90
91
    parser.add_argument(
92
        '-p',
93
        '--port',
94
        default=DEFAULT_PORT,
95
        type=network_port,
96
        help='TCP Port to listen on. Default: %(default)s',
97
    )
98
    parser.add_argument(
99
        '-b',
100
        '--bind-address',
101
        default=DEFAULT_ADDRESS,
102
        help='Address to listen on. Default: %(default)s',
103
    )
104
    parser.add_argument(
105
        '-u', '--unix-socket', help='Unix file socket to listen on.'
106
    )
107
    parser.add_argument(
108
        '-k',
109
        '--key-file',
110
        type=filename,
111
        help='Server key file. Default: {0}'.format(DEFAULT_KEY_FILE),
112
    )
113
    parser.add_argument(
114
        '-c',
115
        '--cert-file',
116
        type=filename,
117
        help='Server cert file. Default: {0}'.format(DEFAULT_CERT_FILE),
118
    )
119
    parser.add_argument(
120
        '--ca-file',
121
        type=cacert_file,
122
        help='CA cert file. Default: {0}'.format(DEFAULT_CA_FILE),
123
    )
124
    parser.add_argument(
125
        '-L',
126
        '--log-level',
127
        default='WARNING',
128
        type=log_level,
129
        help='Wished level of logging. Default: %(default)s',
130
    )
131
    parser.add_argument(
132
        '--foreground',
133
        action='store_true',
134
        help='Run in foreground and logs all messages to console.',
135
    )
136
    parser.add_argument(
137
        '-l', '--log-file', type=filename, help='Path to the logging file.'
138
    )
139
    parser.add_argument(
140
        '--version', action='store_true', help='Print version then exit.'
141
    )
142
    parser.add_argument(
143
        '--niceness',
144
        default=DEFAULT_NICENESS,
145
        type=int,
146
        help='Start the scan with the given niceness. Default %(default)s',
147
    )
148
149
    return parser
150
151
152
def get_common_args(parser, args=None):
153
    """ Return list of OSPD common command-line arguments from parser, after
154
    validating provided values or setting default ones.
155
156
    """
157
158
    options = parser.parse_args(args)
159
    # TCP Port to listen on.
160
    port = options.port
161
162
    # Network address to bind listener to
163
    address = options.bind_address
164
165
    # Unix file socket to listen on
166
    unix_socket = options.unix_socket
167
168
    # Debug level.
169
    log_level = options.log_level
170
171
    # Server key path.
172
    keyfile = options.key_file or DEFAULT_KEY_FILE
173
174
    # Server cert path.
175
    certfile = options.cert_file or DEFAULT_CERT_FILE
176
177
    # CA cert path.
178
    cafile = options.ca_file or DEFAULT_CA_FILE
179
180
    common_args = dict()
181
    common_args['port'] = port
182
    common_args['address'] = address
183
    common_args['unix_socket'] = unix_socket
184
    common_args['keyfile'] = keyfile
185
    common_args['certfile'] = certfile
186
    common_args['cafile'] = cafile
187
    common_args['log_level'] = log_level
188
    common_args['foreground'] = options.foreground
189
    common_args['log_file'] = options.log_file
190
    common_args['version'] = options.version
191
    common_args['niceness'] = options.niceness
192
193
    return common_args
194