/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: Björn Påhlsson
  • Date: 2011-06-23 22:27:15 UTC
  • mto: This revision was merged to the branch mainline in revision 485.
  • Revision ID: belorn@fukt.bsnet.se-20110623222715-q5wro9ma9iyjl367
* Makefile (CFLAGS): Added "-lrt" to include real time library.
* plugins.d/mandos-client.c: use scandir(3) instead of readdir(3)
                             Prefix all debug output with "Mandos plugin " + program_invocation_short_name
                             Retry servers that failed to provide password.
                             New option --retry SECONDS that sets the interval between rechecking.
                             --retry also controls how often it retries a server when using --connect.
* plugins.d/splashy.c:  Prefix all debug output with "Mandos plugin " + program_invocation_short_name
* plugins.d/usplash.c: --||--
* plugins.d/askpass-fifo.c: --||--
* plugins.d/password-prompt.c: --||--
* plugins.d/plymouth.c: --||--
* mandos: Lower logger level from warning to info on failed client requests because client was disabled or unknown fingerprint.
* plugins.d/plymouth.c (get_pid): bug fix. Was not calling free on direntries. 

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)
175
176
        self.rename_count += 1
176
177
    def remove(self):
177
178
        """Derived from the Avahi example code"""
 
179
        if self.entry_group_state_changed_match is not None:
 
180
            self.entry_group_state_changed_match.remove()
 
181
            self.entry_group_state_changed_match = None
178
182
        if self.group is not None:
179
183
            self.group.Reset()
180
184
    def add(self):
181
185
        """Derived from the Avahi example code"""
 
186
        self.remove()
182
187
        if self.group is None:
183
188
            self.group = dbus.Interface(
184
189
                self.bus.get_object(avahi.DBUS_NAME,
185
190
                                    self.server.EntryGroupNew()),
186
191
                avahi.DBUS_INTERFACE_ENTRY_GROUP)
187
 
            self.group.connect_to_signal('StateChanged',
188
 
                                         self
189
 
                                         .entry_group_state_changed)
 
192
        self.entry_group_state_changed_match = (
 
193
            self.group.connect_to_signal(
 
194
                'StateChanged', self .entry_group_state_changed))
190
195
        logger.debug("Adding Zeroconf service '%s' of type '%s' ...",
191
196
                     self.name, self.type)
192
197
        self.group.AddService(
215
220
    def cleanup(self):
216
221
        """Derived from the Avahi example code"""
217
222
        if self.group is not None:
218
 
            self.group.Free()
 
223
            try:
 
224
                self.group.Free()
 
225
            except (dbus.exceptions.UnknownMethodException,
 
226
                    dbus.exceptions.DBusException) as e:
 
227
                pass
219
228
            self.group = None
220
 
    def server_state_changed(self, state):
 
229
        self.remove()
 
230
    def server_state_changed(self, state, error=None):
221
231
        """Derived from the Avahi example code"""
222
232
        logger.debug("Avahi server state change: %i", state)
223
 
        if state == avahi.SERVER_COLLISION:
224
 
            logger.error("Zeroconf server name collision")
225
 
            self.remove()
 
233
        bad_states = { avahi.SERVER_INVALID:
 
234
                           "Zeroconf server invalid",
 
235
                       avahi.SERVER_REGISTERING: None,
 
236
                       avahi.SERVER_COLLISION:
 
237
                           "Zeroconf server name collision",
 
238
                       avahi.SERVER_FAILURE:
 
239
                           "Zeroconf server failure" }
 
240
        if state in bad_states:
 
241
            if bad_states[state] is not None:
 
242
                if error is None:
 
243
                    logger.error(bad_states[state])
 
244
                else:
 
245
                    logger.error(bad_states[state] + ": %r", error)
 
246
            self.cleanup()
226
247
        elif state == avahi.SERVER_RUNNING:
227
248
            self.add()
 
249
        else:
 
250
            if error is None:
 
251
                logger.debug("Unknown state: %r", state)
 
252
            else:
 
253
                logger.debug("Unknown state: %r: %r", state, error)
228
254
    def activate(self):
229
255
        """Derived from the Avahi example code"""
230
256
        if self.server is None:
231
257
            self.server = dbus.Interface(
232
258
                self.bus.get_object(avahi.DBUS_NAME,
233
 
                                    avahi.DBUS_PATH_SERVER),
 
259
                                    avahi.DBUS_PATH_SERVER,
 
260
                                    follow_name_owner_changes=True),
234
261
                avahi.DBUS_INTERFACE_SERVER)
235
262
        self.server.connect_to_signal("StateChanged",
236
263
                                 self.server_state_changed)
445
472
        # If a checker exists, make sure it is not a zombie
446
473
        try:
447
474
            pid, status = os.waitpid(self.checker.pid, os.WNOHANG)
448
 
        except (AttributeError, OSError), error:
 
475
        except (AttributeError, OSError) as error:
449
476
            if (isinstance(error, OSError)
450
477
                and error.errno != errno.ECHILD):
451
478
                raise error
472
499
 
473
500
                try:
474
501
                    command = self.checker_command % escaped_attrs
475
 
                except TypeError, error:
 
502
                except TypeError as error:
476
503
                    logger.error('Could not format string "%s":'
477
504
                                 ' %s', self.checker_command, error)
478
505
                    return True # Try again later
497
524
                if pid:
498
525
                    gobject.source_remove(self.checker_callback_tag)
499
526
                    self.checker_callback(pid, status, command)
500
 
            except OSError, error:
 
527
            except OSError as error:
501
528
                logger.error("Failed to start subprocess: %s",
502
529
                             error)
503
530
        # Re-run this periodically if run by gobject.timeout_add
516
543
            #time.sleep(0.5)
517
544
            #if self.checker.poll() is None:
518
545
            #    os.kill(self.checker.pid, signal.SIGKILL)
519
 
        except OSError, error:
 
546
        except OSError as error:
520
547
            if error.errno != errno.ESRCH: # No such process
521
548
                raise
522
549
        self.checker = None
704
731
            xmlstring = document.toxml("utf-8")
705
732
            document.unlink()
706
733
        except (AttributeError, xml.dom.DOMException,
707
 
                xml.parsers.expat.ExpatError), error:
 
734
                xml.parsers.expat.ExpatError) as error:
708
735
            logger.error("Failed to override Introspection method",
709
736
                         error)
710
737
        return xmlstring
813
840
                                       *args, **kwargs)
814
841
    
815
842
    def checked_ok(self, *args, **kwargs):
816
 
        r = Client.checked_ok(self, *args, **kwargs)
 
843
        Client.checked_ok(self, *args, **kwargs)
817
844
        # Emit D-Bus signal
818
845
        self.PropertyChanged(
819
846
            dbus.String("LastCheckedOK"),
820
847
            (self._datetime_to_dbus(self.last_checked_ok,
821
848
                                    variant_level=1)))
822
 
        return r
823
849
    
824
850
    def need_approval(self, *args, **kwargs):
825
851
        r = Client.need_approval(self, *args, **kwargs)
922
948
    # CheckedOK - method
923
949
    @dbus.service.method(_interface)
924
950
    def CheckedOK(self):
925
 
        return self.checked_ok()
 
951
        self.checked_ok()
926
952
    
927
953
    # Enable - method
928
954
    @dbus.service.method(_interface)
1204
1230
            try:
1205
1231
                if int(line.strip().split()[0]) > 1:
1206
1232
                    raise RuntimeError
1207
 
            except (ValueError, IndexError, RuntimeError), error:
 
1233
            except (ValueError, IndexError, RuntimeError) as error:
1208
1234
                logger.error("Unknown protocol version: %s", error)
1209
1235
                return
1210
1236
 
1211
1237
            # Start GnuTLS connection
1212
1238
            try:
1213
1239
                session.handshake()
1214
 
            except gnutls.errors.GNUTLSError, error:
 
1240
            except gnutls.errors.GNUTLSError as error:
1215
1241
                logger.warning("Handshake failed: %s", error)
1216
1242
                # Do not run session.bye() here: the session is not
1217
1243
                # established.  Just abandon the request.
1223
1249
                try:
1224
1250
                    fpr = self.fingerprint(self.peer_certificate
1225
1251
                                           (session))
1226
 
                except (TypeError, gnutls.errors.GNUTLSError), error:
 
1252
                except (TypeError,
 
1253
                        gnutls.errors.GNUTLSError) as error:
1227
1254
                    logger.warning("Bad certificate: %s", error)
1228
1255
                    return
1229
1256
                logger.debug("Fingerprint: %s", fpr)
1241
1268
                
1242
1269
                while True:
1243
1270
                    if not client.enabled:
1244
 
                        logger.warning("Client %s is disabled",
 
1271
                        logger.info("Client %s is disabled",
1245
1272
                                       client.name)
1246
1273
                        if self.server.use_dbus:
1247
1274
                            # Emit D-Bus signal
1292
1319
                while sent_size < len(client.secret):
1293
1320
                    try:
1294
1321
                        sent = session.send(client.secret[sent_size:])
1295
 
                    except (gnutls.errors.GNUTLSError), error:
 
1322
                    except gnutls.errors.GNUTLSError as error:
1296
1323
                        logger.warning("gnutls send failed")
1297
1324
                        return
1298
1325
                    logger.debug("Sent: %d, remaining: %d",
1312
1339
                    client.approvals_pending -= 1
1313
1340
                try:
1314
1341
                    session.bye()
1315
 
                except (gnutls.errors.GNUTLSError), error:
 
1342
                except gnutls.errors.GNUTLSError as error:
1316
1343
                    logger.warning("GnuTLS bye failed")
1317
1344
    
1318
1345
    @staticmethod
1442
1469
                                           SO_BINDTODEVICE,
1443
1470
                                           str(self.interface
1444
1471
                                               + '\0'))
1445
 
                except socket.error, error:
 
1472
                except socket.error as error:
1446
1473
                    if error[0] == errno.EPERM:
1447
1474
                        logger.error("No permission to"
1448
1475
                                     " bind to interface %s",
1542
1569
                    client = c
1543
1570
                    break
1544
1571
            else:
1545
 
                logger.warning("Client not found for fingerprint: %s, ad"
1546
 
                               "dress: %s", fpr, address)
 
1572
                logger.info("Client not found for fingerprint: %s, ad"
 
1573
                            "dress: %s", fpr, address)
1547
1574
                if self.use_dbus:
1548
1575
                    # Emit D-Bus signal
1549
1576
                    mandos_dbus_service.ClientNotFound(fpr, address[0])
1613
1640
                delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
1614
1641
            else:
1615
1642
                raise ValueError("Unknown suffix %r" % suffix)
1616
 
        except (ValueError, IndexError), e:
 
1643
        except (ValueError, IndexError) as e:
1617
1644
            raise ValueError(*(e.args))
1618
1645
        timevalue += delta
1619
1646
    return timevalue
1816
1843
    try:
1817
1844
        os.setgid(gid)
1818
1845
        os.setuid(uid)
1819
 
    except OSError, error:
 
1846
    except OSError as error:
1820
1847
        if error[0] != errno.EPERM:
1821
1848
            raise error
1822
1849
    
1866
1893
        try:
1867
1894
            bus_name = dbus.service.BusName("se.bsnet.fukt.Mandos",
1868
1895
                                            bus, do_not_queue=True)
1869
 
        except dbus.exceptions.NameExistsException, e:
 
1896
        except dbus.exceptions.NameExistsException as e:
1870
1897
            logger.error(unicode(e) + ", disabling D-Bus")
1871
1898
            use_dbus = False
1872
1899
            server_settings["use_dbus"] = False
2022
2049
        # From the Avahi example code
2023
2050
        try:
2024
2051
            service.activate()
2025
 
        except dbus.exceptions.DBusException, error:
 
2052
        except dbus.exceptions.DBusException as error:
2026
2053
            logger.critical("DBusException: %s", error)
2027
2054
            cleanup()
2028
2055
            sys.exit(1)
2035
2062
        
2036
2063
        logger.debug("Starting main loop")
2037
2064
        main_loop.run()
2038
 
    except AvahiError, error:
 
2065
    except AvahiError as error:
2039
2066
        logger.critical("AvahiError: %s", error)
2040
2067
        cleanup()
2041
2068
        sys.exit(1)