OpenSecurity/bin/opensecurity_tray.pyw
author BarthaM@N3SIM1218.D03.arc.local
Wed, 24 Sep 2014 16:40:43 +0100
changeset 223 a4fb6694e6fe
parent 215 9d777587cdab
child 234 216da9017f8f
permissions -rwxr-xr-x
Added WPAD proxy support.
Not fully tested
     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 'AutoConfigURL' in reg_entries.keys():
   124             return {'ProxyAutoConfigURL': reg_entries['AutoConfigURL']}
   125 
   126         if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1:
   127             proxy_search = re.search(r"(?<=http=)(?P<ProxyServer>.*?)(?=;)", reg_entries['ProxyServer'])
   128             if proxy_search:
   129                 proxies = proxy_search.groupdict()
   130                 if 'ProxyServer' in proxies.keys(): # found http proxy
   131                     return {'ProxyServer': proxies['ProxyServer']}  
   132             return {'ProxyServer': reg_entries['ProxyServer']}
   133             
   134         return None
   135 
   136     def clicked_browser(self):
   137         """wish for safe internet browsing"""
   138         
   139         if not (sys.platform == 'win32' or sys.platform == 'cygwin'):
   140             QtGui.QMessageBox.critical(self.parent(), 'OpenSecurity Error', 'This action is not supported on this platform.\nSorry.')
   141             return
   142        
   143         try:
   144             # get a proper browsing VM
   145             Cygwin.start_X11()
   146 
   147             # TODO: HARDCODED ADDRESS OF OPENSECURITYD
   148             proxy_support = urllib2.ProxyHandler({})
   149             opener = urllib2.build_opener(proxy_support)
   150             urllib2.install_opener(opener)
   151 
   152             req_data = ""
   153             proxy = self.getProxySettings()
   154             if proxy:
   155                 req_data = '?' + urllib.urlencode(proxy) 
   156             req = 'http://127.0.0.1:8080/browsing'+ req_data
   157             browsing_vm = urllib2.urlopen(req).readline()
   158             print('Called '+ req + ' got: ' + str(browsing_vm))
   159         except:
   160             QtGui.QApplication.instance().processEvents()
   161             QtGui.QMessageBox.critical(None, 'Failed to invoke Safe Internet Browsing', 'OpenSecurity Error')
   162             
   163         QtGui.QApplication.instance().processEvents()
   164             
   165             
   166     def clicked_configure(self):
   167         """clicked configure"""
   168         d = ConfigureDialog()
   169         d.exec_()
   170     
   171 
   172     def clicked_exit(self):
   173         """clicked exit"""
   174         opensecurity_client_restful_server.stop()
   175         sys.exit(0)
   176     
   177 
   178     def clicked_launch_application(self):
   179         """clicked the launch an application"""
   180         dlg_launch_image = os.path.join(sys.path[0], 'ui', 'launch_dialog.py')
   181         process_command = [sys.executable, dlg_launch_image]
   182         process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
   183         try:
   184             stdout = process.communicate()[0]
   185             j = json.loads(stdout)
   186         except:
   187             return
   188 
   189         try:
   190         
   191             # get a proper browsing VM
   192             Cygwin.start_X11()
   193 
   194             # TODO: HARDCODED ADDRESS OF OPENSECURITYD
   195             url = 'http://127.0.0.1:8080/sdvms/' + j['vm'] + '/application' + j['application']
   196             result = urllib2.urlopen(url).readline()
   197             
   198         except:
   199             pass 
   200             
   201             
   202     def clicked_mail(self):
   203         
   204         """clicked mail"""
   205         address = 'feedback@opensecurity.at'
   206         subject = 'Feedback zu OpenSecurity V' + opensecurity.__version__
   207 
   208         if sys.platform == 'linux2':
   209             subprocess.Popen(['xdg-email', '--subject', subject, address])
   210         elif sys.platform == 'win32' or sys.platform == 'cygwin':
   211             mail_url = 'mailto:' + urllib.quote(address, '@') + '?' + urllib.quote('subject=' + subject)
   212             subprocess.Popen(['cmd', '/C', 'start', mail_url])
   213    
   214 
   215     def format_drive(self):
   216 
   217         """format drive clicked (the sender should a QAction created with refresh_format_menu)"""
   218         try:
   219 
   220             # fiddle the IP of the VM controlling the VM
   221             s = self.sender()
   222             ip = str(s.text().split('\\\\')[1])
   223 
   224             # invoke the format drive dialog
   225             dlg_format_drive = os.path.join(sys.path[0], 'ui', 'format_drive_dialog.py')
   226             process_command = [sys.executable, dlg_format_drive, ip]
   227             process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
   228 
   229             stdout = process.communicate()[0]
   230 
   231         except:
   232             pass
   233 
   234 
   235     def refresh_format_menu(self):
   236 
   237         """create a new list of format 'drives'"""
   238         self._menu_format.clear()
   239         a = self._menu_format.addAction('<No Drive given>')
   240         a.setEnabled(False)
   241 
   242         try:
   243 
   244             # get machines
   245             machines = json.load(urllib2.urlopen('http://127.0.0.1:8080/sdvms'))
   246             if len(machines) == 0:
   247                 return
   248 
   249             self._icon_network = QtGui.QIcon()
   250             self._icon_network.addPixmap(QtGui.QPixmap(":/opensecurity/gfx/network-workgroup.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   251 
   252             cleared = False
   253             for m in machines:
   254 
   255                 # do not insert Browsing VM
   256                 if u'SecurityDVM0' in m:
   257                     continue
   258 
   259                 if not cleared:
   260                     self._menu_format.clear()
   261                     cleared = True
   262 
   263                 a = self._menu_format.addAction(m + '\\\\' + machines[m])
   264                 a.setIcon(self._icon_network)
   265                 a.triggered.connect(self.format_drive)
   266 
   267         except:
   268             pass
   269 
   270 
   271     def setup_ui(self):
   272         """create the user interface
   273         As for the system tray this is 'just' the context menu.
   274         """
   275     
   276         # define the tray icon menu
   277         menu = QtGui.QMenu(self.parent())
   278         self.setContextMenu(menu)
   279         
   280         # add known apps
   281         self.acBrowser = QtGui.QAction('Secure Browsing', self.parent())
   282         icon = QtGui.QIcon()
   283         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_browsing_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   284         self.acBrowser.setIcon(icon)
   285         menu.addAction(self.acBrowser)
   286         menu.addSeparator()
   287         
   288         # add standard menu items
   289         self.acLaunch = QtGui.QAction('Launch Application', self.parent())
   290         icon = QtGui.QIcon()
   291         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_launch_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   292         self.acLaunch.setIcon(icon)
   293         menu.addAction(self.acLaunch)
   294         self.acConfigure = QtGui.QAction('Configuration', self.parent())
   295         icon = QtGui.QIcon()
   296         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_configure_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   297         self.acConfigure.setIcon(icon)
   298         menu.addAction(self.acConfigure)
   299         menu.addSeparator()
   300 
   301         self._menu_format = menu.addMenu('Format')
   302         menu.addSeparator()
   303 
   304         self.acMail = menu.addAction('Send feedback mail')
   305         icon = QtGui.QIcon()
   306         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_mail_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   307         self.acMail.setIcon(icon)
   308         self.acAbout = menu.addAction('About')
   309         
   310         # diabled as of TICKET #11
   311         # self.acExit = menu.addAction('Exit')
   312        
   313         self.acBrowser.triggered.connect(self.clicked_browser)
   314         self.acLaunch.triggered.connect(self.clicked_launch_application)
   315         self.acConfigure.triggered.connect(self.clicked_configure)
   316         self.acAbout.triggered.connect(self.clicked_about)
   317 
   318         # disabled as for TICKET #11
   319         # self.acExit.triggered.connect(self.clicked_exit)
   320         self.acMail.triggered.connect(self.clicked_mail)
   321         
   322 
   323 def main():
   324     
   325     # parse arguments
   326     parser = argparse.ArgumentParser(description = 'OpenSecurity Tray Icon.')
   327     parser.add_argument('-p', '--port', type=int, default=8090, help='port number of the REST API this instance will listen on.')
   328     args = parser.parse_args()
   329 
   330     # get up Qt
   331     a = QtGui.QApplication(sys.argv)
   332 
   333     # enforce singelton process
   334     if opensecurity_client_restful_server.is_already_running(args.port):
   335         QtGui.QMessageBox.critical(None, 'OpenSecurity Error', 'OpenSecurity Tray Instance already launched.\nClose previous instance first.')
   336         sys.exit(1)
   337 
   338     # start serving
   339     opensecurity_client_restful_server.serve(args.port, True)
   340 
   341     # init tray icon widget
   342     w = QtGui.QWidget()
   343     icon = QtGui.QIcon()
   344     icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   345     trayIcon = OpenSecurityTrayIcon(icon)
   346     opensecurity_client_restful_server.tray_icon = trayIcon
   347 
   348     # go!
   349     trayIcon.show()
   350     a.setQuitOnLastWindowClosed(False)
   351     sys.exit(a.exec_())
   352    
   353 
   354 # start
   355 if __name__ == "__main__":
   356     main()
   357