Show More
@@ -1658,6 +1658,10 b' Controls generic server settings.' | |||
|
1658 | 1658 | the write lock while determining what data to transfer. |
|
1659 | 1659 | (default: True) |
|
1660 | 1660 | |
|
1661 | ``uncompressedallowsecret`` | |
|
1662 | Whether to allow stream clones when the repository contains secret | |
|
1663 | changesets. (default: False) | |
|
1664 | ||
|
1661 | 1665 | ``preferuncompressed`` |
|
1662 | 1666 | When set, clients will try to use the uncompressed streaming |
|
1663 | 1667 | protocol. (default: False) |
@@ -13,6 +13,7 b' from .i18n import _' | |||
|
13 | 13 | from . import ( |
|
14 | 14 | branchmap, |
|
15 | 15 | error, |
|
16 | phases, | |
|
16 | 17 | store, |
|
17 | 18 | util, |
|
18 | 19 | ) |
@@ -162,9 +163,18 b' def maybeperformlegacystreamclone(pullop' | |||
|
162 | 163 | |
|
163 | 164 | repo.invalidate() |
|
164 | 165 | |
|
165 |
def allowservergeneration( |
|
|
166 | def allowservergeneration(repo): | |
|
166 | 167 | """Whether streaming clones are allowed from the server.""" |
|
167 |
|
|
|
168 | if not repo.ui.configbool('server', 'uncompressed', True, untrusted=True): | |
|
169 | return False | |
|
170 | ||
|
171 | # The way stream clone works makes it impossible to hide secret changesets. | |
|
172 | # So don't allow this by default. | |
|
173 | secret = phases.hassecret(repo) | |
|
174 | if secret: | |
|
175 | return repo.ui.configbool('server', 'uncompressedallowsecret', False) | |
|
176 | ||
|
177 | return True | |
|
168 | 178 | |
|
169 | 179 | # This is it's own function so extensions can override it. |
|
170 | 180 | def _walkstreamfiles(repo): |
@@ -754,7 +754,7 b' def _capabilities(repo, proto):' | |||
|
754 | 754 | """ |
|
755 | 755 | # copy to prevent modification of the global list |
|
756 | 756 | caps = list(wireprotocaps) |
|
757 |
if streamclone.allowservergeneration(repo |
|
|
757 | if streamclone.allowservergeneration(repo): | |
|
758 | 758 | if repo.ui.configbool('server', 'preferuncompressed', False): |
|
759 | 759 | caps.append('stream-preferred') |
|
760 | 760 | requiredformats = repo.requirements & repo.supportedformats |
@@ -946,7 +946,7 b' def stream(repo, proto):' | |||
|
946 | 946 | capability with a value representing the version and flags of the repo |
|
947 | 947 | it is serving. Client checks to see if it understands the format. |
|
948 | 948 | ''' |
|
949 |
if not streamclone.allowservergeneration(repo |
|
|
949 | if not streamclone.allowservergeneration(repo): | |
|
950 | 950 | return '1\n' |
|
951 | 951 | |
|
952 | 952 | def getstream(it): |
@@ -49,6 +49,77 b' Clone with background file closing enabl' | |||
|
49 | 49 | bundle2-input-bundle: 1 parts total |
|
50 | 50 | checking for updated bookmarks |
|
51 | 51 | |
|
52 | Cannot stream clone when there are secret changesets | |
|
53 | ||
|
54 | $ hg -R server phase --force --secret -r tip | |
|
55 | $ hg clone --uncompressed -U http://localhost:$HGPORT secret-denied | |
|
56 | warning: stream clone requested but server has them disabled | |
|
57 | requesting all changes | |
|
58 | adding changesets | |
|
59 | adding manifests | |
|
60 | adding file changes | |
|
61 | added 1 changesets with 1 changes to 1 files | |
|
62 | ||
|
63 | $ killdaemons.py | |
|
64 | ||
|
65 | Streaming of secrets can be overridden by server config | |
|
66 | ||
|
67 | $ cd server | |
|
68 | $ hg --config server.uncompressedallowsecret=true serve -p $HGPORT -d --pid-file=hg.pid | |
|
69 | $ cat hg.pid > $DAEMON_PIDS | |
|
70 | $ cd .. | |
|
71 | ||
|
72 | $ hg clone --uncompressed -U http://localhost:$HGPORT secret-allowed | |
|
73 | streaming all changes | |
|
74 | 1027 files to transfer, 96.3 KB of data | |
|
75 | transferred 96.3 KB in * seconds (*/sec) (glob) | |
|
76 | searching for changes | |
|
77 | no changes found | |
|
78 | ||
|
79 | $ killdaemons.py | |
|
80 | ||
|
81 | Verify interaction between preferuncompressed and secret presence | |
|
82 | ||
|
83 | $ cd server | |
|
84 | $ hg --config server.preferuncompressed=true serve -p $HGPORT -d --pid-file=hg.pid | |
|
85 | $ cat hg.pid > $DAEMON_PIDS | |
|
86 | $ cd .. | |
|
87 | ||
|
88 | $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret | |
|
89 | requesting all changes | |
|
90 | adding changesets | |
|
91 | adding manifests | |
|
92 | adding file changes | |
|
93 | added 1 changesets with 1 changes to 1 files | |
|
94 | ||
|
95 | $ killdaemons.py | |
|
96 | ||
|
97 | Clone not allowed when full bundles disabled and can't serve secrets | |
|
98 | ||
|
99 | $ cd server | |
|
100 | $ hg --config server.disablefullbundle=true serve -p $HGPORT -d --pid-file=hg.pid | |
|
101 | $ cat hg.pid > $DAEMON_PIDS | |
|
102 | $ cd .. | |
|
103 | ||
|
104 | $ hg clone --uncompressed http://localhost:$HGPORT secret-full-disabled | |
|
105 | warning: stream clone requested but server has them disabled | |
|
106 | requesting all changes | |
|
107 | remote: abort: server has pull-based clones disabled | |
|
108 | abort: pull failed on remote | |
|
109 | (remove --pull if specified or upgrade Mercurial) | |
|
110 | [255] | |
|
111 | ||
|
112 | Local stream clone with secrets involved | |
|
113 | (This is just a test over behavior: if you have access to the repo's files, | |
|
114 | there is no security so it isn't important to prevent a clone here.) | |
|
115 | ||
|
116 | $ hg clone -U --uncompressed server local-secret | |
|
117 | warning: stream clone requested but server has them disabled | |
|
118 | requesting all changes | |
|
119 | adding changesets | |
|
120 | adding manifests | |
|
121 | adding file changes | |
|
122 | added 1 changesets with 1 changes to 1 files | |
|
52 | 123 | |
|
53 | 124 | Stream clone while repo is changing: |
|
54 | 125 |
General Comments 0
You need to be logged in to leave comments.
Login now