~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to console/python-console

  • Committer: me at id
  • Date: 2009-02-02 04:42:36 UTC
  • Revision ID: svn-v4:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1190
www/apps/userservice#get_user: Fix fallout from the Storm migration.
    ivle.auth.authenticate.authenticate now wants a store, so we give it one.
    We also perform the old password check before we set attributes on the
    user, as otherwise the new password will always succeed (as the hash has
    already been updated).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
 
3
 
# usage:
4
 
#   python-console <port> <magic>
5
 
 
6
 
import cjson
7
 
import codeop
8
 
import cStringIO
9
 
import md5
10
 
import os
11
 
import Queue
12
 
import signal
13
 
import socket
14
 
import sys
15
 
from threading import Thread
16
 
 
17
 
class StdinFromWeb(object):
18
 
    def __init__(self, cmdQ, lineQ):
19
 
        self.cmdQ = cmdQ
20
 
        self.lineQ = lineQ
21
 
 
22
 
    def readline(self):
23
 
        # stop the clock!
24
 
        signal.alarm(0)
25
 
        self.cmdQ.put({"input":None})
26
 
        ln = self.lineQ.get()
27
 
        if 'chat' in ln:
28
 
            # restart the clock:
29
 
            # Some of our 5 seconds may have elapsed, but never mind.
30
 
            signal.alarm(5)
31
 
            return ln['chat']
32
 
 
33
 
class PythonRunner(Thread):
34
 
    def __init__(self, cmdQ, lineQ):
35
 
        self.cmdQ = cmdQ
36
 
        self.lineQ = lineQ
37
 
        self.out = cStringIO.StringIO()
38
 
        Thread.__init__(self)
39
 
 
40
 
    def execCmd(self, cmd):
41
 
        try:
42
 
            sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
43
 
            sys.stdout = self.out
44
 
            sys.stderr = self.out
45
 
            signal.alarm(5)
46
 
            res = eval(cmd, self.globs, self.locls)
47
 
            signal.alarm(0)
48
 
            self.cmdQ.put({"okay":(self.out.getvalue(),res)})
49
 
            self.curr_cmd = ''
50
 
            self.out = cStringIO.StringIO()
51
 
        except Exception, exc:
52
 
            signal.alarm(0)
53
 
            self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
54
 
            self.curr_cmd = ''
55
 
            self.out = cStringIO.StringIO()
56
 
 
57
 
    def run(self):
58
 
        self.init_state()
59
 
        compiler = codeop.CommandCompiler()
60
 
 
61
 
        while True:
62
 
            ln = self.lineQ.get()
63
 
            if 'chat' in ln:
64
 
                if self.curr_cmd == '':
65
 
                    self.curr_cmd = ln['chat']
66
 
                else:
67
 
                    self.curr_cmd = self.curr_cmd + '\n' + ln['chat']
68
 
                try:
69
 
                    cmd = compiler(self.curr_cmd)
70
 
                    if cmd is None:
71
 
                        # The command was incomplete,
72
 
                        # so send back a None, so the
73
 
                        # client can print a '...'
74
 
                        self.cmdQ.put({"more":None})
75
 
                    else:
76
 
                        self.execCmd(cmd)
77
 
                except Exception, exc:
78
 
                    signal.alarm(0)
79
 
                    self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
80
 
                    self.curr_cmd = ''
81
 
                    self.out = cStringIO.StringIO()
82
 
            if 'block' in ln:
83
 
                # throw away a partial command.
84
 
                try:
85
 
                    cmd = compile(ln['block'], "<web session>", 'exec');
86
 
                    self.execCmd(cmd)
87
 
                except Exception, exc:
88
 
                    signal.alarm(0)
89
 
                    self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
90
 
                    self.curr_cmd = ''
91
 
                    self.out = cStringIO.StringIO()
92
 
 
93
 
    def init_state(self):
94
 
        self.globs = {}
95
 
        self.globs['__builtins__'] = globals()['__builtins__']
96
 
        self.locls = {}
97
 
        self.curr_cmd = ''
98
 
 
99
 
def daemonize():
100
 
    if os.fork():   # launch child and...
101
 
        os._exit(0) # kill off parent
102
 
    os.setsid()
103
 
    if os.fork():   # launch child and...
104
 
        os._exit(0) # kill off parent again.
105
 
    os.umask(077)
106
 
 
107
 
# The global 'magic' is the secret that the client and server share
108
 
# which is used to create and md5 digest to authenticate requests.
109
 
# It is assigned a real value at startup.
110
 
magic = ''
111
 
 
112
 
cmdQ = Queue.Queue()
113
 
lineQ = Queue.Queue()
114
 
interpThread = PythonRunner(cmdQ, lineQ)
115
 
 
116
 
if __name__ == "__main__":
117
 
    port = int(sys.argv[1])
118
 
    magic = sys.argv[2]
119
 
 
120
 
    # Attempt to open the socket.
121
 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
122
 
    s.bind(('', port))
123
 
    s.listen(1)
124
 
 
125
 
    # Excellent! It worked. Let's turn ourself into a daemon,
126
 
    # then get on with the job of being a python interpreter.
127
 
    daemonize()
128
 
 
129
 
    interpThread.setDaemon(True)
130
 
    interpThread.start()
131
 
 
132
 
    while True:
133
 
        (conn, addr) = s.accept()
134
 
        try:
135
 
            # Grab the input
136
 
            buf = cStringIO.StringIO()
137
 
            blk = conn.recv(1024)
138
 
            while blk:
139
 
                buf.write(blk)
140
 
                try:
141
 
                    blk = conn.recv(1024, socket.MSG_DONTWAIT)
142
 
                except:
143
 
                    # Exception thrown if it WOULD block (but we
144
 
                    # told it not to wait) - ie. we are done
145
 
                    blk = None
146
 
            inp = buf.getvalue()
147
 
            msg = cjson.decode(inp)
148
 
            
149
 
            # Check that the message is 
150
 
            digest = md5.new(msg['text'] + magic).digest().encode('hex')
151
 
            if msg['digest'] != digest:
152
 
                conn.close()
153
 
                continue
154
 
 
155
 
            lineQ.put({msg['cmd']:msg['text']})
156
 
            r = cmdQ.get()
157
 
            conn.sendall(cjson.encode(r))
158
 
            conn.close()
159
 
        except Exception, e:
160
 
            conn.close()