Merge lp:~rvb/maas/wrong-key-bug-1298788 into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 2207
Proposed branch: lp:~rvb/maas/wrong-key-bug-1298788
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 82 lines (+22/-8)
2 files modified
src/maasserver/models/sshkey.py (+13/-8)
src/maasserver/models/tests/test_sshkey.py (+9/-0)
To merge this branch: bzr merge lp:~rvb/maas/wrong-key-bug-1298788
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+213283@code.launchpad.net

Commit message

Catch all the exceptions raised by twisted.conch.ssh.keys.Key.fromString when validating a SSH key.

Description of the change

I know that catching all exceptions is generally an anti-pattern but in this instance, I think it's preferable to playing hide-and-seek with twisted.conch.ssh.keys.Key.fromString() which clearly can throw many types of exceptions. I just noticed that calling it on 'ssh-r' triggers an IndexError (http://paste.ubuntu.com/7168866/).

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

It's a nasty problem. For the record, I don't think it's wrong to catch Exception per se, just to suppress potentially important error information.

In that spirit, perhaps you could log the Exception that you catch, for debugging purposes?

review: Approve
Revision history for this message
Julian Edwards (julian-edwards) wrote :

On 29/03/14 01:41, Jeroen T. Vermeulen wrote:
> Review: Approve
>
> It's a nasty problem. For the record, I don't think it's wrong to catch Exception per se, just to suppress potentially important error information.
>
> In that spirit, perhaps you could log the Exception that you catch, for debugging purposes?
>

In addition, always comment in the code why you are using bare
Exceptions. Thanks.

Revision history for this message
Raphaël Badin (rvb) wrote :

> It's a nasty problem. For the record, I don't think it's wrong to catch
> Exception per se, just to suppress potentially important error information.
>
> In that spirit, perhaps you could log the Exception that you catch, for
> debugging purposes?

Good point, done.

Revision history for this message
Raphaël Badin (rvb) wrote :

> In addition, always comment in the code why you are using bare
> Exceptions. Thanks.

done.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/models/sshkey.py'
2--- src/maasserver/models/sshkey.py 2014-01-17 08:45:11 +0000
3+++ src/maasserver/models/sshkey.py 2014-03-31 07:34:52 +0000
4@@ -17,7 +17,6 @@
5 ]
6
7
8-import binascii
9 from cgi import escape
10
11 from django.contrib.auth.models import User
12@@ -28,13 +27,13 @@
13 TextField,
14 )
15 from django.utils.safestring import mark_safe
16-from maasserver import DefaultMeta
17+from maasserver import (
18+ DefaultMeta,
19+ logger,
20+ )
21 from maasserver.models.cleansave import CleanSave
22 from maasserver.models.timestampedmodel import TimestampedModel
23-from twisted.conch.ssh.keys import (
24- BadKeyError,
25- Key,
26- )
27+from twisted.conch.ssh.keys import Key
28
29
30 class SSHKeyManager(Manager):
31@@ -49,11 +48,17 @@
32 """Validate that the given value contains a valid SSH public key."""
33 try:
34 key = Key.fromString(value)
35+ except Exception:
36+ # twisted.conch.ssh.keys.Key.fromString raises all sorts of exceptions.
37+ # Here, we catch them all and return a ValidationError since this
38+ # method only aims at validating keys and not return the exact cause of
39+ # the failure.
40+ logger.exception("Invalid SSH public key")
41+ raise ValidationError("Invalid SSH public key.")
42+ else:
43 if not key.isPublic():
44 raise ValidationError(
45 "Invalid SSH public key (this key is a private key).")
46- except (BadKeyError, binascii.Error, UnicodeEncodeError):
47- raise ValidationError("Invalid SSH public key.")
48
49
50 HELLIPSIS = '…'
51
52=== modified file 'src/maasserver/models/tests/test_sshkey.py'
53--- src/maasserver/models/tests/test_sshkey.py 2014-01-17 08:45:01 +0000
54+++ src/maasserver/models/tests/test_sshkey.py 2014-03-31 07:34:52 +0000
55@@ -23,11 +23,13 @@
56 from maasserver.models.sshkey import (
57 get_html_display_for_key,
58 HELLIPSIS,
59+ Key,
60 validate_ssh_public_key,
61 )
62 from maasserver.testing import get_data
63 from maasserver.testing.factory import factory
64 from maasserver.testing.testcase import MAASServerTestCase
65+from mock import Mock
66 from testtools.matchers import EndsWith
67
68
69@@ -63,6 +65,13 @@
70 self.assertRaises(
71 ValidationError, validate_ssh_public_key, key_string)
72
73+ def test_does_not_validate_wrong_key(self):
74+ # If twisted.conch.ssh.keys.Key raises an exception, the validation
75+ # fails.
76+ self.patch(Key, 'fromString', Mock(side_effect=Exception()))
77+ self.assertRaises(
78+ ValidationError, validate_ssh_public_key, factory.make_name('key'))
79+
80 def test_does_not_validate_rsa_private_key(self):
81 key_string = get_data('data/test_rsa')
82 self.assertRaises(