Passed
Pull Request — master (#201)
by
unknown
01:48
created

gvmtools.cli.main()   F

Complexity

Conditions 14

Size

Total Lines 73
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 73
rs 3.6
c 0
b 0
f 0
cc 14
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gvmtools.cli.main() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
import getpass
20
import logging
21
import sys
22
23
from gvm.errors import GvmError
24
from gvm.protocols.latest import Osp
25
from gvm.protocols.gmp import Gmp
26
from gvm.transforms import CheckCommandTransform
27
from gvm.xml import validate_xml_string
28
29
from gvmtools.helper import do_not_run_as_root
30
from gvmtools.parser import (
31
    create_parser,
32
    create_connection,
33
    PROTOCOL_OSP,
34
    PROTOCOL_GMP,
35
)
36
37
logger = logging.getLogger(__name__)
38
39
HELP_TEXT = """
40
    Command line tool to access services via GMP (Greenbone Management Protocol) and OSP (Open Scanner Protocol)
41
42
    Examples:
43
      gvm-cli socket --help
44
      gvm-cli tls --help
45
      gvm-cli ssh --help
46
47
      gvm-cli socket --xml "<get_version/>"
48
      gvm-cli socket --xml "<commands><authenticate><credentials><username>myuser</username><password>mypass</password></credentials></authenticate><get_tasks/></commands>"
49
      gvm-cli socket --gmp-username foo --gmp-password foo < myfile.xml
50
51
    The protocol specifications for GMP and OSP are available at:
52
      https://docs.greenbone.net/index.html#api_documentation"""
53
54
55
def _load_infile(filename=None):
56
    if not filename:
57
        return None
58
59
    with open(filename) as f:
60
        return f.read()
61
62
63
def main():
64
    do_not_run_as_root()
65
66
    parser = create_parser(description=HELP_TEXT, logfilename='gvm-cli.log')
67
68
    parser.add_protocol_argument()
69
70
    parser.add_argument('-X', '--xml', help='XML request to send')
71
    parser.add_argument(
72
        '-r', '--raw', help='Return raw XML', action='store_true', default=False
73
    )
74
    parser.add_argument(
75
        'infile', nargs='?', help='File to read XML commands from.'
76
    )
77
78
    args = parser.parse_args()
79
80
    # If timeout value is -1, then the socket has no timeout for this session
81
    if args.timeout == -1:
82
        args.timeout = None
83
84
    if args.xml is not None:
85
        xml = args.xml
86
    else:
87
        try:
88
            xml = _load_infile(args.infile)
89
        except IOError as e:
90
            print(e, file=sys.stderr)
91
            sys.exit(1)
92
93
    # If no command was given, program asks for one
94
    if len(xml) == 0:
95
        xml = input()
96
97
    try:
98
        validate_xml_string(xml)
99
    except GvmError as e:
100
        print(e, file=sys.stderr)
101
        sys.exit(1)
102
103
    connection = create_connection(**vars(args))
104
105
    if args.raw:
106
        transform = None
107
    else:
108
        transform = CheckCommandTransform()
109
110
    if args.protocol == PROTOCOL_OSP:
111
        protocol_class = Osp
112
    else:
113
        protocol_class = Gmp
114
115
    with protocol_class(connection, transform=transform) as protocol:
116
117
        if args.protocol == PROTOCOL_GMP:
118
            # Ask for password if none are given
119
            if args.gmp_username and not args.gmp_password:
120
                args.gmp_password = getpass.getpass(
121
                    'Enter password for ' + args.gmp_username + ': '
122
                )
123
124
            if args.gmp_username:
125
                protocol.authenticate(args.gmp_username, args.gmp_password)
126
127
        try:
128
            result = protocol.send_command(xml)
129
130
            print(result)
131
        except Exception as e:  # pylint: disable=broad-except
132
            print(e, file=sys.stderr)
133
            sys.exit(1)
134
135
    sys.exit(0)
136
137
138
if __name__ == '__main__':
139
    main()
140