diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..43ae0e2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+__pycache__/
+*.py[cod]
diff --git a/lib/bgr233_palette.py b/lib/bgr233_palette.py
new file mode 100644
index 0000000..8fa16b2
--- /dev/null
+++ b/lib/bgr233_palette.py
@@ -0,0 +1,260 @@
+# BGR233 palette
+
+palette = [
+ 0, 0, 0,
+ 36, 0, 0,
+ 73, 0, 0,
+ 109, 0, 0,
+ 146, 0, 0,
+ 182, 0, 0,
+ 219, 0, 0,
+ 255, 0, 0,
+ 0, 36, 0,
+ 36, 36, 0,
+ 73, 36, 0,
+ 109, 36, 0,
+ 146, 36, 0,
+ 182, 36, 0,
+ 219, 36, 0,
+ 255, 36, 0,
+ 0, 73, 0,
+ 36, 73, 0,
+ 73, 73, 0,
+ 109, 73, 0,
+ 146, 73, 0,
+ 182, 73, 0,
+ 219, 73, 0,
+ 255, 73, 0,
+ 0, 109, 0,
+ 36, 109, 0,
+ 73, 109, 0,
+ 109, 109, 0,
+ 146, 109, 0,
+ 182, 109, 0,
+ 219, 109, 0,
+ 255, 109, 0,
+ 0, 146, 0,
+ 36, 146, 0,
+ 73, 146, 0,
+ 109, 146, 0,
+ 146, 146, 0,
+ 182, 146, 0,
+ 219, 146, 0,
+ 255, 146, 0,
+ 0, 182, 0,
+ 36, 182, 0,
+ 73, 182, 0,
+ 109, 182, 0,
+ 146, 182, 0,
+ 182, 182, 0,
+ 219, 182, 0,
+ 255, 182, 0,
+ 0, 219, 0,
+ 36, 219, 0,
+ 73, 219, 0,
+ 109, 219, 0,
+ 146, 219, 0,
+ 182, 219, 0,
+ 219, 219, 0,
+ 255, 219, 0,
+ 0, 255, 0,
+ 36, 255, 0,
+ 73, 255, 0,
+ 109, 255, 0,
+ 146, 255, 0,
+ 182, 255, 0,
+ 219, 255, 0,
+ 255, 255, 0,
+ 0, 0, 85,
+ 36, 0, 85,
+ 73, 0, 85,
+ 109, 0, 85,
+ 146, 0, 85,
+ 182, 0, 85,
+ 219, 0, 85,
+ 255, 0, 85,
+ 0, 36, 85,
+ 36, 36, 85,
+ 73, 36, 85,
+ 109, 36, 85,
+ 146, 36, 85,
+ 182, 36, 85,
+ 219, 36, 85,
+ 255, 36, 85,
+ 0, 73, 85,
+ 36, 73, 85,
+ 73, 73, 85,
+ 109, 73, 85,
+ 146, 73, 85,
+ 182, 73, 85,
+ 219, 73, 85,
+ 255, 73, 85,
+ 0, 109, 85,
+ 36, 109, 85,
+ 73, 109, 85,
+ 109, 109, 85,
+ 146, 109, 85,
+ 182, 109, 85,
+ 219, 109, 85,
+ 255, 109, 85,
+ 0, 146, 85,
+ 36, 146, 85,
+ 73, 146, 85,
+ 109, 146, 85,
+ 146, 146, 85,
+ 182, 146, 85,
+ 219, 146, 85,
+ 255, 146, 85,
+ 0, 182, 85,
+ 36, 182, 85,
+ 73, 182, 85,
+ 109, 182, 85,
+ 146, 182, 85,
+ 182, 182, 85,
+ 219, 182, 85,
+ 255, 182, 85,
+ 0, 219, 85,
+ 36, 219, 85,
+ 73, 219, 85,
+ 109, 219, 85,
+ 146, 219, 85,
+ 182, 219, 85,
+ 219, 219, 85,
+ 255, 219, 85,
+ 0, 255, 85,
+ 36, 255, 85,
+ 73, 255, 85,
+ 109, 255, 85,
+ 146, 255, 85,
+ 182, 255, 85,
+ 219, 255, 85,
+ 255, 255, 85,
+ 0, 0, 170,
+ 36, 0, 170,
+ 73, 0, 170,
+ 109, 0, 170,
+ 146, 0, 170,
+ 182, 0, 170,
+ 219, 0, 170,
+ 255, 0, 170,
+ 0, 36, 170,
+ 36, 36, 170,
+ 73, 36, 170,
+ 109, 36, 170,
+ 146, 36, 170,
+ 182, 36, 170,
+ 219, 36, 170,
+ 255, 36, 170,
+ 0, 73, 170,
+ 36, 73, 170,
+ 73, 73, 170,
+ 109, 73, 170,
+ 146, 73, 170,
+ 182, 73, 170,
+ 219, 73, 170,
+ 255, 73, 170,
+ 0, 109, 170,
+ 36, 109, 170,
+ 73, 109, 170,
+ 109, 109, 170,
+ 146, 109, 170,
+ 182, 109, 170,
+ 219, 109, 170,
+ 255, 109, 170,
+ 0, 146, 170,
+ 36, 146, 170,
+ 73, 146, 170,
+ 109, 146, 170,
+ 146, 146, 170,
+ 182, 146, 170,
+ 219, 146, 170,
+ 255, 146, 170,
+ 0, 182, 170,
+ 36, 182, 170,
+ 73, 182, 170,
+ 109, 182, 170,
+ 146, 182, 170,
+ 182, 182, 170,
+ 219, 182, 170,
+ 255, 182, 170,
+ 0, 219, 170,
+ 36, 219, 170,
+ 73, 219, 170,
+ 109, 219, 170,
+ 146, 219, 170,
+ 182, 219, 170,
+ 219, 219, 170,
+ 255, 219, 170,
+ 0, 255, 170,
+ 36, 255, 170,
+ 73, 255, 170,
+ 109, 255, 170,
+ 146, 255, 170,
+ 182, 255, 170,
+ 219, 255, 170,
+ 255, 255, 170,
+ 0, 0, 255,
+ 36, 0, 255,
+ 73, 0, 255,
+ 109, 0, 255,
+ 146, 0, 255,
+ 182, 0, 255,
+ 219, 0, 255,
+ 255, 0, 255,
+ 0, 36, 255,
+ 36, 36, 255,
+ 73, 36, 255,
+ 109, 36, 255,
+ 146, 36, 255,
+ 182, 36, 255,
+ 219, 36, 255,
+ 255, 36, 255,
+ 0, 73, 255,
+ 36, 73, 255,
+ 73, 73, 255,
+ 109, 73, 255,
+ 146, 73, 255,
+ 182, 73, 255,
+ 219, 73, 255,
+ 255, 73, 255,
+ 0, 109, 255,
+ 36, 109, 255,
+ 73, 109, 255,
+ 109, 109, 255,
+ 146, 109, 255,
+ 182, 109, 255,
+ 219, 109, 255,
+ 255, 109, 255,
+ 0, 146, 255,
+ 36, 146, 255,
+ 73, 146, 255,
+ 109, 146, 255,
+ 146, 146, 255,
+ 182, 146, 255,
+ 219, 146, 255,
+ 255, 146, 255,
+ 0, 182, 255,
+ 36, 182, 255,
+ 73, 182, 255,
+ 109, 182, 255,
+ 146, 182, 255,
+ 182, 182, 255,
+ 219, 182, 255,
+ 255, 182, 255,
+ 0, 219, 255,
+ 36, 219, 255,
+ 73, 219, 255,
+ 109, 219, 255,
+ 146, 219, 255,
+ 182, 219, 255,
+ 219, 219, 255,
+ 255, 219, 255,
+ 0, 255, 255,
+ 36, 255, 255,
+ 73, 255, 255,
+ 109, 255, 255,
+ 146, 255, 255,
+ 182, 255, 255,
+ 219, 255, 255,
+ 255, 255, 255
+]
diff --git a/lib/encodings/__init__.py b/lib/encodings/__init__.py
index 4d4f35d..2ee2e55 100644
--- a/lib/encodings/__init__.py
+++ b/lib/encodings/__init__.py
@@ -16,5 +16,7 @@
# along with this program. If not, see .
# at least, raw encoding is needed by the rfb protocol
-from . import common as enc
+from . import common
from . import raw
+from . import zlib
+from . import cursor
diff --git a/lib/encodings/common.py b/lib/encodings/common.py
index 948fa94..4b421b6 100644
--- a/lib/encodings/common.py
+++ b/lib/encodings/common.py
@@ -15,5 +15,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see .
+encodings = {}
+
class ENCODINGS:
- pass
\ No newline at end of file
+ raw = 0
+ zlib = 6
+ # supported pseudo-encodings
+ cursor = -239
+
+encodings_priority = [
+ ENCODINGS.zlib,
+ ENCODINGS.raw
+]
diff --git a/lib/encodings/cursor.py b/lib/encodings/cursor.py
index 37cb736..6fbe3a6 100644
--- a/lib/encodings/cursor.py
+++ b/lib/encodings/cursor.py
@@ -16,5 +16,21 @@
# along with this program. If not, see .
from . import common
+from struct import *
+from lib import log
+import zlib
-common.ENCODINGS.cursor = -239
+class Encoding:
+ name = 'Cursor'
+ id = -239
+ description = 'Cursor pseudo encoding'
+ enabled = True
+ pseudoEncoding = True
+
+ cursor_sent = False
+
+ def __init__(self):
+ log.debug("Initialized", __name__)
+
+common.encodings[common.ENCODINGS.cursor] = Encoding
+log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))
diff --git a/lib/encodings/raw.py b/lib/encodings/raw.py
index 85bfcc8..fbfb36b 100644
--- a/lib/encodings/raw.py
+++ b/lib/encodings/raw.py
@@ -17,16 +17,30 @@
from . import common
from struct import *
+from lib import log
-def send_image(x, y, w, h, image):
- _buff = bytearray()
- rectangles = 1
- _buff.extend(pack("!BxH", 0, rectangles))
- _buff.extend(pack("!HHHH", x, y, w, h))
- _buff.extend(pack(">i", common.ENCODINGS.raw))
- _buff.extend( image.tobytes() )
+class Encoding:
+ _buff = None
- return _buff
+ name = 'raw'
+ id = 0
+ description = 'Raw VNC encoding'
+ enabled = True
+ firstUpdateSent = False
-common.ENCODINGS.raw = 0
-common.ENCODINGS.raw_send_image = send_image
\ No newline at end of file
+ def __init__(self):
+ log.debug("Initialized", __name__)
+
+ def send_image(self, x, y, w, h, image):
+ self._buff = bytearray()
+ rectangles = 1
+ self._buff.extend(pack("!BxH", 0, rectangles)) # message type 0 == FramebufferUpdate
+ self._buff.extend(pack("!HHHH", x, y, w, h))
+ self._buff.extend(pack(">i", self.id))
+ self._buff.extend( image.tobytes() )
+
+ return self._buff
+
+common.encodings[common.ENCODINGS.raw] = Encoding
+
+log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))
diff --git a/lib/encodings/zlib.py b/lib/encodings/zlib.py
new file mode 100644
index 0000000..ec25348
--- /dev/null
+++ b/lib/encodings/zlib.py
@@ -0,0 +1,54 @@
+from . import common
+from struct import *
+from lib import log
+import zlib
+
+
+class Encoding:
+ name = 'zlib'
+ id = 6
+ description = 'zlib VNC encoding'
+ enabled = True
+ firstUpdateSent = False
+ _compressObj = None
+
+ def __init__(self):
+ log.debug("Initialized", __name__)
+ self._compressObj = zlib.compressobj(
+ zlib.Z_DEFAULT_COMPRESSION, # level: 0-9
+ zlib.DEFLATED, # method: must be DEFLATED
+ zlib.MAX_WBITS, # window size in bits:
+ # -15..-8: negate, suppress header
+ # 8..15: normal
+ # 16..30: subtract 16, gzip header
+ zlib.DEF_MEM_LEVEL, # mem level: 1..8/9
+ zlib.Z_DEFAULT_STRATEGY # strategy:
+ # 0 = Z_DEFAULT_STRATEGY
+ # 1 = Z_FILTERED
+ # 2 = Z_HUFFMAN_ONLY
+ # 3 = Z_RLE
+ # 4 = Z_FIXED
+ )
+
+ def send_image(self, x, y, w, h, image):
+ sendbuff = bytearray()
+
+ rectangles = 1
+ sendbuff.extend(pack("!BxH", 0, rectangles)) # message type 0 == FramebufferUpdate
+ sendbuff.extend(pack("!HHHH", x, y, w, h))
+ sendbuff.extend(pack(">i", self.id))
+
+ #log.debug("Compressing...")
+ zlibdata = self._compressObj.compress( image.tobytes() )
+ zlibdata += self._compressObj.flush(zlib.Z_FULL_FLUSH)
+ #log.debug("LEN", len(zlibdata))
+
+ l = pack("!I", len(zlibdata) )
+ sendbuff.extend( l ) # send length
+ sendbuff.extend( zlibdata ) # send compressed data
+
+ return sendbuff
+
+common.encodings[common.ENCODINGS.zlib] = Encoding
+
+log.debug("Loaded encoding: %s (%s)" % (__name__, Encoding.id))
diff --git a/lib/imagegrab.py b/lib/imagegrab.py
new file mode 100644
index 0000000..6ff18de
--- /dev/null
+++ b/lib/imagegrab.py
@@ -0,0 +1,41 @@
+import sys
+from PIL import Image
+from lib import log
+
+if sys.platform == "linux" or sys.platform == "linux2":
+ log.debug("ImageGrab: running on Linux")
+ from Xlib import display, X
+ # take screen images, that's not the best way, so here
+ # we use directly use xlib to take the screenshot.
+ class ImageGrab():
+ def grab():
+ dsp = display.Display()
+ root = dsp.screen().root
+ geom = root.get_geometry()
+ w = geom.width
+ h = geom.height
+ raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff)
+ image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX")
+ return image
+
+elif sys.platform == "darwin":
+ log.debug("ImageGrab: running on darwin")
+ import Quartz.CoreGraphics as CG
+ class ImageGrab():
+ def grab():
+ screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault)
+ width = CG.CGImageGetWidth(screenshot)
+ height = CG.CGImageGetHeight(screenshot)
+ bytesperrow = CG.CGImageGetBytesPerRow(screenshot)
+
+ pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot))
+
+ i = Image.frombytes("RGBA", (width, height), pixeldata)
+ (b, g, r, x) = i.split()
+ i = Image.merge("RGBX", (r, g, b, x))
+
+ return i
+
+else:
+ log.debug("ImageGrab: running on Unknown!")
+ from PIL import ImageGrab
diff --git a/lib/kbdctrl.py b/lib/kbdctrl.py
new file mode 100644
index 0000000..5a9456a
--- /dev/null
+++ b/lib/kbdctrl.py
@@ -0,0 +1,47 @@
+import sys
+from struct import pack, unpack
+from pynput import keyboard
+from lib import log
+from lib.kbdmap import *
+
+class KeyboardController:
+ kbdmap = kbdmap
+ kbdkey = ''
+ downflag = None
+ key = None
+ controller = None
+ kbd = None
+
+ def __init__(self):
+ self.kbd = keyboard
+ self.controller = self.kbd.Controller()
+
+ def process_event(self, data):
+ # B = U8, L = U32
+ (self.downflag, self.key) = unpack("!BxxL", data)
+ log.debug("KeyEvent", self.downflag, hex(self.key))
+
+ # special key
+ if self.key in self.kbdmap:
+ self.kbdkey = self.kbdmap[self.key]
+ log.debug("SPECIAL KEY", self.kbdkey)
+ else: # normal key
+ try:
+ self.kbdkey = self.kbd.KeyCode.from_char(chr(self.key))
+ except:
+ self.kbdkey = None
+
+ # debug keypress to stdout
+ try:
+ log.debug("KEY:", self.kbdkey)
+ except:
+ log.debug("KEY: (unprintable)")
+
+ # send the actual keyboard event
+ try:
+ if self.downflag:
+ self.controller.press(self.kbdkey)
+ else:
+ self.controller.release(self.kbdkey)
+ except:
+ log.debug("Error sending key")
diff --git a/lib/kbdmap.py b/lib/kbdmap.py
new file mode 100644
index 0000000..e49e30e
--- /dev/null
+++ b/lib/kbdmap.py
@@ -0,0 +1,79 @@
+import sys
+from pynput import keyboard
+
+__all__ = ['kbdmap']
+
+kbdmap = {
+ 0xff08: keyboard.Key.backspace,
+ 0xff09: keyboard.Key.tab,
+ 0xff0d: keyboard.Key.enter,
+ 0xff1b: keyboard.Key.esc,
+ 0xff63: keyboard.Key.insert if hasattr(keyboard.Key, "insert") else None,
+ 0xffff: keyboard.Key.delete,
+ 0xff50: keyboard.Key.home,
+ 0xff57: keyboard.Key.end,
+ 0xff55: keyboard.Key.page_up,
+ 0xff56: keyboard.Key.page_down,
+ 0xff51: keyboard.Key.left,
+ 0xff52: keyboard.Key.up,
+ 0xff53: keyboard.Key.right,
+ 0xff54: keyboard.Key.down,
+ 0xffbe: keyboard.Key.f1,
+ 0xffbf: keyboard.Key.f2,
+ 0xffc0: keyboard.Key.f3,
+ 0xffc1: keyboard.Key.f4,
+ 0xffc2: keyboard.Key.f5,
+ 0xffc3: keyboard.Key.f6,
+ 0xffc4: keyboard.Key.f7,
+ 0xffc5: keyboard.Key.f8,
+ 0xffc6: keyboard.Key.f9,
+ 0xffc7: keyboard.Key.f10,
+ 0xffc8: keyboard.Key.f11,
+ 0xffc9: keyboard.Key.f12,
+ 0xffca: keyboard.Key.f13,
+ 0xffcb: keyboard.Key.f14,
+ 0xffcc: keyboard.Key.f15,
+ 0xffcd: keyboard.Key.f16,
+ 0xffce: keyboard.Key.f17,
+ 0xffcf: keyboard.Key.f18,
+ 0xffd0: keyboard.Key.f19,
+ 0xffd1: keyboard.Key.f20,
+ 0xffe1: keyboard.Key.shift_l,
+ 0xffe2: keyboard.Key.shift_r,
+ 0xffe3: keyboard.Key.ctrl_l,
+ 0xffe4: keyboard.Key.ctrl_r,
+ 0xffe7: None, # "KEY_MetaLeft"
+ 0xffe8: None, # "KEY_MetaRight"
+ #0xffe9: keyboard.Key.cmd_l,
+ 0xffe9: keyboard.Key.alt,
+ 0xffea: keyboard.Key.alt_gr, # "KEY_AltRight"
+ 0xff14: keyboard.Key.scroll_lock if hasattr(keyboard.Key, "scroll_lock") else None,
+ 0xff15: keyboard.Key.print_screen if hasattr(keyboard.Key, "print_screen") else None, # "KEY_Sys_Req"
+ 0xff7f: keyboard.Key.num_lock if hasattr(keyboard.Key, "num_lock") else None,
+ 0xffe5: keyboard.Key.caps_lock,
+ 0xff13: keyboard.Key.pause if hasattr(keyboard.Key, "pause") else None,
+ 0xffeb: keyboard.Key.cmd_r, # "KEY_Super_L"
+ 0xffec: keyboard.Key.cmd_r, # "KEY_Super_R"
+ 0xffed: None, # "KEY_Hyper_L"
+ 0xffee: None, # "KEY_Hyper_R"
+ 0xffb0: None, # "KEY_KP_0"
+ 0xffb1: None, # "KEY_KP_1"
+ 0xffb2: None, # "KEY_KP_2"
+ 0xffb3: None, # "KEY_KP_3"
+ 0xffb4: None, # "KEY_KP_4"
+ 0xffb5: None, # "KEY_KP_5"
+ 0xffb6: None, # "KEY_KP_6"
+ 0xffb7: None, # "KEY_KP_7"
+ 0xffb8: None, # "KEY_KP_8"
+ 0xffb9: None, # "KEY_KP_9"
+ 0xff8d: None, # "KEY_KP_Enter"
+ 0x002f: "/", # KEY_ForwardSlash
+ 0x005c: "\\", # KEY_BackSlash
+ 0x0020: keyboard.Key.space, # "KEY_SpaceBar"
+ 0xff7e: keyboard.Key.alt_gr, # altgr, at least on a mac (?)
+ #0xfe03: keyboard.Key.alt_l,
+ 0xfe03: keyboard.Key.cmd_l,
+}
+
+if sys.platform == "darwin":
+ kbdmap[0xffe2] = keyboard.Key.shift
diff --git a/lib/mousectrl.py b/lib/mousectrl.py
new file mode 100644
index 0000000..3fc9179
--- /dev/null
+++ b/lib/mousectrl.py
@@ -0,0 +1,60 @@
+from struct import pack, unpack
+from pynput import mouse
+from lib import log
+
+class MouseController():
+ def __init__(self):
+ self.buttonmask = 0
+ self.buttons = [0, 0, 0, 0, 0, 0, 0, 0]
+ self.left_pressed = 0
+ self.right_pressed = 0
+ self.middle_pressed = 0
+
+ def process_event(self, data):
+ (self.buttonmask, x, y) = unpack("!BHH", data)
+ self.buttons[0] = self.buttonmask & int("0000001", 2) # left button
+ self.buttons[1] = self.buttonmask & int("0000010", 2) # middle button
+ self.buttons[2] = self.buttonmask & int("0000100", 2) # right button
+ self.buttons[3] = self.buttonmask & int("0001000", 2) # scroll up
+ self.buttons[4] = self.buttonmask & int("0010000", 2) # scroll down
+
+ # set mouse position
+ mouse.Controller().position = (x, y)
+
+ # process mouse button events
+ if self.buttons[0] and not self.left_pressed:
+ log.debug("LEFT PRESSED")
+ mouse.Controller().press(mouse.Button.left)
+ self.left_pressed = 1
+ elif not self.buttons[0] and self.left_pressed:
+ log.debug("LEFT RELEASED")
+ mouse.Controller().release(mouse.Button.left)
+ self.left_pressed = 0
+
+ if self.buttons[1] and not self.middle_pressed:
+ log.debug("MIDDLE PRESSED")
+ mouse.Controller().press(mouse.Button.middle)
+ self.middle_pressed = 1
+ elif not self.buttons[1] and self.middle_pressed:
+ log.debug("MIDDLE RELEASED")
+ mouse.Controller().release(mouse.Button.middle)
+ self.middle_pressed = 0
+
+ if self.buttons[2] and not self.right_pressed:
+ log.debug("RIGHT PRESSED")
+ mouse.Controller().press(mouse.Button.right)
+ self.right_pressed = 1
+ elif not self.buttons[2] and self.right_pressed:
+ log.debug("RIGHT RELEASED")
+ mouse.Controller().release(mouse.Button.right)
+ self.right_pressed = 0
+
+ if self.buttons[3]:
+ log.debug("SCROLLUP PRESSED")
+ mouse.Controller().scroll(0, 2)
+
+ if self.buttons[4]:
+ log.debug("SCROLLDOWN PRESSED")
+ mouse.Controller().scroll(0, -2)
+
+ #log.debug("PointerEvent", buttonmask, x, y)
diff --git a/lib/oshelpers/windows.py b/lib/oshelpers/windows.py
new file mode 100644
index 0000000..765107c
--- /dev/null
+++ b/lib/oshelpers/windows.py
@@ -0,0 +1,31 @@
+import ctypes
+import sys
+from elevate import elevate
+
+def is_admin():
+ try:
+ return ctypes.windll.shell32.IsUserAnAdmin()
+ except:
+ return False
+
+def run_as_admin_old(argv=None):
+ shell32 = ctypes.windll.shell32
+ if argv is None and shell32.IsUserAnAdmin():
+ return True
+
+ if argv is None:
+ argv = sys.argv
+ if hasattr(sys, '_MEIPASS'):
+ # Support pyinstaller wrapped program.
+ arguments = argv[1:]
+ else:
+ arguments = argv
+ argument_line = u' '.join(arguments)
+ executable = sys.executable
+ ret = shell32.ShellExecuteW(None, u"runas", executable, argument_line, None, 1)
+ if int(ret) <= 32:
+ return False
+ return None
+
+def run_as_admin():
+ elevate()
diff --git a/pyvncs/__pycache__/server.cpython-36.pyc b/pyvncs/__pycache__/server.cpython-36.pyc
deleted file mode 100644
index a87805a..0000000
Binary files a/pyvncs/__pycache__/server.cpython-36.pyc and /dev/null differ
diff --git a/pyvncs/server.py b/pyvncs/server.py
index 8c5c215..7de6298 100644
--- a/pyvncs/server.py
+++ b/pyvncs/server.py
@@ -19,17 +19,24 @@ from struct import *
from pyDes import *
from time import sleep
from pynput import mouse, keyboard
+from PIL import Image, ImageChops, ImageDraw, ImagePalette
import socket
import select
import os
import sys
import random
-import zlib
import numpy as np
-from lib.encodings import *
+from lib import mousectrl
+from lib import kbdctrl
+from lib.imagegrab import ImageGrab
from lib import log
+from lib import bgr233_palette
+
+# encodings support
+import lib.encodings as encs
+from lib.encodings.common import ENCODINGS
def hexdump(data):
str = ""
@@ -39,7 +46,7 @@ def hexdump(data):
return str
def quantizetopalette(silf, palette, dither=False):
- """Convert an RGB or L mode image to use a given P image's palette."""
+ """Converts an RGB or L mode image to use a given P image's palette."""
silf.load()
@@ -60,50 +67,13 @@ def quantizetopalette(silf, palette, dither=False):
except AttributeError:
return silf._makeself(im)
-
-from PIL import Image, ImageChops, ImageDraw, ImagePalette
-if sys.platform == "linux" or sys.platform == "linux2":
- from Xlib import display, X
- # take screen images, that's not the best way, so here
- # we use directly use xlib to take the screenshot.
- class ImageGrab():
- def grab():
- dsp = display.Display()
- root = dsp.screen().root
- geom = root.get_geometry()
- w = geom.width
- h = geom.height
- raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff)
- image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX")
- return image
-
-elif sys.platform == "darwin":
- import Quartz.CoreGraphics as CG
- class ImageGrab():
- def grab():
- screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault)
- width = CG.CGImageGetWidth(screenshot)
- height = CG.CGImageGetHeight(screenshot)
- bytesperrow = CG.CGImageGetBytesPerRow(screenshot)
-
- pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot))
-
- i = Image.frombytes("RGBA", (width, height), pixeldata)
- (b, g, r, x) = i.split()
- i = Image.merge("RGBX", (r, g, b, x))
-
- return i
-
-else:
- from PIL import ImageGrab
-
-
-
class VncServer():
class CONFIG:
_8bitdither = False
+ encoding_object = None
+
def __init__(self, socket, password):
self.RFB_VERSION = '003.008'
self.RFB_SECTYPES = [
@@ -115,73 +85,8 @@ class VncServer():
self.framebuffer = None
self.password = password
self.sectypes = self.RFB_SECTYPES
- self.remotecursor = False
-
- self.BGR233 = [0, 0, 0, 0, 0, 85, 0, 0, 170, 0, 0, 255, 36, 0, 0,
- 36, 0, 85, 36, 0, 170, 36, 0, 255, 73, 0, 0, 73, 0,
- 85, 73, 0, 170, 73, 0, 255, 109, 0, 0, 109, 0, 85,
- 109, 0, 170, 109, 0, 255, 146, 0, 0, 146, 0, 85, 146,
- 0, 170, 146, 0, 255, 182, 0, 0, 182, 0, 85, 182, 0,
- 170, 182, 0, 255, 219, 0, 0, 219, 0, 85, 219, 0, 170,
- 219, 0, 255, 255, 0, 0, 255, 0, 85, 255, 0, 170, 255,
- 0, 255, 0, 36, 0, 0, 36, 85, 0, 36, 170, 0, 36, 255,
- 36, 36, 0, 36, 36, 85, 36, 36, 170, 36, 36, 255, 73,
- 36, 0, 73, 36, 85, 73, 36, 170, 73, 36, 255, 109, 36,
- 0, 109, 36, 85, 109, 36, 170, 109, 36, 255, 146, 36,
- 0, 146, 36, 85, 146, 36, 170, 146, 36, 255, 182, 36,
- 0, 182, 36, 85, 182, 36, 170, 182, 36, 255, 219, 36,
- 0, 219, 36, 85, 219, 36, 170, 219, 36, 255, 255, 36,
- 0, 255, 36, 85, 255, 36, 170, 255, 36, 255, 0, 73, 0,
- 0, 73, 85, 0, 73, 170, 0, 73, 255, 36, 73, 0, 36, 73,
- 85, 36, 73, 170, 36, 73, 255, 73, 73, 0, 73, 73, 85,
- 73, 73, 170, 73, 73, 255, 109, 73, 0, 109, 73, 85,
- 109, 73, 170, 109, 73, 255, 146, 73, 0, 146, 73, 85,
- 146, 73, 170, 146, 73, 255, 182, 73, 0, 182, 73, 85,
- 182, 73, 170, 182, 73, 255, 219, 73, 0, 219, 73, 85,
- 219, 73, 170, 219, 73, 255, 255, 73, 0, 255, 73, 85,
- 255, 73, 170, 255, 73, 255, 0, 109, 0, 0, 109, 85, 0,
- 109, 170, 0, 109, 255, 36, 109, 0, 36, 109, 85, 36,
- 109, 170, 36, 109, 255, 73, 109, 0, 73, 109, 85, 73,
- 109, 170, 73, 109, 255, 109, 109, 0, 109, 109, 85, 109,
- 109, 170, 109, 109, 255, 146, 109, 0, 146, 109, 85,
- 146, 109, 170, 146, 109, 255, 182, 109, 0, 182, 109,
- 85, 182, 109, 170, 182, 109, 255, 219, 109, 0, 219,
- 109, 85, 219, 109, 170, 219, 109, 255, 255, 109, 0,
- 255, 109, 85, 255, 109, 170, 255, 109, 255, 0, 146, 0,
- 0, 146, 85, 0, 146, 170, 0, 146, 255, 36, 146, 0, 36,
- 146, 85, 36, 146, 170, 36, 146, 255, 73, 146, 0, 73,
- 146, 85, 73, 146, 170, 73, 146, 255, 109, 146, 0, 109,
- 146, 85, 109, 146, 170, 109, 146, 255, 146, 146, 0, 146,
- 146, 85, 146, 146, 170, 146, 146, 255, 182, 146, 0, 182,
- 146, 85, 182, 146, 170, 182, 146, 255, 219, 146, 0, 219,
- 146, 85, 219, 146, 170, 219, 146, 255, 255, 146, 0, 255,
- 146, 85, 255, 146, 170, 255, 146, 255, 0, 182, 0, 0,
- 182, 85, 0, 182, 170, 0, 182, 255, 36, 182, 0, 36, 182,
- 85, 36, 182, 170, 36, 182, 255, 73, 182, 0, 73, 182,
- 85, 73, 182, 170, 73, 182, 255, 109, 182, 0, 109, 182,
- 85, 109, 182, 170, 109, 182, 255, 146, 182, 0, 146,
- 182, 85, 146, 182, 170, 146, 182, 255, 182, 182, 0, 182,
- 182, 85, 182, 182, 170, 182, 182, 255, 219, 182, 0, 219,
- 182, 85, 219, 182, 170, 219, 182, 255, 255, 182, 0, 255,
- 182, 85, 255, 182, 170, 255, 182, 255, 0, 219, 0, 20,
- 219, 85, 0, 219, 170, 0, 219, 255, 36, 219, 0, 36, 219,
- 85, 36, 219, 170, 36, 219, 255, 73, 219, 0, 73, 219,
- 85, 73, 219, 170, 73, 219, 255, 109, 219, 0, 109, 219,
- 85, 109, 219, 170, 109, 219, 255, 146, 219, 0, 146, 219,
- 85, 146, 219, 170, 146, 219, 255, 182, 219, 0, 182, 219,
- 85, 182, 219, 170, 182, 219, 255, 219, 219, 0, 219, 219,
- 85, 219, 219, 170, 219, 219, 255, 255, 219, 0, 255, 219,
- 85, 255, 219, 170, 255, 219, 255, 0, 255, 0, 0, 255, 85,
- 0, 255, 170, 0, 255, 255, 36, 255, 0, 36, 255, 85, 36,
- 255, 170, 36, 255, 255, 73, 255, 0, 73, 255, 85, 73,
- 255, 170, 73, 255, 255, 109, 255, 0, 109, 255, 85, 109,
- 255, 170, 109, 255, 255, 146, 255, 0, 146, 255, 85,
- 146, 255, 170, 146, 255, 255, 182, 255, 0, 182, 255, 85,
- 182, 255, 170, 182, 255, 255, 219, 255, 0, 219, 255, 85,
- 219, 255, 170, 219, 255, 255, 255, 255, 0, 255, 255, 85,
- 255, 255, 170, 255, 255, 255]
-
-
+ self.cursor_support = False
+
def __del__(self):
log.debug("VncServer died")
@@ -348,95 +253,19 @@ class VncServer():
def protocol(self):
self.socket.settimeout(None) # set nonblocking socket
-
screen = ImageGrab.grab()
size = screen.size
width = size[0]
height = size[1]
del screen
+
+ mousecontroller = mousectrl.MouseController()
+ kbdcontroller = kbdctrl.KeyboardController()
self.primaryOrder = "rgb"
- self.encoding = enc.ENCODINGS.raw
- buttonmask = 0
- buttons = [0, 0, 0, 0, 0, 0, 0, 0]
- left_pressed = 0
- right_pressed = 0
- middle_pressed = 0
+ self.encoding = ENCODINGS.raw
+ self.encoding_object = encs.common.encodings[self.encoding]()
-
- kbdmap = {
- 0xff08: keyboard.Key.backspace,
- 0xff09: keyboard.Key.tab,
- 0xff0d: keyboard.Key.enter,
- 0xff1b: keyboard.Key.esc,
- 0xff63: keyboard.Key.insert if hasattr(keyboard.Key, "insert") else None,
- 0xffff: keyboard.Key.delete,
- 0xff50: keyboard.Key.home,
- 0xff57: keyboard.Key.end,
- 0xff55: keyboard.Key.page_up,
- 0xff56: keyboard.Key.page_down,
- 0xff51: keyboard.Key.left,
- 0xff52: keyboard.Key.up,
- 0xff53: keyboard.Key.right,
- 0xff54: keyboard.Key.down,
- 0xffbe: keyboard.Key.f1,
- 0xffbf: keyboard.Key.f2,
- 0xffc0: keyboard.Key.f3,
- 0xffc1: keyboard.Key.f4,
- 0xffc2: keyboard.Key.f5,
- 0xffc3: keyboard.Key.f6,
- 0xffc4: keyboard.Key.f7,
- 0xffc5: keyboard.Key.f8,
- 0xffc6: keyboard.Key.f9,
- 0xffc7: keyboard.Key.f10,
- 0xffc8: keyboard.Key.f11,
- 0xffc9: keyboard.Key.f12,
- 0xffca: keyboard.Key.f13,
- 0xffcb: keyboard.Key.f14,
- 0xffcc: keyboard.Key.f15,
- 0xffcd: keyboard.Key.f16,
- 0xffce: keyboard.Key.f17,
- 0xffcf: keyboard.Key.f18,
- 0xffd0: keyboard.Key.f19,
- 0xffd1: keyboard.Key.f20,
- 0xffe1: keyboard.Key.shift_l,
- 0xffe2: keyboard.Key.shift_r,
- 0xffe3: keyboard.Key.ctrl_l,
- 0xffe4: keyboard.Key.ctrl_r,
- 0xffe7: None, # "KEY_MetaLeft"
- 0xffe8: None, # "KEY_MetaRight"
- 0xffe9: keyboard.Key.cmd_l,
- 0xffea: keyboard.Key.alt_gr, # "KEY_AltRight"
- 0xff14: keyboard.Key.scroll_lock if hasattr(keyboard.Key, "scroll_lock") else None,
- 0xff15: keyboard.Key.print_screen if hasattr(keyboard.Key, "print_screen") else None, # "KEY_Sys_Req"
- 0xff7f: keyboard.Key.num_lock if hasattr(keyboard.Key, "num_lock") else None,
- 0xffe5: keyboard.Key.caps_lock,
- 0xff13: keyboard.Key.pause if hasattr(keyboard.Key, "pause") else None,
- 0xffeb: keyboard.Key.cmd_r, # "KEY_Super_L"
- 0xffec: keyboard.Key.cmd_r, # "KEY_Super_R"
- 0xffed: None, # "KEY_Hyper_L"
- 0xffee: None, # "KEY_Hyper_R"
- 0xffb0: None, # "KEY_KP_0"
- 0xffb1: None, # "KEY_KP_1"
- 0xffb2: None, # "KEY_KP_2"
- 0xffb3: None, # "KEY_KP_3"
- 0xffb4: None, # "KEY_KP_4"
- 0xffb5: None, # "KEY_KP_5"
- 0xffb6: None, # "KEY_KP_6"
- 0xffb7: None, # "KEY_KP_7"
- 0xffb8: None, # "KEY_KP_8"
- 0xffb9: None, # "KEY_KP_9"
- 0xff8d: None, # "KEY_KP_Enter"
- 0x002f: "/", # KEY_ForwardSlash
- 0x005c: "\\", # KEY_BackSlash
- 0x0020: keyboard.Key.space, # "KEY_SpaceBar"
- 0xff7e: keyboard.Key.alt_gr, # altgr, at least on a mac (?)
- 0xfe03: keyboard.Key.alt_l,
- }
-
- if sys.platform == "darwin":
- kbdmap[0xffe2] = keyboard.Key.shift
-
while True:
#log.debug(".", end='', flush=True)
r,_,_ = select.select([self.socket],[],[],0)
@@ -476,7 +305,7 @@ class VncServer():
self.primaryOrder = "rgb"
else:
self.primaryOrder = "bgr"
- log.debug("Using order: ", self.primaryOrder)
+ log.debug("Using order:", self.primaryOrder)
continue
@@ -488,16 +317,25 @@ class VncServer():
data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL)
#log.debug("len", len(data2))
self.client_encodings = unpack("!%si" % nencodings, data2)
- #log.debug("data", repr(self.client_encodings), len(self.client_encodings))
+ log.debug("client_encodings", repr(self.client_encodings), len(self.client_encodings))
- if hasattr(enc.ENCODINGS, "cursor") and enc.ENCODINGS.cursor in self.client_encodings:
- log.debug("Remote cursor encoding present")
- self.remotecursor = True
- self.cursorchanged = True
-
- if hasattr(enc.ENCODINGS, "zlib") and enc.ENCODINGS.zlib in self.client_encodings:
- log.debug("Using zlib encoding")
- self.encoding = enc.ENCODINGS.zlib
+ # cursor support?
+ if ENCODINGS.cursor in self.client_encodings:
+ log.debug("client cursor support")
+ self.cursor_support = True
+
+ # which pixel encoding to use?
+ log.debug("encs.common.encodings_priority", encs.common.encodings_priority)
+ for e in encs.common.encodings_priority:
+ log.debug("E", e)
+ if e in self.client_encodings:
+ if self.encoding == e:
+ # don't initialize same encoding again
+ break
+ self.encoding = e
+ log.debug("Using %s encoding" % self.encoding)
+ self.encoding_object = encs.common.encodings[self.encoding]()
+ break
continue
@@ -510,89 +348,14 @@ class VncServer():
#log.debug("RFBU:", incremental, x, y, w, h)
self.SendRectangles(sock, x, y, w, h, incremental)
- if self.remotecursor and self.cursorchanged:
- # FIXME: send cursor to remote client
- self.cursorchanged = False
continue
- if data[0] == 4:
- kbdkey = ''
- data2 = sock.recv(7)
- # B = U8, L = U32
- (downflag, key) = unpack("!BxxL", data2)
- log.debug("KeyEvent", downflag, hex(key))
-
- # special key
- if key in kbdmap:
- kbdkey = kbdmap[key]
- else: # normal key
- try:
- kbdkey = keyboard.KeyCode.from_char(chr(key))
- except:
- kbdkey = None
-
- try:
- log.debug("KEY:", kbdkey)
- except:
- log.debug("KEY: (unprintable)")
-
- try:
- if downflag:
- keyboard.Controller().press(kbdkey)
- else:
- keyboard.Controller().release(kbdkey)
- except:
- log.debug("Error sending key")
-
+ if data[0] == 4: # keyboard event
+ kbdcontroller.process_event(sock.recv(7))
continue
if data[0] == 5: # PointerEvent
- data2 = sock.recv(5, socket.MSG_WAITALL)
- (buttonmask, x, y) = unpack("!BHH", data2)
- buttons[0] = buttonmask & int("0000001", 2) # left button
- buttons[1] = buttonmask & int("0000010", 2) # middle button
- buttons[2] = buttonmask & int("0000100", 2) # right button
- buttons[3] = buttonmask & int("0001000", 2) # scroll up
- buttons[4] = buttonmask & int("0010000", 2) # scroll down
-
- mouse.Controller().position = (x, y)
-
- if buttons[0] and not left_pressed:
- log.debug("LEFT PRESSED")
- mouse.Controller().press(mouse.Button.left)
- left_pressed = 1
- elif not buttons[0] and left_pressed:
- log.debug("LEFT RELEASED")
- mouse.Controller().release(mouse.Button.left)
- left_pressed = 0
-
- if buttons[1] and not middle_pressed:
- log.debug("MIDDLE PRESSED")
- mouse.Controller().press(mouse.Button.middle)
- middle_pressed = 1
- elif not buttons[1] and middle_pressed:
- log.debug("MIDDLE RELEASED")
- mouse.Controller().release(mouse.Button.middle)
- middle_pressed = 0
-
- if buttons[2] and not right_pressed:
- log.debug("RIGHT PRESSED")
- mouse.Controller().press(mouse.Button.right)
- right_pressed = 1
- elif not buttons[2] and right_pressed:
- log.debug("RIGHT RELEASED")
- mouse.Controller().release(mouse.Button.right)
- right_pressed = 0
-
- if buttons[3]:
- log.debug("SCROLLUP PRESSED")
- mouse.Controller().scroll(0, 2)
-
- if buttons[4]:
- log.debug("SCROLLDOWN PRESSED")
- mouse.Controller().scroll(0, -2)
-
- #log.debug("PointerEvent", buttonmask, x, y)
+ mousecontroller.process_event(sock.recv(5, socket.MSG_WAITALL))
continue
else:
@@ -630,19 +393,20 @@ class VncServer():
lastshot = rectangle
sendbuff = bytearray()
- firstUpdateSent = False
+ self.encoding_object.firstUpdateSent = False
# try to send only the actual changes
if self.framebuffer != None and incremental == 1:
diff = ImageChops.difference(rectangle, self.framebuffer)
if diff.getbbox() is None:
+ # no changes...
rectangles = 0
sendbuff.extend(pack("!BxH", 0, rectangles))
try:
sock.sendall(sendbuff)
except:
return False
- sleep(0.3)
+ sleep(0.1)
return
if diff.getbbox() is not None:
@@ -656,119 +420,70 @@ class VncServer():
stimeout = sock.gettimeout()
sock.settimeout(None)
- if self.bpp == 32 or self.bpp == 8:
- if rectangle.mode is not "RGB":
- image = rectangle.convert("RGB")
- else:
- image = rectangle
-
- b = np.asarray(image)
- a = b.copy()
- del b
+ if self.bpp == 32 or self.bpp == 16 or self.bpp == 8:
if self.bpp == 32:
redBits = 8
greenBits = 8
blueBits = 8
- elif self.bpp == 8:
- redBits = 4
- greenBits = 4
- blueBits = 4
- #redMask = ((1 << redBits) - 1) << self.red_shift
- #greenMask = ((1 << greenBits) - 1) << self.green_shift
- #blueMask = ((1 << blueBits) - 1) << self.blue_shift
- #log.debug("redMask", redMask, greenMask, blueMask)
+ # image array
+ a = np.asarray(rectangle).copy()
+
+ if self.primaryOrder == "bgr": # bit shifting
+ blueMask = (1 << blueBits) - 1
+ greenMask = ((1 << greenBits) - 1) << self.green_shift
+ redMask = ((1 << redBits) - 1) << self.red_shift
- if self.primaryOrder == "bgr":
- self.blue_shift = 0
- blueMask = (1 << blueBits) - 1
- self.green_shift = blueBits
- greenMask = ((1 << greenBits) - 1) << self.green_shift
- self.red_shift = self.green_shift + greenBits
- redMask = ((1 << redBits) - 1) << self.red_shift
+ a[..., 0] = ( a[..., 0] ) & blueMask >> self.blue_shift
+ a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift
+ a[..., 2] = ( a[..., 2] ) & redMask >> self.red_shift
+
+ else: # RGB
+ redMask = ((1 << redBits) - 1) << self.red_shift
+ greenMask = ((1 << greenBits) - 1) << self.green_shift
+ blueMask = ((1 << blueBits) - 1) << self.blue_shift
+ a[..., 0] = ( a[..., 0] ) & redMask >> self.red_shift
+ a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift
+ a[..., 2] = ( a[..., 2] ) & blueMask >> self.blue_shift
- else: # RGB
- self.red_shift = 0
- redMask = (1 << redBits) - 1
- self.green_shift = redBits
- greenMask = ((1 << greenBits) - 1) << self.green_shift
- self.blue_shift = self.green_shift + greenBits
- blueMask = ((1 << blueBits) - 1) << self.blue_shift
-
- a[..., 0] = ( a[..., 0] ) & redMask >> self.red_shift
- a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift
- a[..., 2] = ( a[..., 2] ) & blueMask >> self.blue_shift
-
- image = Image.fromarray(a)
- del a
-
- if self.primaryOrder == "rgb":
- (b, g, r) = image.split()
- image = Image.merge("RGB", (r, g, b))
- del b,g,r
-
- if self.bpp == 32:
+ image = Image.fromarray(a)
+ if self.primaryOrder == "rgb":
+ (b, g, r) = image.split()
+ image = Image.merge("RGB", (r, g, b))
+ del b,g,r
image = image.convert("RGBX")
- elif self.bpp == 8:
- #FIXME: improve 8 bit routines up!, image looks awful!
- if rectangle.mode is not "RGB":
- image = rectangle.convert("RGB")
- else:
- image = rectangle
+ if self.bpp == 16: #BGR565
+ greenBits = 5
+ blueBits = 6
+ redBits = 5
- (r, g, b) = image.split()
- image = Image.merge("RGB", (g, r, b))
- del b,g,r
+ image = rectangle
+ if self.depth == 16:
+ image = image.convert('BGR;16')
+ if self.depth == 15:
+ image = image.convert('BGR;15')
+
+ elif self.bpp == 8: #bgr233
+ redBits = 3
+ greenBits = 3
+ blueBits = 2
+
+ image = rectangle
+
+ p = Image.new('P',(16,16))
+ p.putpalette(bgr233_palette.palette)
- p = Image.new("P",(16,16))
- p.putpalette(self.BGR233)
image = quantizetopalette(image, p, dither=self.CONFIG._8bitdither)
- image.putpalette(self.BGR233)
- del p
- rectangles = 1
- sendbuff.extend(pack("!BxH", 0, rectangles))
- sendbuff.extend(pack("!HHHH", x, y, w, h))
- sendbuff.extend(pack(">i", self.encoding))
- sendbuff.extend( image.tobytes() )
+
+ #image = image.convert('RGB', colors=4).quantize(palette=p)
+ #log.debug(image)
- if hasattr(enc.ENCODINGS, "zlib") and self.encoding == enc.ENCODINGS.zlib - 9998:
- if not firstUpdateSent:
- firstUpdateSent = True
- compress = zlib.compressobj(
- zlib.Z_DEFAULT_COMPRESSION, # level: 0-9
- zlib.DEFLATED, # method: must be DEFLATED
- -15, # window size in bits:
- # -15..-8: negate, suppress header
- # 8..15: normal
- # 16..30: subtract 16, gzip header
- 1, # mem level: 1..8/9
- zlib.Z_DEFAULT_STRATEGY # strategy:
- # 0 = Z_DEFAULT_STRATEGY
- # 1 = Z_FILTERED
- # 2 = Z_HUFFMAN_ONLY
- # 3 = Z_RLE
- # 4 = Z_FIXED
- )
- rectangles = 1
- sendbuff.extend(pack("!BxH", 0, rectangles))
- sendbuff.extend(pack("!HHHH", x, y, w, h))
- sendbuff.extend(pack(">i", self.encoding))
-
- log.debug("Compressing...")
- zlibdata = compress.compress( image.tobytes() )
- zlibdata += compress.flush()
- l = pack("!I", len(zlibdata) )
-
- sendbuff.extend( l ) # send length
- sendbuff.extend( zlibdata ) # send compressed data
-
- else:
- # send with RAW encoding
- sendbuff.extend(enc.ENCODINGS.raw_send_image(x, y, w, h, image))
+ # send image with client defined encoding
+ sendbuff.extend(self.encoding_object.send_image(x, y, w, h, image))
else:
log.debug("[!] Unsupported BPP: %s" % self.bpp)
diff --git a/requeriments.txt b/requeriments.txt
index dbfde75..38bbd7e 100644
--- a/requeriments.txt
+++ b/requeriments.txt
@@ -1,4 +1,5 @@
pydes
pynput
numpy
-
+Pillow-PIL
+elevate
diff --git a/server.py b/server.py
index 02a9f95..6101922 100755
--- a/server.py
+++ b/server.py
@@ -10,8 +10,8 @@ import socket
import signal
from lib import log
-#_debug = log.debug
-_debug = print
+_debug = log.debug
+#_debug = print
def signal_handler(signal, frame):
_debug("Exiting on %s signal..." % signal)
@@ -95,6 +95,19 @@ def main(argv):
_debug("Multithreaded Python server : Waiting for connections from TCP clients...")
_debug("Runing on:", sys.platform)
+ if sys.platform in ['win32', 'win64']:
+ from lib.oshelpers import windows as win32
+ if not win32.is_admin():
+ ret = win32.run_as_admin()
+ if ret is None:
+ log.debug("Respawning with admin rights")
+ sys.exit(0)
+ elif ret is True:
+ # admin rights
+ log.debug("Running with admin rights!")
+ else:
+ print('Error(ret=%d): cannot elevate privilege.' % (ret))
+ sys.exit(1)
while True:
sockServer.listen(4)
(conn, (ip,port)) = sockServer.accept()