set the timezone to UTC on cloning a freenet repo to avoid timezonebased attacks.
Title: set the timezone to UTC on cloning a freenet repo to avoid timezone-based attacks. ID: 4dfc4cc28a7fa69f040776a7138da78ee89ec819 *Resolved* Owned By: Arne BabenhauserheideFiled On: Monday, December 17 2012 06:09PM [details] Only file USKs are allowed. Make sure the URI ends with '/ ' with no trailing '/' [expected] Without number it could just assume /0 [comments] Potential patches (export of my experiments to ensure that the code does not get lost): clone: get all bookmarks before updating * * * clone: FIX: also get the bookmarks for remote target repos which support pushkey. diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -353,6 +353,21 @@ def clone(ui, peeropts, source, dest=Non if dircleanup: dircleanup.close() + # clone all bookmarks + if destrepo.local() and srcrepo.capable("pushkey"): + rb = srcrepo.listkeys('bookmarks') + for k, n in rb.iteritems(): + try: + m = destrepo.lookup(n) + destrepo._bookmarks[k] = m + except error.RepoLookupError: + pass + if rb: + bookmarks.write(destrepo) + elif srcrepo.local() and destrepo.capable("pushkey"): + for k, n in srcrepo._bookmarks.iteritems(): + destrepo.pushkey('bookmarks', k, '', hex(n)) + if destrepo.local(): fp = destrepo.opener("hgrc", "w", text=True) fp.write("[paths]\n") @@ -378,21 +393,6 @@ def clone(ui, peeropts, source, dest=Non destrepo.ui.status(_("updating to branch %s\n") % bn) _update(destrepo, uprev) - # clone all bookmarks - if destrepo.local() and srcrepo.capable("pushkey"): - rb = srcrepo.listkeys('bookmarks') - for k, n in rb.iteritems(): - try: - m = destrepo.lookup(n) - destrepo._bookmarks[k] = m - except error.RepoLookupError: - pass - if rb: - bookmarks.write(destrepo) - elif srcrepo.local() and destrepo.capable("pushkey"): - for k, n in srcrepo._bookmarks.iteritems(): - destrepo.pushkey('bookmarks', k, '', hex(n)) - return srcrepo, destrepo finally: release(srclock, destlock) revsets: added branchpoint() for revisions with more than one child. Reason: Get very terse information via hg glog --rev "head() or merge() or branchpoint()" diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -710,6 +710,15 @@ def merge(repo, subset, x): cl = repo.changelog return [r for r in subset if cl.parentrevs(r)[1] != -1] +def branchpoint(repo, subset, x): + """``branchpoint()`` + Changeset has more than one child. + """ + # i18n: "merge" is a keyword + getargs(x, 0, 0, _("branchpoint takes no arguments")) + cl = repo.changelog + return [r for r in subset if cl.children(repo[r].node())[1:]] + def minrev(repo, subset, x): """``min(set)`` Changeset with lowest revision number in set. @@ -1137,6 +1146,7 @@ symbols = { "bisected": bisected, "bookmark": bookmark, "branch": branch, + "branchpoint": branchpoint, "children": children, "closed": closed, "contains": contains, Option to enforce using UTC for commit dates. The timezone entries in commit messages give away location information of the commiter, which can be dangerous when Mercurial is used anonymously. To mitigate that danger, this commit adds an rc-option to use UTC dates, except when the timezone is requested explicitely via a date string or by amending a commit without changing the date and time. To switch to UTC times, add [ui] datetimeutc = True to your ~/.hgrc or a .hg/hgrc. Extensions like infocalypse can also set this option when doing the initial clone from an anonymous source to ensure that the default behaviour of Mercurial is safe. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1586,7 +1586,9 @@ def commit(ui, repo, commitfunc, pats, o '''commit the specified files or all outstanding changes''' date = opts.get('date') if date: - opts['date'] = util.parsedate(date) + opts['date'] = util.timezoneprivacy(ui.configbool('ui', 'datetimeutc'), + date) + message = logmessage(ui, opts) # extract addremove carefully -- this function can be called from a command diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1304,9 +1304,12 @@ def commit(ui, repo, *pats, **opts): if not message: message = old.description() editor = cmdutil.commitforceeditor + date = util.timezoneprivacy(ui.configbool('ui', 'datetimeutc'), + opts.get('date'), + old.date()) return repo.commit(message, opts.get('user') or old.user(), - opts.get('date') or old.date(), + date, match, editor=editor, extra=extra) diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -1128,6 +1128,10 @@ User interface controls. changes, abort the commit. Default is False. +``datetimeutc`` + Whether to always use Universal Time Coordinated (UTC) for date + entries when committing. + ``debug`` Print debugging information. True or False. Default is False. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -980,20 +980,20 @@ def shortdate(date=None): """turn (timestamp, tzoff) tuple into iso 8631 date.""" return datestr(date, format='%Y-%m-%d') +def timezone(string): + tz = string.split()[-1] + if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit(): + sign = (tz[0] == "+") and 1 or -1 + hours = int(tz[1:3]) + minutes = int(tz[3:5]) + return -sign * (hours * 60 + minutes) * 60 + if tz == "GMT" or tz == "UTC": + return 0 + return None + def strdate(string, format, defaults=[]): """parse a localized time string and return a (unixtime, offset) tuple. if the string cannot be parsed, ValueError is raised.""" - def timezone(string): - tz = string.split()[-1] - if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit(): - sign = (tz[0] == "+") and 1 or -1 - hours = int(tz[1:3]) - minutes = int(tz[3:5]) - return -sign * (hours * 60 + minutes) * 60 - if tz == "GMT" or tz == "UTC": - return 0 - return None - # NOTE: unixtime = localunixtime + offset offset, date = timezone(string), string if offset is not None: @@ -1151,6 +1151,35 @@ def matchdate(date): start, stop = lower(date), upper(date) return lambda x: x >= start and x <= stop +def timezoneprivacy(privacy, datestring=None, date=None): + """Switch to UTC if the timezone could be a risk to + privacy and the timezone was not requested explicitly. + + >>> withtz = parsedate("2012-12-23 10:04:23 +0300") + >>> localtz = makedate()[1] + >>> notz = timezoneprivacy(True, "2012-12-23 07:04:23") + >>> notz[1] == 0 + True + >>> notz[0] - localtz == withtz[0] + True + >>> (notz[0], localtz) == timezoneprivacy(False, "2012-12-23 07:04:23") + True + >>> (withtz[0], -3600) == timezoneprivacy(True, "2012-12-23 08:04:23 +0100") + True + >>> (withtz[0], 18000) == timezoneprivacy(True, "2012-12-23 02:04:23 -0500") + True + """ + when = parsedate(datestring or date or makedate()) + if not privacy: + return when + hastimezone = timezone(datestring) is not None + if datestring and not hastimezone: + return when[0], 0 + if datestring or date: + return when + # no explicit datestring or date: use current UTC + return when[0], 0 + def shortuser(user): """Return a short representation of a user name or email address.""" f = user.find('@') diff --git a/tests/test-commit.t b/tests/test-commit.t --- a/tests/test-commit.t +++ b/tests/test-commit.t @@ -90,12 +90,20 @@ commit added file that has been deleted dir/file committed changeset 4:49176991390e -An empty date was interpreted as epoch origin +date argument parsing $ echo foo >> foo $ hg commit -d '' -m commit-no-date $ hg tip --template '{date|isodate}\n' | grep '1970' [1] + $ echo foo >> foo + $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc + $ hg tip --template '{date|isodate}\n' + 1982-04-23 14:23 +0000 + $ echo foo >> foo + $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc + $ hg tip --template '{date|isodate}\n' + 1982-04-23 14:23 +0100 Make sure we do not obscure unknown requires file entries (issue2649) Simpler implementation of enforcing UTC for dates. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1586,9 +1586,7 @@ def commit(ui, repo, commitfunc, pats, o '''commit the specified files or all outstanding changes''' date = opts.get('date') if date: - opts['date'] = util.timezoneprivacy(ui.configbool('ui', 'datetimeutc'), - date) - + opts['date'] = util.parsedate(date) message = logmessage(ui, opts) # extract addremove carefully -- this function can be called from a command diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1276,6 +1276,9 @@ def commit(ui, repo, *pats, **opts): raise util.Abort(_('can only close branch heads')) extra['close'] = 1 + if ui.configbool('ui', 'datetimeutc'): + pass #time.timezone = "UTC" + branch = repo[None].branch() bheads = repo.branchheads(branch) @@ -1304,12 +1307,9 @@ def commit(ui, repo, *pats, **opts): if not message: message = old.description() editor = cmdutil.commitforceeditor - date = util.timezoneprivacy(ui.configbool('ui', 'datetimeutc'), - opts.get('date'), - old.date()) return repo.commit(message, opts.get('user') or old.user(), - date, + opts.get('date') or old.date(), match, editor=editor, extra=extra) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -980,20 +980,20 @@ def shortdate(date=None): """turn (timestamp, tzoff) tuple into iso 8631 date.""" return datestr(date, format='%Y-%m-%d') -def timezone(string): - tz = string.split()[-1] - if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit(): - sign = (tz[0] == "+") and 1 or -1 - hours = int(tz[1:3]) - minutes = int(tz[3:5]) - return -sign * (hours * 60 + minutes) * 60 - if tz == "GMT" or tz == "UTC": - return 0 - return None - def strdate(string, format, defaults=[]): """parse a localized time string and return a (unixtime, offset) tuple. if the string cannot be parsed, ValueError is raised.""" + def timezone(string): + tz = string.split()[-1] + if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit(): + sign = (tz[0] == "+") and 1 or -1 + hours = int(tz[1:3]) + minutes = int(tz[3:5]) + return -sign * (hours * 60 + minutes) * 60 + if tz == "GMT" or tz == "UTC": + return 0 + return None + # NOTE: unixtime = localunixtime + offset offset, date = timezone(string), string if offset is not None: @@ -1151,35 +1151,6 @@ def matchdate(date): start, stop = lower(date), upper(date) return lambda x: x >= start and x <= stop -def timezoneprivacy(privacy, datestring=None, date=None): - """Switch to UTC if the timezone could be a risk to - privacy and the timezone was not requested explicitly. - - >>> withtz = parsedate("2012-12-23 10:04:23 +0300") - >>> localtz = makedate()[1] - >>> notz = timezoneprivacy(True, "2012-12-23 07:04:23") - >>> notz[1] == 0 - True - >>> notz[0] - localtz == withtz[0] - True - >>> (notz[0], localtz) == timezoneprivacy(False, "2012-12-23 07:04:23") - True - >>> (withtz[0], -3600) == timezoneprivacy(True, "2012-12-23 08:04:23 +0100") - True - >>> (withtz[0], 18000) == timezoneprivacy(True, "2012-12-23 02:04:23 -0500") - True - """ - when = parsedate(datestring or date or makedate()) - if not privacy: - return when - hastimezone = timezone(datestring) is not None - if datestring and not hastimezone: - return when[0], 0 - if datestring or date: - return when - # no explicit datestring or date: use current UTC - return when[0], 0 - def shortuser(user): """Return a short representation of a user name or email address.""" f = user.find('@') test. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1277,7 +1277,7 @@ def commit(ui, repo, *pats, **opts): extra['close'] = 1 if ui.configbool('ui', 'datetimeutc'): - pass #time.timezone = "UTC" + time.timezone = "UTC" branch = repo[None].branch() bheads = repo.branchheads(branch) test. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1277,7 +1277,7 @@ def commit(ui, repo, *pats, **opts): extra['close'] = 1 if ui.configbool('ui', 'datetimeutc'): - time.timezone = "UTC" + time.timezone = "GMT+5" branch = repo[None].branch() bheads = repo.branchheads(branch) test. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1278,6 +1278,7 @@ def commit(ui, repo, *pats, **opts): if ui.configbool('ui', 'datetimeutc'): time.timezone = "GMT+5" + print time.timezone branch = repo[None].branch() bheads = repo.branchheads(branch) timezone: Fix test to always use a on-utc timezone. diff --git a/tests/test-commit.t b/tests/test-commit.t --- a/tests/test-commit.t +++ b/tests/test-commit.t @@ -97,11 +97,11 @@ date argument parsing $ hg tip --template '{date|isodate}\n' | grep '1970' [1] $ echo foo >> foo - $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc + $ TZ="Europe/Berlin" hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc $ hg tip --template '{date|isodate}\n' 1982-04-23 14:23 +0000 $ echo foo >> foo - $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc + $ TZ="Europe/Berlin" hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc $ hg tip --template '{date|isodate}\n' 1982-04-23 14:23 +0100 enforce UTC: time.timezone to 0 diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1277,8 +1277,7 @@ def commit(ui, repo, *pats, **opts): extra['close'] = 1 if ui.configbool('ui', 'datetimeutc'): - time.timezone = "GMT+5" - print time.timezone + time.timezone = 0 branch = repo[None].branch() bheads = repo.branchheads(branch) timezone: Fix test to always use a on-utc timezone. diff --git a/tests/test-commit.t b/tests/test-commit.t --- a/tests/test-commit.t +++ b/tests/test-commit.t @@ -97,11 +97,11 @@ date argument parsing $ hg tip --template '{date|isodate}\n' | grep '1970' [1] $ echo foo >> foo - $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc + $ TZ="Europe/Berlin" hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc $ hg tip --template '{date|isodate}\n' 1982-04-23 14:23 +0000 $ echo foo >> foo - $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc + $ TZ="Europe/Berlin" hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc $ hg tip --template '{date|isodate}\n' 1982-04-23 14:23 +0100 Fix the timezoneprivacy test: You give the local time and it records the UTC according to that. diff --git a/tests/test-commit.t b/tests/test-commit.t --- a/tests/test-commit.t +++ b/tests/test-commit.t @@ -99,7 +99,7 @@ date argument parsing $ echo foo >> foo $ TZ="Europe/Berlin" hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc $ hg tip --template '{date|isodate}\n' - 1982-04-23 14:23 +0000 + 1982-04-23 12:23 +0000 $ echo foo >> foo $ TZ="Europe/Berlin" hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc $ hg tip --template '{date|isodate}\n'
- all bugs -