Remove the try-catch block here. It isn't needed.
[xonotic/xonstat.git] / xonstat / d0_blind_id.py
1 import subprocess
2 import os
3 import fcntl
4 import base64
5 import select
6
7 d0_blind_id_keygen = "./crypto-keygen-standalone"
8 d0_blind_id_d0pk = "key_0.d0pk"
9
10 def d0_blind_id_verify(sig, querystring, postdata=None): #-> (idfp, status)
11         data = None
12         if postdata == None:
13                 data = querystring
14         else:
15                 data = postdata + "\0" + querystring
16         if sig != None:
17                 # make some pipes
18                 (dpipe_r, dpipe_w) = os.pipe()
19                 (spipe_r, spipe_w) = os.pipe()
20
21                 # smoke them
22                 def closepipes():
23                         os.close(dpipe_w)
24                         os.close(spipe_w)
25                 checker = subprocess.Popen([d0_blind_id_keygen, "-p", d0_blind_id_d0pk, "-d", "/dev/fd/%d" % (dpipe_r, ), "-s", "/dev/fd/%d" % (spipe_r, )], stdout=subprocess.PIPE, preexec_fn=closepipes)
26
27                 # close them
28                 os.close(dpipe_r)
29                 os.close(spipe_r)
30
31                 # make them nonblocking
32                 fcntl.fcntl(dpipe_w, fcntl.F_SETFL, fcntl.fcntl(dpipe_w, fcntl.F_GETFL) | os.O_NONBLOCK)
33                 fcntl.fcntl(spipe_w, fcntl.F_SETFL, fcntl.fcntl(spipe_w, fcntl.F_GETFL) | os.O_NONBLOCK)
34
35                 # fill vars
36                 rpipes = [dpipe_w, spipe_w]
37                 buffers = [data, base64.b64decode(sig)]
38
39                 # generic nonblocking buffer loop
40                 while len([p for p in rpipes if p != None]) != 0:
41                         (readers, writers, errorers) = select.select([], [p for p in rpipes if p != None], [p for p in rpipes if p != None], None)
42                         n = 0
43                         for e in errorers:
44                                 i = [j for j in range(len(rpipes)) if rpipes[j] == e]
45                                 if len(i) != 1:
46                                         continue
47                                 i = i[0]
48                                 os.close(e)
49                                 buffers[i] = None
50                                 rpipes[i] = None
51                                 n += 1
52                         for w in writers:
53                                 i = [j for j in range(len(rpipes)) if rpipes[j] == w]
54                                 if len(i) != 1:
55                                         continue
56                                 i = i[0]
57                                 written = os.write(w, buffers[i])
58                                 if written > 0:
59                                         buffers[i] = buffers[i][written:]
60                                 if buffers[i] == "":
61                                         os.close(w)
62                                         buffers[i] = None
63                                         rpipes[i] = None
64                                 n += 1
65                         if not n:
66                                 break
67
68                 # close all remaining
69                 for p in rpipes:
70                         if p != None:
71                                 os.close(p)
72
73                 # check
74                 if len([x for x in buffers if x != None]) != 0:
75                         raise Exception("could not write data to process")
76
77                 # retrieve data from stdout
78                 status = checker.stdout.readline().rstrip("\n")
79                 idfp = checker.stdout.readline().rstrip("\n")
80                 checker.stdout.close()
81                 checker.wait()
82                 if checker.returncode != 0:
83                         return (None, None)
84                 return (idfp, (status == "1"))
85
86 if __name__ == "__main__":
87         sig = "gQEBERjDsnVNr4qrYkvaevguF4ypPZHq0yiXfMMKwlu7+kY3HuI8zHx2WhiYj+q26re5uamQ9r8umh54CEJ7zqZAz8IavVblWYznzee9WjIBAB1FeHwILGlKOCDpGBikoZBkMxI4MqjCPzDPAkDMrd1DK0FsWOTpWljLgNGfACTKcgKBAQGPqnGoD6GhuHLYN+Sf73ROColneBdJ7ttuVwm32FvI8LuD5aLDll7bpqfHTWhgbTW02CYvkTAYtoz2RZmIGK5ZHHaM/V6vcSXnq2ab/7mFRiag7D5OUsmIFY9E3IqcqtP7+wXSVgiNFY3DBPy27bXjk8ZJ9nUD5dQBL9sG8TzWd4EBAYrTMfF82EBgsVArIaQjeOuJC3bkPzP5b3El/ZCHkDShpu7wZ82h/82B4W5Ep3KXpgu+YAEULt+5i2WbsfRSXeVZctzD4A++MBqQx9VuN/KsxgHS/20tRiBgd1VElhRD8KJ0lbkxYNcHSkpWSMDFS+eFmizcM3/XQNQ7ukAmM3lkgQEBIZR+FpDFLoGg9mIu2RH9O7lWdifpVhqjrEnvkr4KdB6JzBXAwVPmt1NAVDjGRI/ELlTysOx1b9F2EgdJejY5LgcVxz6irwEckx0z+L10A6Ca2lsGR1E+rViFffNNIJv34dNKgaCInyUNCeBei0AF8KLXLHhRTiBvSVBi6ANb/lY="
88         querystring = ""
89         postdata = "hello world"
90         (idfp, status) = d0_blind_id_verify(sig, querystring, postdata)
91         print(repr((idfp, status)))