stephank / libvirtweb

A simple web interface to libvirt

This URL has Read+Write access

libvirtweb / common.py
100644 60 lines (43 sloc) 1.891 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import os, base64, binascii
from twisted.python import log, threadable
from Crypto.Cipher import AES
 
 
class RFBCookieContainer(object):
   """Container for cookies that are sent to the browser and then received in the RFB connection."""
 
   TIMEOUT = 300
 
   synchronized = ['_expire', 'create', 'pop']
 
   def __init__(self, reactor):
      self.reactor = reactor
      self.cookies = {}
 
   def _expire(self, cookie):
      try:
         del self.cookies[cookie]
         log.msg("Forgotten cookie: %s" % binascii.hexlify(cookie))
      except KeyError:
         pass
 
   def create(self, value):
      """Create a random cookie and associate the give value with it."""
 
      cookie = os.urandom(16)
      timer = self.reactor.callLater(self.TIMEOUT, self._expire, cookie)
      self.cookies[cookie] = (value, timer)
      log.msg("Storing cookie: %s" % binascii.hexlify(cookie))
      return cookie
 
   def pop(self, challenge, attempt):
      """Find a cookie, and pop it's value from the container.
 
Check if the given attempt, based on the given challenge, matches any of the cookies.
If it does, the cookie is removed from the container, and the value returned."""
 
      # The client encrypts the challenge with the cookie. We can't deduce the cookie
      # from the encrypted challenge, so we'll just have to try with each and see if one matches.
      for cookie, item in self.cookies.iteritems():
         aesobj = AES.new(cookie, AES.MODE_ECB)
         expected = aesobj.encrypt(challenge)
         if attempt == expected:
            value, timer = item
            del self.cookies[cookie]
            timer.cancel()
            log.msg("Retrieved cookie: %s" % binascii.hexlify(cookie))
            return cookie, value
 
threadable.synchronize(RFBCookieContainer)
 
 
cookies = None
 
def init(reactor):
   global cookies
   cookies = RFBCookieContainer(reactor)