Merge lp:~jelmer/brz/authconfperm into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/authconfperm
Merge into: lp:brz
Diff against target: 144 lines (+64/-3)
4 files modified
breezy/config.py (+21/-1)
breezy/help_topics/en/configuration.txt (+4/-0)
breezy/tests/test_config.py (+34/-2)
doc/en/release-notes/brz-3.0.txt (+5/-0)
To merge this branch: bzr merge lp:~jelmer/brz/authconfperm
Reviewer Review Type Date Requested Status
Martin Packman Approve
Review via email: mp+325541@code.launchpad.net

Commit message

Use tight permissions on authentication.conf.

Description of the change

When creating authentication.conf, make sure only the user can read it.

When opening an existing authentication.conf, warn if others can read the file - allow this warning to be suppressed by setting ``suppress_warnings=insecure_permissions``.

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

General concept seems fine, though we still don't really want users putting passwords in there. Have some nits about the implementation inline.

Yet another change that makes me want to get to saner trace/warnings soon.

review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Running landing tests failed
http://10.242.247.184:8080/job/brz-dev/129/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/config.py'
2--- breezy/config.py 2017-06-11 01:19:16 +0000
3+++ breezy/config.py 2017-06-13 00:26:53 +0000
4@@ -83,8 +83,10 @@
5 from .lazy_import import lazy_import
6 lazy_import(globals(), """
7 import base64
8+import errno
9 import fnmatch
10 import re
11+import stat
12
13 from breezy import (
14 atomicfile,
15@@ -1655,6 +1657,7 @@
16 if _file is None:
17 self._filename = authentication_config_filename()
18 self._input = self._filename = authentication_config_filename()
19+ self._check_permissions()
20 else:
21 # Tests can provide a string as _file
22 self._filename = None
23@@ -1677,12 +1680,29 @@
24 raise errors.ConfigContentError(self._filename)
25 return self._config
26
27+ def _check_permissions(self):
28+ """Check permission of auth file are user read/write able only."""
29+ try:
30+ st = os.stat(self._filename)
31+ except OSError as e:
32+ if e.errno != errno.ENOENT:
33+ trace.mutter('Unable to stat %r: %r', self._filename, e)
34+ return
35+ mode = stat.S_IMODE(st.st_mode)
36+ if ((stat.S_IXOTH | stat.S_IWOTH | stat.S_IROTH | stat.S_IXGRP |
37+ stat.S_IWGRP | stat.S_IRGRP ) & mode):
38+ if not GlobalConfig().suppress_warning('insecure_permissions'):
39+ trace.warning("The file '%s' has insecure "
40+ "file permissions. Saved passwords may be accessible "
41+ "by other users.", self._filename)
42+
43 def _save(self):
44 """Save the config file, only tests should use it for now."""
45 conf_dir = os.path.dirname(self._filename)
46 ensure_config_dir_exists(conf_dir)
47- f = file(self._filename, 'wb')
48+ fd = os.open(self._filename, os.O_RDWR|os.O_CREAT, 0o600)
49 try:
50+ f = os.fdopen(fd, 'wb')
51 self._get_config().write(f)
52 finally:
53 f.close()
54
55=== modified file 'breezy/help_topics/en/configuration.txt'
56--- breezy/help_topics/en/configuration.txt 2017-05-21 18:10:28 +0000
57+++ breezy/help_topics/en/configuration.txt 2017-06-13 00:26:53 +0000
58@@ -600,6 +600,10 @@
59 whether the format deprecation warning is shown on repositories that are
60 using deprecated formats.
61
62+* ``insecure_permissions``:
63+ whether a warning is shown if ``authentication.conf`` can be read
64+ by other users.
65+
66 default_format
67 ~~~~~~~~~~~~~~
68
69
70=== modified file 'breezy/tests/test_config.py'
71--- breezy/tests/test_config.py 2017-06-11 14:07:05 +0000
72+++ breezy/tests/test_config.py 2017-06-13 00:26:53 +0000
73@@ -956,7 +956,7 @@
74 self.assertEqual(True, suppress_warning('b'))
75
76
77-class TestGetConfig(tests.TestCase):
78+class TestGetConfig(tests.TestCaseInTempDir):
79
80 def test_constructs(self):
81 config.GlobalConfig()
82@@ -4114,6 +4114,38 @@
83 self.assertIs(g1.store, g2.store)
84
85
86+class TestAuthenticationConfigFilePermissions(tests.TestCaseInTempDir):
87+ """Test warning for permissions of authentication.conf."""
88+
89+ def setUp(self):
90+ super(TestAuthenticationConfigFilePermissions, self).setUp()
91+ self.path = osutils.pathjoin(self.test_dir, 'authentication.conf')
92+ with open(self.path, 'w') as f:
93+ f.write(b"""[broken]
94+scheme=ftp
95+user=joe
96+port=port # Error: Not an int
97+""")
98+ self.overrideAttr(config, 'authentication_config_filename',
99+ lambda: self.path)
100+ osutils.chmod_if_possible(self.path, 0o755)
101+
102+ def test_check_warning(self):
103+ conf = config.AuthenticationConfig()
104+ self.assertEqual(conf._filename, self.path)
105+ self.assertContainsRe(self.get_log(),
106+ 'Saved passwords may be accessible by other users.')
107+
108+ def test_check_suppressed_warning(self):
109+ global_config = config.GlobalConfig()
110+ global_config.set_user_option('suppress_warnings',
111+ 'insecure_permissions')
112+ conf = config.AuthenticationConfig()
113+ self.assertEqual(conf._filename, self.path)
114+ self.assertNotContainsRe(self.get_log(),
115+ 'Saved passwords may be accessible by other users.')
116+
117+
118 class TestAuthenticationConfigFile(tests.TestCase):
119 """Test the authentication.conf file matching"""
120
121@@ -4350,7 +4382,7 @@
122 self.assertEqual(CREDENTIALS, credentials)
123
124
125-class TestAuthenticationConfig(tests.TestCase):
126+class TestAuthenticationConfig(tests.TestCaseInTempDir):
127 """Test AuthenticationConfig behaviour"""
128
129 def _check_default_password_prompt(self, expected_prompt_format, scheme,
130
131=== modified file 'doc/en/release-notes/brz-3.0.txt'
132--- doc/en/release-notes/brz-3.0.txt 2017-06-11 13:36:02 +0000
133+++ doc/en/release-notes/brz-3.0.txt 2017-06-13 00:26:53 +0000
134@@ -84,6 +84,11 @@
135 * The ``bisect`` command now works in non-``.bzr`` directories.
136 (Jelmer Vernooij)
137
138+* When creating ``authentication.conf``, umask is now set so only the
139+ current user can read the file. Breezy warns if the file is
140+ accessible for other users when it starts.
141+ (Joke de Buhr, Jelmer Vernooij, #475501)
142+
143 Documentation
144 *************
145

Subscribers

People subscribed via source and target branches