Skip to content

Commit

Permalink
py9p: python3 fixes for pki and 9pfs
Browse files Browse the repository at this point in the history
also, «circular» import removed from pki
  • Loading branch information
Peter V. Saveliev committed Jan 8, 2013
1 parent 1c16d66 commit 3362cb6
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 59 deletions.
44 changes: 18 additions & 26 deletions 9pfs/9pfs
Expand Up @@ -36,9 +36,9 @@ from py9p import py9p
def _os(func, *args):
try:
return func(*args)
except OSError, e:
except OSError as e:
raise py9p.ServerError(e.args)
except IOError, e:
except IOError as e:
raise py9p.ServerError(e.args)


Expand Down Expand Up @@ -88,7 +88,7 @@ class LocalFs(object):
s = _os(os.lstat, f)
u = uidname(s.st_uid)
g = gidname(s.st_gid)
res = s.st_mode & 0777
res = s.st_mode & 0o777
type = 0
ext = ""
if stat.S_ISDIR(s.st_mode):
Expand Down Expand Up @@ -142,7 +142,7 @@ class LocalFs(object):
else: # py9p.OREAD and otherwise
m = "rb"
if not (f.qid.type & py9p.QTDIR) and not stat.S_ISLNK(s.st_mode):
f.fd = _os(file, f.localpath, m)
f.fd = _os(open, f.localpath, m)
srv.respond(req, None)

def walk(self, srv, req):
Expand Down Expand Up @@ -218,13 +218,13 @@ class LocalFs(object):
return
name = f.localpath + '/' + req.ifcall.name
if req.ifcall.perm & py9p.DMDIR:
perm = req.ifcall.perm & (~0777 | (f.mode & 0777))
perm = req.ifcall.perm & (~0o777 | (f.mode & 0o777))
_os(os.mkdir, name, req.ifcall.perm & ~(py9p.DMDIR))
elif req.ifcall.perm & py9p.DMSYMLINK and self.dotu:
_os(os.symlink, req.ifcall.extension, name)
else:
perm = req.ifcall.perm & (~0666 | (f.mode & 0666))
_os(file, name, "w+").close()
perm = req.ifcall.perm & (~0o666 | (f.mode & 0o666))
_os(open, name, "w+").close()
_os(os.chmod, name, perm)
if (req.ifcall.mode & 3) == py9p.OWRITE:
if req.ifcall.mode & py9p.OTRUNC:
Expand Down Expand Up @@ -308,9 +308,8 @@ class LocalFs(object):


def usage(prog):
print >> sys.stderr, \
"usage: %s [-dDw] [-c mode] [-p port] [-r root] " \
"[-a address] [srvuser [domain]]" % prog
print("usage: %s [-dDw] [-c mode] [-p port] [-r root] " \
"[-a address] [srvuser [domain]]" % prog)
sys.exit(1)


Expand Down Expand Up @@ -350,22 +349,15 @@ def main():
if opt == '-c':
authmode = optarg

if authmode == 'sk1':
if len(args) != 2:
print >>sys.stderr, 'missing user and authsrv'
usage(prog)
else:
py9p.sk1 = __import__("py9p.sk1").sk1
user = args[0]
dom = args[1]
passwd = getpass.getpass()
key = py9p.sk1.makeKey(passwd)
elif authmode == 'pki':
py9p.pki = __import__("py9p.pki").pki
user = 'admin'
if authmode == 'pki':
try:
py9p.pki = __import__("py9p.pki").pki
user = 'admin'
except:
import traceback
traceback.print_exc()
elif authmode is not None and authmode != 'none':
print >> sys.stderr, \
"unknown auth type: %s; accepted: pki, sk1, none" % authmode
print("unknown auth type: %s; accepted: pki, sk1, none" % authmode)
sys.exit(1)

srv = py9p.Server(listen=(listen, port),
Expand All @@ -382,4 +374,4 @@ if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print "interrupted."
print("interrupted.")
40 changes: 23 additions & 17 deletions py9p/pki.py
Expand Up @@ -42,10 +42,11 @@
import os
import random
import getpass
import cPickle as pickle
import pickle
import Crypto.Util as util
import hashlib
from py9p import py9p
import sys
from . import utils as c9
from Crypto.Cipher import DES3, AES
from Crypto.PublicKey import RSA, DSA
from Crypto.Util.randpool import RandomPool
Expand Down Expand Up @@ -74,6 +75,10 @@ class BadKeyPassword(Error):
pass


class ServerError(Error):
pass


def gethome(uname):
for x in open('/etc/passwd').readlines():
u = x.split(':')
Expand Down Expand Up @@ -111,10 +116,10 @@ def asn1parse(data):
def asn1pack(data):
ret = ''
for part in data:
if type(part) in (type(()), type([])):
if type(part) in (tuple, list):
partData = asn1pack(part)
partType = SEQUENCE | 0x20
elif type(part) in (type(1), type(1L)):
elif type(part) in (int, long):
partData = number.long_to_bytes(part)
if ord(partData[0]) & (0x80):
partData = '\x00' + partData
Expand Down Expand Up @@ -205,9 +210,9 @@ def pubkeytostr(key, comment=None):


def strtopubkey(data):
d = base64.decodestring(data.split(' ')[1])
d = base64.decodestring(data.split(b' ')[1])
kind, rest = getNS(d)
if kind == 'ssh-rsa':
if kind == b'ssh-rsa':
e, rest = getMP(rest)
n, rest = getMP(rest)
return RSA.construct((n, e))
Expand Down Expand Up @@ -293,8 +298,8 @@ def getchallenge():
# generate a 16-byte long random string. (note that the built-
# in pseudo-random generator uses a 24-bit seed, so this is not
# as good as it may seem...)
challenge = map(lambda i: chr(random.randint(0x20, 0x7e)), range(16))
return ''.join(challenge)
challenge = map(lambda i: c9.bytes3(chr(random.randint(0x20, 0x7e))), range(16))
return b''.join(challenge)


class AuthFs(object):
Expand Down Expand Up @@ -338,11 +343,11 @@ def getpubkey(self, uname, pub=None):
if not os.path.exists(f):
raise BadKeyError("no public key supplied and no " + f)
else:
pubkey = file(f).read()
pubkey = open(f, 'rb').read()
elif not os.path.exists(pub):
raise BadKeyError("file not found: " + pub)
else:
pubkey = file(pub).read()
pubkey = open(pub, 'rb').read()

self.pubkeys[uname] = strtopubkey(pubkey)
return self.pubkeys[uname]
Expand All @@ -352,22 +357,23 @@ def estab(self, fid):
fid.phase = self.HaveChal
if not hasattr(fid, 'uname'):
raise AuthError("no fid.uname")
fid.key = self.getpubkey(fid.uname,
self.keyfiles.get(fid.uname, None))
uname = fid.uname.decode('utf-8')
fid.key = self.getpubkey(uname,
self.keyfiles.get(uname, None))
fid.chal = getchallenge()

def read(self, srv, req):
f = req.fid
if f.phase == self.HaveChal:
f.phase = self.NeedSign
req.ofcall.data = pickle.dumps(f.key.encrypt(f.chal, ''))
req.ofcall.data = pickle.dumps(f.key.encrypt(f.chal, ''), protocol=2)
srv.respond(req, None)
return
elif f.phase == self.Success:
req.ofcall.data = 'success as ' + f.suid
srv.respond(req, None)
return
raise py9p.ServerError("unexpected phase")
raise ServerError("unexpected phase")

def write(self, srv, req):
f = req.fid
Expand All @@ -381,8 +387,8 @@ def write(self, srv, req):
srv.respond(req, None)
return
else:
raise py9p.ServerError('signature not verified')
raise py9p.ServerError("unexpected phase")
raise ServerError('signature not verified')
raise ServerError("unexpected phase")


def clientAuth(cl, fcall, credentials):
Expand All @@ -402,5 +408,5 @@ def wr(x):
chal = credentials.key.decrypt(c)
sign = credentials.key.sign(chal, '')

wr(pickle.dumps(sign))
wr(pickle.dumps(sign, protocol=2))
return
26 changes: 10 additions & 16 deletions py9p/py9p.py
Expand Up @@ -33,17 +33,11 @@
import io
import threading
import struct
from . import utils as c9

if sys.version_info[0] == 2:
def bytes3(x):
if isinstance(x, unicode):
return bytes(x.encode('utf-8'))
else:
return bytes(x)
else:
if sys.version_info[0] == 3:
unicode = str
def bytes3(x):
return bytes(x, 'utf-8')


IOHDRSZ = 24
PORT = 564
Expand Down Expand Up @@ -240,7 +234,7 @@ def encS(self, x):
"""Encode data string with 2-byte length"""
self.buf.write(struct.pack("H", len(x)))
if isinstance(x, str) or isinstance(x, unicode):
x = bytes3(x)
x = c9.bytes3(x)
self.buf.write(x)

def decS(self):
Expand All @@ -251,7 +245,7 @@ def encD(self, d):
"""Encode data string with 4-byte length"""
self.buf.write(struct.pack("I", len(d)))
if isinstance(d, str) or isinstance(d, unicode):
d = bytes3(d)
d = c9.bytes3(d)
self.buf.write(d)

def decD(self):
Expand Down Expand Up @@ -847,7 +841,7 @@ def __init__(self, listen, authmode=None, fs=None, user=None,
if authmode is None:
self.authfs = None
elif authmode == 'pki':
import pki
from py9p import pki
self.authfs = pki.AuthFs(key)
else:
raise ServerError("unsupported auth mode")
Expand Down Expand Up @@ -1009,7 +1003,7 @@ def respond(self, req, error=None, errno=None):
req.ofcall.tag = req.ifcall.tag
if error:
req.ofcall.type = Rerror
req.ofcall.ename = bytes3(error)
req.ofcall.ename = c9.bytes3(error)
if not errno:
errno = ERRUNDEF
req.ofcall.errno = errno
Expand Down Expand Up @@ -1434,8 +1428,8 @@ def rwstat(self, req, error):
class Credentials(object):
def __init__(self, user, authmode=None, passwd=None,
keyfile=None, key=None):
self.user = bytes3(user) if isinstance(user, str) else user
self.passwd = bytes3(passwd) if isinstance(passwd, str) else passwd
self.user = c9.bytes3(user) if isinstance(user, str) else user
self.passwd = c9.bytes3(passwd) if isinstance(passwd, str) else passwd
self.key = key
self.authmode = authmode
if self.authmode == "pki":
Expand Down Expand Up @@ -1515,7 +1509,7 @@ def _walk(self, fid, newfid, wnames):
fcall = Fcall(Twalk)
fcall.fid = fid
fcall.newfid = newfid
fcall.wname = [bytes3(x) for x in wnames]
fcall.wname = [c9.bytes3(x) for x in wnames]
return self._rpc(fcall)

def _open(self, fid, mode):
Expand Down
13 changes: 13 additions & 0 deletions py9p/utils.py
@@ -0,0 +1,13 @@
import sys

if sys.version_info[0] == 2:
def bytes3(x):
if isinstance(x, unicode):
return bytes(x.encode('utf-8'))
else:
return bytes(x)
else:
def bytes3(x):
return bytes(x, 'utf-8')


0 comments on commit 3362cb6

Please sign in to comment.