193
192
self.group.Commit()
194
193
def entry_group_state_changed(self, state, error):
195
194
"""Derived from the Avahi example code"""
196
logger.debug(u"Avahi entry group state change: %i", state)
195
logger.debug(u"Avahi state change: %i", state)
198
197
if state == avahi.ENTRY_GROUP_ESTABLISHED:
199
198
logger.debug(u"Zeroconf service established.")
212
211
self.group = None
213
212
def server_state_changed(self, state):
214
213
"""Derived from the Avahi example code"""
215
logger.debug(u"Avahi server state change: %i", state)
216
214
if state == avahi.SERVER_COLLISION:
217
215
logger.error(u"Zeroconf server name collision")
782
780
dbus.Boolean(False, variant_level=1))
785
## D-Bus methods, signals & properties
783
## D-Bus methods & signals
786
784
_interface = u"se.bsnet.fukt.Mandos.Client"
787
@dbus.service.method(_interface)
789
return self.checked_ok()
790
791
# CheckerCompleted - signal
791
792
@dbus.service.signal(_interface, signature=u"nxs")
997
989
def handle(self):
998
990
logger.info(u"TCP connection from: %s",
999
991
unicode(self.client_address))
1000
logger.debug(u"IPC Pipe FD: %d",
1001
self.server.child_pipe[1].fileno())
992
logger.debug(u"IPC Pipe FD: %d", self.server.child_pipe[1])
1002
993
# Open IPC pipe to parent process
1003
with contextlib.nested(self.server.child_pipe[1],
1004
self.server.parent_pipe[0]
1005
) as (ipc, ipc_return):
994
with contextlib.nested(os.fdopen(self.server.child_pipe[1],
996
os.fdopen(self.server.parent_pipe[0],
1006
999
session = (gnutls.connection
1007
1000
.ClientSession(self.request,
1008
1001
gnutls.connection
1009
1002
.X509Credentials()))
1004
line = self.request.makefile().readline()
1005
logger.debug(u"Protocol version: %r", line)
1007
if int(line.strip().split()[0]) > 1:
1009
except (ValueError, IndexError, RuntimeError), error:
1010
logger.error(u"Unknown protocol version: %s", error)
1011
1013
# Note: gnutls.connection.X509Credentials is really a
1012
1014
# generic GnuTLS certificate credentials object so long as
1013
1015
# no X.509 keys are added to it. Therefore, we can use it
1025
1027
.gnutls_priority_set_direct(session._c_object,
1026
1028
priority, None))
1028
# Start communication using the Mandos protocol
1029
# Get protocol number
1030
line = self.request.makefile().readline()
1031
logger.debug(u"Protocol version: %r", line)
1033
if int(line.strip().split()[0]) > 1:
1035
except (ValueError, IndexError, RuntimeError), error:
1036
logger.error(u"Unknown protocol version: %s", error)
1039
# Start GnuTLS connection
1041
1031
session.handshake()
1042
1032
except gnutls.errors.GNUTLSError, error:
1062
1052
ipc.write(u"NOTFOUND %s %s\n"
1063
1053
% (fpr, unicode(self.client_address)))
1066
class ClientProxy(object):
1067
"""Client proxy object. Not for calling methods."""
1068
def __init__(self, client):
1069
self.client = client
1070
def __getattr__(self, name):
1071
if name.startswith("ipc_"):
1073
ipc.write("%s %s\n" % (name[4:].upper(),
1076
if not hasattr(self.client, name):
1077
raise AttributeError
1078
ipc.write(u"GETATTR %s %s\n"
1079
% (name, self.client.fingerprint))
1080
return pickle.load(ipc_return)
1081
clientproxy = ClientProxy(client)
1082
1055
# Have to check if client.enabled, since it is
1083
1056
# possible that the client was disabled since the
1084
1057
# GnuTLS session was established.
1085
if not clientproxy.enabled:
1086
clientproxy.ipc_disabled()
1058
ipc.write(u"GETATTR enabled %s\n" % fpr)
1059
enabled = pickle.load(ipc_return)
1061
ipc.write(u"DISABLED %s\n" % client.name)
1089
clientproxy.ipc_sending()
1063
ipc.write(u"SENDING %s\n" % client.name)
1091
1065
while sent_size < len(client.secret):
1092
1066
sent = session.send(client.secret[sent_size:])
1169
1143
This function creates a new pipe in self.pipe
1171
# Child writes to child_pipe
1172
self.child_pipe = map(os.fdopen, os.pipe(), u"rw", (1, 0))
1173
# Parent writes to parent_pipe
1174
self.parent_pipe = map(os.fdopen, os.pipe(), u"rw", (1, 0))
1145
self.child_pipe = os.pipe() # Child writes here
1146
self.parent_pipe = os.pipe() # Parent writes here
1175
1147
super(ForkingMixInWithPipes,
1176
1148
self).process_request(request, client_address)
1177
1149
# Close unused ends for parent
1178
self.parent_pipe[0].close() # close read end
1179
self.child_pipe[1].close() # close write end
1150
os.close(self.parent_pipe[0]) # close read end
1151
os.close(self.child_pipe[1]) # close write end
1180
1152
self.add_pipe_fds(self.child_pipe[0], self.parent_pipe[1])
1181
1153
def add_pipe_fds(self, child_pipe_fd, parent_pipe_fd):
1182
1154
"""Dummy function; override as necessary"""
1183
child_pipe_fd.close()
1184
parent_pipe_fd.close()
1155
os.close(child_pipe_fd)
1156
os.close(parent_pipe_fd)
1187
1159
class IPv6_TCPServer(ForkingMixInWithPipes,
1277
1249
self.enabled = True
1278
1250
def add_pipe_fds(self, child_pipe_fd, parent_pipe_fd):
1279
1251
# Call "handle_ipc" for both data and EOF events
1280
gobject.io_add_watch(child_pipe_fd.fileno(),
1252
gobject.io_add_watch(child_pipe_fd,
1281
1253
gobject.IO_IN | gobject.IO_HUP,
1282
1254
functools.partial(self.handle_ipc,
1283
reply = parent_pipe_fd,
1284
sender= child_pipe_fd))
1285
def handle_ipc(self, source, condition, reply=None, sender=None):
1257
def handle_ipc(self, source, condition, reply_fd=None,
1286
1259
condition_names = {
1287
1260
gobject.IO_IN: u"IN", # There is data to read.
1288
1261
gobject.IO_OUT: u"OUT", # Data can be written (without
1300
1273
logger.debug(u"Handling IPC: FD = %d, condition = %s", source,
1301
1274
conditions_string)
1276
# Turn the pipe file descriptors into Python file objects
1277
if source not in file_objects:
1278
file_objects[source] = os.fdopen(source, u"r", 1)
1279
if reply_fd not in file_objects:
1280
file_objects[reply_fd] = os.fdopen(reply_fd, u"w", 0)
1303
1282
# Read a line from the file object
1304
cmdline = sender.readline()
1283
cmdline = file_objects[source].readline()
1305
1284
if not cmdline: # Empty line means end of file
1306
1285
# close the IPC pipes
1286
file_objects[source].close()
1287
del file_objects[source]
1288
file_objects[reply_fd].close()
1289
del file_objects[reply_fd]
1310
1291
# Stop calling this function
1350
1331
if client.fingerprint == fpr:
1351
1332
attr_value = getattr(client, attr_name, None)
1352
1333
logger.debug("IPC reply: %r", attr_value)
1353
pickle.dump(attr_value, reply)
1334
pickle.dump(attr_value, file_objects[reply_fd])
1356
1337
logger.error(u"Client %s on address %s requesting "
1357
1338
u"attribute %s not found", fpr, address,
1359
pickle.dump(None, reply)
1340
pickle.dump(None, file_objects[reply_fd])
1361
1342
logger.error(u"Unknown IPC command: %r", cmdline)
1565
1546
tcp_server = MandosServer((server_settings[u"address"],
1566
1547
server_settings[u"port"]),
1568
interface=(server_settings[u"interface"]
1549
interface=server_settings[u"interface"],
1570
1550
use_ipv6=use_ipv6,
1571
1551
gnutls_priority=
1572
1552
server_settings[u"priority"],