Added ssh public key validation
This commit is contained in:
		
					parent
					
						
							
								46642d816a
							
						
					
				
			
			
				commit
				
					
						79ecdadeb2
					
				
			
		
					 1 changed files with 38 additions and 7 deletions
				
			
		| 
						 | 
					@ -1,13 +1,17 @@
 | 
				
			||||||
 | 
					import base64
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					import struct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
from membership.models import CustomUser
 | 
					 | 
				
			||||||
from django.contrib.auth import authenticate
 | 
					from django.contrib.auth import authenticate
 | 
				
			||||||
 | 
					 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from membership.models import CustomUser
 | 
				
			||||||
from .models import UserHostingKey
 | 
					from .models import UserHostingKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logger = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_ssh_key_name():
 | 
					def generate_ssh_key_name():
 | 
				
			||||||
    return 'dcl-generated-key-' + datetime.datetime.now().strftime('%m%d%y%H%M')
 | 
					    return 'dcl-generated-key-' + datetime.datetime.now().strftime('%m%d%y%H%M')
 | 
				
			||||||
| 
						 | 
					@ -38,7 +42,7 @@ class HostingUserLoginForm(forms.Form):
 | 
				
			||||||
            CustomUser.objects.get(email=email)
 | 
					            CustomUser.objects.get(email=email)
 | 
				
			||||||
            return email
 | 
					            return email
 | 
				
			||||||
        except CustomUser.DoesNotExist:
 | 
					        except CustomUser.DoesNotExist:
 | 
				
			||||||
            raise forms.ValidationError("User does not exist")
 | 
					            raise forms.ValidationError(_("User does not exist"))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return email
 | 
					            return email
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +55,8 @@ class HostingUserSignupForm(forms.ModelForm):
 | 
				
			||||||
        model = CustomUser
 | 
					        model = CustomUser
 | 
				
			||||||
        fields = ['name', 'email', 'password']
 | 
					        fields = ['name', 'email', 'password']
 | 
				
			||||||
        widgets = {
 | 
					        widgets = {
 | 
				
			||||||
            'name': forms.TextInput(attrs={'placeholder': 'Enter your name or company name'}),
 | 
					            'name': forms.TextInput(
 | 
				
			||||||
 | 
					                attrs={'placeholder': 'Enter your name or company name'}),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean_confirm_password(self):
 | 
					    def clean_confirm_password(self):
 | 
				
			||||||
| 
						 | 
					@ -65,19 +70,45 @@ class HostingUserSignupForm(forms.ModelForm):
 | 
				
			||||||
class UserHostingKeyForm(forms.ModelForm):
 | 
					class UserHostingKeyForm(forms.ModelForm):
 | 
				
			||||||
    private_key = forms.CharField(widget=forms.HiddenInput(), required=False)
 | 
					    private_key = forms.CharField(widget=forms.HiddenInput(), required=False)
 | 
				
			||||||
    public_key = forms.CharField(widget=forms.Textarea(
 | 
					    public_key = forms.CharField(widget=forms.Textarea(
 | 
				
			||||||
        attrs={'class': 'form_public_key', 'placeholder': _('Paste here your public key')}),
 | 
					        attrs={'class': 'form_public_key',
 | 
				
			||||||
 | 
					               'placeholder': _('Paste here your public key')}),
 | 
				
			||||||
        required=False,
 | 
					        required=False,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(),
 | 
					    user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(),
 | 
				
			||||||
                                         required=False, widget=forms.HiddenInput())
 | 
					                                         required=False,
 | 
				
			||||||
 | 
					                                         widget=forms.HiddenInput())
 | 
				
			||||||
    name = forms.CharField(required=False, widget=forms.TextInput(
 | 
					    name = forms.CharField(required=False, widget=forms.TextInput(
 | 
				
			||||||
        attrs={'class': 'form_key_name', 'placeholder': _('Give a name to your key')}))
 | 
					        attrs={'class': 'form_key_name',
 | 
				
			||||||
 | 
					               'placeholder': _('Give a name to your key')}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        self.request = kwargs.pop("request")
 | 
					        self.request = kwargs.pop("request")
 | 
				
			||||||
        super(UserHostingKeyForm, self).__init__(*args, **kwargs)
 | 
					        super(UserHostingKeyForm, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.fields['name'].label = _('Key name')
 | 
					        self.fields['name'].label = _('Key name')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clean_public_key(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        A simple validation of ssh public key
 | 
				
			||||||
 | 
					        See https://www.ietf.org/rfc/rfc4716.txt
 | 
				
			||||||
 | 
					        :return:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        KEY_ERROR_MESSAGE = _("Please input a proper SSH key")
 | 
				
			||||||
 | 
					        openssh_pubkey = self.data.get('public_key')
 | 
				
			||||||
 | 
					        data = None
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            key_type, key_string, comment = openssh_pubkey.split()
 | 
				
			||||||
 | 
					            data = base64.decodebytes(key_string.encode('utf-8'))
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            logger.error("Exception while decoding ssh key {}".format(e))
 | 
				
			||||||
 | 
					            raise forms.ValidationError(KEY_ERROR_MESSAGE)
 | 
				
			||||||
 | 
					        int_len = 4
 | 
				
			||||||
 | 
					        str_len = struct.unpack('>I', data[:int_len])[0]  # this should return 7
 | 
				
			||||||
 | 
					        if str_len != 7:
 | 
				
			||||||
 | 
					            raise forms.ValidationError(KEY_ERROR_MESSAGE)
 | 
				
			||||||
 | 
					        if data[int_len:int_len + str_len] != key_type.encode('utf-8'):
 | 
				
			||||||
 | 
					            raise forms.ValidationError(KEY_ERROR_MESSAGE)
 | 
				
			||||||
 | 
					        return openssh_pubkey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean_name(self):
 | 
					    def clean_name(self):
 | 
				
			||||||
        return self.data.get('name')
 | 
					        return self.data.get('name')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue