Merge lp:~cbehrens/nova/lp788979 into lp:~hudson-openstack/nova/trunk

Proposed by Chris Behrens
Status: Merged
Approved by: Vish Ishaya
Approved revision: 1121
Merged at revision: 1118
Proposed branch: lp:~cbehrens/nova/lp788979
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 78 lines (+32/-18)
2 files modified
nova/tests/test_xenapi.py (+22/-4)
nova/virt/xenapi/vmops.py (+10/-14)
To merge this branch: bzr merge lp:~cbehrens/nova/lp788979
Reviewer Review Type Date Requested Status
Vish Ishaya (community) Approve
Mark Washenberger (community) Approve
Review via email: mp+62615@code.launchpad.net

Description of the change

When encrypting passwords in xenapi's SimpleDH(), we shouldn't send a final newline to openssl, as it'll use that as encryption data. However, we do need to make sure there's a newline on the end when we write the base64 string for decoding.. Made these changes and updated the test.

To post a comment you must log in.
Revision history for this message
Mark Washenberger (markwash) wrote :

If you put newlines at the end of your test message, you will see that there are still some problems here.

I was also kind of frustrated by the fact that I could run _run_ssl(text, 'DECAPITATE!') and it would still happily decrypt, rather than decapitating as I asked. But rather than put the burden on you I have a merge prop for this branch that will fix the problems I saw above and make me slightly happier :-)

review: Needs Fixing
Revision history for this message
Chris Behrens (cbehrens) wrote :

Love the DECAPITATE comment. :) Thanks for the additional tests... those should all have been there in the first place!

I've merged your branch and I have all of the tests passing now, reverting to a slightly modified version of what I had initially. I moved most of the openssl command line back into _run_ssl, but I made the 2nd parameter be optional extra arguments, vs just a 'd'. DECAPITATE should return an error now. :)

Revision history for this message
Mark Washenberger (markwash) wrote :

Looks good.

I will say one last thing in favor of adding '-A'. If you were to print the result of encryption in 'test_encrypt_really_long_message', it would be a multiline base64 string. This seems potentially undesirable and there is no check which prevents client code from passing in a sufficiently long text. I believe the text would only need to be 61 characters to trigger the first line break.

With that off my chest, I defer to your judgment.

review: Approve
Revision history for this message
Chris Behrens (cbehrens) wrote :

Ah. I'll go ahead and put it back and re-test.

Revision history for this message
Chris Behrens (cbehrens) wrote :

Ok.. works with -A in.

Revision history for this message
Mark Washenberger (markwash) wrote :

Double approve! :-)

review: Approve
Revision history for this message
Chris Behrens (cbehrens) wrote :

Thanks man :)

Revision history for this message
Chris Behrens (cbehrens) wrote :

No need for the \n with -A. Last fix, hopefully.

Revision history for this message
Vish Ishaya (vishvananda) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/tests/test_xenapi.py'
2--- nova/tests/test_xenapi.py 2011-05-26 19:27:27 +0000
3+++ nova/tests/test_xenapi.py 2011-05-27 20:49:13 +0000
4@@ -592,11 +592,29 @@
5 bob_shared = self.bob.compute_shared(alice_pub)
6 self.assertEquals(alice_shared, bob_shared)
7
8- def test_encryption(self):
9- msg = "This is a top-secret message"
10- enc = self.alice.encrypt(msg)
11+ def _test_encryption(self, message):
12+ enc = self.alice.encrypt(message)
13+ self.assertFalse(enc.endswith('\n'))
14 dec = self.bob.decrypt(enc)
15- self.assertEquals(dec, msg)
16+ self.assertEquals(dec, message)
17+
18+ def test_encrypt_simple_message(self):
19+ self._test_encryption('This is a simple message.')
20+
21+ def test_encrypt_message_with_newlines_at_end(self):
22+ self._test_encryption('This message has a newline at the end.\n')
23+
24+ def test_encrypt_many_newlines_at_end(self):
25+ self._test_encryption('Message with lotsa newlines.\n\n\n')
26+
27+ def test_encrypt_newlines_inside_message(self):
28+ self._test_encryption('Message\nwith\ninterior\nnewlines.')
29+
30+ def test_encrypt_with_leading_newlines(self):
31+ self._test_encryption('\n\nMessage with leading newlines.')
32+
33+ def test_encrypt_really_long_message(self):
34+ self._test_encryption(''.join(['abcd' for i in xrange(1024)]))
35
36 def tearDown(self):
37 super(XenAPIDiffieHellmanTestCase, self).tearDown()
38
39=== modified file 'nova/virt/xenapi/vmops.py'
40--- nova/virt/xenapi/vmops.py 2011-05-26 19:30:23 +0000
41+++ nova/virt/xenapi/vmops.py 2011-05-27 20:49:13 +0000
42@@ -1190,26 +1190,22 @@
43 mpi = M2Crypto.m2.bn_to_mpi(bn)
44 return mpi
45
46- def _run_ssl(self, text, which):
47- base_cmd = ('openssl enc -aes-128-cbc -a -pass pass:%(shared)s '
48- '-nosalt %(dec_flag)s')
49- if which.lower()[0] == 'd':
50- dec_flag = ' -d'
51- else:
52- dec_flag = ''
53- shared = self._shared
54- cmd = base_cmd % locals()
55- proc = _runproc(cmd)
56- proc.stdin.write(text + '\n')
57+ def _run_ssl(self, text, extra_args=None):
58+ if not extra_args:
59+ extra_args = ''
60+ cmd = 'enc -aes-128-cbc -A -a -pass pass:%s -nosalt %s' % (
61+ self._shared, extra_args)
62+ proc = _runproc('openssl %s' % cmd)
63+ proc.stdin.write(text)
64 proc.stdin.close()
65 proc.wait()
66 err = proc.stderr.read()
67 if err:
68 raise RuntimeError(_('OpenSSL error: %s') % err)
69- return proc.stdout.read().strip('\n')
70+ return proc.stdout.read()
71
72 def encrypt(self, text):
73- return self._run_ssl(text, 'enc')
74+ return self._run_ssl(text).strip('\n')
75
76 def decrypt(self, text):
77- return self._run_ssl(text, 'dec')
78+ return self._run_ssl(text, '-d')