/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

half working on-demand password and approved code

Show diffs side-by-side

added added

removed removed

Lines of Context:
257
257
                     runtime with vars(self) as dict, so that for
258
258
                     instance %(name)s can be used in the command.
259
259
    current_checker_command: string; current running checker_command
 
260
    changesignal: File descriptor; written to on object change
 
261
    _reset: File descriptor; for flushing changesignal
 
262
    delay: datetime.timedelta(); how long to wait for approval/secret
 
263
    approved: bool(); None if not yet approved/disapproved
260
264
    """
261
265
    
262
266
    @staticmethod
289
293
                            .replace(u" ", u""))
290
294
        logger.debug(u"  Fingerprint: %s", self.fingerprint)
291
295
        if u"secret" in config:
292
 
            self.secret = config[u"secret"].decode(u"base64")
 
296
            self._secret = config[u"secret"].decode(u"base64")
293
297
        elif u"secfile" in config:
294
298
            with open(os.path.expanduser(os.path.expandvars
295
299
                                         (config[u"secfile"])),
296
300
                      "rb") as secfile:
297
 
                self.secret = secfile.read()
 
301
                self._secret = secfile.read()
298
302
        else:
 
303
            #XXX Need to allow secret on demand!
299
304
            raise TypeError(u"No secret or secfile for client %s"
300
305
                            % self.name)
301
306
        self.host = config.get(u"host", u"")
313
318
        self.checker_command = config[u"checker"]
314
319
        self.current_checker_command = None
315
320
        self.last_connect = None
 
321
        self.changesignal, self._reset = os.pipe()
 
322
        self._approved = None #XXX should be based on configfile
 
323
        self.delay = 10; #XXX Should be based on configfile
 
324
 
 
325
    def setsecret(self, value):
 
326
        self._secret = value
 
327
        os.write(self.changesignal, "\0")
 
328
        os.read(self._reset, 1)
 
329
 
 
330
    secret = property(lambda self: self._secret, setsecret)
 
331
    del setsecret
316
332
    
 
333
    def setapproved(self, value):
 
334
        self._approved = value
 
335
        os.write(self.changesignal, "\0")
 
336
        os.read(self._reset, 1)
 
337
 
 
338
    approved = property(lambda self: self._approved, setapproved)
 
339
    del setapproved
 
340
 
317
341
    def enable(self):
318
342
        """Start this client's checker and timeout hooks"""
319
343
        if getattr(self, u"enabled", False):
1057
1081
                    ipc.write(u"NOTFOUND %s %s\n"
1058
1082
                              % (fpr, unicode(self.client_address)))
1059
1083
                    return
1060
 
                # Have to check if client.enabled, since it is
1061
 
                # possible that the client was disabled since the
1062
 
                # GnuTLS session was established.
1063
 
                ipc.write(u"GETATTR enabled %s\n" % fpr)
1064
 
                enabled = pickle.load(ipc_return)
1065
 
                if not enabled:
1066
 
                    ipc.write(u"DISABLED %s\n" % client.name)
1067
 
                    return
 
1084
 
 
1085
                class proxyclient(object):
 
1086
                    def __getattribute__(self, name):
 
1087
                        ipc.write(u"GETATTR %s %s\n" % name, client.fpr)
 
1088
                        return pickle.load(ipc_reply)
 
1089
                p = proxyclient(client)
 
1090
 
 
1091
                while True:
 
1092
                    if not p.client.enabled:
 
1093
                        icp.write("DISABLED %s\n" % client.fpr)
 
1094
                        return
 
1095
                    if p.client.approved == False:
 
1096
                        icp.write("Disaproved")
 
1097
                        return
 
1098
                    
 
1099
                    if not p.client.secret:
 
1100
                        icp.write("No password")
 
1101
                    elif not p.client.approved:
 
1102
                        icp.write("Need approval"):
 
1103
                    else:
 
1104
                        #We have a password and are approved
 
1105
                        break
 
1106
                    i, o, e = select(p.changesignal, (), (), client.delay)
 
1107
                    if not i:
 
1108
                        icp.write("Timeout passed")
 
1109
                        return
 
1110
                    
1068
1111
                ipc.write(u"SENDING %s\n" % client.name)
1069
1112
                sent_size = 0
1070
1113
                while sent_size < len(client.secret):