##// END OF EJS Templates
ssh: rollback temp changes as it creates even more problems with cross drive linking
super-admin -
r4840:01f10166 default
parent child Browse files
Show More
@@ -1,133 +1,133 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 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 os
21 import os
22 import stat
22 import stat
23 import logging
23 import logging
24 import tempfile
24 import tempfile
25 import datetime
25 import datetime
26
26
27 from . import config_keys
27 from . import config_keys
28 from rhodecode.model.db import true, joinedload, User, UserSshKeys
28 from rhodecode.model.db import true, joinedload, User, UserSshKeys
29
29
30
30
31 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
32
32
33 HEADER = \
33 HEADER = \
34 "# This file is managed by RhodeCode, please do not edit it manually. # \n" \
34 "# This file is managed by RhodeCode, please do not edit it manually. # \n" \
35 "# Current entries: {}, create date: UTC:{}.\n"
35 "# Current entries: {}, create date: UTC:{}.\n"
36
36
37 # Default SSH options for authorized_keys file, can be override via .ini
37 # Default SSH options for authorized_keys file, can be override via .ini
38 SSH_OPTS = 'no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding'
38 SSH_OPTS = 'no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding'
39
39
40
40
41 def get_all_active_keys():
41 def get_all_active_keys():
42 result = UserSshKeys.query() \
42 result = UserSshKeys.query() \
43 .options(joinedload(UserSshKeys.user)) \
43 .options(joinedload(UserSshKeys.user)) \
44 .filter(UserSshKeys.user != User.get_default_user()) \
44 .filter(UserSshKeys.user != User.get_default_user()) \
45 .filter(User.active == true()) \
45 .filter(User.active == true()) \
46 .all()
46 .all()
47 return result
47 return result
48
48
49
49
50 def _generate_ssh_authorized_keys_file(
50 def _generate_ssh_authorized_keys_file(
51 authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, debug):
51 authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, debug):
52 import rhodecode
52 import rhodecode
53
53
54 authorized_keys_file_path = os.path.abspath(
54 authorized_keys_file_path = os.path.abspath(
55 os.path.expanduser(authorized_keys_file_path))
55 os.path.expanduser(authorized_keys_file_path))
56 tmp_file_dir = tempfile.gettempdir()
56 tmp_file_dir = os.path.dirname(authorized_keys_file_path)
57
57
58 all_active_keys = get_all_active_keys()
58 all_active_keys = get_all_active_keys()
59
59
60 if allow_shell:
60 if allow_shell:
61 ssh_wrapper_cmd = ssh_wrapper_cmd + ' --shell'
61 ssh_wrapper_cmd = ssh_wrapper_cmd + ' --shell'
62 if debug:
62 if debug:
63 ssh_wrapper_cmd = ssh_wrapper_cmd + ' --debug'
63 ssh_wrapper_cmd = ssh_wrapper_cmd + ' --debug'
64
64
65 if not os.path.isfile(authorized_keys_file_path):
65 if not os.path.isfile(authorized_keys_file_path):
66 log.debug('Creating file at %s', authorized_keys_file_path)
66 log.debug('Creating file at %s', authorized_keys_file_path)
67 with open(authorized_keys_file_path, 'w'):
67 with open(authorized_keys_file_path, 'w'):
68 pass
68 pass
69
69
70 if not os.access(authorized_keys_file_path, os.R_OK):
70 if not os.access(authorized_keys_file_path, os.R_OK):
71 raise OSError('Access to file {} is without read access'.format(
71 raise OSError('Access to file {} is without read access'.format(
72 authorized_keys_file_path))
72 authorized_keys_file_path))
73
73
74 line_tmpl = '{ssh_opts},command="{wrapper_command} {ini_path} --user-id={user_id} --user={user} --key-id={user_key_id}" {key}\n'
74 line_tmpl = '{ssh_opts},command="{wrapper_command} {ini_path} --user-id={user_id} --user={user} --key-id={user_key_id}" {key}\n'
75
75
76 fd, tmp_authorized_keys = tempfile.mkstemp(
76 fd, tmp_authorized_keys = tempfile.mkstemp(
77 '.authorized_keys_write_operation',
77 '.authorized_keys_write_operation',
78 dir=tmp_file_dir)
78 dir=tmp_file_dir)
79
79
80 now = datetime.datetime.utcnow().isoformat()
80 now = datetime.datetime.utcnow().isoformat()
81 keys_file = os.fdopen(fd, 'wb')
81 keys_file = os.fdopen(fd, 'wb')
82 keys_file.write(HEADER.format(len(all_active_keys), now))
82 keys_file.write(HEADER.format(len(all_active_keys), now))
83 ini_path = rhodecode.CONFIG['__file__']
83 ini_path = rhodecode.CONFIG['__file__']
84
84
85 for user_key in all_active_keys:
85 for user_key in all_active_keys:
86 username = user_key.user.username
86 username = user_key.user.username
87 user_id = user_key.user.user_id
87 user_id = user_key.user.user_id
88 # replace all newline from ends and inside
88 # replace all newline from ends and inside
89 safe_key_data = user_key.ssh_key_data\
89 safe_key_data = user_key.ssh_key_data\
90 .strip()\
90 .strip()\
91 .replace('\n', ' ') \
91 .replace('\n', ' ') \
92 .replace('\t', ' ') \
92 .replace('\t', ' ') \
93 .replace('\r', ' ')
93 .replace('\r', ' ')
94
94
95 line = line_tmpl.format(
95 line = line_tmpl.format(
96 ssh_opts=ssh_opts or SSH_OPTS,
96 ssh_opts=ssh_opts or SSH_OPTS,
97 wrapper_command=ssh_wrapper_cmd,
97 wrapper_command=ssh_wrapper_cmd,
98 ini_path=ini_path,
98 ini_path=ini_path,
99 user_id=user_id,
99 user_id=user_id,
100 user=username,
100 user=username,
101 user_key_id=user_key.ssh_key_id,
101 user_key_id=user_key.ssh_key_id,
102 key=safe_key_data)
102 key=safe_key_data)
103
103
104 keys_file.write(line)
104 keys_file.write(line)
105 log.debug('addkey: Key added for user: `%s`', username)
105 log.debug('addkey: Key added for user: `%s`', username)
106 keys_file.close()
106 keys_file.close()
107
107
108 # Explicitly setting read-only permissions to authorized_keys
108 # Explicitly setting read-only permissions to authorized_keys
109 os.chmod(tmp_authorized_keys, stat.S_IRUSR | stat.S_IWUSR)
109 os.chmod(tmp_authorized_keys, stat.S_IRUSR | stat.S_IWUSR)
110 # Rename is atomic operation
110 # Rename is atomic operation
111 os.rename(tmp_authorized_keys, authorized_keys_file_path)
111 os.rename(tmp_authorized_keys, authorized_keys_file_path)
112
112
113
113
114 def generate_ssh_authorized_keys_file(registry):
114 def generate_ssh_authorized_keys_file(registry):
115 log.info('Generating new authorized key file')
115 log.info('Generating new authorized key file')
116
116
117 authorized_keys_file_path = registry.settings.get(
117 authorized_keys_file_path = registry.settings.get(
118 config_keys.authorized_keys_file_path)
118 config_keys.authorized_keys_file_path)
119
119
120 ssh_wrapper_cmd = registry.settings.get(
120 ssh_wrapper_cmd = registry.settings.get(
121 config_keys.wrapper_cmd)
121 config_keys.wrapper_cmd)
122 allow_shell = registry.settings.get(
122 allow_shell = registry.settings.get(
123 config_keys.wrapper_allow_shell)
123 config_keys.wrapper_allow_shell)
124 ssh_opts = registry.settings.get(
124 ssh_opts = registry.settings.get(
125 config_keys.authorized_keys_line_ssh_opts)
125 config_keys.authorized_keys_line_ssh_opts)
126 debug = registry.settings.get(
126 debug = registry.settings.get(
127 config_keys.enable_debug_logging)
127 config_keys.enable_debug_logging)
128
128
129 _generate_ssh_authorized_keys_file(
129 _generate_ssh_authorized_keys_file(
130 authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts,
130 authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts,
131 debug)
131 debug)
132
132
133 return 0
133 return 0
General Comments 0
You need to be logged in to leave comments. Login now