OpenSecurity/bin/opensecurity_client_restful_server.py
changeset 176 32c895509a2a
parent 168 76267df09d71
child 177 269e73c34b20
child 178 e0c11d73a10c
     1.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py	Thu May 22 11:38:21 2014 +0200
     1.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py	Wed Jun 04 16:42:37 2014 +0100
     1.3 @@ -52,6 +52,9 @@
     1.4  import string
     1.5  import win32api
     1.6  import win32con
     1.7 +import win32wnet
     1.8 +import itertools
     1.9 +import ctypes
    1.10  
    1.11  from opensecurity_util import logger, setupLogger, OpenSecurityException
    1.12  if sys.platform == 'win32' or sys.platform == 'cygwin':
    1.13 @@ -75,6 +78,7 @@
    1.14      '/password',                'os_password',
    1.15      '/netmount',                'os_netmount',
    1.16      '/netumount',               'os_netumount',
    1.17 +    '/netcleanup',              'os_netcleanup',
    1.18      '/',                        'os_root'
    1.19  )
    1.20  
    1.21 @@ -258,20 +262,54 @@
    1.22          
    1.23          return 'user queried for password'
    1.24  
    1.25 +def genNetworkDrive():
    1.26 +    logical_drives = getLogicalDrives()
    1.27 +    logger.info("Used logical drive letters: "+ str(logical_drives).strip('[]') )
    1.28 +    drives = list(map(chr, range(68, 91)))  
    1.29 +    for drive in drives:
    1.30 +        if drive not in logical_drives:
    1.31 +            return drive
    1.32 +    return None
    1.33 +            
    1.34 +def getLogicalDrives():
    1.35 +    drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
    1.36 +    drives = list(itertools.compress(string.ascii_uppercase,  map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
    1.37 +    return drives
    1.38 +
    1.39 +def getNetworkPath(drive):
    1.40 +    return win32wnet.WNetGetConnection(drive+':')
    1.41 +
    1.42 +def getDriveType(drive):
    1.43 +    return ctypes.cdll.kernel32.GetDriveTypeW(u"%s:\\"%drive)
    1.44 +        
    1.45 +def getNetworkDrive(path):
    1.46 +    for drive in getLogicalDrives():
    1.47 +        #if is a network drive
    1.48 +        if getDriveType(drive) == 4:
    1.49 +            network_path = getNetworkPath(drive)
    1.50 +            if path in network_path:
    1.51 +                return drive
    1.52 +    return None
    1.53 +
    1.54  # handles netumount request                    
    1.55  class MountNetworkDriveHandler(threading.Thread): 
    1.56 -    drive = None
    1.57 -    resource = None
    1.58 -    
    1.59 -    def __init__(self, drv, net_path):
    1.60 +    networkPath = None
    1.61 +    def __init__(self, net_path):
    1.62          threading.Thread.__init__(self)
    1.63 -        self.drive = drv
    1.64          self.networkPath = net_path
    1.65      
    1.66      def run(self):
    1.67 +        drive = genNetworkDrive()
    1.68 +        if not drive:
    1.69 +            logger.error("Failed to assign drive letter for: " + self.networkPath)
    1.70 +            return 1
    1.71 +        else:
    1.72 +            logger.info("Assigned drive " + drive + " to " + self.networkPath)
    1.73 +        
    1.74          #Check for drive availability
    1.75 -        if os.path.exists(self.drive):
    1.76 -            logger.error("Drive letter is already in use: " + self.drive)
    1.77 +        drive = drive+':'
    1.78 +        if os.path.exists(drive):
    1.79 +            logger.error("Drive letter is already in use: " + drive)
    1.80              return 1
    1.81          
    1.82          #Check for network resource availability
    1.83 @@ -283,7 +321,7 @@
    1.84              logger.info("Path not accessible: " + self.networkPath + " retrying")
    1.85              retry-=1
    1.86      
    1.87 -        command = 'USE ' + self.drive + ' ' + self.networkPath + ' /PERSISTENT:NO'
    1.88 +        command = 'USE ' + drive + ' ' + self.networkPath + ' /PERSISTENT:NO'
    1.89      
    1.90          result = Cygwin.checkResult(Cygwin.execute('C:\\Windows\\system32\\NET', command))
    1.91          if string.find(result[1], 'successfully',) == -1:
    1.92 @@ -303,41 +341,30 @@
    1.93          if not "net_resource" in args:
    1.94              raise web.badrequest('no net_resource given')
    1.95          
    1.96 -        # we _need_ a drive_letter
    1.97 -        if not "drive_letter" in args:
    1.98 -            raise web.badrequest('no drive_letter given')
    1.99 -
   1.100 -        driveHandler = MountNetworkDriveHandler(args['drive_letter'], args['net_resource'])
   1.101 +        driveHandler = MountNetworkDriveHandler(args['net_resource'])
   1.102          driveHandler.start()
   1.103          driveHandler.join(None)
   1.104          return 'Ok'
   1.105 -
   1.106 -         
   1.107          
   1.108  # handles netumount request                    
   1.109  class UmountNetworkDriveHandler(threading.Thread): 
   1.110 -    drive = None
   1.111 +    networkPath = None
   1.112      running = True
   1.113      
   1.114 -    def __init__(self, drv):
   1.115 +    def __init__(self, path):
   1.116          threading.Thread.__init__(self)
   1.117 -        self.drive = drv
   1.118 +        self.networkPath = path
   1.119  
   1.120      def run(self):
   1.121          while self.running:
   1.122 -            result = Cygwin.checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
   1.123 -            mappedDrives = list()
   1.124 -            for line in result[1].splitlines():
   1.125 -                if 'USB' in line or 'Download' in line:
   1.126 -                    parts = line.split()
   1.127 -                    mappedDrives.append(parts[1])
   1.128 -            
   1.129 -            logger.info(mappedDrives)
   1.130 -            logger.info(self.drive)
   1.131 -            if self.drive not in mappedDrives:
   1.132 +            drive = getNetworkDrive(self.networkPath)
   1.133 +            if not drive:
   1.134 +                logger.info("Failed to retrieve drive letter for: " + self.networkPath + ". Successfully deleted or missing.")
   1.135                  self.running = False
   1.136              else:
   1.137 -                command = 'USE ' + self.drive + ' /DELETE /YES' 
   1.138 +                drive = drive+':'
   1.139 +                logger.info("Unmounting drive " + drive + " for " + self.networkPath)
   1.140 +                command = 'USE ' + drive + ' /DELETE /YES' 
   1.141                  result = Cygwin.checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', command)) 
   1.142                  if string.find(str(result[1]), 'successfully',) == -1:
   1.143                      logger.error(result[2])
   1.144 @@ -352,15 +379,38 @@
   1.145          # pick the arguments
   1.146          args = web.input()
   1.147          
   1.148 -        # we _need_ a drive_letter
   1.149 -        if not "drive_letter" in args:
   1.150 -            raise web.badrequest('no drive_letter given')
   1.151 +        # we _need_ a net_resource
   1.152 +        if not "net_resource" in args:
   1.153 +            raise web.badrequest('no net_resource given')
   1.154          
   1.155 -        driveHandler = UmountNetworkDriveHandler(args['drive_letter'])
   1.156 +        driveHandler = UmountNetworkDriveHandler(args['net_resource'])
   1.157          driveHandler.start()
   1.158          driveHandler.join(None)
   1.159          return 'Ok'
   1.160 +
   1.161 +class os_netcleanup:
   1.162      
   1.163 +    """OpenSecurity '/netcleanup' handler"""
   1.164 +    
   1.165 +    def GET(self):
   1.166 +        # pick the arguments
   1.167 +        args = web.input()
   1.168 +        
   1.169 +        # we _need_ a net_resource
   1.170 +        if not "hostonly_ip" in args:
   1.171 +            raise web.badrequest('no net_resource given')
   1.172 +        
   1.173 +        ip = args['hostonly_ip']
   1.174 +        ip = ip[:ip.rindex('.')]
   1.175 +        drives = getLogicalDrives()
   1.176 +        for drive in drives:
   1.177 +            # found network drive
   1.178 +            if getDriveType(drive) == 4:
   1.179 +                path = getNetworkPath(drive)
   1.180 +                if ip in path:
   1.181 +                    driveHandler = UmountNetworkDriveHandler(path)
   1.182 +                    driveHandler.start()
   1.183 +                    driveHandler.join(None)
   1.184  
   1.185  class os_root:
   1.186