OpenSecurity/bin/opensecurity_tray.pyw
author BarthaM@N3SIM1218.D03.arc.local
Fri, 18 Jul 2014 13:45:09 +0100
changeset 213 2e0b94e12bfc
parent 207 ae931a692b54
child 215 9d777587cdab
permissions -rwxr-xr-x
Addded http proxy server support.
     1 # -*- coding: utf-8 -*-
     2 
     3 # ------------------------------------------------------------
     4 # opensecurity-dialog
     5 # 
     6 # an opensecurity dialog
     7 #
     8 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
     9 #
    10 # Copyright (C) 2013 AIT Austrian Institute of Technology
    11 # AIT Austrian Institute of Technology GmbH
    12 # Donau-City-Strasse 1 | 1220 Vienna | Austria
    13 # http://www.ait.ac.at
    14 #
    15 # This program is free software; you can redistribute it and/or
    16 # modify it under the terms of the GNU General Public License
    17 # as published by the Free Software Foundation version 2.
    18 # 
    19 # This program is distributed in the hope that it will be useful,
    20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    22 # GNU General Public License for more details.
    23 # 
    24 # You should have received a copy of the GNU General Public License
    25 # along with this program; if not, write to the Free Software
    26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, 
    27 # Boston, MA  02110-1301, USA.
    28 # ------------------------------------------------------------
    29 
    30 
    31 # ------------------------------------------------------------
    32 # imports
    33 
    34 import argparse
    35 import json
    36 import os
    37 import subprocess
    38 import sys
    39 import urllib
    40 import urllib2
    41 import webbrowser
    42 import _winreg
    43 import re
    44 
    45 from PyQt4 import QtCore
    46 from PyQt4 import QtGui
    47 
    48 # local
    49 import __init__ as opensecurity
    50 
    51 if sys.platform == 'win32' or sys.platform == 'cygwin':
    52     from cygwin import Cygwin
    53 
    54 import opensecurity_client_restful_server 
    55 from ui import AboutDialog
    56 from ui import ConfigureDialog
    57 from ui import opensecurity_rc
    58 
    59 
    60 # ------------------------------------------------------------
    61 # code
    62 
    63 
    64 class OpenSecurityWait(QtGui.QDialog):
    65 
    66     """OpenSecurity: please wait ..."""
    67     
    68     def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags(0)):
    69         super(OpenSecurityWait, self).__init__(parent, flags)
    70         self.setWindowTitle('OpenSecurity')
    71         self.setup_ui()
    72         
    73         
    74     def setup_ui(self):
    75         """Create the widgets."""
    76         
    77         lyMain = QtGui.QVBoxLayout(self)
    78         lyMain.setContentsMargins(8, 8, 8, 8)
    79         
    80         # content area: left pixmap, right text
    81         lbTitle = QtGui.QLabel('Creating secure subsystem. Please stand by ...')
    82         lyMain.addWidget(lbTitle)
    83         
    84         self.setMinimumSize(400, 50)
    85         self.resize(lyMain.minimumSize())
    86 
    87 
    88 class OpenSecurityTrayIcon(QtGui.QSystemTrayIcon):
    89     
    90     """This is the OpenSecuirty Tray Icon"""
    91 
    92     def __init__(self, icon, parent=None):
    93         
    94         super(OpenSecurityTrayIcon, self).__init__(icon, parent)
    95         self.setup_ui()
    96         self.activated.connect(self.activated_)
    97        
    98 
    99     def activated_(self, reason):
   100 
   101         """the system tray icon was activated"""
   102         self.refresh_format_menu()
   103 
   104         
   105     def clicked_about(self):
   106         """clicked about"""
   107         d = AboutDialog()
   108         d.exec_()
   109     
   110     def getProxySettings(self):        
   111         aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_CURRENT_USER)
   112         aKey = _winreg.OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings")
   113         subCount, valueCount, lastModified = _winreg.QueryInfoKey(aKey)
   114         reg_entries = dict()
   115         for i in range(valueCount):                                           
   116             try:
   117                 n,v,t = _winreg.EnumValue(aKey,i)
   118                 reg_entries[n] = v
   119             except EnvironmentError:                                               
   120                 break
   121         _winreg.CloseKey(aKey)
   122 
   123         if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1:
   124             proxy_search = re.search(r"(?<=http=)(?P<ProxyServer>.*?)(?=;)", reg_entries['ProxyServer'])
   125             if proxy_search:
   126                 proxies = proxy_search.groupdict()
   127                 if 'ProxyServer' in proxies.keys(): # found http proxy
   128                     return {'ProxyServer': proxies['ProxyServer']}  
   129             return {'ProxyServer': reg_entries['ProxyServer']}
   130         return None
   131 
   132     def clicked_browser(self):
   133         """wish for safe internet browsing"""
   134         
   135         if not (sys.platform == 'win32' or sys.platform == 'cygwin'):
   136             QtGui.QMessageBox.critical(self.parent(), 'OpenSecurity Error', 'This action is not supported on this platform.\nSorry.')
   137             return
   138        
   139         try:
   140             # get a proper browsing VM
   141             Cygwin.start_X11()
   142 
   143             # TODO: HARDCODED ADDRESS OF OPENSECURITYD
   144             proxy_support = urllib2.ProxyHandler({})
   145             opener = urllib2.build_opener(proxy_support)
   146             urllib2.install_opener(opener)
   147 
   148             req_data = ""
   149             proxy = self.getProxySettings()
   150             if proxy:
   151                 req_data = '?' + urllib.urlencode(proxy) 
   152             req = 'http://127.0.0.1:8080/browsing'+ req_data
   153             browsing_vm = urllib2.urlopen(req).readline()
   154             print('Called '+ req + ' got: ' + str(browsing_vm))
   155         except:
   156             QtGui.QApplication.instance().processEvents()
   157             QtGui.QMessageBox.critical(None, 'Failed to invoke Safe Internet Browsing', 'OpenSecurity Error')
   158             
   159         QtGui.QApplication.instance().processEvents()
   160             
   161             
   162     def clicked_configure(self):
   163         """clicked configure"""
   164         d = ConfigureDialog()
   165         d.exec_()
   166     
   167 
   168     def clicked_exit(self):
   169         """clicked exit"""
   170         opensecurity_client_restful_server.stop()
   171         sys.exit(0)
   172     
   173 
   174     def clicked_launch_application(self):
   175         """clicked the launch an application"""
   176         dlg_launch_image = os.path.join(sys.path[0], 'ui', 'launch_dialog.py')
   177         process_command = [sys.executable, dlg_launch_image]
   178         process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
   179         try:
   180             stdout = process.communicate()[0]
   181             j = json.loads(stdout)
   182         except:
   183             return
   184 
   185         try:
   186         
   187             # get a proper browsing VM
   188             Cygwin.start_X11()
   189 
   190             # TODO: HARDCODED ADDRESS OF OPENSECURITYD
   191             url = 'http://127.0.0.1:8080/sdvms/' + j['vm'] + '/application' + j['application']
   192             result = urllib2.urlopen(url).readline()
   193             
   194         except:
   195             pass 
   196             
   197             
   198     def clicked_mail(self):
   199         
   200         """clicked mail"""
   201         address = 'feedback@opensecurity.at'
   202         subject = 'Feedback zu OpenSecurity V' + opensecurity.__version__
   203 
   204         if sys.platform == 'linux2':
   205             subprocess.Popen(['xdg-email', '--subject', subject, address])
   206         elif sys.platform == 'win32' or sys.platform == 'cygwin':
   207             mail_url = 'mailto:' + urllib.quote(address, '@') + '?' + urllib.quote('subject=' + subject)
   208             subprocess.Popen(['cmd', '/C', 'start', mail_url])
   209    
   210 
   211     def format_drive(self):
   212 
   213         """format drive clicked (the sender should a QAction created with refresh_format_menu)"""
   214         try:
   215 
   216             # fiddle the IP of the VM controlling the VM
   217             s = self.sender()
   218             ip = str(s.text().split('\\\\')[1])
   219 
   220             # invoke the format drive dialog
   221             dlg_format_drive = os.path.join(sys.path[0], 'ui', 'format_drive_dialog.py')
   222             process_command = [sys.executable, dlg_format_drive, ip]
   223             process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
   224 
   225             stdout = process.communicate()[0]
   226 
   227         except:
   228             pass
   229 
   230 
   231     def refresh_format_menu(self):
   232 
   233         """create a new list of format 'drives'"""
   234         self._menu_format.clear()
   235         a = self._menu_format.addAction('<No Drive given>')
   236         a.setEnabled(False)
   237 
   238         try:
   239 
   240             # get machines
   241             machines = json.load(urllib2.urlopen('http://127.0.0.1:8080/sdvms'))
   242             if len(machines) == 0:
   243                 return
   244 
   245             self._icon_network = QtGui.QIcon()
   246             self._icon_network.addPixmap(QtGui.QPixmap(":/opensecurity/gfx/network-workgroup.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   247 
   248             self._menu_format.clear()
   249             for m in machines:
   250                 if u'SecurityDVM0' in m:
   251                     continue
   252                 a = self._menu_format.addAction(m + '\\\\' + machines[m])
   253                 a.setIcon(self._icon_network)
   254                 a.triggered.connect(self.format_drive)
   255 
   256         except:
   257             pass
   258 
   259 
   260     def setup_ui(self):
   261         """create the user interface
   262         As for the system tray this is 'just' the context menu.
   263         """
   264     
   265         # define the tray icon menu
   266         menu = QtGui.QMenu(self.parent())
   267         self.setContextMenu(menu)
   268         
   269         # add known apps
   270         self.acBrowser = QtGui.QAction('Secure Browsing', self.parent())
   271         icon = QtGui.QIcon()
   272         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_browsing_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   273         self.acBrowser.setIcon(icon)
   274         menu.addAction(self.acBrowser)
   275         menu.addSeparator()
   276         
   277         # add standard menu items
   278         self.acLaunch = QtGui.QAction('Launch Application', self.parent())
   279         icon = QtGui.QIcon()
   280         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_launch_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   281         self.acLaunch.setIcon(icon)
   282         menu.addAction(self.acLaunch)
   283         self.acConfigure = QtGui.QAction('Configuration', self.parent())
   284         icon = QtGui.QIcon()
   285         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_configure_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   286         self.acConfigure.setIcon(icon)
   287         menu.addAction(self.acConfigure)
   288         menu.addSeparator()
   289 
   290         self._menu_format = menu.addMenu('Format')
   291         menu.addSeparator()
   292 
   293         self.acMail = menu.addAction('Send feedback mail')
   294         icon = QtGui.QIcon()
   295         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_mail_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   296         self.acMail.setIcon(icon)
   297         self.acAbout = menu.addAction('About')
   298         self.acExit = menu.addAction('Exit')
   299        
   300         self.acBrowser.triggered.connect(self.clicked_browser)
   301         self.acLaunch.triggered.connect(self.clicked_launch_application)
   302         self.acConfigure.triggered.connect(self.clicked_configure)
   303         self.acAbout.triggered.connect(self.clicked_about)
   304         self.acExit.triggered.connect(self.clicked_exit)
   305         self.acMail.triggered.connect(self.clicked_mail)
   306         
   307 
   308 def main():
   309     
   310     # parse arguments
   311     parser = argparse.ArgumentParser(description = 'OpenSecurity Tray Icon.')
   312     parser.add_argument('-p', '--port', type=int, default=8090, help='port number of the REST API this instance will listen on.')
   313     args = parser.parse_args()
   314 
   315     # get up Qt
   316     a = QtGui.QApplication(sys.argv)
   317 
   318     # enforce singelton process
   319     if opensecurity_client_restful_server.is_already_running(args.port):
   320         QtGui.QMessageBox.critical(None, 'OpenSecurity Error', 'OpenSecurity Tray Instance already launched.\nClose previous instance first.')
   321         sys.exit(1)
   322 
   323     # start serving
   324     opensecurity_client_restful_server.serve(args.port, True)
   325 
   326     # init tray icon widget
   327     w = QtGui.QWidget()
   328     icon = QtGui.QIcon()
   329     icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   330     trayIcon = OpenSecurityTrayIcon(icon)
   331     opensecurity_client_restful_server.tray_icon = trayIcon
   332 
   333     # go!
   334     trayIcon.show()
   335     a.setQuitOnLastWindowClosed(False)
   336     sys.exit(a.exec_())
   337    
   338 
   339 # start
   340 if __name__ == "__main__":
   341     main()
   342