crypto.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. from django.core.exceptions import ValidationError
  2. from django.db import models
  3. from django.utils.translation import gettext_lazy as _
  4. from netbox.models import PrimaryModel
  5. from vpn.choices import *
  6. __all__ = (
  7. 'IKEPolicy',
  8. 'IKEProposal',
  9. 'IPSecPolicy',
  10. 'IPSecProfile',
  11. 'IPSecProposal',
  12. )
  13. #
  14. # IKE
  15. #
  16. class IKEProposal(PrimaryModel):
  17. name = models.CharField(
  18. verbose_name=_('name'),
  19. max_length=100,
  20. unique=True
  21. )
  22. authentication_method = models.CharField(
  23. verbose_name=('authentication method'),
  24. choices=AuthenticationMethodChoices
  25. )
  26. encryption_algorithm = models.CharField(
  27. verbose_name=_('encryption algorithm'),
  28. choices=EncryptionAlgorithmChoices
  29. )
  30. authentication_algorithm = models.CharField(
  31. verbose_name=_('authentication algorithm'),
  32. choices=AuthenticationAlgorithmChoices,
  33. blank=True
  34. )
  35. group = models.PositiveSmallIntegerField(
  36. verbose_name=_('group'),
  37. choices=DHGroupChoices,
  38. help_text=_('Diffie-Hellman group ID')
  39. )
  40. sa_lifetime = models.PositiveIntegerField(
  41. verbose_name=_('SA lifetime'),
  42. blank=True,
  43. null=True,
  44. help_text=_('Security association lifetime (in seconds)')
  45. )
  46. clone_fields = (
  47. 'authentication_method', 'encryption_algorithm', 'authentication_algorithm', 'group', 'sa_lifetime',
  48. )
  49. class Meta:
  50. ordering = ('name',)
  51. verbose_name = _('IKE proposal')
  52. verbose_name_plural = _('IKE proposals')
  53. def __str__(self):
  54. return self.name
  55. class IKEPolicy(PrimaryModel):
  56. name = models.CharField(
  57. verbose_name=_('name'),
  58. max_length=100,
  59. unique=True
  60. )
  61. version = models.PositiveSmallIntegerField(
  62. verbose_name=_('version'),
  63. choices=IKEVersionChoices,
  64. default=IKEVersionChoices.VERSION_2
  65. )
  66. mode = models.CharField(
  67. verbose_name=_('mode'),
  68. choices=IKEModeChoices,
  69. blank=True
  70. )
  71. proposals = models.ManyToManyField(
  72. to='vpn.IKEProposal',
  73. related_name='ike_policies',
  74. verbose_name=_('proposals')
  75. )
  76. preshared_key = models.TextField(
  77. verbose_name=_('pre-shared key'),
  78. blank=True
  79. )
  80. clone_fields = (
  81. 'version', 'mode', 'proposals',
  82. )
  83. prerequisite_models = (
  84. 'vpn.IKEProposal',
  85. )
  86. class Meta:
  87. ordering = ('name',)
  88. verbose_name = _('IKE policy')
  89. verbose_name_plural = _('IKE policies')
  90. def __str__(self):
  91. return self.name
  92. def clean(self):
  93. super().clean()
  94. # Mode is required
  95. if self.version == IKEVersionChoices.VERSION_1 and not self.mode:
  96. raise ValidationError(_("Mode is required for selected IKE version"))
  97. # Mode cannot be used
  98. if self.version == IKEVersionChoices.VERSION_2 and self.mode:
  99. raise ValidationError(_("Mode cannot be used for selected IKE version"))
  100. #
  101. # IPSec
  102. #
  103. class IPSecProposal(PrimaryModel):
  104. name = models.CharField(
  105. verbose_name=_('name'),
  106. max_length=100,
  107. unique=True
  108. )
  109. encryption_algorithm = models.CharField(
  110. verbose_name=_('encryption'),
  111. choices=EncryptionAlgorithmChoices,
  112. blank=True
  113. )
  114. authentication_algorithm = models.CharField(
  115. verbose_name=_('authentication'),
  116. choices=AuthenticationAlgorithmChoices,
  117. blank=True
  118. )
  119. sa_lifetime_seconds = models.PositiveIntegerField(
  120. verbose_name=_('SA lifetime (seconds)'),
  121. blank=True,
  122. null=True,
  123. help_text=_('Security association lifetime (seconds)')
  124. )
  125. sa_lifetime_data = models.PositiveIntegerField(
  126. verbose_name=_('SA lifetime (KB)'),
  127. blank=True,
  128. null=True,
  129. help_text=_('Security association lifetime (in kilobytes)')
  130. )
  131. clone_fields = (
  132. 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds', 'sa_lifetime_data',
  133. )
  134. class Meta:
  135. ordering = ('name',)
  136. verbose_name = _('IPSec proposal')
  137. verbose_name_plural = _('IPSec proposals')
  138. def __str__(self):
  139. return self.name
  140. def clean(self):
  141. super().clean()
  142. # Encryption and/or authentication algorithm must be defined
  143. if not self.encryption_algorithm and not self.authentication_algorithm:
  144. raise ValidationError(_("Encryption and/or authentication algorithm must be defined"))
  145. class IPSecPolicy(PrimaryModel):
  146. name = models.CharField(
  147. verbose_name=_('name'),
  148. max_length=100,
  149. unique=True
  150. )
  151. proposals = models.ManyToManyField(
  152. to='vpn.IPSecProposal',
  153. related_name='ipsec_policies',
  154. verbose_name=_('proposals')
  155. )
  156. pfs_group = models.PositiveSmallIntegerField(
  157. verbose_name=_('PFS group'),
  158. choices=DHGroupChoices,
  159. blank=True,
  160. null=True,
  161. help_text=_('Diffie-Hellman group for Perfect Forward Secrecy')
  162. )
  163. clone_fields = (
  164. 'proposals', 'pfs_group',
  165. )
  166. prerequisite_models = (
  167. 'vpn.IPSecProposal',
  168. )
  169. class Meta:
  170. ordering = ('name',)
  171. verbose_name = _('IPSec policy')
  172. verbose_name_plural = _('IPSec policies')
  173. def __str__(self):
  174. return self.name
  175. class IPSecProfile(PrimaryModel):
  176. name = models.CharField(
  177. verbose_name=_('name'),
  178. max_length=100,
  179. unique=True
  180. )
  181. mode = models.CharField(
  182. verbose_name=_('mode'),
  183. choices=IPSecModeChoices
  184. )
  185. ike_policy = models.ForeignKey(
  186. to='vpn.IKEPolicy',
  187. on_delete=models.PROTECT,
  188. related_name='ipsec_profiles'
  189. )
  190. ipsec_policy = models.ForeignKey(
  191. to='vpn.IPSecPolicy',
  192. on_delete=models.PROTECT,
  193. related_name='ipsec_profiles'
  194. )
  195. clone_fields = (
  196. 'mode', 'ike_policy', 'ipsec_policy',
  197. )
  198. prerequisite_models = (
  199. 'vpn.IKEPolicy',
  200. 'vpn.IPSecPolicy',
  201. )
  202. class Meta:
  203. ordering = ('name',)
  204. verbose_name = _('IPSec profile')
  205. verbose_name_plural = _('IPSec profiles')
  206. def __str__(self):
  207. return self.name