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