OpenSecurity/bin/opensecurity_tray.pyw
author BarthaM@N3SIM1218.D03.arc.local
Thu, 02 Oct 2014 13:08:09 +0100
changeset 234 216da9017f8f
parent 223 a4fb6694e6fe
child 238 d33edf5c2717
permissions -rwxr-xr-x
- changed opensecurity to always hold at least 2 SDVM sessions to be ready when needed
- added automatic wpad proxy detection
     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 
    43 from PyQt4 import QtCore
    44 from PyQt4 import QtGui
    45 
    46 # local
    47 import __init__ as opensecurity
    48 
    49 if sys.platform == 'win32' or sys.platform == 'cygwin':
    50     from cygwin import Cygwin
    51 
    52 import opensecurity_client_restful_server 
    53 import proxy_getter
    54 from ui import AboutDialog
    55 from ui import ConfigureDialog
    56 from ui import opensecurity_rc
    57 
    58 # ------------------------------------------------------------
    59 # code
    60 
    61 
    62 class OpenSecurityWait(QtGui.QDialog):
    63 
    64     """OpenSecurity: please wait ..."""
    65     
    66     def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags(0)):
    67         super(OpenSecurityWait, self).__init__(parent, flags)
    68         self.setWindowTitle('OpenSecurity')
    69         self.setup_ui()
    70         
    71         
    72     def setup_ui(self):
    73         """Create the widgets."""
    74         
    75         lyMain = QtGui.QVBoxLayout(self)
    76         lyMain.setContentsMargins(8, 8, 8, 8)
    77         
    78         # content area: left pixmap, right text
    79         lbTitle = QtGui.QLabel('Creating secure subsystem. Please stand by ...')
    80         lyMain.addWidget(lbTitle)
    81         
    82         self.setMinimumSize(400, 50)
    83         self.resize(lyMain.minimumSize())
    84 
    85 
    86 class OpenSecurityTrayIcon(QtGui.QSystemTrayIcon):
    87     
    88     """This is the OpenSecuirty Tray Icon"""
    89 
    90     def __init__(self, icon, parent=None):
    91         
    92         super(OpenSecurityTrayIcon, self).__init__(icon, parent)
    93         self.setup_ui()
    94         self.activated.connect(self.activated_)
    95        
    96 
    97     def activated_(self, reason):
    98 
    99         """the system tray icon was activated"""
   100         self.refresh_format_menu()
   101 
   102         
   103     def clicked_about(self):
   104         """clicked about"""
   105         d = AboutDialog()
   106         d.exec_()
   107 
   108     def clicked_browser(self):
   109         """wish for safe internet browsing"""
   110         
   111         if not (sys.platform == 'win32' or sys.platform == 'cygwin'):
   112             QtGui.QMessageBox.critical(self.parent(), 'OpenSecurity Error', 'This action is not supported on this platform.\nSorry.')
   113             return
   114        
   115         try:
   116             # get a proper browsing VM
   117             Cygwin.start_X11()
   118 
   119             # TODO: HARDCODED ADDRESS OF OPENSECURITYD
   120             proxy_support = urllib2.ProxyHandler({})
   121             opener = urllib2.build_opener(proxy_support)
   122             urllib2.install_opener(opener)
   123 
   124             req_data = ""
   125             proxy = proxy_getter.getProxySettings()
   126             if proxy:
   127                 req_data = '?' + urllib.urlencode(proxy) 
   128             req = 'http://127.0.0.1:8080/browsing'+ req_data
   129             browsing_vm = urllib2.urlopen(req).readline()
   130             print('Called '+ req + ' got: ' + str(browsing_vm))
   131         except:
   132             QtGui.QApplication.instance().processEvents()
   133             QtGui.QMessageBox.critical(None, 'Failed to invoke Safe Internet Browsing', 'OpenSecurity Error')
   134             
   135         QtGui.QApplication.instance().processEvents()
   136             
   137             
   138     def clicked_configure(self):
   139         """clicked configure"""
   140         d = ConfigureDialog()
   141         d.exec_()
   142     
   143 
   144     def clicked_exit(self):
   145         """clicked exit"""
   146         opensecurity_client_restful_server.stop()
   147         sys.exit(0)
   148     
   149 
   150     def clicked_launch_application(self):
   151         """clicked the launch an application"""
   152         dlg_launch_image = os.path.join(sys.path[0], 'ui', 'launch_dialog.py')
   153         process_command = [sys.executable, dlg_launch_image]
   154         process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
   155         try:
   156             stdout = process.communicate()[0]
   157             j = json.loads(stdout)
   158         except:
   159             return
   160 
   161         try:
   162             # get a proper browsing VM
   163             Cygwin.start_X11()
   164             # TODO: HARDCODED ADDRESS OF OPENSECURITYD
   165             url = 'http://127.0.0.1:8080/sdvms/' + j['vm'] + '/application' + j['application']
   166             result = urllib2.urlopen(url).readline()
   167         except:
   168             pass 
   169             
   170             
   171     def clicked_mail(self):
   172         
   173         """clicked mail"""
   174         address = 'feedback@opensecurity.at'
   175         subject = 'Feedback zu OpenSecurity V' + opensecurity.__version__
   176 
   177         if sys.platform == 'linux2':
   178             subprocess.Popen(['xdg-email', '--subject', subject, address])
   179         elif sys.platform == 'win32' or sys.platform == 'cygwin':
   180             mail_url = 'mailto:' + urllib.quote(address, '@') + '?' + urllib.quote('subject=' + subject)
   181             subprocess.Popen(['cmd', '/C', 'start', mail_url])
   182    
   183 
   184     def format_drive(self):
   185 
   186         """format drive clicked (the sender should a QAction created with refresh_format_menu)"""
   187         try:
   188 
   189             # fiddle the IP of the VM controlling the VM
   190             s = self.sender()
   191             ip = str(s.text().split('\\\\')[1])
   192 
   193             # invoke the format drive dialog
   194             dlg_format_drive = os.path.join(sys.path[0], 'ui', 'format_drive_dialog.py')
   195             process_command = [sys.executable, dlg_format_drive, ip]
   196             process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)        
   197 
   198             stdout = process.communicate()[0]
   199 
   200         except:
   201             pass
   202 
   203 
   204     def refresh_format_menu(self):
   205 
   206         """create a new list of format 'drives'"""
   207         self._menu_format.clear()
   208         a = self._menu_format.addAction('<No Drive given>')
   209         a.setEnabled(False)
   210 
   211         try:
   212 
   213             # get machines
   214             machines = json.load(urllib2.urlopen('http://127.0.0.1:8080/sdvms'))
   215             if len(machines) == 0:
   216                 return
   217 
   218             self._icon_network = QtGui.QIcon()
   219             self._icon_network.addPixmap(QtGui.QPixmap(":/opensecurity/gfx/network-workgroup.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   220 
   221             cleared = False
   222             for m in machines:
   223 
   224                 # do not insert Browsing VM
   225                 if u'SecurityDVM0' in m:
   226                     continue
   227 
   228                 if not cleared:
   229                     self._menu_format.clear()
   230                     cleared = True
   231 
   232                 a = self._menu_format.addAction(m + '\\\\' + machines[m])
   233                 a.setIcon(self._icon_network)
   234                 a.triggered.connect(self.format_drive)
   235 
   236         except:
   237             pass
   238 
   239 
   240     def setup_ui(self):
   241         """create the user interface
   242         As for the system tray this is 'just' the context menu.
   243         """
   244     
   245         # define the tray icon menu
   246         menu = QtGui.QMenu(self.parent())
   247         self.setContextMenu(menu)
   248         
   249         # add known apps
   250         self.acBrowser = QtGui.QAction('Secure Browsing', self.parent())
   251         icon = QtGui.QIcon()
   252         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_browsing_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   253         self.acBrowser.setIcon(icon)
   254         menu.addAction(self.acBrowser)
   255         menu.addSeparator()
   256         
   257         # add standard menu items
   258         self.acLaunch = QtGui.QAction('Launch Application', self.parent())
   259         icon = QtGui.QIcon()
   260         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_launch_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   261         self.acLaunch.setIcon(icon)
   262         menu.addAction(self.acLaunch)
   263         self.acConfigure = QtGui.QAction('Configuration', self.parent())
   264         icon = QtGui.QIcon()
   265         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_configure_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   266         self.acConfigure.setIcon(icon)
   267         menu.addAction(self.acConfigure)
   268         menu.addSeparator()
   269 
   270         self._menu_format = menu.addMenu('Format')
   271         menu.addSeparator()
   272 
   273         self.acMail = menu.addAction('Send feedback mail')
   274         icon = QtGui.QIcon()
   275         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_mail_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   276         self.acMail.setIcon(icon)
   277         self.acAbout = menu.addAction('About')
   278         
   279         # diabled as of TICKET #11
   280         # self.acExit = menu.addAction('Exit')
   281        
   282         self.acBrowser.triggered.connect(self.clicked_browser)
   283         self.acLaunch.triggered.connect(self.clicked_launch_application)
   284         self.acConfigure.triggered.connect(self.clicked_configure)
   285         self.acAbout.triggered.connect(self.clicked_about)
   286 
   287         # disabled as for TICKET #11
   288         # self.acExit.triggered.connect(self.clicked_exit)
   289         self.acMail.triggered.connect(self.clicked_mail)
   290         
   291 
   292 def main():
   293     
   294     # parse arguments
   295     parser = argparse.ArgumentParser(description = 'OpenSecurity Tray Icon.')
   296     parser.add_argument('-p', '--port', type=int, default=8090, help='port number of the REST API this instance will listen on.')
   297     args = parser.parse_args()
   298 
   299     # get up Qt
   300     a = QtGui.QApplication(sys.argv)
   301 
   302     # enforce singelton process
   303     if opensecurity_client_restful_server.is_already_running(args.port):
   304         QtGui.QMessageBox.critical(None, 'OpenSecurity Error', 'OpenSecurity Tray Instance already launched.\nClose previous instance first.')
   305         sys.exit(1)
   306 
   307     # start serving
   308     opensecurity_client_restful_server.serve(args.port, True)
   309 
   310     # init tray icon widget
   311     w = QtGui.QWidget()
   312     icon = QtGui.QIcon()
   313     icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   314     trayIcon = OpenSecurityTrayIcon(icon)
   315     opensecurity_client_restful_server.tray_icon = trayIcon
   316 
   317     # go!
   318     trayIcon.show()
   319     a.setQuitOnLastWindowClosed(False)
   320     sys.exit(a.exec_())
   321    
   322 
   323 # start
   324 if __name__ == "__main__":
   325     main()
   326