Explorar el Código

Fixes #14499: Relax requirements for encryption/auth algorithms on IKE & IPSec proposals

Jeremy Stretch hace 2 años
padre
commit
b794bd6fb8

+ 1 - 1
docs/models/vpn/ikeproposal.md

@@ -28,7 +28,7 @@ The protocol employed for data encryption. Options include DES, 3DES, and variou
 
 ### Authentication Algorithm
 
-The mechanism employed to ensure data integrity. Options include MD5 and SHA HMAC implementations.
+The mechanism employed to ensure data integrity. Options include MD5 and SHA HMAC implementations. Specifying an authentication algorithm is optional, as some encryption algorithms (e.g. AES-GCM) provide authentication natively.
 
 ### Group
 

+ 6 - 0
docs/models/vpn/ipsecproposal.md

@@ -12,10 +12,16 @@ The unique user-assigned name for the proposal.
 
 The protocol employed for data encryption. Options include DES, 3DES, and various flavors of AES.
 
+!!! note
+    If an encryption algorithm is not specified, an authentication algorithm must be specified.
+
 ### Authentication Algorithm
 
 The mechanism employed to ensure data integrity. Options include MD5 and SHA HMAC implementations.
 
+!!! note
+    If an authentication algorithm is not specified, an encryption algorithm must be specified.
+
 ### SA Lifetime (Seconds)
 
 The maximum amount of time for which the security association (SA) may be active, in seconds.

+ 3 - 3
netbox/vpn/migrations/0001_initial.py

@@ -29,7 +29,7 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(max_length=100, unique=True)),
                 ('authentication_method', models.CharField()),
                 ('encryption_algorithm', models.CharField()),
-                ('authentication_algorithm', models.CharField()),
+                ('authentication_algorithm', models.CharField(blank=True)),
                 ('group', models.PositiveSmallIntegerField()),
                 ('sa_lifetime', models.PositiveIntegerField(blank=True, null=True)),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
@@ -82,8 +82,8 @@ class Migration(migrations.Migration):
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
                 ('name', models.CharField(max_length=100, unique=True)),
-                ('encryption_algorithm', models.CharField()),
-                ('authentication_algorithm', models.CharField()),
+                ('encryption_algorithm', models.CharField(blank=True)),
+                ('authentication_algorithm', models.CharField(blank=True)),
                 ('sa_lifetime_seconds', models.PositiveIntegerField(blank=True, null=True)),
                 ('sa_lifetime_data', models.PositiveIntegerField(blank=True, null=True)),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),

+ 14 - 3
netbox/vpn/models/crypto.py

@@ -1,3 +1,4 @@
+from django.core.exceptions import ValidationError
 from django.db import models
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
@@ -34,7 +35,8 @@ class IKEProposal(PrimaryModel):
     )
     authentication_algorithm = models.CharField(
         verbose_name=_('authentication algorithm'),
-        choices=AuthenticationAlgorithmChoices
+        choices=AuthenticationAlgorithmChoices,
+        blank=True
     )
     group = models.PositiveSmallIntegerField(
         verbose_name=_('group'),
@@ -120,11 +122,13 @@ class IPSecProposal(PrimaryModel):
     )
     encryption_algorithm = models.CharField(
         verbose_name=_('encryption'),
-        choices=EncryptionAlgorithmChoices
+        choices=EncryptionAlgorithmChoices,
+        blank=True
     )
     authentication_algorithm = models.CharField(
         verbose_name=_('authentication'),
-        choices=AuthenticationAlgorithmChoices
+        choices=AuthenticationAlgorithmChoices,
+        blank=True
     )
     sa_lifetime_seconds = models.PositiveIntegerField(
         verbose_name=_('SA lifetime (seconds)'),
@@ -154,6 +158,13 @@ class IPSecProposal(PrimaryModel):
     def get_absolute_url(self):
         return reverse('vpn:ipsecproposal', args=[self.pk])
 
+    def clean(self):
+        super().clean()
+
+        # Encryption and/or authentication algorithm must be defined
+        if not self.encryption_algorithm and not self.authentication_algorithm:
+            raise ValidationError(_("Encryption and/or authentication algorithm must be defined"))
+
 
 class IPSecPolicy(PrimaryModel):
     name = models.CharField(