tsig_keyring.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  8. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  9. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  10. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  12. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  13. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  14. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. """
  16. This module conveniently keeps a copy of TSIG keyring loaded from the
  17. tsig_keys module.
  18. """
  19. import isc.dns
  20. import isc.log
  21. from isc.server_common.logger import logger
  22. from isc.log_messages.server_common_messages import *
  23. updater = None
  24. class Unexpected(Exception):
  25. """
  26. Raised when an unexpected operation is requested by the user of this
  27. module. For example if calling keyring() before init_keyring().
  28. """
  29. pass
  30. class AddError(Exception):
  31. """
  32. Raised when a key can not be added. This usually means there's a
  33. duplicate.
  34. """
  35. pass
  36. class Updater:
  37. """
  38. The updater of tsig key ring. Not to be used directly.
  39. """
  40. def __init__(self, session):
  41. """
  42. Constructor. Pass the ccsession object so the key ring can be
  43. downloaded.
  44. """
  45. logger.debug(logger.DBGLVL_TRACE_BASIC,
  46. PYSERVER_COMMON_TSIG_KEYRING_INIT)
  47. self.__session = session
  48. self.__keyring = isc.dns.TSIGKeyRing()
  49. session.add_remote_config_by_name('tsig_keys', self.__update)
  50. self.__update()
  51. def __update(self, value=None, module_cfg=None):
  52. """
  53. Update the key ring by the configuration.
  54. Note that this function is used as a callback, but can raise
  55. on bad data. The bad data is expected to be handled by the
  56. configuration plugin and not be allowed as far as here.
  57. The parameters are there just to match the signature which
  58. the callback should have (i.e. they are ignored).
  59. """
  60. logger.debug(logger.DBGLVL_TRACE_BASIC,
  61. PYSERVER_COMMON_TSIG_KEYRING_UPDATE)
  62. (data, _) = self.__session.get_remote_config_value('tsig_keys', 'keys')
  63. if data is not None: # There's an update
  64. keyring = isc.dns.TSIGKeyRing()
  65. for key_data in data:
  66. key = isc.dns.TSIGKey(key_data)
  67. if keyring.add(key) != isc.dns.TSIGKeyRing.SUCCESS:
  68. raise AddError("Can't add key " + str(key))
  69. self.__keyring = keyring
  70. def get_keyring(self):
  71. """
  72. Return the current key ring.
  73. """
  74. return self.__keyring
  75. def deinit(self):
  76. """
  77. Unregister from getting updates. The object will not be
  78. usable any more after this.
  79. """
  80. logger.debug(logger.DBGLVL_TRACE_BASIC,
  81. PYSERVER_COMMON_TSIG_KEYRING_DEINIT)
  82. self.__session.remove_remote_config('tsig_keys')
  83. def get_keyring():
  84. """
  85. Get the current key ring. You need to call init_keyring first.
  86. """
  87. if updater is None:
  88. raise Unexpected("You need to initialize the keyring first by " +
  89. "init_keyring()")
  90. return updater.get_keyring()
  91. def init_keyring(session):
  92. """
  93. Initialize the key ring for future use. It does nothing if already
  94. initialized.
  95. """
  96. global updater
  97. if updater is None:
  98. updater = Updater(session)
  99. def deinit_keyring():
  100. """
  101. Deinit key ring. Yoeu can no longer access keyring() after this.
  102. Does nothing if not initialized.
  103. """
  104. global updater
  105. if updater is not None:
  106. updater.deinit()
  107. updater = None