예제 #1
0
 def testComparable(self):
     overlapped = pywintypes.OVERLAPPED()
     self.assertEqual(overlapped, overlapped)
     # ensure we explicitly test the operators.
     self.assertTrue(overlapped == overlapped)
     self.assertFalse(overlapped != overlapped)
 def testHashable(self):
     overlapped = pywintypes.OVERLAPPED()
     d = {}
     d[overlapped] = "hello"
     self.failUnlessEqual(d[overlapped], "hello")
예제 #3
0
    def log(self,
            level,
            message,
            raiseException=False,
            formatArgs=[],
            formatKwargs={}):
        '''
		Log a message with the given level.

		:param level: The log level of this message.
		:param message: The message to log.
		:param raiseException: True raises an exception if any error occurs. \
False suppresses exceptions.
		:type raiseException: bool
		'''
        if (level > self.__messageSubjectLevel and level > self.__consoleLevel
                and level > self.__fileLevel and level > self.__syslogLevel
                and not self.univentionLogger_priv):

            return

        def formatMessage(unformattedMessage, removeConfidential=False):
            tempMessage = unicode(unformattedMessage)
            tempMessage = tempMessage.replace(u'%M', message)

            if removeConfidential:
                for string in self.__confidentialStrings:
                    tempMessage = tempMessage.replace(string,
                                                      u'*** confidential ***')

            tempMessage = tempMessage.replace(u'%D', datetime)
            tempMessage = tempMessage.replace(u'%T', threadId)
            tempMessage = tempMessage.replace(u'%l', unicode(level))
            tempMessage = tempMessage.replace(u'%L', levelname)
            tempMessage = tempMessage.replace(u'%C', componentname)
            tempMessage = tempMessage.replace(u'%F', filename)
            tempMessage = tempMessage.replace(u'%N', linenumber)
            return tempMessage

        try:
            if not isinstance(message, unicode):
                if not isinstance(message, str):
                    message = unicode(message)
                else:
                    message = unicode(message, 'utf-8', 'replace')

            try:
                message = message.format(*formatArgs, **formatKwargs)
            except KeyError as e:
                if 'missing format for key ' not in str(e).lower():
                    raise e
            except ValueError as e:
                if 'invalid conversion specification' not in str(e).lower():
                    raise e

            componentname = self.__componentName
            datetime = unicode(
                time.strftime(u"%b %d %H:%M:%S", time.localtime()), 'utf-8',
                'replace')
            threadId = unicode(thread.get_ident())
            specialConfig = None

            try:
                levelname, color = _LOGLEVEL_NAME_AND_COLOR_MAPPING[level]
            except KeyError:
                levelname = u''
                color = COLOR_NORMAL

            try:
                filename = unicode(
                    os.path.basename(sys._getframe(2).f_code.co_filename))
                linenumber = unicode(sys._getframe(2).f_lineno)

                specialConfig = self._getThreadConfig()
                if not specialConfig and self.__objectConfig:
                    # Ouch, this hurts...
                    f = sys._getframe(2)
                    while f is not None:
                        obj = f.f_locals.get('self')
                        if obj:
                            c = self._getObjectConfig(id(obj))
                            if c:
                                specialConfig = c
                                break
                        f = f.f_back
            except Exception:
                # call stack not deep enough?
                try:
                    filename
                except NameError:
                    filename = u''

                try:
                    linenumber
                except NameError:
                    linenumber = u''

            if specialConfig:
                componentname = specialConfig.get('componentName',
                                                  componentname)

            if level <= self.__messageSubjectLevel:
                m = self.__messageSubjectFormat
                if specialConfig:
                    m = specialConfig.get('messageSubjectFormat', m)
                m = formatMessage(m,
                                  removeConfidential=self.__messageSubjectLevel
                                  < LOG_CONFIDENTIAL)

                self.__loggerSubject.setMessage(m, level)

            if level <= self.__consoleLevel:
                # Log to terminal
                m = self.__consoleFormat
                if specialConfig:
                    m = specialConfig.get('consoleFormat', m)
                m = formatMessage(
                    m,
                    removeConfidential=self.__consoleLevel < LOG_CONFIDENTIAL)

                if self.__consoleStdout:
                    fh = sys.stdout
                else:
                    fh = sys.stderr

                try:
                    fhEncoding = fh.encoding
                except Exception:
                    fhEncoding = None

                if fhEncoding is None:
                    fhEncoding = locale.getpreferredencoding()

                if self.__consoleColor:
                    m = u"%s%s%s\n" % (color, m, COLOR_NORMAL)
                else:
                    m = u"%s\n" % m
                fh.write(m.encode(fhEncoding, 'backslashreplace'))

            if level <= self.__fileLevel:
                # Log to file
                logFile = self.__logFile
                if specialConfig:
                    logFile = specialConfig.get('logFile', logFile)
                if logFile:
                    m = self.__fileFormat
                    if specialConfig:
                        m = specialConfig.get('fileFormat', m)
                    m = formatMessage(
                        m,
                        removeConfidential=self.__fileLevel < LOG_CONFIDENTIAL)

                    try:
                        lf = codecs.open(logFile, 'a+', 'utf-8', 'replace')
                    except Exception as err:
                        lf = None

                    if lf:
                        timeout = 0
                        locked = False
                        while not locked and timeout < 2000:
                            # While not timed out and not locked
                            try:
                                # Try to lock file
                                if os.name == 'nt':
                                    hfile = win32file._get_osfhandle(
                                        lf.fileno())
                                    win32file.LockFileEx(
                                        hfile,
                                        win32con.LOCKFILE_EXCLUSIVE_LOCK, 0,
                                        -0x7fff0000, pywintypes.OVERLAPPED())
                                    # win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped)
                                elif os.name == 'posix':
                                    # Flags for exclusive, non-blocking lock
                                    fcntl.flock(lf.fileno(),
                                                fcntl.LOCK_EX | fcntl.LOCK_NB)
                            except IOError as err:
                                # Locking failed
                                # increase timeout counter, sleep 100 millis
                                timeout += 100
                                time.sleep(0.1)
                            else:
                                # File successfully locked
                                locked = True

                        if locked:
                            if self.__fileColor:
                                m = u"%s%s%s" % (color, m, COLOR_NORMAL)
                            m += u'\n'
                            if os.name == 'nt':
                                m = m.replace(u'\n', u'\r\n')
                            lf.write(m)
                            lf.close()

            if syslog is not None and level <= self.__syslogLevel:
                # Log to syslog
                m = self.__syslogFormat
                if specialConfig:
                    m = specialConfig.get('syslogFormat', m)
                m = formatMessage(
                    m,
                    removeConfidential=self.__syslogLevel < LOG_CONFIDENTIAL)

                try:
                    syslog.syslog(_SYSLOG_LEVEL_MAPPING[level], m)
                except KeyError:
                    # No known log level - ignoring.
                    pass

            if self.univentionLogger_priv:
                # univention log
                m = self.__univentionFormat
                if specialConfig:
                    m = specialConfig.get('univentionFormat', m)
                m = formatMessage(m, removeConfidential=True)

                if level in (LOG_DEBUG2, LOG_DEBUG, LOG_INFO):
                    univentionLevel = self.univentionLogger_priv.ALL
                elif level == LOG_NOTICE:
                    univentionLevel = self.univentionLogger_priv.INFO
                elif level == LOG_WARNING:
                    univentionLevel = self.univentionLogger_priv.WARN
                elif level in (LOG_ERROR, LOG_CRITICAL, LOG_COMMENT):
                    univentionLevel = self.univentionLogger_priv.ERROR
                else:
                    univentionLevel = None

                if univentionLevel:
                    self.univentionLogger_priv.debug(self.__univentionClass,
                                                     univentionLevel, m)
        except Exception as err:
            if raiseException:
                raise err
예제 #4
0
    def communication_win(self, is_check):
        import win32event
        import win32file
        import win32api
        import pywintypes
        import winerror

        # event for the socket
        hEvent_sock = win32event.CreateEvent(None, 0, 0, None)
        win32file.WSAEventSelect(self.comms_socket, hEvent_sock,
                                 win32file.FD_READ)

        # descriptor list
        self.rlist = [self.comms_socket]
        # overlapped list
        self.olist = [0]
        # event list
        self.elist = [hEvent_sock]
        # message buffer list
        self.mlist = [0]
        # id of the read object - put in this if it was read
        self.ulist = []
        if not self.serverorclient and self.tunnel:
            # client mode
            # objects created for the tunnel and put in the corresponding
            # lists
            hEvent_pipe = win32event.CreateEvent(
                None, 0, 0, None)  # for reading from the pipe
            overlapped_pipe = pywintypes.OVERLAPPED()
            overlapped_pipe.hEvent = hEvent_pipe
            message_buffer = win32file.AllocateReadBuffer(4096)
            self.rlist.append(self.tunnel)
            self.olist.append(overlapped_pipe)
            self.elist.append(hEvent_pipe)
            self.mlist.append(message_buffer)
            self.ulist.append(1)

        while not self._stop:
            try:
                if not self.tunnel:
                    # check or server mode without client only with socket
                    rc = win32event.WaitForSingleObject(
                        hEvent_sock, int(self.timeout * 1000))
                    if rc == winerror.WAIT_TIMEOUT:
                        # timed out, just rerun and wait
                        continue
                else:
                    if self.ulist:
                        # there is somebody waiting to be read
                        for idx in self.ulist:
                            # issueing ReadFile on all not yet read mailslots/tunnel
                            hr, _ = win32file.ReadFile(self.rlist[idx],
                                                       self.mlist[idx],
                                                       self.olist[idx])
                            if (hr != 0) and (hr != winerror.ERROR_IO_PENDING):
                                common.internal_print(
                                    "UDP ReadFile failed: {0}".format(hr), -1)
                                raise

                        self.ulist = []

                    # waiting to get some data somewhere
                    rc = win32event.WaitForMultipleObjects(
                        self.elist, 0, int(self.timeout * 1000))
                    if rc == winerror.WAIT_TIMEOUT:
                        # timed out, just rerun and wait
                        continue

                if rc < 0x80:  # STATUS_ABANDONED_WAIT_0
                    if rc > 0:
                        # the tunnel or one of the mailslots got signalled
                        self.ulist.append(rc)
                        if (self.olist[rc].InternalHigh <
                                4) or (self.mlist[rc][0:1] !=
                                       "\x45"):  #Only care about IPv4
                            continue

                        readytogo = self.mlist[rc][0:self.olist[rc].
                                                   InternalHigh]
                        if self.serverorclient:
                            c = self.lookup_client_priv(readytogo)
                            if c:
                                self.send(
                                    common.DATA_CHANNEL_BYTE, readytogo,
                                    ((socket.inet_ntoa(c.get_public_ip_addr()),
                                      c.get_public_src_port()), None))
                            else:
                                common.internal_print(
                                    "Client not found, strange?!", 0,
                                    self.verbosity, common.DEBUG)
                                continue
                        else:
                            if self.authenticated:
                                self.send(common.DATA_CHANNEL_BYTE, readytogo,
                                          (self.server_tuple, None))
                    if rc == 0:
                        # socket got signalled
                        messages = self.recv()
                        if len(messages) == 0:
                            continue

                        for addr in messages:
                            for message in messages[addr]:
                                c = None
                                if self.serverorclient:
                                    self.authenticated = False
                                    c = self.lookup_client_pub((addr, 0))

                                if common.is_control_channel(message[0:1]):
                                    if self.controlchannel.handle_control_messages(
                                            self, message[len(
                                                common.CONTROL_CHANNEL_BYTE):],
                                        (addr, None)):
                                        continue
                                    else:
                                        self.stop()
                                        break

                                if c:
                                    self.authenticated = c.get_authenticated()

                                if self.authenticated:
                                    try:
                                        self.packet_writer(message[
                                            len(common.CONTROL_CHANNEL_BYTE):])
                                    except OSError as e:
                                        print(e)

            except win32api.error as e:
                common.internal_print("UDP Exception: {0}".format(e), -1)
            except socket.error as se:
                if se.args[0] == 10054:  # port is unreachable
                    common.internal_print(
                        "Server's port is unreachable: {0}".format(se), -1)
                    self._stop = True

        return True
예제 #5
0
        def __init__(self, path_handle, mode='r', share=None):
            """If 'path_handle' is a string, opens that file for
            asynchronous I/O; if it is a handle (pipe client / server,
            for example), sets up for asynchronous I/O. 'mode' is as
            per 'open' Python function, although limited to
            basic/common modes.
            """
            if not _AsyncFile._notifier:
                _AsyncFile._notifier = asyncoro._AsyncNotifier.instance()
            self._asyncoro = AsynCoro.scheduler()
            self._overlap = pywintypes.OVERLAPPED()
            if isinstance(path_handle, str):
                self._path = path_handle
                if mode.startswith('r'):
                    access = win32file.GENERIC_READ
                    if share is None:
                        share = win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE
                    create = win32file.OPEN_EXISTING
                    if '+' in mode:
                        access |= win32file.GENERIC_WRITE
                elif mode.startswith('w'):
                    access = win32file.GENERIC_WRITE
                    if share is None:
                        share = win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE
                    create = win32file.CREATE_ALWAYS
                    if '+' in mode:
                        access |= win32file.GENERIC_READ
                elif mode.startswith('a'):
                    access = win32file.GENERIC_WRITE
                    if share is None:
                        share = win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE
                    create = win32file.OPEN_ALWAYS
                    if '+' in mode:
                        access |= win32file.GENERIC_READ
                        # TODO: if reading, offset should be 0?
                    sb = os.stat(path_handle)
                    self._overlap.Offset = sb.st_size
                else:
                    self._overlap = None
                    raise ValueError('invalid mode "%s"' % mode)

                flags = win32file.FILE_FLAG_OVERLAPPED

                try:
                    self._handle = win32file.CreateFile(path_handle, access, share, None, create,
                                                        flags, None)
                except:
                    self._overlap = None
                    raise
                if mode.startswith('r'):
                    flags = os.O_RDONLY
                elif mode.startswith('a'):
                    flags = os.O_APPEND
                else:
                    flags = 0
                self._fileno = msvcrt.open_osfhandle(self._handle, flags)
            else:
                self._handle = path_handle
                # pipe mode should be either 'r' or 'w'
                flags = os.O_RDONLY if mode.startswith('r') else 0
                self._fileno = msvcrt.open_osfhandle(self._handle, flags)

            self._buflist = []
            self._read_result = None
            self._write_result = None
            self._timeout = None
            self._timeout_id = None
            _AsyncFile._notifier.register(self._handle)
예제 #6
0
    def communication_win(self, is_check):
        # event, overlapped struct for the pipe or tunnel
        hEvent_pipe = win32event.CreateEvent(None, 0, 0,
                                             None)  # for reading from the pipe
        overlapped_pipe = pywintypes.OVERLAPPED()
        overlapped_pipe.hEvent = hEvent_pipe

        # event, overlapped struct for the pipe or tunnel
        hEvent_rdp = win32event.CreateEvent(None, 0, 0,
                                            None)  # for reading from the pipe
        overlapped_rdp = pywintypes.OVERLAPPED()
        overlapped_rdp.hEvent = hEvent_rdp

        # buffer for the packets
        message_readfile_pipe = win32file.AllocateReadBuffer(4096)
        message_readfile_rdp = win32file.AllocateReadBuffer(4096)

        # showing if we already async reading or not
        read_pipe = True
        read_rdp = False
        first_run = True

        while not self._stop:
            try:
                if not self.tunnel_r:
                    # user is not authenticated yet, so there is no pipe
                    # only checking the socket for data
                    hr, _ = win32file.ReadFile(self.comms_socket,
                                               message_readfile_rdp,
                                               overlapped_rdp)
                    if (hr == winerror.ERROR_IO_PENDING):
                        rc = win32event.WaitForSingleObject(
                            hEvent_rdp, int(self.timeout * 1000))
                        read_rdp = True
                    else:
                        raise
                        rc = 0
                else:
                    # client mode so we have the socket and tunnel as well
                    # or the client authenticated and the pipe was created
                    if read_pipe or first_run:
                        # no ReadFile was called before or finished, so we
                        # are calling it again
                        first_run = False
                        hr, _ = win32file.ReadFile(self.tunnel_r,
                                                   message_readfile_pipe,
                                                   overlapped_pipe)

                    if read_rdp:
                        # no ReadFile was called before or finished, so we
                        # are calling it again
                        hr, _ = win32file.ReadFile(self.comms_socket,
                                                   message_readfile_rdp,
                                                   overlapped_rdp)

                    if (hr == winerror.ERROR_IO_PENDING):
                        # well, this was an async read, so we need to wait
                        # until it happens
                        rc = win32event.WaitForMultipleObjects(
                            [hEvent_rdp, hEvent_pipe], 0,
                            int(self.timeout * 1000))
                        if rc == winerror.WAIT_TIMEOUT:
                            # timed out, just rerun and wait
                            continue
                    else:
                        if hr != 0:
                            common.internal_print(
                                "RDP ReadFile failed: {0}".format(hr), -1)
                            raise

                if rc < 0x80:  # STATUS_ABANDONED_WAIT_0
                    if rc == 0:
                        read_rdp = True
                        read_pipe = False
                        # socket got signalled
                        # skipping header (8):length of read
                        messages = self.recv(
                            message_readfile_rdp[8:overlapped_rdp.
                                                 InternalHigh])  # SLOW?
                        for message in messages:
                            # looping through the messages from socket
                            if len(message) == 0:
                                # this could happen when the socket died or
                                # partial message was read.
                                continue

                            if common.is_control_channel(message[0:1]):
                                # parse control messages
                                if self.controlchannel.handle_control_messages(
                                        self,
                                        message[len(common.CONTROL_CHANNEL_BYTE
                                                    ):], None):
                                    continue
                                else:
                                    # If the module is stopped right away, then
                                    # the channel will be closing down as well.
                                    # Because of the buffering the message will
                                    # not be sent. That is why we need to sleep
                                    time.sleep(0.5)
                                    self.stop()
                                    break

                            if self.authenticated:
                                try:
                                    # write packet to the tunnel
                                    self.packet_writer(
                                        message[len(common.CONTROL_CHANNEL_BYTE
                                                    ):])
                                except OSError as e:
                                    print(e)  # wut?
                                except Exception as e:
                                    if e.args[0] == 995:
                                        common.internal_print(
                                            "Interface disappered, exiting thread: {0}"
                                            .format(e), -1)
                                        self.stop()
                                        continue
                                    print(e)
                    if rc == 1:
                        read_rdp = False
                        read_pipe = True
                        # pipe/tunnel got signalled
                        if (overlapped_pipe.InternalHigh <
                                4) or (message_readfile_pipe[0:1] !=
                                       "\x45"):  #Only care about IPv4
                            # too small which should not happen or not IPv4, so we just drop it.
                            continue

                        # reading out the packet from the buffer and discarding the rest
                        readytogo = message_readfile_pipe[0:overlapped_pipe.
                                                          InternalHigh]
                        self.send(common.DATA_CHANNEL_BYTE, readytogo, None)

            except win32api.error as e:
                if e.args[0] == 233:
                    # No process is on the other end of the pipe.
                    self._stop = True
                    common.internal_print("Client disconnected from the pipe.",
                                          -1)
                    continue
                common.internal_print("RDP Exception: {0}".format(e), -1)

        self.cleanup()

        return True
예제 #7
0
 def __enter__(self):
     self.file = open('LinkLock', 'w+')
     self.file_handle = win32file._get_osfhandle(self.file.fileno())
     win32file.LockFileEx(self.file_handle,
                          win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000,
                          pywintypes.OVERLAPPED())
예제 #8
0
        t = threading.Thread(target=self.connect_thread_runner,
                             args=(False, giveup_event))
        t.start()
        time.sleep(0.1)
        s2 = socket.socket()
        ol = pywintypes.OVERLAPPED()
        s2.bind(('0.0.0.0', 0)) # connectex requires the socket be bound beforehand
        try:
            win32file.ConnectEx(s2, self.addr, ol)
        except win32file.error, exc:
            win32event.SetEvent(giveup_event)
            if exc.winerror == 10022: # WSAEINVAL
                raise TestSkipped("ConnectEx is not available on this platform")
            raise # some error error we don't expect.
        win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        ol = pywintypes.OVERLAPPED()
        buff = win32file.AllocateReadBuffer(1024)
        win32file.WSARecv(s2, buff, ol, 0)
        length = win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        self.response = buff[:length]
        self.assertEqual(self.response, str2bytes('some expected response'))
        t.join(5)
        self.failIf(t.isAlive(), "worker thread didn't terminate")

class TestTransmit(unittest.TestCase):
    def test_transmit(self):
        import binascii
        bytes = os.urandom(1024*1024)
        val = binascii.hexlify(bytes)
        val_length = len(val)
        f = tempfile.TemporaryFile()
예제 #9
0
class TestConnect(unittest.TestCase):
    def connect_thread_runner(self, expect_payload, giveup_event):
        # As Windows 2000 doesn't do ConnectEx, we need to use a non-blocking
        # accept, as our test connection may never come.  May as well use
        # AcceptEx for this...
        listener = socket.socket()
        self.addr = ('localhost', random.randint(10000,64000))
        listener.bind(self.addr)
        listener.listen(1)

        # create accept socket
        accepter = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # An overlapped
        overlapped = pywintypes.OVERLAPPED()
        overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)
        # accept the connection.
        if expect_payload:
            buf_size = 1024
        else:
            # when we don't expect data we must be careful to only pass the
            # exact number of bytes for the endpoint data...
            buf_size = win32file.CalculateSocketEndPointSize(listener)

        buffer = win32file.AllocateReadBuffer(buf_size)
        win32file.AcceptEx(listener, accepter, buffer, overlapped)
        # wait for the connection or our test to fail.
        events = giveup_event, overlapped.hEvent
        rc = win32event.WaitForMultipleObjects(events, False, 2000)
        if rc == win32event.WAIT_TIMEOUT:
            self.fail("timed out waiting for a connection")
        if rc == win32event.WAIT_OBJECT_0:
            # Our main thread running the test failed and will never connect.
            return
        # must be a connection.
        nbytes = win32file.GetOverlappedResult(listener.fileno(), overlapped, False)
        if expect_payload:
            self.request = buffer[:nbytes]
        accepter.send(str2bytes('some expected response'))

    def test_connect_with_payload(self):
        giveup_event = win32event.CreateEvent(None, 0, 0, None)
        t = threading.Thread(target=self.connect_thread_runner,
                             args=(True, giveup_event))
        t.start()
        time.sleep(0.1)
        s2 = socket.socket()
        ol = pywintypes.OVERLAPPED()
        s2.bind(('0.0.0.0', 0)) # connectex requires the socket be bound beforehand
        try:
            win32file.ConnectEx(s2, self.addr, ol, str2bytes("some expected request"))
        except win32file.error, exc:
            win32event.SetEvent(giveup_event)
            if exc.winerror == 10022: # WSAEINVAL
                raise TestSkipped("ConnectEx is not available on this platform")
            raise # some error error we don't expect.
        win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        ol = pywintypes.OVERLAPPED()
        buff = win32file.AllocateReadBuffer(1024)
        win32file.WSARecv(s2, buff, ol, 0)
        length = win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        self.response = buff[:length]
        self.assertEqual(self.response, str2bytes('some expected response'))
        self.assertEqual(self.request, str2bytes('some expected request'))
        t.join(5)
        self.failIf(t.isAlive(), "worker thread didn't terminate")
예제 #10
0
    def run_windows(self):
        import win32file
        import win32event
        import pywintypes
        import winerror
        import win32api

        # creating events, overlapped structures and a buffer for reading and writing
        hEvent_read = win32event.CreateEvent(None, 0, 0, None)
        overlapped_read = pywintypes.OVERLAPPED()
        overlapped_read.hEvent = hEvent_read
        overlapped_write = pywintypes.OVERLAPPED()
        message = win32file.AllocateReadBuffer(4096)

        while not self._stop:
            try:
                # Overlapped/async read, it either blocks or returns pending
                hr, _ = win32file.ReadFile(self.tunnel, message,
                                           overlapped_read)
                if (hr == winerror.ERROR_IO_PENDING):
                    # when the event gets signalled or timeout happens it will return
                    rc = win32event.WaitForSingleObject(
                        hEvent_read, int(self.timeout * 1000))
                    if rc == winerror.WAIT_TIMEOUT:
                        # timed out, just rerun read
                        continue

                    if rc == win32event.WAIT_OBJECT_0:
                        # read happened, packet is in "message"
                        if (overlapped_read.InternalHigh < 4) or (
                                message[0:1] != "\x45"):  #Only care about IPv4
                            # too small which should not happen or not IPv4, so we just drop it.
                            continue

                        # reading out the packet from the buffer and discarding the rest
                        readytogo = message[0:overlapped_read.InternalHigh]

                # looking for client
                for c in self.clients:
                    if c.get_private_ip_addr() == readytogo[16:20]:
                        # client found, writing packet on client's pipe
                        # ignoring outcome, it is async so it will happen when it will happen ;)
                        win32file.WriteFile(c.get_pipe_w(), readytogo,
                                            overlapped_write)

            except win32api.error as e:
                if e.args[0] == 995:
                    common.internal_print(
                        "Interface disappered, exiting PS thread: {0}".format(
                            e), -1)
                    self.stop()
                    continue
                if e.args[0] == 1453:
                    common.internal_print("OS Internal error: {0}".format(e),
                                          -1)
                    self.stop()
                    continue

                common.internal_print("PS Exception: {0}".format(e), -1)

        return
예제 #11
0
    def __init__(self, tun_dev, tun_addr, tun_remote_addr, tun_nm, tun_mtu,
                 wsfactory):
        self.tun_dev = tun_dev
        self.tun_addr = tun_addr
        self.addr = tun_addr  # used by mtcrypt
        self.tun_nm = tun_nm
        self.tun_mtu = int(tun_mtu)
        self.wsfactory = wsfactory

        if BSD == True:
            try:
                self.tunfd = os.open("/dev/" + tun_dev, os.O_RDWR)
                call([
                    "/sbin/ifconfig", tun_dev, tun_addr, tun_remote_addr, "up"
                ])
            except:
                log.msg("Error opening TUN device.  In use?  Permissions?",
                        logLevel=logging.WARN)
                sys.exit(ERR)

            reactor.addReader(self)

            logstr = ("Opened TUN device on %s") % (self.tun_dev)
            log.msg(logstr, logLevel=logging.INFO)

        elif LINUX == True:
            try:
                self.tun = TunTapDevice(name=tun_dev,
                                        flags=(IFF_TUN | IFF_NO_PI))
            except:
                log.msg("Error opening TUN device.  In use?  Permissions?",
                        logLevel=logging.WARN)
                sys.exit(ERR)

            self.tun.addr = tun_addr
            self.tun.dstaddr = tun_remote_addr
            self.tun.netmask = tun_nm
            self.tun.mtu = int(tun_mtu)
            self.tun.up()

            reactor.addReader(self)

            logstr = ("Opened TUN device on %s") % (self.tun.name)
            log.msg(logstr, logLevel=logging.INFO)

        elif WINDOWS == True:
            self.overlappedTx = pywintypes.OVERLAPPED()
            self.overlappedTx.hEvent = win32event.CreateEvent(None, 0, 0, None)

            addr_tmp = self.tun_addr.split('.')
            self.tun_ipv4_address = list()
            for i in range(0, 4):
                self.tun_ipv4_address.append(int(addr_tmp[i]))

            nm_tmp = self.tun_nm.split('.')
            self.tun_ipv4_netmask = list()
            self.tun_ipv4_network = list()
            for i in range(0, 4):
                self.tun_ipv4_netmask.append(int(nm_tmp[i]))
                self.tun_ipv4_network.append(int(addr_tmp[i]) & int(nm_tmp[i]))

            self.TAP_IOCTL_CONFIG_POINT_TO_POINT = self.TAP_CONTROL_CODE(5, 0)
            self.TAP_IOCTL_SET_MEDIA_STATUS = self.TAP_CONTROL_CODE(6, 0)
            self.TAP_IOCTL_CONFIG_TUN = self.TAP_CONTROL_CODE(10, 0)

            try:
                self.tun_handle = self.openTunTap()
            except:
                log.msg("Could not open TUN device.  Permissions?",
                        logLevel=logging.WARN)
                sys.exit(ERR)

            log.msg("Opened TUN device", logLevel=logging.INFO)

            self.tunRead = TunRead(self.tun_handle, self.wsfactory)
            self.tunRead.start()
예제 #12
0
    def init_client(self, control_message, additional_data):
        addr = additional_data[0]
        client_local = client.Client()

        # stripping out the private IP from the message
        client_private_ip = control_message[0:4]
        # saving public IP address and port
        client_public_source_ip = socket.inet_aton(addr[0])
        client_public_source_port = addr[1]

        # If this private IP is already used, the server removes that client.
        # For example: client reconnect on connection reset, duplicated configs
        # and yes, this can be used to kick somebody off the tunnel

        # close client related pipes
        for c in self.clients:
            # find and remove client from module's list
            if c.get_private_ip_addr() == client_private_ip:
                save_to_close = c
                self.clients.remove(c)
                if c.get_pipe_r() in self.rlist:
                    if self.os_type == common.OS_WINDOWS:
                        # removing client related elements from lists
                        idx = 0
                        while self.rlist[idx] != c.get_pipe_r():
                            idx += 1
                        if idx < len(self.rlist):
                            self.olist = self.olist[:idx] + self.olist[idx +
                                                                       1:]
                            self.elist = self.elist[:idx] + self.elist[idx +
                                                                       1:]
                            self.mlist = self.mlist[:idx] + self.mlist[idx +
                                                                       1:]
                        else:
                            self.olist = self.olist[:idx]
                            self.elist = self.elist[:idx]
                            self.mlist = self.mlist[:idx]

                        self.ulist.remove(idx)
                    self.rlist.remove(c.get_pipe_r())

        found = False
        for c in self.packetselector.get_clients():
            # find and remove client from packetselector's list
            if c.get_private_ip_addr() == client_private_ip:
                found = True
                self.packetselector.delete_client(c)

        # If client was created but not added to the PacketSelector, then the
        # pipes still need to be closed. This could happen when the authenti-
        # cation fails or gets interrupted.
        if not found:
            if self.os_type == common.OS_WINDOWS:
                import win32file

                try:
                    win32file.CloseHandle(save_to_close.get_pipe_r())
                    win32file.CloseHandle(save_to_close.get_pipe_w())
                except:
                    pass
            else:
                try:
                    save_to_close.get_pipe_r_fd().close()
                    save_to_close.get_pipe_w_fd().close()
                except:
                    pass

        # creating new pipes for the client
        if self.os_type == common.OS_WINDOWS:
            import win32pipe
            import win32file
            import pywintypes
            import win32event

            import win32api
            import winerror

            overlapped = pywintypes.OVERLAPPED()
            # setting up nameslot
            mailslotname = "\\\\.\\mailslot\\XFLTReaT_{0}".format(
                socket.inet_ntoa(client_private_ip))

            mailslot_r = win32file.CreateMailslot(mailslotname, 0, -1, None)
            if (mailslot_r == None) or (mailslot_r
                                        == win32file.INVALID_HANDLE_VALUE):
                internal_print("Invalid handle - mailslot", -1)
                sys.exit(-1)

            mailslot_w = win32file.CreateFile(
                mailslotname, win32file.GENERIC_WRITE,
                win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, None,
                win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL
                | win32file.FILE_FLAG_OVERLAPPED, None)
            if (mailslot_w == None) or (mailslot_w
                                        == win32file.INVALID_HANDLE_VALUE):
                internal_print("Invalid handle - readable pipe", -1)
                sys.exit(-1)

            client_local.set_pipes_fdnum(mailslot_r, mailslot_w)

        else:
            pipe_r, pipe_w = os.pipe()
            client_local.set_pipes_fdnum(pipe_r, pipe_w)
            client_local.set_pipes_fd(os.fdopen(pipe_r, "r"),
                                      os.fdopen(pipe_w, "w"))

        # set connection related things and authenticated to True
        client_local.set_public_ip_addr(client_public_source_ip)
        client_local.set_public_src_port(client_public_source_port)
        client_local.set_private_ip_addr(client_private_ip)

        client_local.get_encryption().set_module(self.encryption.get_module())
        self.encryption = client_local.get_encryption()

        if self.encryption.get_module().get_step_count():
            # add encryption steps
            self.merge_cmh(self.encryption.get_module().get_cmh_struct())

        if self.authentication.get_step_count():
            # add authentication steps
            self.merge_cmh(self.authentication.get_cmh_struct())

        client_local.set_initiated(True)
        self.clients.append(client_local)

        return
예제 #13
0

hfile = win32file.CreateFile(file,

                             win32con.GENERIC_READ | win32con.GENERIC_WRITE,

                             win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,

                             secur_att,

                             win32con.OPEN_ALWAYS,

                             win32con.FILE_ATTRIBUTE_NORMAL, 0)


ov = pywintypes.OVERLAPPED()  # used to indicate starting region to lock

win32file.LockFileEx(hfile, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, highbits, ov)

win32api.Sleep(4000)  # do something here

win32file.UnlockFileEx(hfile, 0, highbits, ov)

hfile.Close()


# <nl > Below, I have fleshed it out with a more useable Flock class.  The

# code below works like this: You create an instance of the class,

# providing a filename. It will create/access the file in a default way
예제 #14
0
def __win32_lock_fd(fd, timeout=None):
    '''returns True if the file descriptor is successfully locked'''
    import pywintypes
    import win32con
    import win32file
    import winerror

    try:
        handle = win32file._get_osfhandle(fd)

        if timeout is None:
            win32file.LockFileEx(handle, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, pywintypes.OVERLAPPED())
            return True

        if timeout > 0:
            start = time.time()
            while True:
                try:
                    win32file.LockFileEx(handle, win32con.LOCKFILE_EXCLUSIVE_LOCK | win32con.LOCKFILE_FAIL_IMMEDIATELY, 0, -0x10000, pywintypes.OVERLAPPED())
                    return True
                except pywintypes.error as e:
                    if e.winerror != winerror.ERROR_LOCK_VIOLATION:
                        break
                    time.sleep(0.05)
                    if time.time() > start + timeout:
                        break
        else:
            win32file.LockFileEx(handle, win32con.LOCKFILE_EXCLUSIVE_LOCK | win32con.LOCKFILE_FAIL_IMMEDIATELY, 0, -0x10000, pywintypes.OVERLAPPED())
            return True
    except pywintypes.error:
        pass
    return False
예제 #15
0
def pipe_server():
    pipe = win32pipe.CreateNamedPipe(
        r'\\.\pipe\my_pipe',
        win32pipe.PIPE_ACCESS_INBOUND | win32file.FILE_FLAG_OVERLAPPED,
        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE
        | win32pipe.PIPE_WAIT, 1, 65536, 65536, 0, None)
    quit = False
    overlapped_obj1 = pywintypes.OVERLAPPED()

    completion_port = win32file.CreateIoCompletionPort(pipe, None, 0, 0)

    while not quit:
        try:
            win32pipe.ConnectNamedPipe(pipe, overlapped_obj1)

            while True:  # Doing some sleep (2 seconds): Actually, other things could be done in this time
                for i in range(10):
                    time.sleep(0.2)

                # If the function succeeds, rc will be set to 0, otherwise it will be set to the win32 error code (258).
                (rc, byte_num, key,
                 ovrlpd) = win32file.GetQueuedCompletionStatus(
                     completion_port, 50)  #1000)

                if rc == 0:  # The message can be retrieved
                    msg = ''  # Will contain the whole message at the end
                    """
                    in order to read the characters we need to distinguish two cases:
                        -the character is a normal (unicode) character, which takes 1 byte
                        -the character is non_unicode (German, Russian...), which takes 2 bytes
                    as we are reading 1 byte at a time, the above-mentioned discussion is essential.
                    When a 1 byte character is coming, its decoding is done without problems.
                    Let's see what happens, when a 2-byte character is coming. In this case, we read
                    1 byte, try to decode, get an error. Now we know that the character takes 2-bytes.
                    Then, we read 1 byte again, combine them and decode.
                    """
                    # 1-byte character case
                    try:
                        rtnvalue, data = win32file.ReadFile(
                            pipe, 1, overlapped_obj1)
                        msg = msg + bytes(data).decode("utf-8")
                    # 2-bytes character case
                    except:
                        rtnvalue, data1 = win32file.ReadFile(
                            pipe, 1, overlapped_obj1)
                        non_unicode = data.tobytes() + data1.tobytes()
                        msg = msg + non_unicode.decode("utf-8")

                    while rtnvalue == 234:  # more data is available

                        try:  # 1-byte character case
                            rtnvalue, data = win32file.ReadFile(
                                pipe, 1, overlapped_obj1)
                            msg = msg + bytes(data).decode("utf-8")

                        except:  # 2-bytes character case
                            rtnvalue, data1 = win32file.ReadFile(
                                pipe, 1, overlapped_obj1)
                            non_unicode = data.tobytes() + data1.tobytes()
                            msg = msg + non_unicode.decode("utf-8")

                    # the next line helps with writing Russian and Armenian characters into a text file
                    with codecs.open('test.txt', 'w', encoding='utf-8') as f:
                        f.write(msg)
                    f.close()
                    print("Successfully received and written")
                    print("Closing Handle")
                    exit(0)

        except pywintypes.error as e:
            if e.args[0] == 109:
                print("broken pipe")
                quit = True
            else:
                print(e)
                quit = True
    win32file.CloseHandle(pipe)
예제 #16
0
파일: ICMP.py 프로젝트: saraiva/XFLTReaT
    def communication_win(self, is_check):
        import win32event
        import win32file
        import win32api
        import pywintypes
        import winerror

        # event for the socket
        hEvent_sock = win32event.CreateEvent(None, 0, 0, None)
        win32file.WSAEventSelect(self.comms_socket, hEvent_sock,
                                 win32file.FD_READ)

        # descriptor list
        self.rlist = [self.comms_socket]
        # overlapped list
        self.olist = [0]
        # event list
        self.elist = [hEvent_sock]
        # message buffer list
        self.mlist = [0]
        # id of the read object - put in this if it was read
        self.ulist = []
        if not self.serverorclient and self.tunnel:
            # client mode
            # objects created for the tunnel and put in the corresponding
            # lists
            hEvent_pipe = win32event.CreateEvent(
                None, 0, 0, None)  # for reading from the pipe
            overlapped_pipe = pywintypes.OVERLAPPED()
            overlapped_pipe.hEvent = hEvent_pipe
            message_buffer = win32file.AllocateReadBuffer(4096)
            self.rlist.append(self.tunnel)
            self.olist.append(overlapped_pipe)
            self.elist.append(hEvent_pipe)
            self.mlist.append(message_buffer)
            self.ulist.append(1)

        while not self._stop:
            try:
                if not self.tunnel:
                    # check or server mode without client only with socket
                    #message, addr = self.comms_socket.recvfrom(1508)
                    rc = win32event.WaitForSingleObject(
                        hEvent_sock, int(self.timeout * 1000))
                    if rc == winerror.WAIT_TIMEOUT:
                        # timed out, just rerun and wait
                        continue

                else:
                    if self.ulist:
                        # there is somebody waiting to be read
                        for idx in self.ulist:
                            # issueing ReadFile on all not yet read mailslots/tunnel
                            hr, _ = win32file.ReadFile(self.rlist[idx],
                                                       self.mlist[idx],
                                                       self.olist[idx])
                            if (hr != 0) and (hr != winerror.ERROR_IO_PENDING):
                                common.internal_print(
                                    "UDP ReadFile failed: {0}".format(hr), -1)
                                raise

                        self.ulist = []

                    # waiting to get some data somewhere
                    rc = win32event.WaitForMultipleObjects(
                        self.elist, 0, int(self.timeout * 1000))
                    if rc == winerror.WAIT_TIMEOUT:
                        # timed out, just rerun and wait
                        continue

                if rc < 0x80:  # STATUS_ABANDONED_WAIT_0
                    if rc > 0:
                        # the tunnel or one of the mailslots got signalled
                        self.ulist.append(rc)
                        if (self.olist[rc].InternalHigh <
                                4) or (self.mlist[rc][0:1] !=
                                       "\x45"):  #Only care about IPv4
                            continue

                        readytogo = self.mlist[rc][0:self.olist[rc].
                                                   InternalHigh]

                        if self.serverorclient:
                            c = self.lookup_client_priv(readytogo)
                            if c:
                                # if the differece between the received and set sequences too big
                                # some routers/firewalls just drop older sequences. If it gets
                                # too big, we just drop the older ones and use the latest X packet
                                # this helps on stabality.
                                if (c.get_ICMP_received_sequence() -
                                        c.get_ICMP_sent_sequence()
                                    ) >= self.TRACKING_THRESHOLD:
                                    c.set_ICMP_sent_sequence(
                                        c.get_ICMP_received_sequence() -
                                        self.TRACKING_ADJUST)

                                # get client related values: identifier and sequence number
                                identifier = c.get_ICMP_sent_identifier()
                                sequence = c.get_ICMP_sent_sequence()

                                # queueing every packet first
                                c.queue_put(readytogo)
                                # are there any packets to answer?
                                if (c.get_ICMP_received_sequence() -
                                        sequence) == 0:
                                    continue
                                else:
                                    request_num = 0
                                    # if there is less packet than that we have in the queue
                                    # then we cap the outgoing packet number
                                    if (c.get_ICMP_received_sequence() -
                                            sequence) < (c.queue_length()):
                                        number_to_get = (
                                            c.get_ICMP_received_sequence() -
                                            sequence)
                                    else:
                                        # send all packets from the queue
                                        number_to_get = c.queue_length()

                                    for i in range(0, number_to_get):
                                        # get first packet
                                        readytogo = c.queue_get()
                                        # is it he last one we are sending now?
                                        if i == (number_to_get - 1):
                                            # if the last one and there is more in the queue
                                            # then we ask for dummy packets
                                            request_num = c.queue_length()
                                        # go packets go!
                                        self.send(common.DATA_CHANNEL_BYTE,
                                                  readytogo,
                                                  ((socket.inet_ntoa(
                                                      c.get_public_ip_addr()),
                                                    c.get_public_src_port()),
                                                   identifier, sequence + i +
                                                   1, request_num))

                                    sequence = (sequence + i + 1) % 65536
                                    c.set_ICMP_sent_sequence(sequence)
                            else:
                                # there is no client with that IP
                                common.internal_print(
                                    "Client not found, strange?!", 0,
                                    self.verbosity, common.DEBUG)
                                continue
                        else:
                            if self.authenticated:
                                # whatever we have from the tunnel, just encapsulate it
                                # and send it out
                                self.ICMP_sequence = (self.ICMP_sequence +
                                                      1) % 65536
                                self.send(
                                    common.DATA_CHANNEL_BYTE, readytogo,
                                    (self.server_tuple, self.ICMP_identifier,
                                     self.ICMP_sequence, 0))  #??
                            else:
                                common.internal_print(
                                    "Spoofed packets, strange?!", 0,
                                    self.verbosity, common.DEBUG)
                                continue
                    if rc == 0:
                        # socket got signalled
                        message, addr, identifier, sequence, queue_length = self.recv(
                        )

                        if len(message) == 0:
                            continue

                        c = None
                        if self.serverorclient:
                            self.authenticated = False
                            c = self.lookup_client_pub((addr, 0))
                            if c:
                                c.set_ICMP_received_identifier(identifier)
                                # packets does not arrive in order sometime
                                # if higher sequence arrived already, then we
                                # do not modify
                                # 16bit integer MAX could be a bit tricky, a
                                # threshold had to be introduced to make it
                                # fail safe. Hacky but should work.
                                ICMP_THRESHOLD = 100
                                if (sequence > c.get_ICMP_received_sequence()
                                    ) or ((sequence < ICMP_THRESHOLD) and
                                          ((sequence + 65536) >
                                           c.get_ICMP_received_sequence()) and
                                          (c.get_ICMP_received_sequence() >
                                           ICMP_THRESHOLD)):
                                    c.set_ICMP_received_sequence(sequence)
                        else:
                            if queue_length:
                                common.internal_print(
                                    "sending {0} dummy packets".format(
                                        queue_length), 0, self.verbosity,
                                    common.DEBUG)
                                for i in range(queue_length + 10):
                                    self.ICMP_sequence = (self.ICMP_sequence +
                                                          1) % 65536
                                    self.do_dummy_packet(
                                        self.ICMP_identifier,
                                        self.ICMP_sequence)

                        if common.is_control_channel(message[0:1]):
                            if self.controlchannel.handle_control_messages(
                                    self,
                                    message[len(common.CONTROL_CHANNEL_BYTE):],
                                (addr, identifier, sequence, 0)):
                                continue
                            else:
                                self.stop()
                                break

                        if c:
                            self.authenticated = c.get_authenticated()

                        if self.authenticated:
                            try:
                                self.packet_writer(
                                    message[len(common.CONTROL_CHANNEL_BYTE):])
                            except OSError as e:
                                print(e)

            except win32api.error as e:
                common.internal_print("UDP Exception: {0}".format(e), -1)
            except socket.error as se:
                if se.args[0] == 10054:  # port is unreachable
                    common.internal_print(
                        "Server's port is unreachable: {0}".format(se), -1)
                    self._stop = True

        return True
예제 #17
0
    def communication_win(self, is_check):
        import win32event
        import win32file
        import win32api
        import pywintypes
        import winerror

        # event for the socket
        hEvent_sock = win32event.CreateEvent(None, 0, 0, None)
        win32file.WSAEventSelect(self.comms_socket, hEvent_sock,
                                 win32file.FD_READ)

        # event, overlapped struct for the pipe or tunnel
        hEvent_pipe = win32event.CreateEvent(None, 0, 0,
                                             None)  # for reading from the pipe
        overlapped_pipe = pywintypes.OVERLAPPED()
        overlapped_pipe.hEvent = hEvent_pipe

        # buffer for the packets
        message_readfile = win32file.AllocateReadBuffer(4096)

        # showing if we already async reading or not
        not_reading_already = True
        first_run = True
        while not self._stop:
            try:
                if not self.tunnel_r:
                    # user is not authenticated yet, so there is no pipe
                    # only checking the socket for data
                    rc = win32event.WaitForSingleObject(
                        hEvent_sock, int(self.timeout * 1000))
                    if rc == winerror.WAIT_TIMEOUT:
                        # timed out, just rerun and wait
                        continue
                else:
                    # client mode so we have the socket and tunnel as well
                    # or the client authenticated and the pipe was created
                    if first_run or not_reading_already:
                        # no ReadFile was called before or finished, so we
                        # are calling it again
                        hr, _ = win32file.ReadFile(self.tunnel_r,
                                                   message_readfile,
                                                   overlapped_pipe)
                        not_reading_already = first_run = False

                    if (hr == winerror.ERROR_IO_PENDING):
                        # well, this was an async read, so we need to wait
                        # until it happens
                        rc = win32event.WaitForMultipleObjects(
                            [hEvent_sock, hEvent_pipe], 0,
                            int(self.timeout * 1000))
                        if rc == winerror.WAIT_TIMEOUT:
                            # timed out, just rerun and wait
                            continue
                    else:
                        if hr != 0:
                            common.internal_print(
                                "{0} ReadFile failed: {1}".format(
                                    self.module_short, hr), -1)
                            raise

                if rc < 0x80:  # STATUS_ABANDONED_WAIT_0
                    if rc == 0:
                        # socket got signalled
                        not_reading_already = False
                        messages = self.recv()
                        for message in messages:
                            # looping through the messages from socket
                            if len(message) == 0:
                                # this could happen when the socket died or
                                # partial message was read.
                                continue

                            if common.is_control_channel(message[0:1]):
                                # parse control messages
                                if self.controlchannel.handle_control_messages(
                                        self,
                                        message[len(common.CONTROL_CHANNEL_BYTE
                                                    ):], None):
                                    continue
                                else:
                                    self.stop()
                                    break

                            if self.authenticated:
                                try:
                                    # write packet to the tunnel
                                    self.packet_writer(
                                        message[len(common.CONTROL_CHANNEL_BYTE
                                                    ):])
                                except OSError as e:
                                    print(e)  # wut?
                                except Exception as e:
                                    if e.args[0] == 995:
                                        common.internal_print(
                                            "Interface disappered, exiting thread: {0}"
                                            .format(e), -1)
                                        self.stop()
                                        continue

                    if rc == 1:
                        # pipe/tunnel got signalled
                        not_reading_already = True
                        if (overlapped_pipe.InternalHigh <
                                4) or (message_readfile[0:1] !=
                                       "\x45"):  #Only care about IPv4
                            # too small which should not happen or not IPv4, so we just drop it.
                            continue

                        # reading out the packet from the buffer and discarding the rest
                        readytogo = message_readfile[0:overlapped_pipe.
                                                     InternalHigh]
                        self.send(common.DATA_CHANNEL_BYTE, readytogo, None)

            except win32api.error as e:
                common.internal_print("TCP Exception: {0}".format(e), -1)

        self.cleanup()

        return True
예제 #18
0
 def testHashable(self):
     overlapped = pywintypes.OVERLAPPED()
     d = {}
     d[overlapped] = "hello"
     assert d[overlapped] == "hello"
예제 #19
0
    def test_transmit(self):
        import binascii
        bytes = os.urandom(1024*1024)
        val = binascii.hexlify(bytes)
        val_length = len(val)
        f = tempfile.TemporaryFile()
        f.write(val)

        def runner():
            s1 = socket.socket()
            self.addr = ('localhost', random.randint(10000,64000))
            s1.bind(self.addr)
            s1.listen(1)
            cli, addr = s1.accept()
            buf = 1
            self.request = []
            while buf:
                buf = cli.recv(1024*100)
                self.request.append(buf)

        th = threading.Thread(target=runner)
        th.start()
        time.sleep(0.5)
        s2 = socket.socket()
        s2.connect(self.addr)
        
        length = 0
        aaa = str2bytes("[AAA]")
        bbb = str2bytes("[BBB]")
        ccc = str2bytes("[CCC]")
        ddd = str2bytes("[DDD]")
        empty = str2bytes("")
        ol = pywintypes.OVERLAPPED()
        f.seek(0)
        win32file.TransmitFile(s2, win32file._get_osfhandle(f.fileno()), val_length, 0, ol, 0)
        length += win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        
        ol = pywintypes.OVERLAPPED()
        f.seek(0)
        win32file.TransmitFile(s2, win32file._get_osfhandle(f.fileno()), val_length, 0, ol, 0, aaa, bbb)
        length += win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        
        ol = pywintypes.OVERLAPPED()
        f.seek(0)
        win32file.TransmitFile(s2, win32file._get_osfhandle(f.fileno()), val_length, 0, ol, 0, empty, empty)
        length += win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        
        ol = pywintypes.OVERLAPPED()
        f.seek(0)
        win32file.TransmitFile(s2, win32file._get_osfhandle(f.fileno()), val_length, 0, ol, 0, None, ccc)
        length += win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        
        ol = pywintypes.OVERLAPPED()
        f.seek(0)
        win32file.TransmitFile(s2, win32file._get_osfhandle(f.fileno()), val_length, 0, ol, 0, ddd)
        length += win32file.GetOverlappedResult(s2.fileno(), ol, 1)
        
        s2.close()
        th.join()
        buf = str2bytes('').join(self.request)
        self.assertEqual(length, len(buf))
        expected = val + aaa + val + bbb + val + val + ccc + ddd + val
        self.assertEqual(type(expected), type(buf))
        self.assert_(expected == buf)
예제 #20
0
 def testComparable(self):
     overlapped = pywintypes.OVERLAPPED()
     assert overlapped == overlapped
     # ensure we explicitly test the operators.
     assert overlapped == overlapped
     assert not (overlapped != overlapped)
예제 #21
0
 def __exit__(self, type, value, traceback):
     win32file.UnlockFileEx(self.file_handle, 0, -0x10000,
                            pywintypes.OVERLAPPED())
     self.file.close()
예제 #22
0
    def init_client(self, control_message, additional_data):
        self.client = client.Client()
        self.client.set_socket(self.comms_socket)

        # stripping out the private IP from the message
        client_private_ip = control_message[0:4]
        # saving public IP address and port
        client_public_source_ip = socket.inet_aton(self.client_addr[0])
        client_public_source_port = self.client_addr[1]

        # If this private IP is already used, the server removes that client.
        # For example: client reconnect on connection reset, duplicated configs
        # and yes, this can be used to kick somebody off the tunnel
        for c in self.packetselector.get_clients():
            if c.get_private_ip_addr() == client_private_ip:
                self.packetselector.delete_client(c)

        # creating new pipes for the client
        if self.os_type == common.OS_WINDOWS:
            import win32pipe
            import win32file
            import pywintypes
            import win32event

            import win32api
            import winerror

            overlapped = pywintypes.OVERLAPPED()
            # setting up nameslot
            mailslotname = "\\\\.\\mailslot\\XFLTReaT_{0}".format(
                socket.inet_ntoa(client_private_ip))

            mailslot_r = win32file.CreateMailslot(mailslotname, 0, -1, None)
            if (mailslot_r == None) or (mailslot_r
                                        == win32file.INVALID_HANDLE_VALUE):
                internal_print("Invalid handle - mailslot", -1)
                sys.exit(-1)

            mailslot_w = win32file.CreateFile(
                mailslotname, win32file.GENERIC_WRITE,
                win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, None,
                win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL
                | win32file.FILE_FLAG_OVERLAPPED, None)
            if (mailslot_w == None) or (mailslot_w
                                        == win32file.INVALID_HANDLE_VALUE):
                internal_print("Invalid handle - readable pipe", -1)
                sys.exit(-1)

            self.client.set_pipes_fdnum(mailslot_r, mailslot_w)

        else:
            pipe_r, pipe_w = os.pipe()
            self.client.set_pipes_fdnum(pipe_r, pipe_w)
            self.client.set_pipes_fd(os.fdopen(pipe_r, "r"),
                                     os.fdopen(pipe_w, "w"))

        # set connection related things and authenticated to True
        self.client.set_public_ip_addr(client_public_source_ip)
        self.client.set_public_src_port(client_public_source_port)
        self.client.set_private_ip_addr(client_private_ip)
        self.client.set_stopfp(self.stop)

        # unifying encryption variable

        self.client.get_encryption().set_module(self.encryption.get_module())
        self.encryption = self.client.get_encryption()

        if self.encryption.get_module().get_step_count():
            # add encryption steps
            self.merge_cmh(self.encryption.get_module().get_cmh_struct())

        if self.authentication.get_step_count():
            # add authentication steps
            self.merge_cmh(self.authentication.get_cmh_struct())

        self.client.set_initiated(True)

        return
예제 #23
0
    class _Win32Opener(_Opener):
        """Open, lock, and unlock a file using windows primitives."""

        # Error #33:
        #  'The process cannot access the file because another process'
        FILE_IN_USE_ERROR = 33

        # Error #158:
        #  'The segment is already unlocked.'
        FILE_ALREADY_UNLOCKED_ERROR = 158

        def open_and_lock(self, timeout, delay):
            """Open the file and lock it.

      Args:
        timeout: float, How long to try to lock for.
        delay: float, How long to wait between retries

      Raises:
        AlreadyLockedException: if the lock is already acquired.
        IOError: if the open fails.
        CredentialsFileSymbolicLinkError if the file is a symbolic link.
      """
            if self._locked:
                raise AlreadyLockedException('File %s is already locked' %
                                             self._filename)
            start_time = time.time()

            validate_file(self._filename)
            try:
                self._fh = open(self._filename, self._mode)
            except IOError, e:
                # If we can't access with _mode, try _fallback_mode and don't lock.
                if e.errno == errno.EACCES:
                    self._fh = open(self._filename, self._fallback_mode)
                    return

            # We opened in _mode, try to lock the file.
            while True:
                try:
                    hfile = win32file._get_osfhandle(self._fh.fileno())
                    win32file.LockFileEx(hfile,
                                         (win32con.LOCKFILE_FAIL_IMMEDIATELY
                                          | win32con.LOCKFILE_EXCLUSIVE_LOCK),
                                         0, -0x10000, pywintypes.OVERLAPPED())
                    self._locked = True
                    return
                except pywintypes.error, e:
                    if timeout == 0:
                        raise e

                    # If the error is not that the file is already in use, raise.
                    if e[0] != _Win32Opener.FILE_IN_USE_ERROR:
                        raise

                    # We could not acquire the lock. Try again.
                    if (time.time() - start_time) >= timeout:
                        logger.warn('Could not lock %s in %s seconds' %
                                    (self._filename, timeout))
                        if self._fh:
                            self._fh.close()
                        self._fh = open(self._filename, self._fallback_mode)
                        return
                    time.sleep(delay)
예제 #24
0
    def lock(file_, flags):
        if flags & constants.LOCK_SH:
            import win32file
            import pywintypes
            import winerror
            __overlapped = pywintypes.OVERLAPPED()
            if sys.version_info.major == 2:
                if flags & constants.LOCK_NB:
                    mode = constants.LOCKFILE_FAIL_IMMEDIATELY
                else:
                    mode = 0

            else:
                if flags & constants.LOCK_NB:
                    mode = msvcrt.LK_NBRLCK
                else:
                    mode = msvcrt.LK_RLCK

            # is there any reason not to reuse the following structure?
            hfile = win32file._get_osfhandle(file_.fileno())
            try:
                win32file.LockFileEx(hfile, mode, 0, -0x10000, __overlapped)
            except pywintypes.error as exc_value:
                # error: (33, 'LockFileEx', 'The process cannot access the file
                # because another process has locked a portion of the file.')
                if exc_value.winerror == winerror.ERROR_LOCK_VIOLATION:
                    raise exceptions.LockException(
                        exceptions.LockException.LOCK_FAILED,
                        exc_value.strerror,
                        fh=file_)
                else:
                    # Q:  Are there exceptions/codes we should be dealing with
                    # here?
                    raise
        else:
            mode = constants.LOCKFILE_EXCLUSIVE_LOCK
            if flags & constants.LOCK_NB:
                mode |= constants.LOCKFILE_FAIL_IMMEDIATELY

            if flags & constants.LOCK_NB:
                mode = msvcrt.LK_NBLCK
            else:
                mode = msvcrt.LK_LOCK

            # windows locks byte ranges, so make sure to lock from file start
            try:
                savepos = file_.tell()
                if savepos:
                    # [ ] test exclusive lock fails on seek here
                    # [ ] test if shared lock passes this point
                    file_.seek(0)
                    # [x] check if 0 param locks entire file (not documented in
                    #     Python)
                    # [x] fails with "IOError: [Errno 13] Permission denied",
                    #     but -1 seems to do the trick

                try:
                    msvcrt.locking(file_.fileno(), mode, lock_length)
                except IOError as exc_value:
                    # [ ] be more specific here
                    raise exceptions.LockException(
                        exceptions.LockException.LOCK_FAILED,
                        exc_value.strerror,
                        fh=file_)
                finally:
                    if savepos:
                        file_.seek(savepos)
            except IOError as exc_value:
                raise exceptions.LockException(
                    exceptions.LockException.LOCK_FAILED,
                    exc_value.strerror,
                    fh=file_)
예제 #25
0
        try:
            import win32con
            import win32file
            import pywintypes
            os_locking = 'windows'
        except:
            pass

if os_locking == 'windows':
    LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
    LOCK_SH = 0  # the default
    LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY

    # is there any reason not to reuse the following structure?

    __overlapped = pywintypes.OVERLAPPED()

    def lock(file, flags):
        hfile = win32file._get_osfhandle(file.fileno())
        win32file.LockFileEx(hfile, flags, 0, 0x7fff0000, __overlapped)

    def unlock(file):
        hfile = win32file._get_osfhandle(file.fileno())
        win32file.UnlockFileEx(hfile, 0, 0x7fff0000, __overlapped)


elif os_locking == 'posix':
    LOCK_EX = fcntl.LOCK_EX
    LOCK_SH = fcntl.LOCK_SH
    LOCK_NB = fcntl.LOCK_NB
예제 #26
0
 def __init__(self, args):
     win32serviceutil.ServiceFramework.__init__(self, args)
     self.hWaitStop = CreateEvent(None, 0, 0, None)
     self.overlapped = pywintypes.OVERLAPPED()
     self.overlapped.hEvent = CreateEvent(None, 0, 0, None)
     self.thread_handles = []
 def testComparable(self):
     overlapped = pywintypes.OVERLAPPED()
     self.failUnlessEqual(overlapped, overlapped)
     # ensure we explicitly test the operators.
     self.failUnless(overlapped == overlapped)
     self.failIf(overlapped != overlapped)
예제 #28
0
    def __init__(self, autoSetup=False):

        #These can be used, or not.
        self.myGUID = ""
        self.myInterface = 0
        self.trimEthnHeaders = False
        self.ethernetMTU = 1500
        self.myMACaddr = b""
        self.writeDataQueue = queue.Queue()
        self.dataThreads = []

        #Set up an overlapped structure for deviceIoControl
        #This originally created an array of overlapped stuctures used throughout this class, but now threads create their own for safety
        self.overlapped = pywintypes.OVERLAPPED()
        self.overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)

        #Some function encapsulation
        #In case anyone else reads this, the tap control codes use the windows io control code interface to pass special
        #codes to the tap driver. Also, some constants are borrowed from the win iocontrol library (which are simply replaced with numbers here)
        self.TAP_IOCTL_GET_MAC = self.TAP_CONTROL_CODE(1, 0)
        self.TAP_IOCTL_GET_VERSION = self.TAP_CONTROL_CODE(2, 0)
        self.TAP_IOCTL_GET_MTU = self.TAP_CONTROL_CODE(3, 0)
        self.TAP_IOCTL_GET_INFO = self.TAP_CONTROL_CODE(4, 0)
        self.TAP_IOCTL_CONFIG_POINT_TO_POINT = self.TAP_CONTROL_CODE(
            5, 0)  #This call has been obsoleted, use CONFIG_TUN instead
        self.TAP_IOCTL_SET_MEDIA_STATUS = self.TAP_CONTROL_CODE(6, 0)
        self.TAP_IOCTL_CONFIG_DHCP_MASQ = self.TAP_CONTROL_CODE(7, 0)
        self.TAP_IOCTL_GET_LOG_LINE = self.TAP_CONTROL_CODE(8, 0)
        self.TAP_IOCTL_CONFIG_DHCP_SET_OPT = self.TAP_CONTROL_CODE(9, 0)
        self.TAP_IOCTL_CONFIG_TUN = self.TAP_CONTROL_CODE(10, 0)

        #Whether the object should attempt to initialize itself
        if autoSetup:
            self.myGUID = self.getDeviceGUID()

            #Force close if no adapter was found
            if not self.myGUID:
                alert(
                    "Fatal error: could not locate tap adapter. (Is the adapter properly installed?) \nAutoclosing in 5 seconds.",
                    "_all")
                time.sleep(5)
                sys.exit()

            alert("Tap GUID: " + self.myGUID)

            self.myInterface = self.createInterface()
            print(self.myInterface)
            if (self.myInterface):
                #Connect media, and get our MAC address
                self.setMediaConnectionStatus(True)
                self.updateMAC()
            else:
                alert(
                    "Failed to interface with TAP adapter. Exiting in 5 seconds.",
                    "_all")
                time.sleep(5)
                sys.exit()

            self.dataThreads.append(
                threading.Thread(target=self.dataListenerThread,
                                 args=(mainTaskQueue, ethernetMTU),
                                 daemon=True))
            self.dataThreads.append(
                threading.Thread(target=self.dataWriterThread,
                                 args=(self.writeDataQueue, ),
                                 daemon=True))
            self.dataThreads[0].start()
            alert('Data listener thread started as daemon.')
            self.dataThreads[1].start()
            alert('Data injector thread started as daemon.')