Example #1
0
 def _pipe_write(self, buf):
     size = len(buf)
     log("pipe_write: %i bytes", size)  #binascii.hexlify(buf))
     written = c_ulong(0)
     r = WriteFile(self.pipe_handle, c_char_p(buf), len(buf),
                   byref(written), byref(self.write_overlapped))
     log("WriteFile(..)=%s, len=%i", r, written.value)
     if not r and self.pipe_handle:
         e = GetLastError()
         if e != ERROR_IO_PENDING:
             log("WriteFile: %s", IO_ERROR_STR.get(e, e))
         r = WaitForSingleObject(self.write_event, INFINITE)
         log("WaitForSingleObject(..)=%s, len=%i", WAIT_STR.get(r, r),
             written.value)
         if not self.pipe_handle:
             #closed already!
             return written.value
         if r:
             raise Exception(
                 "failed to write buffer to named pipe handle %s" %
                 self.pipe_handle)
     if self.pipe_handle:
         if not GetOverlappedResult(self.pipe_handle,
                                    byref(self.write_overlapped),
                                    byref(written), False):
             e = GetLastError()
             raise Exception("overlapped write failed: %s" %
                             IO_ERROR_STR.get(e, e))
         log("pipe_write: %i bytes written", written.value)
         if self.pipe_handle:
             FlushFileBuffers(self.pipe_handle)
     #SetFilePointer(self.pipe_handle, 0, FILE_BEGIN)
     return written.value
Example #2
0
 def _pipe_read(self, n):
     read = c_ulong(0)
     n_bytes = DWORD(min(n, BUFSIZE))
     r = ReadFile(self.pipe_handle, self.read_buffer_ptr, n_bytes, byref(read), byref(self.read_overlapped))
     log("ReadFile(%i)=%i, len=%s", n, r, read.value)
     if not r and self.pipe_handle:
         e = GetLastError()
         if e!=ERROR_IO_PENDING:
             log("ReadFile: %s", IO_ERROR_STR.get(e, e))
             if e in CONNECTION_CLOSED_ERRORS:
                 raise ConnectionClosedException(CONNECTION_CLOSED_ERRORS[e])
         r = WaitForSingleObject(self.read_event, INFINITE)
         log("WaitForSingleObject(..)=%s, len=%s", WAIT_STR.get(r, r), read.value)
         if r and self.pipe_handle:
             raise Exception("failed to read from named pipe handle %s" % self.pipe_handle)
     if self.pipe_handle:
         if not GetOverlappedResult(self.pipe_handle, byref(self.read_overlapped), byref(read), False):
             e = GetLastError()
             if e in CONNECTION_CLOSED_ERRORS:
                 raise ConnectionClosedException(CONNECTION_CLOSED_ERRORS[e])
             raise Exception("overlapped read failed: %s" % IO_ERROR_STR.get(e, e))
     if read.value==0:
         data = None
     else:
         data = string_at(self.read_buffer_ptr, read.value)
     log("pipe_read: %i bytes", len(data or ""))          #, binascii.hexlify(s))
     return data
Example #3
0
 def _pipe_read(self, buf):
     read = c_ulong(0)
     r = ReadFile(self.pipe_handle, self.read_buffer_ptr, BUFSIZE,
                  byref(read), byref(self.read_overlapped))
     log("ReadFile(..)=%i, len=%s", r, read.value)
     if not r and self.pipe_handle:
         e = GetLastError()
         if e != ERROR_IO_PENDING:
             log("ReadFile: %s", IO_ERROR_STR.get(e, e))
         r = WaitForSingleObject(self.read_event, INFINITE)
         log("WaitForSingleObject(..)=%s, len=%s", WAIT_STR.get(r, r),
             read.value)
         if r and self.pipe_handle:
             raise Exception("failed to read from named pipe handle %s" %
                             self.pipe_handle)
     if self.pipe_handle:
         if not GetOverlappedResult(self.pipe_handle,
                                    byref(self.read_overlapped),
                                    byref(read), False):
             e = GetLastError()
             if e != ERROR_BROKEN_PIPE:
                 raise Exception("overlapped read failed: %s" %
                                 IO_ERROR_STR.get(e, e))
     if read.value == 0:
         data = None
     else:
         data = string_at(self.read_buffer_ptr, read.value)
     log("pipe_read: %i bytes", len(data or ""))  #, binascii.hexlify(s))
     return data
Example #4
0
 def do_run(self):
     pipe_handle = None
     while not self.exit_loop:
         if not pipe_handle:
             try:
                 pipe_handle = self.CreatePipeHandle()
             except Exception as e:
                 log("CreatePipeHandle()", exc_info=True)
                 log.error("Error: failed to create named pipe")
                 log.error(" at path '%s'", self.pipe_name)
                 log.error(" %s", e)
                 return
             log("CreatePipeHandle()=%#x", pipe_handle)
             if c_long(pipe_handle).value==INVALID_HANDLE_VALUE:
                 log.error("Error: invalid handle for named pipe '%s'", self.pipe_name)
                 e = GetLastError()
                 log.error(" '%s' (%i)", FormatMessageSystem(e).rstrip("\n\r."), e)
                 return
         event = CreateEventA(None, True, False, None)
         overlapped = OVERLAPPED()
         overlapped.hEvent = event
         overlapped.Internal = None
         overlapped.InternalHigh = None
         overlapped.union.Pointer = None
         r = ConnectNamedPipe(pipe_handle, overlapped)
         log("ConnectNamedPipe()=%s", r)
         if self.exit_loop:
             break
         if r==0:
             e = GetLastError()
             log("GetLastError()=%s (%i)", FormatMessageSystem(e).rstrip("\n\r"), e)
             if e==ERROR_PIPE_CONNECTED:
                 pass
             elif e==ERROR_IO_PENDING:
                 while not self.exit_loop:
                     r = WaitForSingleObject(event, INFINITE)
                     log("WaitForSingleObject(..)=%s", WAIT_STR.get(r, r))
                     if r==WAIT_TIMEOUT:
                         continue
                     if r==0:
                         break
                     log.error("Error: cannot connect to named pipe '%s'", self.pipe_name)
                     log.error(" %s", WAIT_STR.get(r, r))
                     CloseHandle(pipe_handle)
                     pipe_handle = None
                     break
             else:
                 log.error("Error: cannot connect to named pipe '%s'", self.pipe_name)
                 log.error(" error %s", e)
                 CloseHandle(pipe_handle)
                 pipe_handle = None
             if self.exit_loop:
                 break
         #from now on, the pipe_handle will be managed elsewhere:
         if pipe_handle:
             self.new_connection_cb("named-pipe", self, pipe_handle)
             pipe_handle = None
     if pipe_handle:
         self.close_handle(pipe_handle)
Example #5
0
def connect_to_namedpipe(pipe_name, timeout=10):
    log("connect_to_namedpipe(%s, %i)", pipe_name, timeout)
    import time
    start = time.time()
    while True:
        if time.time() - start >= timeout:
            raise Exception("timeout waiting for named pipe '%s'" % pipe_name)
        pipe_handle = CreateFileA(strtobytes(pipe_name),
                                  GENERIC_READ | GENERIC_WRITE, 0, None,
                                  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)
        log("CreateFileA(%s)=%#x", pipe_name, pipe_handle)
        if pipe_handle != INVALID_HANDLE_VALUE:
            break
        err = GetLastError()
        log("CreateFileA(..) error=%s", err)
        if err == ERROR_PIPE_BUSY:
            if WaitNamedPipeA(pipe_name, timeout * 10000) == 0:
                raise Exception("timeout waiting for named pipe '%s'" %
                                pipe_name)
        else:
            raise Exception("cannot open named pipe '%s': %s" %
                            (pipe_name, FormatMessageSystem(err)))
    #we have a valid handle!
    dwMode = c_ulong(PIPE_READMODE_BYTE)
    r = SetNamedPipeHandleState(pipe_handle, byref(dwMode), None, None)
    log("SetNamedPipeHandleState(..)=%i", r)
    if not r:
        log.warn("Warning: SetNamedPipeHandleState failed")
    return pipe_handle
Example #6
0
 def untilConcludes(self, fn, *args, **kwargs):
     try:
         return super().untilConcludes(fn, *args, **kwargs)
     except Exception as e:
         code = GetLastError()
         log("untilConcludes(%s, ) exception: %s, error code=%s", fn, e, code, exc_info=True)
         closed = CONNECTION_CLOSED_ERRORS.get(code)
         if closed:
             return None
         raise IOError("%s: %s" % (e, code)) from None
Example #7
0
 def untilConcludes(self, fn, *args, **kwargs):
     try:
         return Connection.untilConcludes(self, fn, *args, **kwargs)
     except Exception as e:
         code = GetLastError()
         log("untilConcludes(%s, ) exception: %s, error code=%s",
             fn,
             e,
             code,
             exc_info=True)
         if code == ERROR_PIPE_NOT_CONNECTED:
             return None
         raise IOError("%s: %s" % (e, code))
Example #8
0
 def GetToken(self, token_type, token_struct):
     assert self.token_process
     data_size = DWORD()
     if not GetTokenInformation(self.token_process, token_type, 0, 0, byref(data_size)):
         if GetLastError()!=ERROR_INSUFFICIENT_BUFFER:
             raise WindowsError()  # @UndefinedVariable
     log("GetTokenInformation data size %#x", data_size.value)
     token_data = create_string_buffer(data_size.value)
     self.tokens.append(token_data)
     if not GetTokenInformation(self.token_process, token_type, byref(token_data), data_size.value, byref(data_size)):
         raise WindowsError()    #@UndefinedVariable
     token = cast(token_data, POINTER(token_struct)).contents
     return token
Example #9
0
 def do_run(self):
     while not self.exit_loop:
         pipe_handle = None
         try:
             pipe_handle = self.CreatePipeHandle()
         except Exception as e:
             log("CreatePipeHandle()", exc_info=True)
             log.error("Error: failed to create named pipe")
             log.error(" at path '%s'", self.pipe_name)
             log.error(" %s", e)
             return
         log("CreatePipeHandle()=%s", pipe_handle)
         if pipe_handle == INVALID_HANDLE_VALUE:
             log.error("Error: invalid handle for named pipe '%s'",
                       self.pipe_name)
             return
         event = CreateEventA(None, True, False, None)
         overlapped = OVERLAPPED()
         overlapped.hEvent = event
         overlapped.Internal = None
         overlapped.InternalHigh = None
         overlapped.union.Pointer = None
         r = ConnectNamedPipe(pipe_handle, overlapped)
         log("ConnectNamedPipe()=%s", r)
         if not r and not self.exit_loop:
             r = WaitForSingleObject(event, INFINITE)
             log("WaitForSingleObject(..)=%s", WAIT_STR.get(r, r))
             if r:
                 log("do_run() error on WaitForSingleObject", exc_info=True)
                 log.error("Error: cannot connect to named pipe '%s'",
                           self.pipe_name)
                 CloseHandle(pipe_handle)
                 continue
         if self.exit_loop:
             CloseHandle(pipe_handle)
             break
         if r == 0 and False:
             e = GetLastError()
             if e == ERROR_PIPE_CONNECTED:
                 pass
             else:
                 log.error("Error: cannot connect to named pipe '%s'",
                           self.pipe_name)
                 log.error(" error %s", e)
                 CloseHandle(pipe_handle)
                 continue
         #from now on, the pipe_handle will be managed elsewhere:
         self.new_connection_cb(self, pipe_handle)
Example #10
0
    def CreatePipeSecurityAttributes(self):
        user = self.GetToken(TokenUser, TOKEN_USER)
        user_SID = user.SID.contents
        log("user SID=%s, attributes=%#x", user_SID, user.ATTRIBUTES)

        group = self.GetToken(TokenPrimaryGroup, TOKEN_PRIMARY_GROUP)
        group_SID = group.PrimaryGroup.contents
        log("group SID=%s", group_SID)

        SD = SECURITY_DESCRIPTOR()
        self.security_descriptor = SD
        log("SECURITY_DESCRIPTOR=%s", SD)
        if not InitializeSecurityDescriptor(byref(SD),
                                            SECURITY_DESCRIPTOR.REVISION):
            raise WindowsError()  #@UndefinedVariable
        log("InitializeSecurityDescriptor: %s", SD)
        if not SetSecurityDescriptorOwner(byref(SD), user.SID, False):
            raise WindowsError()  #@UndefinedVariable
        log("SetSecurityDescriptorOwner: %s", SD)
        if not SetSecurityDescriptorGroup(byref(SD), group.PrimaryGroup,
                                          False):
            raise WindowsError()  #@UndefinedVariable
        log("SetSecurityDescriptorGroup: %s", SD)
        SA = SECURITY_ATTRIBUTES()
        log("CreatePipeSecurityObject() SECURITY_ATTRIBUTES=%s", SA)
        if not UNRESTRICTED:
            SA.descriptor = SD
            SA.bInheritHandle = False
            return SA
        if not SetSecurityDescriptorSacl(byref(SD), False, None, False):
            raise WindowsError()  #@UndefinedVariable
        if not SetSecurityDescriptorDacl(byref(SD), True, None, False):
            raise WindowsError()  #@UndefinedVariable
        #this doesn't work - and I don't know why:
        #SECURITY_NT_AUTHORITY = 5
        #sia_anonymous = SID_IDENTIFIER_AUTHORITY((0, 0, 0, 0, 0, SECURITY_NT_AUTHORITY))
        #log("SID_IDENTIFIER_AUTHORITY(SECURITY_NT_AUTHORITY)=%s", sia_anonymous)
        #sid_allow = SID()
        #log("empty SID: %s", sid_allow)
        #if not AllocateAndInitializeSid(byref(sia_anonymous), 1,
        #                         SECURITY_ANONYMOUS_LOGON_RID, 0, 0, 0, 0, 0, 0, 0,
        #                         byref(sid_allow),
        #                         ):
        #    raise WindowsError()
        #    log("AllocateAndInitializeSid(..) sid_anonymous=%s", sid_allow)
        sid_allow = SID()
        sid_size = DWORD(sizeof(SID))
        sid_type = WinWorldSid
        SECURITY_MAX_SID_SIZE = 68
        assert sizeof(SID) >= SECURITY_MAX_SID_SIZE
        if not CreateWellKnownSid(sid_type, None, byref(sid_allow),
                                  byref(sid_size)):
            log.error("error=%s", GetLastError())
            raise WindowsError()  #@UndefinedVariable
        assert sid_size.value <= SECURITY_MAX_SID_SIZE
        log("CreateWellKnownSid(..) sid_allow=%s, sid_size=%s", sid_allow,
            sid_size)

        acl_size = sizeof(ACL)
        acl_size += 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
        acl_size += GetLengthSid(byref(sid_allow))
        acl_size += GetLengthSid(byref(user.SID.contents))
        #acl_size += GetLengthSid(user.SID)
        acl_data = create_string_buffer(acl_size)
        acl = cast(acl_data, POINTER(ACL)).contents
        log("acl_size=%s, acl_data=%s, acl=%s", acl_size, acl_data, acl)
        if not InitializeAcl(byref(acl), acl_size, ACL_REVISION):
            raise WindowsError()  #@UndefinedVariable
        log("InitializeAcl(..) acl=%s", acl)

        rights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL
        add_sid = user.SID
        r = AddAccessAllowedAce(byref(acl), ACL_REVISION, rights, add_sid)
        if r == 0:
            err = GetLastError()
            log("AddAccessAllowedAce(..)=%s", ACL_ERRORS.get(err, err))
            raise WindowsError()  #@UndefinedVariable

        rights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL
        add_sid = byref(sid_allow)
        r = AddAccessAllowedAce(byref(acl), ACL_REVISION, rights, add_sid)
        if r == 0:
            err = GetLastError()
            log("AddAccessAllowedAce(..)=%s", ACL_ERRORS.get(err, err))
            raise WindowsError()  #@UndefinedVariable
        if not SetSecurityDescriptorDacl(byref(SD), True, byref(acl), False):
            raise WindowsError()  #@UndefinedVariable
        SA.nLength = sizeof(SECURITY_ATTRIBUTES)
        SA.lpSecurityDescriptor = cast(pointer(SD), c_void_p)
        SA.bInheritHandle = True
        self.security_attributes = SA
        return SA