/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: 2011-04-02 06:37:18 UTC
  • Revision ID: teddy@fukt.bsnet.se-20110402063718-13ldrcuu0t33sdc4
* mandos: Tolerate restarting Avahi servers.  Also Changed to new
          "except x as y" exception syntax.
  (AvahiService.entry_group_state_changed_match): New; contains the
                                                  SignalMatch object.
  (AvahiService.remove): Really remove the group and the signal
                         connection, if any.
  (AvahiService.add): Always create a new group and signal connection.
  (AvahiService.cleanup): Changed to simply call remove().
  (AvahiService.server_state_changed): Handle and log more bad states.
  (AvahiService.activate): Set "follow_name_owner_changes=True" on the
                           Avahi Server proxy object.
  (ClientDBus.checked_ok): Do not return anything.
  (ClientDBus.CheckedOK): Do not return anything, as documented.
* mandos-monitor: Call D-Bus methods asynchronously.

Show diffs side-by-side

added added

removed removed

Lines of Context:
151
151
        self.group = None       # our entry group
152
152
        self.server = None
153
153
        self.bus = bus
 
154
        self.entry_group_state_changed_match = None
154
155
    def rename(self):
155
156
        """Derived from the Avahi example code"""
156
157
        if self.rename_count >= self.max_renames:
168
169
        self.remove()
169
170
        try:
170
171
            self.add()
171
 
        except dbus.exceptions.DBusException, error:
 
172
        except dbus.exceptions.DBusException as error:
172
173
            logger.critical("DBusException: %s", error)
173
174
            self.cleanup()
174
175
            os._exit(1)
176
177
    def remove(self):
177
178
        """Derived from the Avahi example code"""
178
179
        if self.group is not None:
179
 
            self.group.Reset()
 
180
            try:
 
181
                self.group.Free()
 
182
            except (dbus.exceptions.UnknownMethodException,
 
183
                    dbus.exceptions.DBusException) as e:
 
184
                pass
 
185
            self.group = None
 
186
        if self.entry_group_state_changed_match is not None:
 
187
            self.entry_group_state_changed_match.remove()
 
188
            self.entry_group_state_changed_match = None
180
189
    def add(self):
181
190
        """Derived from the Avahi example code"""
182
 
        if self.group is None:
183
 
            self.group = dbus.Interface(
184
 
                self.bus.get_object(avahi.DBUS_NAME,
185
 
                                    self.server.EntryGroupNew()),
186
 
                avahi.DBUS_INTERFACE_ENTRY_GROUP)
187
 
            self.group.connect_to_signal('StateChanged',
188
 
                                         self
189
 
                                         .entry_group_state_changed)
 
191
        self.remove()
 
192
        self.group = dbus.Interface(
 
193
            self.bus.get_object(avahi.DBUS_NAME,
 
194
                                self.server.EntryGroupNew(),
 
195
                                follow_name_owner_changes=True),
 
196
            avahi.DBUS_INTERFACE_ENTRY_GROUP)
 
197
        self.entry_group_state_changed_match = (
 
198
            self.group.connect_to_signal(
 
199
                'StateChanged', self .entry_group_state_changed))
190
200
        logger.debug("Adding Zeroconf service '%s' of type '%s' ...",
191
201
                     self.name, self.type)
192
202
        self.group.AddService(
214
224
                                  % unicode(error))
215
225
    def cleanup(self):
216
226
        """Derived from the Avahi example code"""
217
 
        if self.group is not None:
218
 
            self.group.Free()
219
 
            self.group = None
220
 
    def server_state_changed(self, state):
 
227
        self.remove()
 
228
    def server_state_changed(self, state, error=None):
221
229
        """Derived from the Avahi example code"""
222
230
        logger.debug("Avahi server state change: %i", state)
223
 
        if state == avahi.SERVER_COLLISION:
224
 
            logger.error("Zeroconf server name collision")
 
231
        bad_states = { avahi.SERVER_INVALID:
 
232
                           "Zeroconf server invalid",
 
233
                       avahi.SERVER_REGISTERING: None,
 
234
                       avahi.SERVER_COLLISION:
 
235
                           "Zeroconf server name collision",
 
236
                       avahi.SERVER_FAILURE:
 
237
                           "Zeroconf server failure" }
 
238
        if state in bad_states:
 
239
            if bad_states[state]:
 
240
                logger.error(bad_states[state])
225
241
            self.remove()
226
242
        elif state == avahi.SERVER_RUNNING:
227
243
            self.add()
 
244
        else:
 
245
            logger.debug("Unknown state: %r", state)
228
246
    def activate(self):
229
247
        """Derived from the Avahi example code"""
230
248
        if self.server is None:
231
249
            self.server = dbus.Interface(
232
250
                self.bus.get_object(avahi.DBUS_NAME,
233
 
                                    avahi.DBUS_PATH_SERVER),
 
251
                                    avahi.DBUS_PATH_SERVER,
 
252
                                    follow_name_owner_changes=True),
234
253
                avahi.DBUS_INTERFACE_SERVER)
235
254
        self.server.connect_to_signal("StateChanged",
236
255
                                 self.server_state_changed)
445
464
        # If a checker exists, make sure it is not a zombie
446
465
        try:
447
466
            pid, status = os.waitpid(self.checker.pid, os.WNOHANG)
448
 
        except (AttributeError, OSError), error:
 
467
        except (AttributeError, OSError) as error:
449
468
            if (isinstance(error, OSError)
450
469
                and error.errno != errno.ECHILD):
451
470
                raise error
472
491
 
473
492
                try:
474
493
                    command = self.checker_command % escaped_attrs
475
 
                except TypeError, error:
 
494
                except TypeError as error:
476
495
                    logger.error('Could not format string "%s":'
477
496
                                 ' %s', self.checker_command, error)
478
497
                    return True # Try again later
497
516
                if pid:
498
517
                    gobject.source_remove(self.checker_callback_tag)
499
518
                    self.checker_callback(pid, status, command)
500
 
            except OSError, error:
 
519
            except OSError as error:
501
520
                logger.error("Failed to start subprocess: %s",
502
521
                             error)
503
522
        # Re-run this periodically if run by gobject.timeout_add
516
535
            #time.sleep(0.5)
517
536
            #if self.checker.poll() is None:
518
537
            #    os.kill(self.checker.pid, signal.SIGKILL)
519
 
        except OSError, error:
 
538
        except OSError as error:
520
539
            if error.errno != errno.ESRCH: # No such process
521
540
                raise
522
541
        self.checker = None
704
723
            xmlstring = document.toxml("utf-8")
705
724
            document.unlink()
706
725
        except (AttributeError, xml.dom.DOMException,
707
 
                xml.parsers.expat.ExpatError), error:
 
726
                xml.parsers.expat.ExpatError) as error:
708
727
            logger.error("Failed to override Introspection method",
709
728
                         error)
710
729
        return xmlstring
813
832
                                       *args, **kwargs)
814
833
    
815
834
    def checked_ok(self, *args, **kwargs):
816
 
        r = Client.checked_ok(self, *args, **kwargs)
 
835
        Client.checked_ok(self, *args, **kwargs)
817
836
        # Emit D-Bus signal
818
837
        self.PropertyChanged(
819
838
            dbus.String("LastCheckedOK"),
820
839
            (self._datetime_to_dbus(self.last_checked_ok,
821
840
                                    variant_level=1)))
822
 
        return r
823
841
    
824
842
    def need_approval(self, *args, **kwargs):
825
843
        r = Client.need_approval(self, *args, **kwargs)
922
940
    # CheckedOK - method
923
941
    @dbus.service.method(_interface)
924
942
    def CheckedOK(self):
925
 
        return self.checked_ok()
 
943
        self.checked_ok()
926
944
    
927
945
    # Enable - method
928
946
    @dbus.service.method(_interface)
1204
1222
            try:
1205
1223
                if int(line.strip().split()[0]) > 1:
1206
1224
                    raise RuntimeError
1207
 
            except (ValueError, IndexError, RuntimeError), error:
 
1225
            except (ValueError, IndexError, RuntimeError) as error:
1208
1226
                logger.error("Unknown protocol version: %s", error)
1209
1227
                return
1210
1228
 
1211
1229
            # Start GnuTLS connection
1212
1230
            try:
1213
1231
                session.handshake()
1214
 
            except gnutls.errors.GNUTLSError, error:
 
1232
            except gnutls.errors.GNUTLSError as error:
1215
1233
                logger.warning("Handshake failed: %s", error)
1216
1234
                # Do not run session.bye() here: the session is not
1217
1235
                # established.  Just abandon the request.
1223
1241
                try:
1224
1242
                    fpr = self.fingerprint(self.peer_certificate
1225
1243
                                           (session))
1226
 
                except (TypeError, gnutls.errors.GNUTLSError), error:
 
1244
                except (TypeError,
 
1245
                        gnutls.errors.GNUTLSError) as error:
1227
1246
                    logger.warning("Bad certificate: %s", error)
1228
1247
                    return
1229
1248
                logger.debug("Fingerprint: %s", fpr)
1292
1311
                while sent_size < len(client.secret):
1293
1312
                    try:
1294
1313
                        sent = session.send(client.secret[sent_size:])
1295
 
                    except (gnutls.errors.GNUTLSError), error:
 
1314
                    except gnutls.errors.GNUTLSError as error:
1296
1315
                        logger.warning("gnutls send failed")
1297
1316
                        return
1298
1317
                    logger.debug("Sent: %d, remaining: %d",
1312
1331
                    client.approvals_pending -= 1
1313
1332
                try:
1314
1333
                    session.bye()
1315
 
                except (gnutls.errors.GNUTLSError), error:
 
1334
                except gnutls.errors.GNUTLSError as error:
1316
1335
                    logger.warning("GnuTLS bye failed")
1317
1336
    
1318
1337
    @staticmethod
1442
1461
                                           SO_BINDTODEVICE,
1443
1462
                                           str(self.interface
1444
1463
                                               + '\0'))
1445
 
                except socket.error, error:
 
1464
                except socket.error as error:
1446
1465
                    if error[0] == errno.EPERM:
1447
1466
                        logger.error("No permission to"
1448
1467
                                     " bind to interface %s",
1613
1632
                delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
1614
1633
            else:
1615
1634
                raise ValueError("Unknown suffix %r" % suffix)
1616
 
        except (ValueError, IndexError), e:
 
1635
        except (ValueError, IndexError) as e:
1617
1636
            raise ValueError(*(e.args))
1618
1637
        timevalue += delta
1619
1638
    return timevalue
1816
1835
    try:
1817
1836
        os.setgid(gid)
1818
1837
        os.setuid(uid)
1819
 
    except OSError, error:
 
1838
    except OSError as error:
1820
1839
        if error[0] != errno.EPERM:
1821
1840
            raise error
1822
1841
    
1866
1885
        try:
1867
1886
            bus_name = dbus.service.BusName("se.bsnet.fukt.Mandos",
1868
1887
                                            bus, do_not_queue=True)
1869
 
        except dbus.exceptions.NameExistsException, e:
 
1888
        except dbus.exceptions.NameExistsException as e:
1870
1889
            logger.error(unicode(e) + ", disabling D-Bus")
1871
1890
            use_dbus = False
1872
1891
            server_settings["use_dbus"] = False
2022
2041
        # From the Avahi example code
2023
2042
        try:
2024
2043
            service.activate()
2025
 
        except dbus.exceptions.DBusException, error:
 
2044
        except dbus.exceptions.DBusException as error:
2026
2045
            logger.critical("DBusException: %s", error)
2027
2046
            cleanup()
2028
2047
            sys.exit(1)
2035
2054
        
2036
2055
        logger.debug("Starting main loop")
2037
2056
        main_loop.run()
2038
 
    except AvahiError, error:
 
2057
    except AvahiError as error:
2039
2058
        logger.critical("AvahiError: %s", error)
2040
2059
        cleanup()
2041
2060
        sys.exit(1)