/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos

  • Committer: Teddy Hogeborn
  • Date: 2019-07-29 16:35:53 UTC
  • Revision ID: teddy@recompile.se-20190729163553-1i442i2cbx64c537
Make tests and man page examples match

Make the tests test_manual_page_example[1-5] match exactly what is
written in the manual page, and add comments to manual page as
reminders to keep tests and manual page examples in sync.

* mandos-ctl (Test_commands_from_options.test_manual_page_example_1):
  Remove "--verbose" option, since the manual does not have it as the
  first example, and change assertion to match.
* mandos-ctl.xml (EXAMPLE): Add comments to all examples documenting
  which test function they correspond to.  Also remove unnecessary
  quotes from option arguments in fourth example, and clarify language
  slightly in fifth example.

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
 
81
81
import dbus
82
82
import dbus.service
83
 
import gi
84
83
from gi.repository import GLib
85
84
from dbus.mainloop.glib import DBusGMainLoop
86
85
import ctypes
88
87
import xml.dom.minidom
89
88
import inspect
90
89
 
91
 
if sys.version_info.major == 2:
92
 
    __metaclass__ = type
93
 
 
94
90
# Try to find the value of SO_BINDTODEVICE:
95
91
try:
96
92
    # This is where SO_BINDTODEVICE is in Python 3.3 (or 3.4?) and
119
115
if sys.version_info.major == 2:
120
116
    str = unicode
121
117
 
122
 
if sys.version_info < (3, 2):
123
 
    configparser.Configparser = configparser.SafeConfigParser
124
 
 
125
 
version = "1.8.7"
 
118
version = "1.8.4"
126
119
stored_state_file = "clients.pickle"
127
120
 
128
121
logger = logging.getLogger()
186
179
    pass
187
180
 
188
181
 
189
 
class PGPEngine:
 
182
class PGPEngine(object):
190
183
    """A simple class for OpenPGP symmetric encryption & decryption"""
191
184
 
192
185
    def __init__(self):
282
275
 
283
276
 
284
277
# Pretend that we have an Avahi module
285
 
class avahi:
 
278
class avahi(object):
286
279
    """This isn't so much a class as it is a module-like namespace."""
287
280
    IF_UNSPEC = -1               # avahi-common/address.h
288
281
    PROTO_UNSPEC = -1            # avahi-common/address.h
322
315
    pass
323
316
 
324
317
 
325
 
class AvahiService:
 
318
class AvahiService(object):
326
319
    """An Avahi (Zeroconf) service.
327
320
 
328
321
    Attributes:
510
503
 
511
504
 
512
505
# Pretend that we have a GnuTLS module
513
 
class gnutls:
 
506
class gnutls(object):
514
507
    """This isn't so much a class as it is a module-like namespace."""
515
508
 
516
509
    library = ctypes.util.find_library("gnutls")
579
572
        pass
580
573
 
581
574
    # Classes
582
 
    class Credentials:
 
575
    class Credentials(object):
583
576
        def __init__(self):
584
577
            self._c_object = gnutls.certificate_credentials_t()
585
578
            gnutls.certificate_allocate_credentials(
589
582
        def __del__(self):
590
583
            gnutls.certificate_free_credentials(self._c_object)
591
584
 
592
 
    class ClientSession:
 
585
    class ClientSession(object):
593
586
        def __init__(self, socket, credentials=None):
594
587
            self._c_object = gnutls.session_t()
595
588
            gnutls_flags = gnutls.CLIENT
821
814
    connection.close()
822
815
 
823
816
 
824
 
class Client:
 
817
class Client(object):
825
818
    """A representation of a client host served by this server.
826
819
 
827
820
    Attributes:
828
821
    approved:   bool(); 'None' if not yet approved/disapproved
829
822
    approval_delay: datetime.timedelta(); Time to wait for approval
830
823
    approval_duration: datetime.timedelta(); Duration of one approval
831
 
    checker: multiprocessing.Process(); a running checker process used
832
 
             to see if the client lives. 'None' if no process is
833
 
             running.
 
824
    checker:    subprocess.Popen(); a running checker process used
 
825
                                    to see if the client lives.
 
826
                                    'None' if no process is running.
834
827
    checker_callback_tag: a GLib event source tag, or None
835
828
    checker_command: string; External command which is run to check
836
829
                     if client lives.  %() expansions are done at
1043
1036
    def checker_callback(self, source, condition, connection,
1044
1037
                         command):
1045
1038
        """The checker has completed, so take appropriate actions."""
 
1039
        self.checker_callback_tag = None
 
1040
        self.checker = None
1046
1041
        # Read return code from connection (see call_pipe)
1047
1042
        returncode = connection.recv()
1048
1043
        connection.close()
1049
 
        self.checker.join()
1050
 
        self.checker_callback_tag = None
1051
 
        self.checker = None
1052
1044
 
1053
1045
        if returncode >= 0:
1054
1046
            self.last_checker_status = returncode
2216
2208
    del _interface
2217
2209
 
2218
2210
 
2219
 
class ProxyClient:
 
2211
class ProxyClient(object):
2220
2212
    def __init__(self, child_pipe, key_id, fpr, address):
2221
2213
        self._pipe = child_pipe
2222
2214
        self._pipe.send(('init', key_id, fpr, address))
2495
2487
        return hex_fpr
2496
2488
 
2497
2489
 
2498
 
class MultiprocessingMixIn:
 
2490
class MultiprocessingMixIn(object):
2499
2491
    """Like socketserver.ThreadingMixIn, but with multiprocessing"""
2500
2492
 
2501
2493
    def sub_process_main(self, request, address):
2513
2505
        return proc
2514
2506
 
2515
2507
 
2516
 
class MultiprocessingMixInWithPipe(MultiprocessingMixIn):
 
2508
class MultiprocessingMixInWithPipe(MultiprocessingMixIn, object):
2517
2509
    """ adds a pipe to the MixIn """
2518
2510
 
2519
2511
    def process_request(self, request, client_address):
2534
2526
 
2535
2527
 
2536
2528
class IPv6_TCPServer(MultiprocessingMixInWithPipe,
2537
 
                     socketserver.TCPServer):
 
2529
                     socketserver.TCPServer, object):
2538
2530
    """IPv6-capable TCP server.  Accepts 'None' as address and/or port
2539
2531
 
2540
2532
    Attributes:
3005
2997
    del priority
3006
2998
 
3007
2999
    # Parse config file for server-global settings
3008
 
    server_config = configparser.ConfigParser(server_defaults)
 
3000
    server_config = configparser.SafeConfigParser(server_defaults)
3009
3001
    del server_defaults
3010
3002
    server_config.read(os.path.join(options.configdir, "mandos.conf"))
3011
 
    # Convert the ConfigParser object to a dict
 
3003
    # Convert the SafeConfigParser object to a dict
3012
3004
    server_settings = server_config.defaults()
3013
3005
    # Use the appropriate methods on the non-string config options
3014
3006
    for option in ("debug", "use_dbus", "use_ipv6", "restore",
3086
3078
                                  server_settings["servicename"])))
3087
3079
 
3088
3080
    # Parse config file with clients
3089
 
    client_config = configparser.ConfigParser(Client.client_defaults)
 
3081
    client_config = configparser.SafeConfigParser(Client
 
3082
                                                  .client_defaults)
3090
3083
    client_config.read(os.path.join(server_settings["configdir"],
3091
3084
                                    "clients.conf"))
3092
3085
 
3163
3156
        # Close all input and output, do double fork, etc.
3164
3157
        daemon()
3165
3158
 
3166
 
    if gi.version_info < (3, 10, 2):
3167
 
        # multiprocessing will use threads, so before we use GLib we
3168
 
        # need to inform GLib that threads will be used.
3169
 
        GLib.threads_init()
 
3159
    # multiprocessing will use threads, so before we use GLib we need
 
3160
    # to inform GLib that threads will be used.
 
3161
    GLib.threads_init()
3170
3162
 
3171
3163
    global main_loop
3172
3164
    # From the Avahi example code