##// END OF EJS Templates
ssh: replaced pycrypto with cryptography to generate SSH keys....
marcink -
r3520:d8bf39a6 default
parent child Browse files
Show More
@@ -1,123 +1,136 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2019 RhodeCode GmbH
3 # Copyright (C) 2013-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import traceback
22 import traceback
23
23
24 import sshpubkeys
24 import sshpubkeys
25 import sshpubkeys.exceptions
25 import sshpubkeys.exceptions
26
26
27 from cryptography.hazmat.primitives.asymmetric import rsa
28 from cryptography.hazmat.primitives import serialization as crypto_serialization
29 from cryptography.hazmat.backends import default_backend as crypto_default_backend
30
27 from rhodecode.model import BaseModel
31 from rhodecode.model import BaseModel
28 from rhodecode.model.db import UserSshKeys
32 from rhodecode.model.db import UserSshKeys
29 from rhodecode.model.meta import Session
33 from rhodecode.model.meta import Session
30
34
35
31 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
32
37
33
38
34 class SshKeyModel(BaseModel):
39 class SshKeyModel(BaseModel):
35 cls = UserSshKeys
40 cls = UserSshKeys
36
41
37 def parse_key(self, key_data):
42 def parse_key(self, key_data):
38 """
43 """
39 print(ssh.bits) # 768
44 print(ssh.bits) # 768
40 print(ssh.hash_md5()) # 56:84:1e:90:08:3b:60:c7:29:70:5f:5e:25:a6:3b:86
45 print(ssh.hash_md5()) # 56:84:1e:90:08:3b:60:c7:29:70:5f:5e:25:a6:3b:86
41 print(ssh.hash_sha256()) # SHA256:xk3IEJIdIoR9MmSRXTP98rjDdZocmXJje/28ohMQEwM
46 print(ssh.hash_sha256()) # SHA256:xk3IEJIdIoR9MmSRXTP98rjDdZocmXJje/28ohMQEwM
42 print(ssh.hash_sha512()) # SHA512:1C3lNBhjpDVQe39hnyy+xvlZYU3IPwzqK1rVneGavy6O3/ebjEQSFvmeWoyMTplIanmUK1hmr9nA8Skmj516HA
47 print(ssh.hash_sha512()) # SHA512:1C3lNBhjpDVQe39hnyy+xvlZYU3IPwzqK1rVneGavy6O3/ebjEQSFvmeWoyMTplIanmUK1hmr9nA8Skmj516HA
43 print(ssh.comment) # ojar@ojar-laptop
48 print(ssh.comment) # ojar@ojar-laptop
44 print(ssh.options_raw) # None (string of optional options at the beginning of public key)
49 print(ssh.options_raw) # None (string of optional options at the beginning of public key)
45 print(ssh.options) # None (options as a dictionary, parsed and validated)
50 print(ssh.options) # None (options as a dictionary, parsed and validated)
46
51
47 :param key_data:
52 :param key_data:
48 :return:
53 :return:
49 """
54 """
50 ssh = sshpubkeys.SSHKey(strict_mode=True)
55 ssh = sshpubkeys.SSHKey(strict_mode=True)
51 try:
56 try:
52 ssh.parse(key_data)
57 ssh.parse(key_data)
53 return ssh
58 return ssh
54 except sshpubkeys.exceptions.InvalidKeyException as err:
59 except sshpubkeys.exceptions.InvalidKeyException as err:
55 log.error("Invalid key: %s", err)
60 log.error("Invalid key: %s", err)
56 raise
61 raise
57 except NotImplementedError as err:
62 except NotImplementedError as err:
58 log.error("Invalid key type: %s", err)
63 log.error("Invalid key type: %s", err)
59 raise
64 raise
60 except Exception as err:
65 except Exception as err:
61 log.error("Key Parse error: %s", err)
66 log.error("Key Parse error: %s", err)
62 raise
67 raise
63
68
64 def generate_keypair(self, comment=None):
69 def generate_keypair(self, comment=None):
65 from Crypto.PublicKey import RSA
66
67 key = RSA.generate(2048)
68 private = key.exportKey('PEM')
69
70
70 pubkey = key.publickey()
71 key = rsa.generate_private_key(
71 public = pubkey.exportKey('OpenSSH')
72 backend=crypto_default_backend(),
73 public_exponent=65537,
74 key_size=2048
75 )
76 private_key = key.private_bytes(
77 crypto_serialization.Encoding.PEM,
78 crypto_serialization.PrivateFormat.PKCS8,
79 crypto_serialization.NoEncryption())
80 public_key = key.public_key().public_bytes(
81 crypto_serialization.Encoding.OpenSSH,
82 crypto_serialization.PublicFormat.OpenSSH
83 )
84
72 if comment:
85 if comment:
73 public = public + " " + comment
86 public_key = public_key + " " + comment
74 return private, public
87 return private_key, public_key
75
88
76 def create(self, user, fingerprint, key_data, description):
89 def create(self, user, fingerprint, key_data, description):
77 """
90 """
78 """
91 """
79 user = self._get_user(user)
92 user = self._get_user(user)
80
93
81 new_ssh_key = UserSshKeys()
94 new_ssh_key = UserSshKeys()
82 new_ssh_key.ssh_key_fingerprint = fingerprint
95 new_ssh_key.ssh_key_fingerprint = fingerprint
83 new_ssh_key.ssh_key_data = key_data
96 new_ssh_key.ssh_key_data = key_data
84 new_ssh_key.user_id = user.user_id
97 new_ssh_key.user_id = user.user_id
85 new_ssh_key.description = description
98 new_ssh_key.description = description
86
99
87 Session().add(new_ssh_key)
100 Session().add(new_ssh_key)
88
101
89 return new_ssh_key
102 return new_ssh_key
90
103
91 def delete(self, ssh_key_id, user=None):
104 def delete(self, ssh_key_id, user=None):
92 """
105 """
93 Deletes given api_key, if user is set it also filters the object for
106 Deletes given api_key, if user is set it also filters the object for
94 deletion by given user.
107 deletion by given user.
95 """
108 """
96 ssh_key = UserSshKeys.query().filter(
109 ssh_key = UserSshKeys.query().filter(
97 UserSshKeys.ssh_key_id == ssh_key_id)
110 UserSshKeys.ssh_key_id == ssh_key_id)
98
111
99 if user:
112 if user:
100 user = self._get_user(user)
113 user = self._get_user(user)
101 ssh_key = ssh_key.filter(UserSshKeys.user_id == user.user_id)
114 ssh_key = ssh_key.filter(UserSshKeys.user_id == user.user_id)
102 ssh_key = ssh_key.scalar()
115 ssh_key = ssh_key.scalar()
103
116
104 if ssh_key:
117 if ssh_key:
105 try:
118 try:
106 Session().delete(ssh_key)
119 Session().delete(ssh_key)
107 except Exception:
120 except Exception:
108 log.error(traceback.format_exc())
121 log.error(traceback.format_exc())
109 raise
122 raise
110
123
111 def get_ssh_keys(self, user):
124 def get_ssh_keys(self, user):
112 user = self._get_user(user)
125 user = self._get_user(user)
113 user_ssh_keys = UserSshKeys.query()\
126 user_ssh_keys = UserSshKeys.query()\
114 .filter(UserSshKeys.user_id == user.user_id)
127 .filter(UserSshKeys.user_id == user.user_id)
115 user_ssh_keys = user_ssh_keys.order_by(UserSshKeys.ssh_key_id)
128 user_ssh_keys = user_ssh_keys.order_by(UserSshKeys.ssh_key_id)
116 return user_ssh_keys
129 return user_ssh_keys
117
130
118 def get_ssh_key_by_fingerprint(self, ssh_key_fingerprint):
131 def get_ssh_key_by_fingerprint(self, ssh_key_fingerprint):
119 user_ssh_key = UserSshKeys.query()\
132 user_ssh_key = UserSshKeys.query()\
120 .filter(UserSshKeys.ssh_key_fingerprint == ssh_key_fingerprint)\
133 .filter(UserSshKeys.ssh_key_fingerprint == ssh_key_fingerprint)\
121 .first()
134 .first()
122
135
123 return user_ssh_key
136 return user_ssh_key
General Comments 0
You need to be logged in to leave comments. Login now