Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
django-sshkey
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
A prog2-höz tartozó friss repo anyagok itt elérhetőek:
https://git.iit.bme.hu/
Commit
3550b54a
authored
Jul 01, 2014
by
Scott Duckworth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make parse_key() return a PublicKey instance
parent
80071eb9
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
90 additions
and
77 deletions
+90
-77
django_sshkey/models.py
+9
-39
django_sshkey/util.py
+81
-38
No files found.
django_sshkey/models.py
View file @
3550b54a
...
...
@@ -29,28 +29,7 @@
from
django.db
import
models
from
django.contrib.auth.models
import
User
from
django.core.exceptions
import
ValidationError
from
django_sshkey.util
import
SSHKeyFormatError
,
key_parse
def
wrap
(
text
,
width
,
end
=
None
):
n
=
0
t
=
''
if
end
is
None
:
while
n
<
len
(
text
):
m
=
n
+
width
t
+=
text
[
n
:
m
]
if
len
(
text
)
<=
m
:
return
t
t
+=
'
\n
'
n
=
m
else
:
while
n
<
len
(
text
):
m
=
n
+
width
if
len
(
text
)
<=
m
:
return
t
+
text
[
n
:
m
]
m
-=
len
(
end
)
t
+=
text
[
n
:
m
]
+
end
+
'
\n
'
n
=
m
return
t
from
django_sshkey.util
import
SSHKeyFormatError
,
pubkey_parse
class
UserKey
(
models
.
Model
):
user
=
models
.
ForeignKey
(
User
,
db_index
=
True
)
...
...
@@ -75,18 +54,15 @@ class UserKey(models.Model):
def
clean
(
self
):
try
:
info
=
key_parse
(
self
.
key
)
self
.
fingerprint
=
info
.
fingerprint
if
info
.
comment
:
self
.
key
=
"
%
s
%
s
%
s"
%
(
info
.
type
.
decode
(),
info
.
b64key
.
decode
(),
info
.
comment
)
else
:
self
.
key
=
"
%
s
%
s"
%
(
info
.
type
.
decode
(),
info
.
b64key
.
decode
())
pubkey
=
pubkey_parse
(
self
.
key
)
except
SSHKeyFormatError
as
e
:
raise
ValidationError
(
str
(
e
))
self
.
key
=
pubkey
.
format_openssh
()
self
.
fingerprint
=
pubkey
.
fingerprint
()
if
not
self
.
name
:
if
not
info
.
comment
:
if
not
pubkey
.
comment
:
raise
ValidationError
(
'Name or key comment required'
)
self
.
name
=
info
.
comment
self
.
name
=
pubkey
.
comment
def
validate_unique
(
self
,
exclude
=
None
):
if
self
.
pk
is
None
:
...
...
@@ -109,14 +85,8 @@ class UserKey(models.Model):
pass
def
export_openssh
(
self
):
return
self
.
key
.
encode
(
'utf-8'
)
return
self
.
key
def
export_rfc4716
(
self
):
info
=
key_parse
(
self
.
key
)
out
=
b
'---- BEGIN SSH2 PUBLIC KEY ----
\n
'
if
info
.
comment
:
comment
=
'Comment: "
%
s"'
%
info
.
comment
out
+=
wrap
(
comment
,
72
,
'
\\
'
)
.
encode
(
'ascii'
)
+
b
'
\n
'
out
+=
wrap
(
info
.
b64key
,
72
)
.
encode
(
'ascii'
)
+
b
'
\n
'
out
+=
b
'---- END SSH2 PUBLIC KEY ----'
return
out
pubkey
=
pubkey_parse
(
self
.
key
)
return
pubkey
.
format_rfc4716
()
django_sshkey/util.py
View file @
3550b54a
...
...
@@ -26,11 +26,31 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from
collections
import
namedtuple
import
base64
import
struct
SSHKEY_LOOKUP_URL_DEFAULT
=
'http://localhost:8000/sshkey/lookup'
KeyInfo
=
namedtuple
(
'KeyInfo'
,
'type b64key comment fingerprint'
)
def
wrap
(
text
,
width
,
wrap_end
=
None
):
n
=
0
t
=
''
if
wrap_end
is
None
:
while
n
<
len
(
text
):
m
=
n
+
width
t
+=
text
[
n
:
m
]
if
len
(
text
)
<=
m
:
return
t
t
+=
'
\n
'
n
=
m
else
:
while
n
<
len
(
text
):
m
=
n
+
width
if
len
(
text
)
<=
m
:
return
t
+
text
[
n
:
m
]
m
-=
len
(
wrap_end
)
t
+=
text
[
n
:
m
]
+
wrap_end
+
'
\n
'
n
=
m
return
t
class
SSHKeyFormatError
(
Exception
):
def
__init__
(
self
,
text
):
...
...
@@ -39,63 +59,86 @@ class SSHKeyFormatError(Exception):
def
__str__
(
self
):
return
"Unrecognized public key format"
def
key_parse
(
text
):
import
base64
import
hashlib
import
struct
lines
=
text
.
splitlines
()
class
PublicKey
(
object
):
def
__init__
(
self
,
b64key
,
comment
=
None
):
self
.
b64key
=
b64key
self
.
comment
=
comment
self
.
keydata
=
base64
.
b64decode
(
b64key
.
encode
(
'ascii'
))
n
=
struct
.
unpack
(
'>I'
,
self
.
keydata
[:
4
])
self
.
algorithm
=
self
.
keydata
[
4
:
4
+
n
[
0
]]
# OpenSSH public key
if
len
(
lines
)
==
1
and
text
.
startswith
(
b
'ssh-'
):
def
fingerprint
(
self
):
import
hashlib
fp
=
hashlib
.
md5
(
self
.
keydata
)
.
hexdigest
()
return
':'
.
join
(
a
+
b
for
a
,
b
in
zip
(
fp
[::
2
],
fp
[
1
::
2
]))
def
format_openssh
(
self
):
out
=
self
.
algorithm
+
' '
+
self
.
b64key
if
self
.
comment
:
out
+=
' '
+
self
.
comment
return
out
def
format_rfc4716
(
self
):
out
=
'---- BEGIN SSH2 PUBLIC KEY ----
\n
'
if
self
.
comment
:
comment
=
'Comment: "
%
s"'
%
self
.
comment
out
+=
wrap
(
comment
,
72
,
'
\\
'
)
+
'
\n
'
out
+=
wrap
(
self
.
b64key
,
72
)
+
'
\n
'
out
+=
'---- END SSH2 PUBLIC KEY ----'
return
out
def
pubkey_parse_openssh
(
text
):
fields
=
text
.
split
(
None
,
2
)
if
len
(
fields
)
<
2
:
raise
SSHKeyFormatError
(
text
)
type
=
fields
[
0
]
b64key
=
fields
[
1
]
comment
=
None
if
len
(
fields
)
==
3
:
comment
=
fields
[
2
]
try
:
key
=
base64
.
b64decode
(
b64key
)
if
len
(
fields
)
==
2
:
key
=
PublicKey
(
fields
[
1
])
else
:
key
=
PublicKey
(
fields
[
1
],
fields
[
2
])
except
TypeError
:
raise
SSHKeyFormatError
(
text
)
if
fields
[
0
]
!=
key
.
algorithm
:
raise
SSHKeyFormatError
(
text
)
return
key
# SSH2 public key
elif
(
lines
[
0
]
==
b
'---- BEGIN SSH2 PUBLIC KEY ----'
and
lines
[
-
1
]
==
b
'---- END SSH2 PUBLIC KEY ----'
def
pubkey_parse_rfc4716
(
text
):
lines
=
text
.
splitlines
()
if
not
(
lines
[
0
]
==
'---- BEGIN SSH2 PUBLIC KEY ----'
and
lines
[
-
1
]
==
'---- END SSH2 PUBLIC KEY ----'
):
b64key
=
b
''
headers
=
{}
raise
SSHKeyFormatError
(
text
)
lines
=
lines
[
1
:
-
1
]
b64key
=
''
headers
=
{}
while
lines
:
line
=
lines
.
pop
(
0
)
if
b
':'
in
line
:
while
line
[
-
1
]
==
b
'
\\
'
:
if
':'
in
line
:
while
line
[
-
1
]
==
'
\\
'
:
line
=
line
[:
-
1
]
+
lines
.
pop
(
0
)
k
,
v
=
line
.
split
(
b
':'
,
1
)
headers
[
k
.
lower
()
.
decode
(
'ascii'
)]
=
v
.
lstrip
()
.
decode
(
'utf-8'
)
k
,
v
=
line
.
split
(
':'
,
1
)
headers
[
k
.
lower
()]
=
v
.
lstrip
(
)
else
:
b64key
+=
line
comment
=
headers
.
get
(
'comment'
)
if
comment
and
comment
[
0
]
in
(
'"'
,
"'"
)
and
comment
[
0
]
==
comment
[
-
1
]:
comment
=
comment
[
1
:
-
1
]
try
:
key
=
base64
.
b64decode
(
b64key
)
return
PublicKey
(
b64key
,
comment
)
except
TypeError
:
raise
SSHKeyFormatError
(
text
)
if
len
(
key
)
<
4
:
raise
SSHKeyFormatError
(
text
)
n
=
struct
.
unpack
(
'>I'
,
key
[:
4
])
type
=
key
[
4
:
4
+
n
[
0
]]
# unrecognized format
else
:
raise
SSHKeyFormatError
(
text
)
def
pubkey_parse
(
text
):
lines
=
text
.
splitlines
()
if
len
(
lines
)
==
1
:
return
pubkey_parse_openssh
(
text
)
fp
=
hashlib
.
md5
(
key
)
.
hexdigest
()
fp
=
':'
.
join
(
a
+
b
for
a
,
b
in
zip
(
fp
[::
2
],
fp
[
1
::
2
]))
return
KeyInfo
(
type
,
b64key
,
comment
,
fp
)
if
lines
[
0
]
==
'---- BEGIN SSH2 PUBLIC KEY ----'
:
return
pubkey_parse_rfc4716
(
text
)
raise
SSHKeyFormatError
(
text
)
def
lookup_all
(
url
):
import
urllib
...
...
@@ -146,11 +189,11 @@ def lookup_by_fingerprint_main():
)
sys
.
exit
(
1
)
try
:
info
=
key_parse
(
key
)
fingerprint
=
info
.
fingerprint
pubkey
=
pubkey_parse
(
key
)
except
SSHKeyFormatError
as
e
:
sys
.
stderr
.
write
(
"Error: "
+
str
(
e
))
sys
.
exit
(
1
)
fingerprint
=
pubkey
.
fingerprint
()
url
=
getenv
(
'SSHKEY_LOOKUP_URL'
,
SSHKEY_LOOKUP_URL_DEFAULT
)
for
key
in
lookup_by_fingerprint
(
url
,
fingerprint
):
sys
.
stdout
.
write
(
key
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment