OpenSecurity/bin/opensecurity_tray.pyw
author Bartha Mihai <mihai.bartha@ait.ac.at>
Fri, 07 Nov 2014 16:24:10 +0100
changeset 245 727367d7f395
parent 240 d7ef04254e9c
child 246 49efb610d200
permissions -rwxr-xr-x
fix for 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 
   245         except:
   246             pass
   247 
   248 
   249     def setup_ui(self):
   250         """create the user interface
   251         As for the system tray this is 'just' the context menu.
   252         """
   253     
   254         # define the tray icon menu
   255         menu = QtGui.QMenu(self.parent())
   256         self.setContextMenu(menu)
   257         
   258         # add known apps
   259         self.acBrowser = QtGui.QAction('Secure Browsing', self.parent())
   260         icon = QtGui.QIcon()
   261         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_browsing_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   262         self.acBrowser.setIcon(icon)
   263         menu.addAction(self.acBrowser)
   264         menu.addSeparator()
   265         
   266         # add standard menu items
   267         self.acLaunch = QtGui.QAction('Launch Application', self.parent())
   268         icon = QtGui.QIcon()
   269         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_launch_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   270         self.acLaunch.setIcon(icon)
   271         menu.addAction(self.acLaunch)
   272         self.acConfigure = QtGui.QAction('Configuration', self.parent())
   273         icon = QtGui.QIcon()
   274         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_configure_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   275         self.acConfigure.setIcon(icon)
   276         menu.addAction(self.acConfigure)
   277         menu.addSeparator()
   278 
   279         self._menu_format = menu.addMenu('Format')
   280         menu.addSeparator()
   281 
   282         self.acMail = menu.addAction('Send feedback mail')
   283         icon = QtGui.QIcon()
   284         icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(':/opensecurity/gfx/opensecurity_mail_64.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   285         self.acMail.setIcon(icon)
   286         self.acAbout = menu.addAction('About')
   287         
   288         # diabled as of TICKET #11
   289         # self.acExit = menu.addAction('Exit')
   290        
   291         self.acBrowser.triggered.connect(self.clicked_browser)
   292         self.acLaunch.triggered.connect(self.clicked_launch_application)
   293         self.acConfigure.triggered.connect(self.clicked_configure)
   294         self.acAbout.triggered.connect(self.clicked_about)
   295 
   296         # disabled as for TICKET #11
   297         # self.acExit.triggered.connect(self.clicked_exit)
   298         self.acMail.triggered.connect(self.clicked_mail)
   299         
   300 
   301 def main():
   302     
   303     # parse arguments
   304     parser = argparse.ArgumentParser(description = 'OpenSecurity Tray Icon.')
   305     parser.add_argument('-p', '--port', type=int, default=8090, help='port number of the REST API this instance will listen on.')
   306     args = parser.parse_args()
   307 
   308     # get up Qt
   309     a = QtGui.QApplication(sys.argv)
   310 
   311     # enforce singelton process
   312     if opensecurity_client_restful_server.is_already_running(args.port):
   313         QtGui.QMessageBox.critical(None, 'OpenSecurity Error', 'OpenSecurity Tray Instance already launched.\nClose previous instance first.')
   314         sys.exit(1)
   315 
   316     # start serving
   317     opensecurity_client_restful_server.serve(args.port, True)
   318 
   319     # init tray icon widget
   320     w = QtGui.QWidget()
   321     icon = QtGui.QIcon()
   322     icon.addPixmap(QtGui.QPixmap(QtCore.QString.fromUtf8(":/opensecurity/gfx/opensecurity_icon_64.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
   323     trayIcon = OpenSecurityTrayIcon(icon)
   324     opensecurity_client_restful_server.tray_icon = trayIcon
   325 
   326     # go!
   327     trayIcon.show()
   328     a.setQuitOnLastWindowClosed(False)
   329     sys.exit(a.exec_())
   330    
   331 
   332 # start
   333 if __name__ == "__main__":
   334     main()
   335