151
151
def __enter__(self):
154
def __exit__(self, exc_type, exc_value, traceback):
154
def __exit__ (self, exc_type, exc_value, traceback):
1016
1016
return xmlstring
1019
def datetime_to_dbus(dt, variant_level=0):
1019
def datetime_to_dbus (dt, variant_level=0):
1020
1020
"""Convert a UTC datetime.datetime() to a D-Bus type."""
1022
1022
return dbus.String("", variant_level = variant_level)
1030
1030
interface names according to the "alt_interface_names" mapping.
1033
@alternate_dbus_interfaces({"org.example.Interface":
1034
"net.example.AlternateInterface"})
1033
@alternate_dbus_names({"org.example.Interface":
1034
"net.example.AlternateInterface"})
1035
1035
class SampleDBusObject(dbus.service.Object):
1036
1036
@dbus.service.method("org.example.Interface")
1037
1037
def SampleDBusMethod():
1899
1899
use_ipv6: Boolean; to use IPv6 or not
1901
1901
def __init__(self, server_address, RequestHandlerClass,
1902
interface=None, use_ipv6=True, socketfd=None):
1903
"""If socketfd is set, use that file descriptor instead of
1904
creating a new one with socket.socket().
1902
interface=None, use_ipv6=True):
1906
1903
self.interface = interface
1908
1905
self.address_family = socket.AF_INET6
1909
if socketfd is not None:
1910
# Save the file descriptor
1911
self.socketfd = socketfd
1912
# Save the original socket.socket() function
1913
self.socket_socket = socket.socket
1914
# To implement --socket, we monkey patch socket.socket.
1916
# (When socketserver.TCPServer is a new-style class, we
1917
# could make self.socket into a property instead of monkey
1918
# patching socket.socket.)
1920
# Create a one-time-only replacement for socket.socket()
1921
@functools.wraps(socket.socket)
1922
def socket_wrapper(*args, **kwargs):
1923
# Restore original function so subsequent calls are
1925
socket.socket = self.socket_socket
1926
del self.socket_socket
1927
# This time only, return a new socket object from the
1928
# saved file descriptor.
1929
return socket.fromfd(self.socketfd, *args, **kwargs)
1930
# Replace socket.socket() function with wrapper
1931
socket.socket = socket_wrapper
1932
# The socketserver.TCPServer.__init__ will call
1933
# socket.socket(), which might be our replacement,
1934
# socket_wrapper(), if socketfd was set.
1935
1906
socketserver.TCPServer.__init__(self, server_address,
1936
1907
RequestHandlerClass)
1938
1908
def server_bind(self):
1939
1909
"""This overrides the normal server_bind() function
1940
1910
to bind to an interface if one was specified, and also NOT to
1949
1919
self.socket.setsockopt(socket.SOL_SOCKET,
1950
1920
SO_BINDTODEVICE,
1951
str(self.interface + '\0'))
1952
1923
except socket.error as error:
1953
1924
if error.errno == errno.EPERM:
1954
logger.error("No permission to bind to"
1955
" interface %s", self.interface)
1925
logger.error("No permission to"
1926
" bind to interface %s",
1956
1928
elif error.errno == errno.ENOPROTOOPT:
1957
1929
logger.error("SO_BINDTODEVICE not available;"
1958
1930
" cannot bind to interface %s",
1959
1931
self.interface)
1960
1932
elif error.errno == errno.ENODEV:
1961
logger.error("Interface %s does not exist,"
1962
" cannot bind", self.interface)
1933
logger.error("Interface %s does not"
1934
" exist, cannot bind",
1965
1938
# Only bind(2) the socket if we really need to.
1996
1969
def __init__(self, server_address, RequestHandlerClass,
1997
1970
interface=None, use_ipv6=True, clients=None,
1998
gnutls_priority=None, use_dbus=True, socketfd=None):
1971
gnutls_priority=None, use_dbus=True):
1999
1972
self.enabled = False
2000
1973
self.clients = clients
2001
1974
if self.clients is None:
2193
2165
parser.add_argument("--no-restore", action="store_false",
2194
2166
dest="restore", help="Do not restore stored"
2196
parser.add_argument("--socket", type=int,
2197
help="Specify a file descriptor to a network"
2198
" socket to use instead of creating one")
2199
2168
parser.add_argument("--statedir", metavar="DIR",
2200
2169
help="Directory to save/restore state in")
2201
parser.add_argument("--foreground", action="store_true",
2202
help="Run in foreground")
2204
2171
options = parser.parse_args()
2233
2198
# Convert the SafeConfigParser object to a dict
2234
2199
server_settings = server_config.defaults()
2235
2200
# Use the appropriate methods on the non-string config options
2236
for option in ("debug", "use_dbus", "use_ipv6", "foreground"):
2201
for option in ("debug", "use_dbus", "use_ipv6"):
2237
2202
server_settings[option] = server_config.getboolean("DEFAULT",
2239
2204
if server_settings["port"]:
2240
2205
server_settings["port"] = server_config.getint("DEFAULT",
2242
if server_settings["socket"]:
2243
server_settings["socket"] = server_config.getint("DEFAULT",
2245
# Later, stdin will, and stdout and stderr might, be dup'ed
2246
# over with an opened os.devnull. But we don't want this to
2247
# happen with a supplied network socket.
2248
if 0 <= server_settings["socket"] <= 2:
2249
server_settings["socket"] = os.dup(server_settings
2251
2207
del server_config
2253
2209
# Override the settings from the config file with command line
2255
2211
for option in ("interface", "address", "port", "debug",
2256
2212
"priority", "servicename", "configdir",
2257
2213
"use_dbus", "use_ipv6", "debuglevel", "restore",
2258
"statedir", "socket", "foreground"):
2259
2215
value = getattr(options, option)
2260
2216
if value is not None:
2261
2217
server_settings[option] = value
2264
2220
for option in server_settings.keys():
2265
2221
if type(server_settings[option]) is str:
2266
2222
server_settings[option] = unicode(server_settings[option])
2267
# Debug implies foreground
2268
if server_settings["debug"]:
2269
server_settings["foreground"] = True
2270
2223
# Now we have our good server settings in "server_settings"
2272
2225
##################################################################
2278
2231
use_ipv6 = server_settings["use_ipv6"]
2279
2232
stored_state_path = os.path.join(server_settings["statedir"],
2280
2233
stored_state_file)
2281
foreground = server_settings["foreground"]
2284
2236
initlogger(debug, logging.DEBUG)
2313
2265
use_ipv6=use_ipv6,
2314
2266
gnutls_priority=
2315
2267
server_settings["priority"],
2317
socketfd=(server_settings["socket"]
2320
2270
pidfilename = "/var/run/mandos.pid"
2323
2272
pidfile = open(pidfilename, "w")
2324
2273
except IOError as e:
2365
2314
# Need to fork before connecting to D-Bus
2367
2316
# Close all input and output, do double fork, etc.
2370
# multiprocessing will use threads, so before we use gobject we
2371
# need to inform gobject that threads will be used.
2372
2319
gobject.threads_init()
2374
2321
global main_loop
2502
2449
if not tcp_server.clients:
2503
2450
logger.warning("No clients defined")
2506
if pidfile is not None:
2510
pidfile.write(str(pid) + "\n".encode("utf-8"))
2512
logger.error("Could not write to file %r with PID %d",
2456
pidfile.write(str(pid) + "\n".encode("utf-8"))
2459
logger.error("Could not write to file %r with PID %d",
2462
# "pidfile" was never created
2515
2464
del pidfilename
2517
2466
signal.signal(signal.SIGHUP, lambda signum, frame: sys.exit())