gui.py 7.09 KB
Newer Older
tarokkk committed
1 2 3 4 5 6 7
#!/usr/bin/env python

import gtk
import webkit
import gobject
import base64
import os
8 9 10
import sys
import rdp
from multiprocessing import Process
11 12
import subprocess
import tempfile
13

tarokkk committed
14 15 16 17 18
class KeyGen:
    """Attributes:
    private_key
    public_key
    """
19

tarokkk committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
    def __init__(self):
        self.private_key, self.public_key = self.keygen(2048)
  
    def keygen(self,length=1024):
        """Generate Keypair for SSH
        (private_key, public_key)
        """
        import os, base64
        from datetime import date
        from Crypto.PublicKey import RSA
        key = RSA.generate(length, os.urandom)
        try:
            pub = key.exportKey('OpenSSH')
            if not pub.startswith("ssh-"):
                raise ValueError(pub)
        except:
            ssh_rsa = '00000007' + base64.b16encode('ssh-rsa')
            exponent = '%x' % (key.e, )
            if len(exponent) % 2:
                exponent = '0' + exponent
40

tarokkk committed
41 42
            ssh_rsa += '%08x' % (len(exponent) / 2, )
            ssh_rsa += exponent
43

tarokkk committed
44 45 46
            modulus = '%x' % (key.n, )
            if len(modulus) % 2:
                modulus = '0' + modulus
47

tarokkk committed
48 49
            if modulus[0] in '89abcdef':
                modulus = '00' + modulus
50

tarokkk committed
51 52 53 54 55 56
            ssh_rsa += '%08x' % (len(modulus) / 2, )
            ssh_rsa += modulus

            pub = 'ssh-rsa %s' % (
                base64.b64encode(base64.b16decode(ssh_rsa.upper())), )
        return key.exportKey(), "%s %s" % (pub, "cloud-%s" % date.today())
57 58


tarokkk committed
59 60 61


class Browser:
62
    version = "0.1"
tarokkk committed
63
    mounted = False
tarokkk committed
64 65
    neptun = ""
    host = ""
tarokkk committed
66 67
    private_key_file = ""
    public_key_b64 = ""
68
    params = {}
tarokkk committed
69 70 71
    def __init__(self):
        #Init window components
        gobject.threads_init()
tarokkk committed
72 73
        self.window = gtk.Window(type=gtk.WINDOW_TOPLEVEL)
        #Register window events
74
        self.window.connect("destroy", self.destroy)
tarokkk committed
75 76 77 78


        #DEBUG
        self.window.set_decorated(True)
tarokkk committed
79
        self.window.set_title("IK CloudStore Login")
tarokkk committed
80 81
        self.window.set_default_size(1024,600)
        self.window.set_position(gtk.WIN_POS_CENTER)
tarokkk committed
82 83

        #Init browser
tarokkk committed
84 85
        self.webview = webkit.WebView()
        self.webview.connect('onload-event', self.load_committed_cb)
tarokkk committed
86
        self.webview.open("https://cloud.ik.bme.hu/store/gui/")
tarokkk committed
87
        self.webview.connect("navigation-requested", self.on_navigation_requested)
88 89
        settings = webkit.WebSettings()
        settings.set_property('user-agent', 'cloud-gui '+self.version)
90 91
        settings.set_property('enable-accelerated-compositing', True)
        settings.set_property("enable-default-context-menu", False)
92 93
        self.webview.set_settings(settings)

tarokkk committed
94
        #Connect things
tarokkk committed
95 96
        self.scrolledwindow = gtk.ScrolledWindow()
        self.scrolledwindow.add(self.webview)
97
        self.window.add(self.scrolledwindow)
tarokkk committed
98
        self.window.maximize()
tarokkk committed
99 100
        self.window.show_all()

101
    def init_keypair(self):
tarokkk committed
102 103 104 105 106 107 108 109 110 111
        keygen = KeyGen()
        private_key = keygen.private_key
        public_key = keygen.public_key

        #Saver private_key to KEY_FILE
        with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
            f.write(private_key)
            self.private_key_file = f.name
        self.public_key_b64 =  base64.b64encode(public_key)
    
112
    def destroy(self, dummy):
tarokkk committed
113 114 115 116 117 118 119 120
        try:
            os.unlink(self.private_key_file)
        except:
            pass
        try:
            self.umount_sshfs_folder()
        except:
            pass
121 122
        gtk.main_quit()

tarokkk committed
123 124
    def on_navigation_requested(self, view, frame, req, data=None):
        uri = req.get_uri()
125 126 127 128 129 130 131 132 133
        if uri == "https://login.bme.hu/admin/":
            gobject.threads_init()
            window = gtk.Window(type=gtk.WINDOW_TOPLEVEL)
            browser = webkit.WebView()
            browser.open(uri)
            window.add(browser)
            window.show_all()
            return True
        elif uri == "https://cloud.ik.bme.hu/logout/":
134 135 136 137
            self.umount_sshfs_folder()
        try:
            scheme, rest = uri.split(":", 1)
            if scheme == "nx" or scheme == "rdp" or scheme == "sshterm":
tarokkk committed
138
                subprocess.Popen(["/usr/local/bin/rdp",uri])
139
                return True
tarokkk committed
140 141 142 143
            elif scheme == "cloudfile":
                file_path = os.path.normpath(rest)
                subprocess.call(["xdg-open","file://"+self.folder+file_path])
                return True
144 145 146 147 148
            else:
                return False
        except:
            False
    def mount_sshfs_folder(self):
tarokkk committed
149
        self.folder = os.path.expanduser("~/sshfs")
150 151
        neptun = self.params["neptun"]
        host = self.params["host"]
tarokkk committed
152
        try:
153
            os.makedirs(self.folder)
tarokkk committed
154
        except:
tarokkk committed
155
            pass
tarokkk committed
156
        result = subprocess.call(['/usr/bin/sshfs', '-o', 'IdentityFile='+self.private_key_file+',StrictHostKeyChecking=no', neptun+"@"+host+":home", self.folder])
tarokkk committed
157 158
        #print result
    def umount_sshfs_folder(self):
159
        try:
160
            result = subprocess.call(['/bin/fusermount', '-u', self.folder])
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
        except:
            pass
    def post_key(self,key = None):
        if key != None:
            js = '''
            $.post("/store/gui/", { "KEY" : "%(key)s" }, 
                                function (respond) {
                                    window.location = respond;
                                    }
                                )
                             .error(function (respond) { alert(JSON.stringify(respond)); });
                           ''' % { "key" : key }
        else:
            js = '''
            $.post("/store/gui/", "", 
                                function (respond) {
                                    window.alert(respond);
                                    }
                                )
                             .error(function (respond) { alert(JSON.stringify(respond)); });
                           '''
        self.webview.execute_script(js)
        
tarokkk committed
184
    def load_committed_cb(self,web_view, frame):
185
        uri = frame.get_uri()
186
        print uri
187 188 189 190 191 192 193 194 195 196
        try:
            self.webview.execute_script('document.getElementsByTagName("a")[0].target="";')
        except:
            pass
        ### Send keys via JavaScript ###
        if uri == "https://cloud.ik.bme.hu/store/gui/":
            self.init_keypair()
            ### JS
            self.post_key(self.public_key_b64)
            ### Parse values and do mounting ###
197
        elif uri.startswith("https://cloud.ik.bme.hu/home/?"):
tarokkk committed
198
            if self.mounted != True:
199
                try:
tarokkk committed
200 201 202 203 204 205 206 207 208 209 210 211 212 213
                    uri, params = uri.split('?', 1)
                    values = params.split('&')
                    for p in values:
                        key, value = p.split('=',1)
                        self.params[key] = value
                    try:
                        self.mount_sshfs_folder()
                    except Exception as e:
                        print e
                    self.mounted = True
                except:
                    pass 
                finally:
                    os.unlink(self.private_key_file)
214
        return True
tarokkk committed
215 216
    def main(self):
        gtk.main()
217
    
tarokkk committed
218 219 220 221
if __name__ == "__main__":
    browser = Browser()
    browser.main()