Merge lp:~dpb/landscape-charm/strip-url-newline-1411353 into lp:~landscape/landscape-charm/trunk

Proposed by David Britton
Status: Merged
Approved by: David Britton
Approved revision: 218
Merged at revision: 217
Proposed branch: lp:~dpb/landscape-charm/strip-url-newline-1411353
Merge into: lp:~landscape/landscape-charm/trunk
Diff against target: 82 lines (+34/-5)
2 files modified
hooks/hooks.py (+4/-2)
hooks/test_hooks.py (+30/-3)
To merge this branch: bzr merge lp:~dpb/landscape-charm/strip-url-newline-1411353
Reviewer Review Type Date Requested Status
Andreas Hasenack Approve
Adam Collard (community) Approve
Review via email: mp+246628@code.launchpad.net

Commit message

Strip newlines from url before passing to cURL.

Description of the change

Strip newlines from url before passing to cURL.

To post a comment you must log in.
Revision history for this message
Adam Collard (adam-collard) wrote :

Change is good, I think the tests need to be modified as suggested below, to make them easier to grok

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

+1, just a minor comment about the test.

review: Approve
218. By David Britton

sparkiegeek[diff]: check url explicitly
andreas[diff]: catch \r as well

Revision history for this message
David Britton (dpb) wrote :
Download full text (3.5 KiB)

Thanks, I've addressed all feedback.

On Thu, Jan 15, 2015 at 1:12 PM, Andreas Hasenack <email address hidden>
wrote:

> Review: Approve
>
> +1, just a minor comment about the test.
>
>
> Diff comments:
>
> > === modified file 'hooks/hooks.py'
> > --- hooks/hooks.py 2015-01-12 10:40:19 +0000
> > +++ hooks/hooks.py 2015-01-15 19:11:45 +0000
> > @@ -501,11 +501,13 @@
> > notify_website_relation()
> >
> >
> > -def _download_file(url):
> > +def _download_file(url, Curl=pycurl.Curl):
> > """ Download from a url and save to the filename given """
> > + # Fix for CVE-2014-8150, urls cannot end with newline
> > + url = url.rstrip()
> > buf = cStringIO.StringIO()
> > juju.juju_log("Fetching License: %s" % url)
> > - curl = pycurl.Curl()
> > + curl = Curl()
> > curl.setopt(pycurl.URL, str(url))
> > curl.setopt(pycurl.WRITEFUNCTION, buf.write)
> > curl.perform()
> >
> > === modified file 'hooks/test_hooks.py'
> > --- hooks/test_hooks.py 2014-12-10 22:08:57 +0000
> > +++ hooks/test_hooks.py 2015-01-15 19:11:45 +0000
> > @@ -12,6 +12,23 @@
> > import yaml
> >
> >
> > +class CurlStub(object):
> > +
> > + def __init__(self, result=None, infos=None, error=None):
> > + pass
> > +
> > + def setopt(self, option, value):
> > + if option == pycurl.URL:
> > + if "\n" in value:
>
> The curl patch (http://curl.haxx.se/CVE-2014-8150.patch) blocks both \n
> and \r, can we do the same in the test just to be consistent?
>
> > + raise AssertionError("URL cannot contain newline")
> > +
> > + def perform(self):
> > + pass
> > +
> > + def close(self):
> > + pass
> > +
> > +
> > class TestJuju(object):
> > """
> > Testing object to intercept juju calls and inject data, or make sure
> > @@ -908,13 +925,19 @@
> > filename = self.makeFile()
> > with open(filename, "w") as fp:
> > fp.write("foobar")
> > - output = hooks._download_file("file://%s" % filename)
> > + output = hooks._download_file("file:///%s" % filename)
> > self.assertIn("foobar", output)
> >
> > + def test__download_file_success_trailing_newline(self):
> > + """Test that newlines are stripped before passing to curl.
> CVE-2014-8150."""
> > + # put two newlines, since that could be a common pattern in a
> text
> > + # file when using an editor
> > + hooks._download_file("http://example.com/\n\n", Curl=CurlStub)
> > +
> > def test__download_file_failure(self):
> > """The fail path of download file raises an exception."""
> > self.assertRaises(
> > - pycurl.error, hooks._download_file, "file://FOO/NO/EXIST")
> > + pycurl.error, hooks._download_file, "file:///FOO/NO/EXIST")
> >
> > def test__replace_in_file(self):
> > """
> > @@ -962,7 +985,7 @@
> > source = self.makeFile()
> > with open(source, "w") as fp:
> > fp.write("LICENSE_FILE_TEXT from curl")
> > - hooks.juju.config["license-file"] = "file://%s" % source
> > + hooks.juju.config["license-file"] = "file:///%s" % source
> > ho...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'hooks/hooks.py'
--- hooks/hooks.py 2015-01-12 10:40:19 +0000
+++ hooks/hooks.py 2015-01-15 20:51:34 +0000
@@ -501,11 +501,13 @@
501 notify_website_relation()501 notify_website_relation()
502502
503503
504def _download_file(url):504def _download_file(url, Curl=pycurl.Curl):
505 """ Download from a url and save to the filename given """505 """ Download from a url and save to the filename given """
506 # Fix for CVE-2014-8150, urls cannot end with newline
507 url = url.rstrip()
506 buf = cStringIO.StringIO()508 buf = cStringIO.StringIO()
507 juju.juju_log("Fetching License: %s" % url)509 juju.juju_log("Fetching License: %s" % url)
508 curl = pycurl.Curl()510 curl = Curl()
509 curl.setopt(pycurl.URL, str(url))511 curl.setopt(pycurl.URL, str(url))
510 curl.setopt(pycurl.WRITEFUNCTION, buf.write)512 curl.setopt(pycurl.WRITEFUNCTION, buf.write)
511 curl.perform()513 curl.perform()
512514
=== modified file 'hooks/test_hooks.py'
--- hooks/test_hooks.py 2014-12-10 22:08:57 +0000
+++ hooks/test_hooks.py 2015-01-15 20:51:34 +0000
@@ -12,6 +12,26 @@
12import yaml12import yaml
1313
1414
15class CurlStub(object):
16
17 urls = []
18
19 def __init__(self, result=None, infos=None, error=None):
20 pass
21
22 def setopt(self, option, value):
23 if option == pycurl.URL:
24 if "\n" in value or "\r" in value:
25 raise AssertionError("URL cannot contain linefeed or newline")
26 self.urls.append(value)
27
28 def perform(self):
29 pass
30
31 def close(self):
32 pass
33
34
15class TestJuju(object):35class TestJuju(object):
16 """36 """
17 Testing object to intercept juju calls and inject data, or make sure37 Testing object to intercept juju calls and inject data, or make sure
@@ -908,13 +928,20 @@
908 filename = self.makeFile()928 filename = self.makeFile()
909 with open(filename, "w") as fp:929 with open(filename, "w") as fp:
910 fp.write("foobar")930 fp.write("foobar")
911 output = hooks._download_file("file://%s" % filename)931 output = hooks._download_file("file:///%s" % filename)
912 self.assertIn("foobar", output)932 self.assertIn("foobar", output)
913933
934 def test__download_file_success_trailing_newline(self):
935 """Test that newlines are stripped before passing to curl. CVE-2014-8150."""
936 # put two newlines, since that could be a common pattern in a text
937 # file when using an editor
938 hooks._download_file("http://example.com/\n\n", Curl=CurlStub)
939 self.assertEqual(["http://example.com/"], CurlStub.urls)
940
914 def test__download_file_failure(self):941 def test__download_file_failure(self):
915 """The fail path of download file raises an exception."""942 """The fail path of download file raises an exception."""
916 self.assertRaises(943 self.assertRaises(
917 pycurl.error, hooks._download_file, "file://FOO/NO/EXIST")944 pycurl.error, hooks._download_file, "file:///FOO/NO/EXIST")
918945
919 def test__replace_in_file(self):946 def test__replace_in_file(self):
920 """947 """
@@ -962,7 +989,7 @@
962 source = self.makeFile()989 source = self.makeFile()
963 with open(source, "w") as fp:990 with open(source, "w") as fp:
964 fp.write("LICENSE_FILE_TEXT from curl")991 fp.write("LICENSE_FILE_TEXT from curl")
965 hooks.juju.config["license-file"] = "file://%s" % source992 hooks.juju.config["license-file"] = "file:///%s" % source
966 hooks._install_license()993 hooks._install_license()
967 self.assertFileContains(994 self.assertFileContains(
968 hooks.LANDSCAPE_LICENSE_DEST, "LICENSE_FILE_TEXT from curl")995 hooks.LANDSCAPE_LICENSE_DEST, "LICENSE_FILE_TEXT from curl")

Subscribers

People subscribed via source and target branches