From aa980d5195312a12a690bc7fdaf36ce6c9dc890a Mon Sep 17 00:00:00 2001 From: Marco Fortina Date: Sun, 17 May 2026 06:22:17 +0000 Subject: [PATCH 1/3] libvncclient: add client-aware logging helpers --- CMakeLists.txt | 9 ++ include/rfb/rfbclient.h | 12 ++ src/libvncclient/rfbclient.c | 255 ++++++++++++++++++++++------------- test/client_log_test.c | 66 +++++++++ 4 files changed, 245 insertions(+), 97 deletions(-) create mode 100644 test/client_log_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d9709c809..59651a04d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -704,6 +704,12 @@ if(WITH_LIBVNCSERVER) ) endif(WITH_LIBVNCSERVER) +if(WITH_LIBVNCCLIENT) + list(APPEND SIMPLETESTS + client_log_test + ) +endif(WITH_LIBVNCCLIENT) + if(WITH_THREADS AND (CMAKE_USE_PTHREADS_INIT OR CMAKE_USE_WIN32_THREADS_INIT) AND WITH_LIBVNCSERVER AND WITH_LIBVNCCLIENT) set(SIMPLETESTS @@ -759,6 +765,9 @@ endif(LIBVNCSERVER_WITH_WEBSOCKETS AND WITH_LIBVNCSERVER) if(WITH_LIBVNCSERVER) add_test(NAME cargs COMMAND test_cargstest) endif(WITH_LIBVNCSERVER) +if(WITH_LIBVNCCLIENT) + add_test(NAME client_log COMMAND test_client_log_test) +endif(WITH_LIBVNCCLIENT) if(UNIX) if(WITH_LIBVNCSERVER) add_test(NAME includetest_server COMMAND ${TESTS_DIR}/includetest.sh ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_MAKE_PROGRAM} "rfb/rfb.h") diff --git a/include/rfb/rfbclient.h b/include/rfb/rfbclient.h index f72d84a49..9006a99c6 100644 --- a/include/rfb/rfbclient.h +++ b/include/rfb/rfbclient.h @@ -47,6 +47,7 @@ #include #include #include +#include #if LIBVNCSERVER_HAVE_SYS_TIME_H #include #endif @@ -526,7 +527,18 @@ extern int listenForIncomingConnectionsNoFork(rfbClient* viewer, int usec_timeou extern rfbBool rfbEnableClientLogging; typedef void (*rfbClientLogProc)(const char *format, ...); +/** + * Optional client-aware logging callback used by rfbClientLogEx() and + * rfbClientErrEx(). When this callback is NULL, the helpers fall back to the + * legacy global rfbClientLog/rfbClientErr callbacks. + */ +typedef void (*rfbClientLogProcWithClient)(struct _rfbClient *client, const char *format, va_list args); extern rfbClientLogProc rfbClientLog,rfbClientErr; +extern rfbClientLogProcWithClient rfbClientLogWithClient,rfbClientErrWithClient; +/** Log a message with optional rfbClient context. */ +extern void rfbClientLogEx(rfbClient *client, const char *format, ...); +/** Log an error message with optional rfbClient context. */ +extern void rfbClientErrEx(rfbClient *client, const char *format, ...); extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort); extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size); diff --git a/src/libvncclient/rfbclient.c b/src/libvncclient/rfbclient.c index f6baf641c..1d4cf6b00 100644 --- a/src/libvncclient/rfbclient.c +++ b/src/libvncclient/rfbclient.c @@ -97,6 +97,67 @@ rfbDefaultClientLog(const char *format, ...) rfbClientLogProc rfbClientLog=rfbDefaultClientLog; rfbClientLogProc rfbClientErr=rfbDefaultClientLog; +rfbClientLogProcWithClient rfbClientLogWithClient=NULL; +rfbClientLogProcWithClient rfbClientErrWithClient=NULL; + +static void +rfbClientLogFallback(rfbClientLogProc legacyLog, const char *format, va_list args) +{ + va_list argsCopy; + char *message; + int messageLen; + + if(!legacyLog) + return; + + va_copy(argsCopy, args); + messageLen = vsnprintf(NULL, 0, format, argsCopy); + va_end(argsCopy); + + if(messageLen < 0) { + legacyLog("%s", format); + return; + } + + message = malloc((size_t)messageLen + 1); + if(!message) { + legacyLog("%s", format); + return; + } + + va_copy(argsCopy, args); + vsnprintf(message, (size_t)messageLen + 1, format, argsCopy); + va_end(argsCopy); + + legacyLog("%s", message); + free(message); +} + +void +rfbClientLogEx(rfbClient *client, const char *format, ...) +{ + va_list args; + + va_start(args, format); + if(rfbClientLogWithClient) + rfbClientLogWithClient(client, format, args); + else + rfbClientLogFallback(rfbClientLog, format, args); + va_end(args); +} + +void +rfbClientErrEx(rfbClient *client, const char *format, ...) +{ + va_list args; + + va_start(args, format); + if(rfbClientErrWithClient) + rfbClientErrWithClient(client, format, args); + else + rfbClientLogFallback(rfbClientErr, format, args); + va_end(args); +} /* extensions */ @@ -299,7 +360,7 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) char buffer[10]; rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec)); if(!rec) { - rfbClientLog("Could not allocate rfbVNCRec memory\n"); + rfbClientLogEx(client, "Could not allocate rfbVNCRec memory\n"); return FALSE; } client->vncRec = rec; @@ -310,13 +371,13 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) rec->doNotSleep = FALSE; if (!rec->file) { - rfbClientLog("Could not open %s.\n",client->serverHost); + rfbClientLogEx(client, "Could not open %s.\n",client->serverHost); return FALSE; } setbuf(rec->file,NULL); if (fread(buffer,1,strlen(magic),rec->file) != strlen(magic) || strncmp(buffer,magic,strlen(magic))) { - rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost); + rfbClientLogEx(client, "File %s was not recorded by vncrec.\n",client->serverHost); fclose(rec->file); return FALSE; } @@ -338,7 +399,7 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) /* serverHost is a hostname */ if (!StringToIPAddr(hostname, &host)) { - rfbClientLog("Couldn't convert '%s' to host address\n", hostname); + rfbClientLogEx(client, "Couldn't convert '%s' to host address\n", hostname); return FALSE; } client->sock = ConnectClientToTcpAddrWithTimeout(host, port, client->connectTimeout); @@ -346,7 +407,7 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) } if (client->sock == RFB_INVALID_SOCKET) { - rfbClientLog("Unable to connect to VNC server\n"); + rfbClientLogEx(client, "Unable to connect to VNC server\n"); return FALSE; } @@ -371,7 +432,7 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep #else unsigned int host; if (!StringToIPAddr(repeaterHost, &host)) { - rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost); + rfbClientLogEx(client, "Couldn't convert '%s' to host address\n", repeaterHost); return FALSE; } @@ -379,7 +440,7 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep #endif if (client->sock == RFB_INVALID_SOCKET) { - rfbClientLog("Unable to connect to VNC repeater\n"); + rfbClientLogEx(client, "Unable to connect to VNC repeater\n"); return FALSE; } @@ -389,11 +450,11 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep /* UltraVNC repeater always report version 000.000 to identify itself */ if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) { - rfbClientLog("Not a valid VNC repeater (%s)\n",pv); + rfbClientLogEx(client, "Not a valid VNC repeater (%s)\n",pv); return FALSE; } - rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor); + rfbClientLogEx(client, "Connected to VNC repeater, using protocol version %d.%d\n", major, minor); memset(tmphost, 0, sizeof(tmphost)); if(snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort) >= (int)sizeof(tmphost)) @@ -416,13 +477,13 @@ ReadReason(rfbClient* client) if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return; reasonLen = rfbClientSwap32IfLE(reasonLen); if(reasonLen > 1<<20) { - rfbClientLog("VNC connection failed, but sent reason length of %u exceeds limit of 1MB",(unsigned int)reasonLen); + rfbClientLogEx(client, "VNC connection failed, but sent reason length of %u exceeds limit of 1MB",(unsigned int)reasonLen); return; } reason = malloc(reasonLen+1); if (!reason || !ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; } reason[reasonLen]=0; - rfbClientLog("VNC connection failed: %s\n",reason); + rfbClientLogEx(client, "VNC connection failed: %s\n",reason); free(reason); } @@ -437,7 +498,7 @@ rfbHandleAuthResult(rfbClient* client) switch (authResult) { case rfbVncAuthOK: - rfbClientLog("VNC authentication succeeded\n"); + rfbClientLogEx(client, "VNC authentication succeeded\n"); return TRUE; break; case rfbVncAuthFailed: @@ -447,14 +508,14 @@ rfbHandleAuthResult(rfbClient* client) ReadReason(client); return FALSE; } - rfbClientLog("VNC authentication failed\n"); + rfbClientLogEx(client, "VNC authentication failed\n"); return FALSE; case rfbVncAuthTooMany: - rfbClientLog("VNC authentication failed - too many tries\n"); + rfbClientLogEx(client, "VNC authentication failed - too many tries\n"); return FALSE; } - rfbClientLog("Unknown VNC authentication result: %d\n", + rfbClientLogEx(client, "Unknown VNC authentication result: %d\n", (int)authResult); return FALSE; } @@ -476,26 +537,26 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) if (count==0) { - rfbClientLog("List of security types is ZERO, expecting an error to follow\n"); + rfbClientLogEx(client, "List of security types is ZERO, expecting an error to follow\n"); ReadReason(client); return FALSE; } - rfbClientLog("We have %d security types to read\n", count); + rfbClientLogEx(client, "We have %d security types to read\n", count); authScheme=0; /* now, we have a list of available security types to read ( uint8_t[] ) */ for (loop=0;loop0 ? ", %d" : "%d"), (int)tAuth[loop]); strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); } - rfbClientLog("Unknown authentication scheme from VNC server: %s\n", + rfbClientLogEx(client, "Unknown authentication scheme from VNC server: %s\n", buf1); return FALSE; } @@ -578,7 +639,7 @@ HandleVncAuth(rfbClient *client) passwd = client->GetPassword(client); if ((!passwd) || (strlen(passwd) == 0)) { - rfbClientLog("Reading password failed\n"); + rfbClientLogEx(client, "Reading password failed\n"); return FALSE; } if (strlen(passwd) > 8) { @@ -619,13 +680,13 @@ HandlePlainAuth(rfbClient *client) if (!client->GetCredential) { - rfbClientLog("GetCredential callback is not set.\n"); + rfbClientLogEx(client, "GetCredential callback is not set.\n"); return FALSE; } cred = client->GetCredential(client, rfbCredentialTypeUser); if (!cred) { - rfbClientLog("Reading credential failed\n"); + rfbClientLogEx(client, "Reading credential failed\n"); return FALSE; } @@ -704,26 +765,26 @@ HandleUltraMSLogonIIAuth(rfbClient *client) if (!ReadFromRFBServer(client, (char *)resp, sizeof(resp))) return FALSE; if(!dh_generate_keypair(priv, pub, gen, sizeof(gen), mod, sizeof(priv))) { - rfbClientErr("HandleUltraMSLogonIIAuth: generating keypair failed\n"); + rfbClientErrEx(client, "HandleUltraMSLogonIIAuth: generating keypair failed\n"); return FALSE; } if(!dh_compute_shared_key(key, priv, resp, mod, sizeof(key))) { - rfbClientErr("HandleUltraMSLogonIIAuth: creating shared key failed\n"); + rfbClientErrEx(client, "HandleUltraMSLogonIIAuth: creating shared key failed\n"); return FALSE; } if (!client->GetCredential) { - rfbClientLog("GetCredential callback is not set.\n"); + rfbClientLogEx(client, "GetCredential callback is not set.\n"); return FALSE; } - rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\ + rfbClientLogEx(client, "WARNING! MSLogon security type has very low password encryption! "\ "Use it only with SSH tunnel or trusted network.\n"); cred = client->GetCredential(client, rfbCredentialTypeUser); if (!cred) { - rfbClientLog("Reading credential failed\n"); + rfbClientLogEx(client, "Reading credential failed\n"); return FALSE; } @@ -762,15 +823,15 @@ HandleMSLogonAuth(rfbClient *client) if (!client->GetCredential) { - rfbClientLog("GetCredential callback is not set.\n"); + rfbClientLogEx(client, "GetCredential callback is not set.\n"); return FALSE; } - rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\ + rfbClientLogEx(client, "WARNING! MSLogon security type has very low password encryption! "\ "Use it only with SSH tunnel or trusted network.\n"); cred = client->GetCredential(client, rfbCredentialTypeUser); if (!cred) { - rfbClientLog("Reading credential failed\n"); + rfbClientLogEx(client, "Reading credential failed\n"); return FALSE; } @@ -818,11 +879,11 @@ HandleARDAuth(rfbClient *client) /* Step 1: Read the authentication material from the socket. A two-byte generator value, a two-byte key length value. */ if (!ReadFromRFBServer(client, (char *)gen, 2)) { - rfbClientErr("HandleARDAuth: reading generator value failed\n"); + rfbClientErrEx(client, "HandleARDAuth: reading generator value failed\n"); goto out; } if (!ReadFromRFBServer(client, (char *)len, 2)) { - rfbClientErr("HandleARDAuth: reading key length failed\n"); + rfbClientErrEx(client, "HandleARDAuth: reading key length failed\n"); goto out; } keylen = 256*len[0]+len[1]; /* convert from char[] to int */ @@ -839,17 +900,17 @@ HandleARDAuth(rfbClient *client) /* Step 1: Read the authentication material from the socket. The prime modulus (keylen bytes) and the peer's generated public key (keylen bytes). */ if (!ReadFromRFBServer(client, (char *)mod, keylen)) { - rfbClientErr("HandleARDAuth: reading prime modulus failed\n"); + rfbClientErrEx(client, "HandleARDAuth: reading prime modulus failed\n"); goto out; } if (!ReadFromRFBServer(client, (char *)resp, keylen)) { - rfbClientErr("HandleARDAuth: reading peer's generated public key failed\n"); + rfbClientErrEx(client, "HandleARDAuth: reading peer's generated public key failed\n"); goto out; } /* Step 2: Generate own Diffie-Hellman public-private key pair. */ if(!dh_generate_keypair(priv, pub, gen, 2, mod, keylen)) { - rfbClientErr("HandleARDAuth: generating keypair failed\n"); + rfbClientErrEx(client, "HandleARDAuth: generating keypair failed\n"); goto out; } @@ -857,7 +918,7 @@ HandleARDAuth(rfbClient *client) prime (mod), and the peer's public key. The output will be a shared secret known to both us and the peer. */ if(!dh_compute_shared_key(key, priv, resp, mod, keylen)) { - rfbClientErr("HandleARDAuth: creating shared key failed\n"); + rfbClientErrEx(client, "HandleARDAuth: creating shared key failed\n"); goto out; } @@ -865,7 +926,7 @@ HandleARDAuth(rfbClient *client) This 128-bit (16-byte) value will be used as the AES key. */ shared = malloc(MD5_HASH_SIZE); if(!hash_md5(shared, key, keylen)) { - rfbClientErr("HandleARDAuth: hashing shared key failed\n"); + rfbClientErrEx(client, "HandleARDAuth: hashing shared key failed\n"); goto out; } @@ -874,12 +935,12 @@ HandleARDAuth(rfbClient *client) Null-terminate each. Fill the unused bytes with random characters so that the encryption output is less predictable. */ if(!client->GetCredential) { - rfbClientErr("HandleARDAuth: GetCredential callback is not set\n"); + rfbClientErrEx(client, "HandleARDAuth: GetCredential callback is not set\n"); goto out; } cred = client->GetCredential(client, rfbCredentialTypeUser); if(!cred) { - rfbClientErr("HandleARDAuth: reading credential failed\n"); + rfbClientErrEx(client, "HandleARDAuth: reading credential failed\n"); goto out; } passwordLen = strlen(cred->userCredential.password)+1; @@ -896,7 +957,7 @@ HandleARDAuth(rfbClient *client) from step 4, using the AES 128-bit symmetric cipher in electronic codebook (ECB) mode. Use no further padding for this block cipher. */ if(!encrypt_aes128ecb(ciphertext, &ciphertext_len, shared, userpass, sizeof(userpass))) { - rfbClientErr("HandleARDAuth: encrypting credentials failed\n"); + rfbClientErrEx(client, "HandleARDAuth: encrypting credentials failed\n"); goto out; } @@ -982,7 +1043,7 @@ InitialiseRFBConnection(rfbClient* client) pv[sz_rfbProtocolVersionMsg] = 0; if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { - rfbClientLog("Not a valid VNC server (%s)\n",pv); + rfbClientLogEx(client, "Not a valid VNC server (%s)\n",pv); return FALSE; } @@ -998,7 +1059,7 @@ InitialiseRFBConnection(rfbClient* client) /* Legacy version of UltraVNC uses minor codes 4 and 6 for the server */ /* left in for backwards compatibility */ if (major==3 && (minor==4 || minor==6)) { - rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv); + rfbClientLogEx(client, "UltraVNC server detected, enabling UltraVNC specific messages\n",pv); DefaultSupportedMessagesUltraVNC(client); } @@ -1007,14 +1068,14 @@ InitialiseRFBConnection(rfbClient* client) if (major==3 && (minor==14 || minor==16)) { minor = minor - 10; client->minor = minor; - rfbClientLog("UltraVNC Single Click server detected, enabling UltraVNC specific messages\n",pv); + rfbClientLogEx(client, "UltraVNC Single Click server detected, enabling UltraVNC specific messages\n",pv); DefaultSupportedMessagesUltraVNC(client); } /* Legacy version of TightVNC uses minor codes 5 for the server */ /* left in for backwards compatibility */ if (major==3 && minor==5) { - rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv); + rfbClientLogEx(client, "TightVNC server detected, enabling TightVNC specific messages\n",pv); DefaultSupportedMessagesTightVNC(client); } @@ -1025,7 +1086,7 @@ InitialiseRFBConnection(rfbClient* client) client->minor=8; } - rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n", + rfbClientLogEx(client, "VNC server supports protocol version %d.%d (viewer %d.%d)\n", major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion); sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor); @@ -1044,7 +1105,7 @@ InitialiseRFBConnection(rfbClient* client) authScheme = rfbClientSwap32IfLE(authScheme); } - rfbClientLog("Selected Security Scheme %d\n", authScheme); + rfbClientLogEx(client, "Selected Security Scheme %d\n", authScheme); client->authScheme = authScheme; switch (authScheme) { @@ -1054,7 +1115,7 @@ InitialiseRFBConnection(rfbClient* client) return FALSE; case rfbNoAuth: - rfbClientLog("No authentication needed\n"); + rfbClientLogEx(client, "No authentication needed\n"); /* 3.8 and upwards sends a Security Result for rfbNoAuth */ if ((client->major==3 && client->minor > 7) || client->major>3) @@ -1099,7 +1160,7 @@ InitialiseRFBConnection(rfbClient* client) return FALSE; case rfbNoAuth: - rfbClientLog("No sub authentication needed\n"); + rfbClientLogEx(client, "No sub authentication needed\n"); /* 3.8 and upwards sends a Security Result for rfbNoAuth */ if ((client->major==3 && client->minor > 7) || client->major>3) if (!rfbHandleAuthResult(client)) return FALSE; @@ -1116,7 +1177,7 @@ InitialiseRFBConnection(rfbClient* client) #endif /* LIBVNCSERVER_HAVE_SASL */ default: - rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n", + rfbClientLogEx(client, "Unknown sub authentication scheme from VNC server: %d\n", (int)subAuthScheme); return FALSE; } @@ -1146,7 +1207,7 @@ InitialiseRFBConnection(rfbClient* client) case rfbNoAuth: case rfbVeNCryptTLSNone: case rfbVeNCryptX509None: - rfbClientLog("No sub authentication needed\n"); + rfbClientLogEx(client, "No sub authentication needed\n"); if (!rfbHandleAuthResult(client)) return FALSE; break; @@ -1170,7 +1231,7 @@ InitialiseRFBConnection(rfbClient* client) #endif /* LIBVNCSERVER_HAVE_SASL */ default: - rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n", + rfbClientLogEx(client, "Unknown sub authentication scheme from VNC server: %d\n", client->subAuthScheme); return FALSE; } @@ -1194,7 +1255,7 @@ InitialiseRFBConnection(rfbClient* client) } if (authHandled) break; } - rfbClientLog("Unknown authentication scheme from VNC server: %d\n", + rfbClientLogEx(client, "Unknown authentication scheme from VNC server: %d\n", (int)authScheme); return FALSE; } @@ -1213,13 +1274,13 @@ InitialiseRFBConnection(rfbClient* client) client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength); if (client->si.nameLength > 1<<20) { - rfbClientErr("Too big desktop name length sent by server: %u B > 1 MB\n", (unsigned int)client->si.nameLength); + rfbClientErrEx(client, "Too big desktop name length sent by server: %u B > 1 MB\n", (unsigned int)client->si.nameLength); return FALSE; } client->desktopName = malloc(client->si.nameLength + 1); if (!client->desktopName) { - rfbClientLog("Error allocating memory for desktop name, %lu bytes\n", + rfbClientLogEx(client, "Error allocating memory for desktop name, %lu bytes\n", (unsigned long)client->si.nameLength); return FALSE; } @@ -1228,12 +1289,12 @@ InitialiseRFBConnection(rfbClient* client) client->desktopName[client->si.nameLength] = 0; - rfbClientLog("Desktop name \"%s\"\n",client->desktopName); + rfbClientLogEx(client, "Desktop name \"%s\"\n",client->desktopName); - rfbClientLog("Connected to VNC server, using protocol version %d.%d\n", + rfbClientLogEx(client, "Connected to VNC server, using protocol version %d.%d\n", client->major, client->minor); - rfbClientLog("VNC server default format:\n"); + rfbClientLogEx(client, "VNC server default format:\n"); PrintPixelFormat(&client->si.format); return TRUE; @@ -1336,7 +1397,7 @@ SetFormatAndEncodings(rfbClient* client) } else if (strncasecmp(encStr,"rre",encStrLen) == 0) { encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE); } else { - rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr); + rfbClientLogEx(client, "Unknown encoding '%.*s'\n",encStrLen,encStr); } encStr = nextEncStr; @@ -1359,11 +1420,11 @@ SetFormatAndEncodings(rfbClient* client) /* TODO: if (!tunnelSpecified) { */ - rfbClientLog("Same machine: preferring raw encoding\n"); + rfbClientLogEx(client, "Same machine: preferring raw encoding\n"); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw); /* } else { - rfbClientLog("Tunneling active: preferring tight encoding\n"); + rfbClientLogEx(client, "Tunneling active: preferring tight encoding\n"); } */ } @@ -1497,7 +1558,7 @@ SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbB if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE; if (client->requestedResize) { - rfbClientLog("Skipping Update - resize in progress\n"); + rfbClientLogEx(client, "Skipping Update - resize in progress\n"); return TRUE; } @@ -1705,12 +1766,12 @@ SendExtDesktopSize(rfbClient* client, uint16_t width, uint16_t height) rfbExtDesktopScreen screen; if (client->screen.width == 0 && client->screen.height == 0 ) { - rfbClientLog("Screen not yet received from server - not sending dimensions %dx%d\n", width, height); + rfbClientLogEx(client, "Screen not yet received from server - not sending dimensions %dx%d\n", width, height); return TRUE; } if (client->screen.width != rfbClientSwap16IfLE(width) || client->screen.height != rfbClientSwap16IfLE(height)) { - rfbClientLog("Sending dimensions %dx%d\n", width, height); + rfbClientLogEx(client, "Sending dimensions %dx%d\n", width, height); sdm.type = rfbSetDesktopSize; sdm.width = rfbClientSwap16IfLE(width); sdm.height = rfbClientSwap16IfLE(height); @@ -1865,7 +1926,7 @@ sendExtClientCutTextProvide(rfbClient *client, char* data, int len) unsigned char *buf = malloc(sz_to_compressed); if (!buf) { - rfbClientLog("sendExtClientCutTextProvide. alloc buf failed\n"); + rfbClientLogEx(client, "sendExtClientCutTextProvide. alloc buf failed\n"); return FALSE; } memcpy(buf, &be_size, sizeof(be_size)); @@ -1874,13 +1935,13 @@ sendExtClientCutTextProvide(rfbClient *client, char* data, int len) unsigned char *cbuf = malloc(sizeof(be_flags) + csz); /*flag, compressed*/ if (!cbuf) { - rfbClientLog("sendExtClientCutTextProvide. alloc cbuf failed\n"); + rfbClientLogEx(client, "sendExtClientCutTextProvide. alloc cbuf failed\n"); free(buf); return FALSE; } memcpy(cbuf, &be_flags, sizeof(be_flags)); if (CompressClipData(cbuf + sizeof(be_flags), &csz, buf, sz_to_compressed) != Z_OK) { - rfbClientLog("sendExtClientCutTextProvide: compress cbuf failed\n"); + rfbClientLogEx(client, "sendExtClientCutTextProvide: compress cbuf failed\n"); free(buf); free(cbuf); return FALSE; @@ -1936,7 +1997,7 @@ rfbClientProcessExtServerCutText(rfbClient* client, char *data, int len) { uint32_t flags; if (len < sizeof(flags)) { - rfbClientLog("rfbClientProcessExtServerCutText. len < 4\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. len < 4\n"); return FALSE; } memcpy(&flags, data, sizeof(flags)); @@ -1949,15 +2010,15 @@ rfbClientProcessExtServerCutText(rfbClient* client, char *data, int len) * modify here if need more types(rtf,html,dib,files) */ if (!(flags & rfbExtendedClipboard_Text)) { - rfbClientLog("rfbClientProcessExtServerCutText. not text type. ignore\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. not text type. ignore\n"); return TRUE; } if (!(flags & rfbExtendedClipboard_Provide)) { - rfbClientLog("rfbClientProcessExtServerCutText. not provide type. ignore\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. not provide type. ignore\n"); return TRUE; } if (flags & rfbExtendedClipboard_Caps) { - rfbClientLog("rfbClientProcessExtServerCutText. default cap.\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. default cap.\n"); client->extendedClipboardServerCapabilities |= rfbExtendedClipboard_Text; /* for now, only text */ return TRUE; } @@ -1969,7 +2030,7 @@ rfbClientProcessExtServerCutText(rfbClient* client, char *data, int len) stream.avail_in = 0; stream.next_in = NULL; if (inflateInit(&stream) != Z_OK) { - rfbClientLog("rfbClientProcessExtServerCutText. inflateInit failed\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. inflateInit failed\n"); return FALSE; } stream.avail_in = len; @@ -1979,20 +2040,20 @@ rfbClientProcessExtServerCutText(rfbClient* client, char *data, int len) stream.avail_out = sizeof(size); stream.next_out = (unsigned char *)&size; if (inflate(&stream, Z_SYNC_FLUSH) != Z_OK) { - rfbClientLog("rfbClientProcessExtServerCutText. inflate size failed\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. inflate size failed\n"); inflateEnd(&stream); return FALSE; } size = rfbClientSwap32IfLE(size); if (size > (1 << 20)) { - rfbClientLog("rfbClientProcessExtServerCutText. size too large\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. size too large\n"); inflateEnd(&stream); return FALSE; } unsigned char *buf = malloc(size); if (!buf) { - rfbClientLog("rfbClientProcessExtServerCutText. alloc buf failed\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. alloc buf failed\n"); inflateEnd(&stream); return FALSE; } @@ -2001,13 +2062,13 @@ rfbClientProcessExtServerCutText(rfbClient* client, char *data, int len) uLong out_before = stream.total_out; int err = inflate(&stream, Z_SYNC_FLUSH); if (err != Z_OK && err != Z_STREAM_END) { - rfbClientLog("rfbClientProcessExtServerCutText. inflate buf failed\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. inflate buf failed\n"); free(buf); inflateEnd(&stream); return FALSE; } if ((stream.total_out - out_before) != size) { - rfbClientLog("rfbClientProcessExtServerCutText. inflate size error\n"); + rfbClientLogEx(client, "rfbClientProcessExtServerCutText. inflate size error\n"); free(buf); inflateEnd(&stream); return FALSE; @@ -2149,7 +2210,7 @@ HandleRFBServerMessage(rfbClient* client) if(!ResizeClientBuffer(client, rect.r.w, rect.r.h)) return FALSE; SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE); - rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h); + rfbClientLogEx(client, "Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h); continue; } @@ -2181,7 +2242,7 @@ HandleRFBServerMessage(rfbClient* client) if(!ResizeClientBuffer(client, rect.r.w, rect.r.h)) { return FALSE; } - rfbClientLog("Updated desktop size: %dx%d\n", rect.r.w, rect.r.h); + rfbClientLogEx(client, "Updated desktop size: %dx%d\n", rect.r.w, rect.r.h); } client->requestedResize = FALSE; @@ -2197,17 +2258,17 @@ HandleRFBServerMessage(rfbClient* client) /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */ /* currently ignored by this library */ - rfbClientLog("client2server supported messages (bit flags)\n"); + rfbClientLogEx(client, "client2server supported messages (bit flags)\n"); for (loop=0;loop<32;loop+=8) - rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, + rfbClientLogEx(client, "%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, client->supportedMessages.client2server[loop], client->supportedMessages.client2server[loop+1], client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3], client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5], client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]); - rfbClientLog("server2client supported messages (bit flags)\n"); + rfbClientLogEx(client, "server2client supported messages (bit flags)\n"); for (loop=0;loop<32;loop+=8) - rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, + rfbClientLogEx(client, "%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, client->supportedMessages.server2client[loop], client->supportedMessages.server2client[loop+1], client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3], client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5], @@ -2241,7 +2302,7 @@ HandleRFBServerMessage(rfbClient* client) return FALSE; } buffer[rect.r.w]=0; /* null terminate, just in case */ - rfbClientLog("Connected to Server \"%s\"\n", buffer); + rfbClientLogEx(client, "Connected to Server \"%s\"\n", buffer); free(buffer); continue; } @@ -2252,7 +2313,7 @@ HandleRFBServerMessage(rfbClient* client) if ((rect.r.x + rect.r.w > client->width) || (rect.r.y + rect.r.h > client->height)) { - rfbClientLog("Rect too large: %dx%d at (%d, %d)\n", + rfbClientLogEx(client, "Rect too large: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); return FALSE; } @@ -2262,7 +2323,7 @@ HandleRFBServerMessage(rfbClient* client) if ((rect.encoding != rfbEncodingTight) && (rect.r.h * rect.r.w == 0)) { - rfbClientLog("Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h); + rfbClientLogEx(client, "Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h); continue; } */ @@ -2556,7 +2617,7 @@ HandleRFBServerMessage(rfbClient* client) handled = TRUE; if(!handled) { - rfbClientLog("Unknown rect encoding %d\n", + rfbClientLogEx(client, "Unknown rect encoding %d\n", (int)rect.encoding); return FALSE; } @@ -2604,7 +2665,7 @@ HandleRFBServerMessage(rfbClient* client) #endif if (msg.sct.length > 1<<20) { - rfbClientErr("Ignoring too big cut text length sent by server: %u B > 1 MB\n", (unsigned int)msg.sct.length); + rfbClientErrEx(client, "Ignoring too big cut text length sent by server: %u B > 1 MB\n", (unsigned int)msg.sct.length); return FALSE; } @@ -2644,17 +2705,17 @@ HandleRFBServerMessage(rfbClient* client) msg.tc.length = rfbClientSwap32IfLE(msg.sct.length); switch(msg.tc.length) { case rfbTextChatOpen: - rfbClientLog("Received TextChat Open\n"); + rfbClientLogEx(client, "Received TextChat Open\n"); if (client->HandleTextChat!=NULL) client->HandleTextChat(client, (int)rfbTextChatOpen, NULL); break; case rfbTextChatClose: - rfbClientLog("Received TextChat Close\n"); + rfbClientLogEx(client, "Received TextChat Close\n"); if (client->HandleTextChat!=NULL) client->HandleTextChat(client, (int)rfbTextChatClose, NULL); break; case rfbTextChatFinished: - rfbClientLog("Received TextChat Finished\n"); + rfbClientLogEx(client, "Received TextChat Finished\n"); if (client->HandleTextChat!=NULL) client->HandleTextChat(client, (int)rfbTextChatFinished, NULL); break; @@ -2669,7 +2730,7 @@ HandleRFBServerMessage(rfbClient* client) } /* Null Terminate */ buffer[msg.tc.length]=0; - rfbClientLog("Received TextChat \"%s\"\n", buffer); + rfbClientLogEx(client, "Received TextChat \"%s\"\n", buffer); if (client->HandleTextChat!=NULL) client->HandleTextChat(client, (int)msg.tc.length, buffer); free(buffer); @@ -2705,7 +2766,7 @@ HandleRFBServerMessage(rfbClient* client) return FALSE; SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); - rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); + rfbClientLogEx(client, "Got new framebuffer size: %dx%d\n", client->width, client->height); break; } @@ -2717,7 +2778,7 @@ HandleRFBServerMessage(rfbClient* client) if (!ResizeClientBuffer(client, rfbClientSwap16IfLE(msg.prsfb.buffer_w), rfbClientSwap16IfLE(msg.prsfb.buffer_h))) return FALSE; SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); - rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); + rfbClientLogEx(client, "Got new framebuffer size: %dx%d\n", client->width, client->height); break; } @@ -2732,7 +2793,7 @@ HandleRFBServerMessage(rfbClient* client) if(!handled) { char buffer[256]; - rfbClientLog("Unknown message type %d from VNC server\n",msg.type); + rfbClientLogEx(client, "Unknown message type %d from VNC server\n",msg.type); ReadFromRFBServer(client, buffer, 256); return FALSE; } diff --git a/test/client_log_test.c b/test/client_log_test.c new file mode 100644 index 000000000..98d69e1e1 --- /dev/null +++ b/test/client_log_test.c @@ -0,0 +1,66 @@ +#include + +#include +#include +#include + +static rfbClient *seenClient; +static int clientLogCalls; +static char clientLogMessage[128]; +static int legacyLogCalls; +static char legacyLogMessage[128]; + +static void +clientAwareLog(rfbClient *client, const char *format, va_list args) +{ + seenClient = client; + clientLogCalls++; + vsnprintf(clientLogMessage, sizeof(clientLogMessage), format, args); +} + +static void +legacyLog(const char *format, ...) +{ + va_list args; + + legacyLogCalls++; + va_start(args, format); + vsnprintf(legacyLogMessage, sizeof(legacyLogMessage), format, args); + va_end(args); +} + +int +main(void) +{ + rfbClientLogProc oldLog = rfbClientLog; + rfbClientLogProc oldErr = rfbClientErr; + rfbClientLogProcWithClient oldLogWithClient = rfbClientLogWithClient; + rfbClientLogProcWithClient oldErrWithClient = rfbClientErrWithClient; + rfbClient *client = rfbGetClient(8, 3, 4); + + if(!client) + return 1; + + rfbClientLogWithClient = clientAwareLog; + rfbClientLogEx(client, "client %s", "message"); + if(clientLogCalls != 1 || seenClient != client || strcmp(clientLogMessage, "client message") != 0) + return 2; + + rfbClientLogWithClient = NULL; + rfbClientLog = legacyLog; + rfbClientLogEx(client, "legacy %d", 42); + if(legacyLogCalls != 1 || strcmp(legacyLogMessage, "legacy 42") != 0) + return 3; + + rfbClientErrWithClient = clientAwareLog; + rfbClientErrEx(client, "err %s", "message"); + if(clientLogCalls != 2 || seenClient != client || strcmp(clientLogMessage, "err message") != 0) + return 4; + + rfbClientLog = oldLog; + rfbClientErr = oldErr; + rfbClientLogWithClient = oldLogWithClient; + rfbClientErrWithClient = oldErrWithClient; + rfbClientCleanup(client); + return 0; +} From c40b111e4f2f6748e53298a026798a765d545e4f Mon Sep 17 00:00:00 2001 From: Marco Fortina Date: Sun, 17 May 2026 06:22:35 +0000 Subject: [PATCH 2/3] libvncclient: use client-aware logging in client paths --- src/libvncclient/rfbclient.c | 26 ++++++---- src/libvncclient/sasl.c | 88 +++++++++++++++++----------------- src/libvncclient/sockets.c | 26 +++++----- src/libvncclient/tight.c | 36 +++++++------- src/libvncclient/tls_gnutls.c | 86 ++++++++++++++++----------------- src/libvncclient/tls_none.c | 10 ++-- src/libvncclient/tls_openssl.c | 75 +++++++++++++++-------------- src/libvncclient/trle.c | 6 +-- src/libvncclient/ultra.c | 36 +++++++------- src/libvncclient/vncviewer.c | 28 +++++------ src/libvncclient/zlib.c | 12 ++--- src/libvncclient/zrle.c | 24 +++++----- 12 files changed, 235 insertions(+), 218 deletions(-) diff --git a/src/libvncclient/rfbclient.c b/src/libvncclient/rfbclient.c index 1d4cf6b00..4d3a20365 100644 --- a/src/libvncclient/rfbclient.c +++ b/src/libvncclient/rfbclient.c @@ -67,6 +67,8 @@ #define MAX_TEXTCHAT_SIZE 10485760 /* 10MB */ +static void PrintPixelFormatForClient(rfbClient *client, rfbPixelFormat *format); + /* * rfbClientLog prints a time-stamped message to the log file (stderr). */ @@ -1295,7 +1297,7 @@ InitialiseRFBConnection(rfbClient* client) client->major, client->minor); rfbClientLogEx(client, "VNC server default format:\n"); - PrintPixelFormat(&client->si.format); + PrintPixelFormatForClient(client, &client->si.format); return TRUE; } @@ -2878,31 +2880,37 @@ HandleRFBServerMessage(rfbClient* client) * PrintPixelFormat. */ -void -PrintPixelFormat(rfbPixelFormat *format) +static void +PrintPixelFormatForClient(rfbClient *client, rfbPixelFormat *format) { if (format->bitsPerPixel == 1) { - rfbClientLog(" Single bit per pixel.\n"); - rfbClientLog( + rfbClientLogEx(client, " Single bit per pixel.\n"); + rfbClientLogEx(client, " %s significant bit in each byte is leftmost on the screen.\n", (format->bigEndian ? "Most" : "Least")); } else { - rfbClientLog(" %d bits per pixel.\n",format->bitsPerPixel); + rfbClientLogEx(client, " %d bits per pixel.\n",format->bitsPerPixel); if (format->bitsPerPixel != 8) { - rfbClientLog(" %s significant byte first in each pixel.\n", + rfbClientLogEx(client, " %s significant byte first in each pixel.\n", (format->bigEndian ? "Most" : "Least")); } if (format->trueColour) { - rfbClientLog(" TRUE colour: max red %d green %d blue %d" + rfbClientLogEx(client, " TRUE colour: max red %d green %d blue %d" ", shift red %d green %d blue %d\n", format->redMax, format->greenMax, format->blueMax, format->redShift, format->greenShift, format->blueShift); } else { - rfbClientLog(" Colour map (not true colour).\n"); + rfbClientLogEx(client, " Colour map (not true colour).\n"); } } } +void +PrintPixelFormat(rfbPixelFormat *format) +{ + PrintPixelFormatForClient(NULL, format); +} + /* avoid name clashes with LibVNCServer */ #define rfbEncryptBytes rfbClientEncryptBytes diff --git a/src/libvncclient/sasl.c b/src/libvncclient/sasl.c index 68dd8eec5..361207d34 100644 --- a/src/libvncclient/sasl.c +++ b/src/libvncclient/sasl.c @@ -64,7 +64,9 @@ static int log_func(void *context, int level, const char *message) { - rfbClientLog("SASL: %s\n", message); + rfbClient *client = (rfbClient *)context; + + rfbClientLogEx(client, "SASL: %s\n", message); return SASL_OK; } @@ -77,12 +79,12 @@ static int user_callback_adapt(void *context, rfbClient* client = (rfbClient *)context; if (id != SASL_CB_AUTHNAME) { - rfbClientLog("Unrecognized SASL callback ID %d\n", id); + rfbClientLogEx(client, "Unrecognized SASL callback ID %d\n", id); return SASL_FAIL; } if (!client->GetUser) { - rfbClientLog("Client user callback not found\n"); + rfbClientLogEx(client, "Client user callback not found\n"); return SASL_FAIL; } @@ -102,7 +104,7 @@ static int password_callback_adapt(sasl_conn_t *conn, char * password; if (id != SASL_CB_PASS) { - rfbClientLog("Unrecognized SASL callback ID %d\n", id); + rfbClientLogEx(client, "Unrecognized SASL callback ID %d\n", id); return SASL_FAIL; } @@ -112,7 +114,7 @@ static int password_callback_adapt(sasl_conn_t *conn, } if (!client->GetPassword) { - rfbClientLog("Client password callback not found\n"); + rfbClientLogEx(client, "Client password callback not found\n"); return SASL_FAIL; } @@ -122,7 +124,7 @@ static int password_callback_adapt(sasl_conn_t *conn, sasl_secret_t *lsec = (sasl_secret_t *)malloc(sizeof(sasl_secret_t) + strlen(password)); if (!lsec) { - rfbClientLog("Could not allocate sasl_secret_t\n"); + rfbClientLogEx(client, "Could not allocate sasl_secret_t\n"); return SASL_FAIL; } @@ -161,7 +163,7 @@ HandleSASLAuth(rfbClient *client) const void *val; sasl_ssf_t ssf; sasl_callback_t saslcb[] = { - {SASL_CB_LOG, (void *)log_func, NULL}, + {SASL_CB_LOG, (void *)log_func, client}, {SASL_CB_AUTHNAME, client->GetUser ? (void *)user_callback_adapt : NULL, client}, {SASL_CB_PASS, client->GetPassword ? (void *)password_callback_adapt : NULL, client}, { .id = 0 }, @@ -177,9 +179,9 @@ HandleSASLAuth(rfbClient *client) /* Sets up the SASL library as a whole */ err = sasl_client_init(NULL); - rfbClientLog("Client initialize SASL authentication %d\n", err); + rfbClientLogEx(client, "Client initialize SASL authentication %d\n", err); if (err != SASL_OK) { - rfbClientLog("failed to initialize SASL library: %d (%s)\n", + rfbClientLogEx(client, "failed to initialize SASL library: %d (%s)\n", err, sasl_errstring(err, NULL, NULL)); goto error; } @@ -191,7 +193,7 @@ HandleSASLAuth(rfbClient *client) int port; if (getsockname(client->sock, (struct sockaddr*)&localAddress, &addressLength)) { - rfbClientLog("failed to get local address\n"); + rfbClientLogEx(client, "failed to get local address\n"); goto error; } @@ -206,14 +208,14 @@ HandleSASLAuth(rfbClient *client) port = ntohs(sa_in->sin6_port); localAddr = vnc_connection_addr_to_string(buf, port); } else { - rfbClientLog("failed to get local address\n"); + rfbClientLogEx(client, "failed to get local address\n"); goto error; } /* Get remote address in form IPADDR:PORT */ remoteAddr = vnc_connection_addr_to_string(client->serverHost, client->serverPort); - rfbClientLog("Client SASL new host:'%s' local:'%s' remote:'%s'\n", client->serverHost, localAddr, remoteAddr); + rfbClientLogEx(client, "Client SASL new host:'%s' local:'%s' remote:'%s'\n", client->serverHost, localAddr, remoteAddr); /* Setup a handle for being a client */ err = sasl_client_new("vnc", @@ -227,7 +229,7 @@ HandleSASLAuth(rfbClient *client) free(remoteAddr); if (err != SASL_OK) { - rfbClientLog("Failed to create SASL client context: %d (%s)\n", + rfbClientLogEx(client, "Failed to create SASL client context: %d (%s)\n", err, sasl_errstring(err, NULL, NULL)); goto error; } @@ -235,14 +237,14 @@ HandleSASLAuth(rfbClient *client) /* Initialize some connection props we care about */ if (client->tlsSession) { if (!(ssf = (sasl_ssf_t)GetTLSCipherBits(client))) { - rfbClientLog("%s", "invalid cipher size for TLS session\n"); + rfbClientLogEx(client, "%s", "invalid cipher size for TLS session\n"); goto error; } - rfbClientLog("Setting external SSF %d\n", ssf); + rfbClientLogEx(client, "Setting external SSF %d\n", ssf); err = sasl_setprop(saslconn, SASL_SSF_EXTERNAL, &ssf); if (err != SASL_OK) { - rfbClientLog("cannot set external SSF %d (%s)\n", + rfbClientLogEx(client, "cannot set external SSF %d (%s)\n", err, sasl_errstring(err, NULL, NULL)); goto error; } @@ -259,20 +261,20 @@ HandleSASLAuth(rfbClient *client) err = sasl_setprop(saslconn, SASL_SEC_PROPS, &secprops); if (err != SASL_OK) { - rfbClientLog("cannot set security props %d (%s)\n", + rfbClientLogEx(client, "cannot set security props %d (%s)\n", err, sasl_errstring(err, NULL, NULL)); goto error; } /* Get the supported mechanisms from the server */ if (!ReadFromRFBServer(client, (char *)&mechlistlen, 4)) { - rfbClientLog("failed to read mechlistlen\n"); + rfbClientLogEx(client, "failed to read mechlistlen\n"); goto error; } mechlistlen = rfbClientSwap32IfLE(mechlistlen); - rfbClientLog("mechlistlen is %d\n", mechlistlen); + rfbClientLogEx(client, "mechlistlen is %d\n", mechlistlen); if (mechlistlen > SASL_MAX_MECHLIST_LEN) { - rfbClientLog("mechlistlen %d too long\n", mechlistlen); + rfbClientLogEx(client, "mechlistlen %d too long\n", mechlistlen); goto error; } @@ -289,7 +291,7 @@ HandleSASLAuth(rfbClient *client) if (wantmech && *wantmech != 0) { if (strstr(mechlist, wantmech) == NULL) { - rfbClientLog("Client requested SASL mechanism %s not supported by server\n", + rfbClientLogEx(client, "Client requested SASL mechanism %s not supported by server\n", wantmech); free(mechlist); free(wantmech); @@ -301,7 +303,7 @@ HandleSASLAuth(rfbClient *client) } } - rfbClientLog("Client start negotiation mechlist '%s'\n", mechlist); + rfbClientLogEx(client, "Client start negotiation mechlist '%s'\n", mechlist); /* Start the auth negotiation on the client end first */ err = sasl_client_start(saslconn, @@ -311,7 +313,7 @@ HandleSASLAuth(rfbClient *client) &clientoutlen, &mechname); if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) { - rfbClientLog("Failed to start SASL negotiation: %d (%s)\n", + rfbClientLogEx(client, "Failed to start SASL negotiation: %d (%s)\n", err, sasl_errdetail(saslconn)); free(mechlist); mechlist = NULL; @@ -320,15 +322,15 @@ HandleSASLAuth(rfbClient *client) /* Need to gather some credentials from the client */ if (err == SASL_INTERACT) { - rfbClientLog("User interaction required but not currently supported\n"); + rfbClientLogEx(client, "User interaction required but not currently supported\n"); goto error; } - rfbClientLog("Server start negotiation with mech %s. Data %d bytes %p '%s'\n", + rfbClientLogEx(client, "Server start negotiation with mech %s. Data %d bytes %p '%s'\n", mechname, clientoutlen, clientout, clientout); if (clientoutlen > SASL_MAX_DATA_LEN) { - rfbClientLog("SASL negotiation data too long: %d bytes\n", + rfbClientLogEx(client, "SASL negotiation data too long: %d bytes\n", clientoutlen); goto error; } @@ -348,13 +350,13 @@ HandleSASLAuth(rfbClient *client) if (!WriteToRFBServer(client, (char *)&temp, 4)) goto error; } - rfbClientLog("%s", "Getting sever start negotiation reply\n"); + rfbClientLogEx(client, "%s", "Getting sever start negotiation reply\n"); /* Read the 'START' message reply from server */ if (!ReadFromRFBServer(client, (char *)&serverinlen, 4)) goto error; serverinlen = rfbClientSwap32IfLE(serverinlen); if (serverinlen > SASL_MAX_DATA_LEN) { - rfbClientLog("SASL negotiation data too long: %d bytes\n", + rfbClientLogEx(client, "SASL negotiation data too long: %d bytes\n", serverinlen); goto error; } @@ -370,7 +372,7 @@ HandleSASLAuth(rfbClient *client) } if (!ReadFromRFBServer(client, (char *)&complete, 1)) goto error; - rfbClientLog("Client start result complete: %d. Data %d bytes %p '%s'\n", + rfbClientLogEx(client, "Client start result complete: %d. Data %d bytes %p '%s'\n", complete, serverinlen, serverin, serverin); /* Loop-the-loop... @@ -384,14 +386,14 @@ HandleSASLAuth(rfbClient *client) &clientout, &clientoutlen); if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) { - rfbClientLog("Failed SASL step: %d (%s)\n", + rfbClientLogEx(client, "Failed SASL step: %d (%s)\n", err, sasl_errdetail(saslconn)); goto error; } /* Need to gather some credentials from the client */ if (err == SASL_INTERACT) { - rfbClientLog("User interaction required but not currently supported\n"); + rfbClientLogEx(client, "User interaction required but not currently supported\n"); goto error; } @@ -400,7 +402,7 @@ HandleSASLAuth(rfbClient *client) serverin = NULL; } - rfbClientLog("Client step result %d. Data %d bytes %p '%s'\n", err, clientoutlen, clientout, clientout); + rfbClientLogEx(client, "Client step result %d. Data %d bytes %p '%s'\n", err, clientoutlen, clientout, clientout); /* Previous server call showed completion & we're now locally complete too */ if (complete && err == SASL_OK) @@ -418,13 +420,13 @@ HandleSASLAuth(rfbClient *client) if (!WriteToRFBServer(client, (char *)&temp, 4)) goto error; } - rfbClientLog("Server step with %d bytes %p\n", clientoutlen, clientout); + rfbClientLogEx(client, "Server step with %d bytes %p\n", clientoutlen, clientout); if (!ReadFromRFBServer(client, (char *)&serverinlen, 4)) goto error; serverinlen = rfbClientSwap32IfLE(serverinlen); if (serverinlen > SASL_MAX_DATA_LEN) { - rfbClientLog("SASL negotiation data too long: %d bytes\n", + rfbClientLogEx(client, "SASL negotiation data too long: %d bytes\n", serverinlen); goto error; } @@ -440,7 +442,7 @@ HandleSASLAuth(rfbClient *client) } if (!ReadFromRFBServer(client, (char *)&complete, 1)) goto error; - rfbClientLog("Client step result complete: %d. Data %d bytes %p '%s'\n", + rfbClientLogEx(client, "Client step result complete: %d. Data %d bytes %p '%s'\n", complete, serverinlen, serverin, serverin); /* This server call shows complete, and earlier client step was OK */ @@ -455,32 +457,32 @@ HandleSASLAuth(rfbClient *client) if (!client->tlsSession) { err = sasl_getprop(saslconn, SASL_SSF, &val); if (err != SASL_OK) { - rfbClientLog("cannot query SASL ssf on connection %d (%s)\n", + rfbClientLogEx(client, "cannot query SASL ssf on connection %d (%s)\n", err, sasl_errstring(err, NULL, NULL)); goto error; } ssf = *(const int *)val; - rfbClientLog("SASL SSF value %d\n", ssf); + rfbClientLogEx(client, "SASL SSF value %d\n", ssf); if (ssf < 56) { /* 56 == DES level, good for Kerberos */ - rfbClientLog("negotiation SSF %d was not strong enough\n", ssf); + rfbClientLogEx(client, "negotiation SSF %d was not strong enough\n", ssf); goto error; } } - rfbClientLog("%s", "SASL authentication complete\n"); + rfbClientLogEx(client, "%s", "SASL authentication complete\n"); uint32_t result; if (!ReadFromRFBServer(client, (char *)&result, 4)) { - rfbClientLog("Failed to read authentication result\n"); + rfbClientLogEx(client, "Failed to read authentication result\n"); goto error; } result = rfbClientSwap32IfLE(result); if (result != 0) { - rfbClientLog("Authentication failure\n"); + rfbClientLogEx(client, "Authentication failure\n"); goto error; } - rfbClientLog("Authentication successful - switching to SSF\n"); + rfbClientLogEx(client, "Authentication successful - switching to SSF\n"); /* This must come *after* check-auth-result, because the former * is defined to be sent unencrypted, and setting saslconn turns @@ -541,7 +543,7 @@ ReadFromSASL(rfbClient* client, char *out, unsigned int n) &client->saslDecoded, &client->saslDecodedLength); free(encoded); if (err != SASL_OK) { - rfbClientLog("Failed to decode SASL data %s\n", + rfbClientLogEx(client, "Failed to decode SASL data %s\n", sasl_errstring(err, NULL, NULL)); return -EINVAL; } diff --git a/src/libvncclient/sockets.c b/src/libvncclient/sockets.c index d914f0744..9d78919a9 100644 --- a/src/libvncclient/sockets.c +++ b/src/libvncclient/sockets.c @@ -68,7 +68,7 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) #ifdef DEBUG_READ_EXACT char* oout=out; unsigned int nn=n; - rfbClientLog("ReadFromRFBServer %d bytes\n",n); + rfbClientLogEx(client, "ReadFromRFBServer %d bytes\n",n); #endif /* Handle attempts to write to NULL out buffer that might occur @@ -156,7 +156,7 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) if (client->readTimeout > 0 && ++retries > (client->readTimeout * 1000 * 1000 / USECS_WAIT_PER_RETRY)) { - rfbClientLog("Connection timed out\n"); + rfbClientLogEx(client, "Connection timed out\n"); return FALSE; } /* TODO: @@ -165,12 +165,12 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) WaitForMessage(client, USECS_WAIT_PER_RETRY); i = 0; } else { - rfbClientErr("read (%d: %s)\n",errno,strerror(errno)); + rfbClientErrEx(client, "read (%d: %s)\n",errno,strerror(errno)); return FALSE; } } else { if (errorMessageOnReadFailure) { - rfbClientLog("VNC server closed connection\n"); + rfbClientLogEx(client, "VNC server closed connection\n"); } return FALSE; } @@ -205,7 +205,7 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) if (client->readTimeout > 0 && ++retries > (client->readTimeout * 1000 * 1000 / USECS_WAIT_PER_RETRY)) { - rfbClientLog("Connection timed out\n"); + rfbClientLogEx(client, "Connection timed out\n"); return FALSE; } /* TODO: @@ -214,12 +214,12 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) WaitForMessage(client, USECS_WAIT_PER_RETRY); i = 0; } else { - rfbClientErr("read (%s)\n",strerror(errno)); + rfbClientErrEx(client, "read (%s)\n",strerror(errno)); return FALSE; } } else { if (errorMessageOnReadFailure) { - rfbClientLog("VNC server closed connection\n"); + rfbClientLogEx(client, "VNC server closed connection\n"); } return FALSE; } @@ -275,7 +275,7 @@ WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n) buf, n, &output, &outputlen); if (err != SASL_OK) { - rfbClientLog("Failed to encode SASL data %s", + rfbClientLogEx(client, "Failed to encode SASL data %s", sasl_errstring(err, NULL, NULL)); return FALSE; } @@ -298,7 +298,7 @@ WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n) errno == EAGAIN) { if(client->sock == RFB_INVALID_SOCKET) { errno = EBADF; - rfbClientErr("socket invalid\n"); + rfbClientErrEx(client, "socket invalid\n"); return FALSE; } @@ -306,16 +306,16 @@ WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n) FD_SET(client->sock,&fds); if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) { - rfbClientErr("select\n"); + rfbClientErrEx(client, "select\n"); return FALSE; } j = 0; } else { - rfbClientErr("write\n"); + rfbClientErrEx(client, "write\n"); return FALSE; } } else { - rfbClientLog("write failed\n"); + rfbClientLogEx(client, "write failed\n"); return FALSE; } } @@ -884,7 +884,7 @@ int WaitForMessage(rfbClient* client,unsigned int usecs) #ifdef WIN32 errno=WSAGetLastError(); #endif - rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno)); + rfbClientLogEx(client, "Waiting for message failed: %d (%s)\n",errno,strerror(errno)); } return num; diff --git a/src/libvncclient/tight.c b/src/libvncclient/tight.c index dad5514f4..f63106674 100644 --- a/src/libvncclient/tight.c +++ b/src/libvncclient/tight.c @@ -147,7 +147,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) return FALSE; if (rx + rw > client->width || ry + rh > client->height) { - rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", rx, ry, rw, rh); + rfbClientLogEx(client, "Rect out of bounds: %dx%d at (%d, %d)\n", rx, ry, rw, rh); return FALSE; } @@ -159,7 +159,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) if ((comp_ctl & 1) && client->zlibStreamActive[stream_id]) { if (inflateEnd (&client->zlibStream[stream_id]) != Z_OK && client->zlibStream[stream_id].msg != NULL) - rfbClientLog("inflateEnd: %s\n", client->zlibStream[stream_id].msg); + rfbClientLogEx(client, "inflateEnd: %s\n", client->zlibStream[stream_id].msg); client->zlibStreamActive[stream_id] = FALSE; } comp_ctl >>= 1; @@ -194,7 +194,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) #if BPP == 8 if (comp_ctl == rfbTightJpeg) { - rfbClientLog("Tight encoding: JPEG is not supported in 8 bpp mode.\n"); + rfbClientLogEx(client, "Tight encoding: JPEG is not supported in 8 bpp mode.\n"); return FALSE; } #else @@ -205,7 +205,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* Quit on unsupported subencoding value. */ if (comp_ctl > rfbTightMaxSubencoding) { - rfbClientLog("Tight encoding: bad subencoding value received.\n"); + rfbClientLogEx(client, "Tight encoding: bad subencoding value received.\n"); return FALSE; } @@ -230,7 +230,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) break; case rfbTightFilterGradient: if (rw > TIGHT_GRADIENT_MAX_WIDTH) { - rfbClientLog("Tight Gradient rectangle width %d exceeds maximum %d.\n", + rfbClientLogEx(client, "Tight Gradient rectangle width %d exceeds maximum %d.\n", rw, TIGHT_GRADIENT_MAX_WIDTH); return FALSE; } @@ -238,7 +238,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) bitsPixel = InitFilterGradientBPP(client, rw, rh); break; default: - rfbClientLog("Tight encoding: unknown filter code received.\n"); + rfbClientLogEx(client, "Tight encoding: unknown filter code received.\n"); return FALSE; } } else { @@ -246,7 +246,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) bitsPixel = InitFilterCopyBPP(client, rw, rh); } if (bitsPixel == 0) { - rfbClientLog("Tight encoding: error receiving palette.\n"); + rfbClientLogEx(client, "Tight encoding: error receiving palette.\n"); return FALSE; } @@ -264,12 +264,12 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* Read the length (1..3 bytes) of compressed data following. */ compressedLen = (int)ReadCompactLen(client); if (compressedLen <= 0) { - rfbClientLog("Incorrect data received from the server.\n"); + rfbClientLogEx(client, "Incorrect data received from the server.\n"); return FALSE; } if (readUncompressed) { if (compressedLen > RFB_BUFFER_SIZE) { - rfbClientErr("Received uncompressed byte count exceeds our buffer size.\n"); + rfbClientErrEx(client, "Received uncompressed byte count exceeds our buffer size.\n"); return FALSE; } @@ -291,7 +291,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) err = inflateInit(zs); if (err != Z_OK) { if (zs->msg != NULL) - rfbClientLog("InflateInit error: %s.\n", zs->msg); + rfbClientLogEx(client, "InflateInit error: %s.\n", zs->msg); return FALSE; } client->zlibStreamActive[stream_id] = TRUE; @@ -302,7 +302,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) bufferSize = RFB_BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC; if (rowSize > bufferSize) { /* Should be impossible when RFB_BUFFER_SIZE >= 16384 */ - rfbClientLog("Internal error: incorrect buffer size.\n"); + rfbClientLogEx(client, "Internal error: incorrect buffer size.\n"); return FALSE; } @@ -332,9 +332,9 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) break; if (err != Z_OK && err != Z_STREAM_END) { if (zs->msg != NULL) { - rfbClientLog("Inflate error: %s.\n", zs->msg); + rfbClientLogEx(client, "Inflate error: %s.\n", zs->msg); } else { - rfbClientLog("Inflate error: %d.\n", err); + rfbClientLogEx(client, "Inflate error: %d.\n", err); } return FALSE; } @@ -353,7 +353,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) } if (rowsProcessed != rh) { - rfbClientLog("Incorrect number of scan lines after decompression.\n"); + rfbClientLogEx(client, "Incorrect number of scan lines after decompression.\n"); return FALSE; } @@ -608,13 +608,13 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) compressedLen = (int)ReadCompactLen(client); if (compressedLen <= 0) { - rfbClientLog("Incorrect data received from the server.\n"); + rfbClientLogEx(client, "Incorrect data received from the server.\n"); return FALSE; } compressedData = malloc(compressedLen); if (compressedData == NULL) { - rfbClientLog("Memory allocation error.\n"); + rfbClientLogEx(client, "Memory allocation error.\n"); return FALSE; } @@ -628,7 +628,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) if (!client->tjhnd) { if ((client->tjhnd = tjInitDecompress()) == NULL) { - rfbClientLog("TurboJPEG error: %s\n", tjGetErrorStr()); + rfbClientLogEx(client, "TurboJPEG error: %s\n", tjGetErrorStr()); free(compressedData); return FALSE; } @@ -651,7 +651,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) if (tjDecompress(client->tjhnd, compressedData, (unsigned long)compressedLen, dst, w, pitch, h, pixelSize, flags)==-1) { - rfbClientLog("TurboJPEG error: %s\n", tjGetErrorStr()); + rfbClientLogEx(client, "TurboJPEG error: %s\n", tjGetErrorStr()); free(compressedData); return FALSE; } diff --git a/src/libvncclient/tls_gnutls.c b/src/libvncclient/tls_gnutls.c index 6e46029a2..fb1990bde 100644 --- a/src/libvncclient/tls_gnutls.c +++ b/src/libvncclient/tls_gnutls.c @@ -45,12 +45,12 @@ typedef struct { static int cert_fingerprint_mismatch_callback(rfbClient *client, gnutls_x509_crt_t cert) { if(!cert) { - rfbClientErr("No cert given in fingerprint mismatch handling\n"); + rfbClientErrEx(client, "No cert given in fingerprint mismatch handling\n"); return 0; } if (!client || !client->GetX509CertFingerprintMismatchDecision) { - rfbClientErr("No client callback given in fingerprint mismatch handling\n"); + rfbClientErrEx(client, "No client callback given in fingerprint mismatch handling\n"); return 0; } @@ -106,7 +106,7 @@ verify_certificate_callback (gnutls_session_t session) hostname = sptr->serverHost; if (!hostname) { - rfbClientLog("No server hostname found for client\n"); + rfbClientLogEx(sptr, "No server hostname found for client\n"); return GNUTLS_E_CERTIFICATE_ERROR; } @@ -116,49 +116,49 @@ verify_certificate_callback (gnutls_session_t session) ret = gnutls_certificate_verify_peers2 (session, &status); if (ret < 0) { - rfbClientLog ("Certificate validation call failed\n"); + rfbClientLogEx(sptr, "Certificate validation call failed\n"); return GNUTLS_E_CERTIFICATE_ERROR; } if (status & GNUTLS_CERT_INVALID) - rfbClientLog("The certificate is not trusted.\n"); + rfbClientLogEx(sptr, "The certificate is not trusted.\n"); if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - rfbClientLog("The certificate hasn't got a known issuer.\n"); + rfbClientLogEx(sptr, "The certificate hasn't got a known issuer.\n"); if (status & GNUTLS_CERT_REVOKED) - rfbClientLog("The certificate has been revoked.\n"); + rfbClientLogEx(sptr, "The certificate has been revoked.\n"); if (status & GNUTLS_CERT_EXPIRED) - rfbClientLog("The certificate has expired\n"); + rfbClientLogEx(sptr, "The certificate has expired\n"); if (status & GNUTLS_CERT_NOT_ACTIVATED) - rfbClientLog("The certificate is not yet activated\n"); + rfbClientLogEx(sptr, "The certificate is not yet activated\n"); /* status would be 0 if cert was trusted */ if (status) { if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { - rfbClientErr("The certificate was not X509\n"); + rfbClientErrEx(sptr, "The certificate was not X509\n"); return GNUTLS_E_CERTIFICATE_ERROR; } if (gnutls_x509_crt_init (&cert) < 0) { - rfbClientErr("Error initialising certificate structure\n"); + rfbClientErrEx(sptr, "Error initialising certificate structure\n"); return GNUTLS_E_CERTIFICATE_ERROR; } cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) { - rfbClientErr("No certificate was found!\n"); + rfbClientErrEx(sptr, "No certificate was found!\n"); return GNUTLS_E_CERTIFICATE_ERROR; } if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { - rfbClientErr("Error parsing certificate\n"); + rfbClientErrEx(sptr, "Error parsing certificate\n"); return GNUTLS_E_CERTIFICATE_ERROR; } @@ -169,7 +169,7 @@ verify_certificate_callback (gnutls_session_t session) if (gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, remote_fingerprint, &fingerprint_size) == 0) { if (memcmp(remote_fingerprint, cred->x509Credential.x509ExpectedFingerprint, 32) == 0) { - rfbClientLog("The certificate's fingerprint matched the expected one - accepting.\n"); + rfbClientLogEx(sptr, "The certificate's fingerprint matched the expected one - accepting.\n"); gnutls_x509_crt_deinit (cert); return 0; } @@ -178,7 +178,7 @@ verify_certificate_callback (gnutls_session_t session) /* Fingerprint didn't match or no expected fingerprint - ask user */ if (cert_fingerprint_mismatch_callback(sptr, cert)) { - rfbClientLog("User decided to trust certificate - accepting.\n"); + rfbClientLogEx(sptr, "User decided to trust certificate - accepting.\n"); gnutls_x509_crt_deinit (cert); return 0; } @@ -189,32 +189,32 @@ verify_certificate_callback (gnutls_session_t session) /* Certificate is trusted by system CA or via given rfbCredential.x509Credential.x509CACertfile */ if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { - rfbClientLog("The certificate was not X509\n"); + rfbClientLogEx(sptr, "The certificate was not X509\n"); return GNUTLS_E_CERTIFICATE_ERROR; } if (gnutls_x509_crt_init (&cert) < 0) { - rfbClientLog("Error initialising certificate structure\n"); + rfbClientLogEx(sptr, "Error initialising certificate structure\n"); return GNUTLS_E_CERTIFICATE_ERROR; } cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) { - rfbClientLog("No certificate was found!\n"); + rfbClientLogEx(sptr, "No certificate was found!\n"); return GNUTLS_E_CERTIFICATE_ERROR; } if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { - rfbClientLog("Error parsing certificate\n"); + rfbClientLogEx(sptr, "Error parsing certificate\n"); return GNUTLS_E_CERTIFICATE_ERROR; } if (!gnutls_x509_crt_check_hostname (cert, hostname)) { - rfbClientLog("The certificate's owner does not match hostname '%s'\n", + rfbClientLogEx(sptr, "The certificate's owner does not match hostname '%s'\n", hostname); return GNUTLS_E_CERTIFICATE_ERROR; } @@ -355,14 +355,14 @@ InitializeTLSSession(rfbClient* client, rfbBool anonTLS) if ((ret = gnutls_init((gnutls_session_t*)&client->tlsSession, GNUTLS_CLIENT)) < 0) { - rfbClientLog("Failed to initialized TLS session: %s.\n", gnutls_strerror(ret)); + rfbClientLogEx(client, "Failed to initialized TLS session: %s.\n", gnutls_strerror(ret)); return FALSE; } if ((ret = gnutls_priority_set_direct((gnutls_session_t)client->tlsSession, anonTLS ? rfbAnonTLSPriority : rfbTLSPriority, &p)) < 0) { - rfbClientLog("Warning: Failed to set TLS priority: %s (%s).\n", gnutls_strerror(ret), p); + rfbClientLogEx(client, "Warning: Failed to set TLS priority: %s (%s).\n", gnutls_strerror(ret), p); } gnutls_transport_set_ptr((gnutls_session_t)client->tlsSession, (gnutls_transport_ptr_t)client); @@ -374,7 +374,7 @@ InitializeTLSSession(rfbClient* client, rfbBool anonTLS) INIT_MUTEX(client->tlsRwMutex); - rfbClientLog("TLS session initialized.\n"); + rfbClientLogEx(client, "TLS session initialized.\n"); return TRUE; } @@ -389,10 +389,10 @@ SetTLSAnonCredential(rfbClient* client) (ret = gnutls_credentials_set((gnutls_session_t)client->tlsSession, GNUTLS_CRD_ANON, anonCred)) < 0) { FreeTLS(client); - rfbClientLog("Failed to create anonymous credentials: %s", gnutls_strerror(ret)); + rfbClientLogEx(client, "Failed to create anonymous credentials: %s", gnutls_strerror(ret)); return FALSE; } - rfbClientLog("TLS anonymous credential created.\n"); + rfbClientLogEx(client, "TLS anonymous credential created.\n"); return TRUE; } @@ -405,15 +405,15 @@ HandshakeTLS(rfbClient* client) { if (!gnutls_error_is_fatal(ret)) { - rfbClientLog("TLS handshake got a temporary error: %s.\n", gnutls_strerror(ret)); + rfbClientLogEx(client, "TLS handshake got a temporary error: %s.\n", gnutls_strerror(ret)); continue; } - rfbClientLog("TLS handshake failed: %s\n", gnutls_strerror(ret)); + rfbClientLogEx(client, "TLS handshake failed: %s\n", gnutls_strerror(ret)); FreeTLS(client); return FALSE; } - rfbClientLog("TLS handshake done.\n"); + rfbClientLogEx(client, "TLS handshake done.\n"); return TRUE; } @@ -431,18 +431,18 @@ ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result) if (count==0) { - rfbClientLog("List of security types is ZERO. Giving up.\n"); + rfbClientLogEx(client, "List of security types is ZERO. Giving up.\n"); return FALSE; } - rfbClientLog("We have %d security types to read\n", count); + rfbClientLogEx(client, "We have %d security types to read\n", count); authScheme=0; /* now, we have a list of available security types to read ( uint8_t[] ) */ for (loop=0;loop0 ? ", %d" : "%d"), (int)tAuth[loop]); strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); } - rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n", + rfbClientLogEx(client, "Unknown VeNCrypt authentication scheme from VNC server: %s\n", buf1); return FALSE; } else { - rfbClientLog("Selecting security type %d\n", authScheme); + rfbClientLogEx(client, "Selecting security type %d\n", authScheme); /* send back 4 bytes (in original byte order!) indicating which security type to use */ if (!WriteToRFBServer(client, (char *)&origAuthScheme, 4)) return FALSE; } @@ -588,11 +588,11 @@ HandleVeNCryptAuth(rfbClient* client) { return FALSE; } - rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); + rfbClientLogEx(client, "Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); if (major != 0 && minor != 2) { - rfbClientLog("Unsupported VeNCrypt version.\n"); + rfbClientLogEx(client, "Unsupported VeNCrypt version.\n"); return FALSE; } @@ -605,7 +605,7 @@ HandleVeNCryptAuth(rfbClient* client) if (status != 0) { - rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); + rfbClientLogEx(client, "Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); return FALSE; } @@ -639,7 +639,7 @@ HandleVeNCryptAuth(rfbClient* client) /* Ack is only requred for the encrypted connection */ if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1) { - rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); + rfbClientLogEx(client, "Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); return FALSE; } @@ -651,13 +651,13 @@ HandleVeNCryptAuth(rfbClient* client) { if (!client->GetCredential) { - rfbClientLog("GetCredential callback is not set.\n"); + rfbClientLogEx(client, "GetCredential callback is not set.\n"); return FALSE; } cred = client->GetCredential(client, rfbCredentialTypeX509); if (!cred) { - rfbClientLog("Reading credential failed\n"); + rfbClientLogEx(client, "Reading credential failed\n"); return FALSE; } @@ -683,7 +683,7 @@ HandleVeNCryptAuth(rfbClient* client) /* We need the client plus the rfbCredential in the verification callback */ TLSCallbackData *callback_data = malloc(sizeof(TLSCallbackData)); if (!callback_data) { - rfbClientErr("Cannot allocate callback data\n"); + rfbClientErrEx(client, "Cannot allocate callback data\n"); FreeTLS(client); gnutls_certificate_free_credentials(x509_cred); FreeX509Credential(cred); @@ -697,7 +697,7 @@ HandleVeNCryptAuth(rfbClient* client) if ((ret = gnutls_credentials_set((gnutls_session_t)client->tlsSession, GNUTLS_CRD_CERTIFICATE, x509_cred)) < 0) { - rfbClientLog("Cannot set x509 credential: %s.\n", gnutls_strerror(ret)); + rfbClientLogEx(client, "Cannot set x509 credential: %s.\n", gnutls_strerror(ret)); FreeTLS(client); gnutls_certificate_free_credentials(x509_cred); free(callback_data); @@ -728,7 +728,7 @@ ReadFromTLS(rfbClient* client, char *out, unsigned int n) errno = EAGAIN; } else { - rfbClientLog("Error reading from TLS: %s.\n", gnutls_strerror(ret)); + rfbClientLogEx(client, "Error reading from TLS: %s.\n", gnutls_strerror(ret)); errno = EINTR; } return -1; @@ -750,7 +750,7 @@ WriteToTLS(rfbClient* client, const char *buf, unsigned int n) if (ret < 0) { if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) continue; - rfbClientLog("Error writing to TLS: %s.\n", gnutls_strerror(ret)); + rfbClientLogEx(client, "Error writing to TLS: %s.\n", gnutls_strerror(ret)); return -1; } offset += (unsigned int)ret; diff --git a/src/libvncclient/tls_none.c b/src/libvncclient/tls_none.c index d436ce9cd..2a951b5e3 100644 --- a/src/libvncclient/tls_none.c +++ b/src/libvncclient/tls_none.c @@ -23,21 +23,21 @@ rfbBool HandleAnonTLSAuth(rfbClient* client) { - rfbClientLog("TLS is not supported.\n"); + rfbClientLogEx(client, "TLS is not supported.\n"); return FALSE; } rfbBool HandleVeNCryptAuth(rfbClient* client) { - rfbClientLog("TLS is not supported.\n"); + rfbClientLogEx(client, "TLS is not supported.\n"); return FALSE; } int ReadFromTLS(rfbClient* client, char *out, unsigned int n) { - rfbClientLog("TLS is not supported.\n"); + rfbClientLogEx(client, "TLS is not supported.\n"); errno = EINTR; return -1; } @@ -45,7 +45,7 @@ int ReadFromTLS(rfbClient* client, char *out, unsigned int n) int WriteToTLS(rfbClient* client, const char *buf, unsigned int n) { - rfbClientLog("TLS is not supported.\n"); + rfbClientLogEx(client, "TLS is not supported.\n"); errno = EINTR; return -1; } @@ -60,7 +60,7 @@ void FreeTLS(rfbClient* client) int GetTLSCipherBits(rfbClient* client) { - rfbClientLog("TLS is not supported.\n"); + rfbClientLogEx(client, "TLS is not supported.\n"); return 0; } #endif /* LIBVNCSERVER_HAVE_SASL */ diff --git a/src/libvncclient/tls_openssl.c b/src/libvncclient/tls_openssl.c index 57265afb6..a5b9b3abb 100644 --- a/src/libvncclient/tls_openssl.c +++ b/src/libvncclient/tls_openssl.c @@ -243,12 +243,12 @@ static time_t asn1time_to_time_t(const ASN1_TIME *t) { static int cert_fingerprint_mismatch_callback(rfbClient *client, X509 *cert) { if(!cert) { - rfbClientErr("No cert given in fingerprint mismatch handling\n"); + rfbClientErrEx(client, "No cert given in fingerprint mismatch handling\n"); return 0; } if (!client || !client->GetX509CertFingerprintMismatchDecision) { - rfbClientErr("No client callback given in fingerprint mismatch handling\n"); + rfbClientErrEx(client, "No client callback given in fingerprint mismatch handling\n"); return 0; } @@ -293,8 +293,11 @@ static int cert_fingerprint_mismatch_callback(rfbClient *client, X509 *cert) { } static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { + SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + rfbClient *client = ssl ? SSL_get_ex_data(ssl, rfbTLSClientIndex) : NULL; + if (preverify_ok) { - rfbClientLog("Server cert trusted\n"); + rfbClientLogEx(client, "Server cert trusted\n"); return 1; // Accept } @@ -306,11 +309,10 @@ static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { return 0; } - SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - const unsigned char *expected_fingerprint = SSL_get_ex_data(ssl, rfbTLSExpectedFingerprintIndex); + const unsigned char *expected_fingerprint = ssl ? SSL_get_ex_data(ssl, rfbTLSExpectedFingerprintIndex) : NULL; // Check if we already have a cached user decision for this certificate - int cached_decision = (int)(intptr_t)SSL_get_ex_data(ssl, rfbTLSCertDecisionIndex); + int cached_decision = ssl ? (int)(intptr_t)SSL_get_ex_data(ssl, rfbTLSCertDecisionIndex) : 0; int verify; if (cached_decision || (expected_fingerprint && memcmp(remote_fingerprint, expected_fingerprint, 32) == 0)) { @@ -318,9 +320,10 @@ static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { verify = 1; } else { // ask user - verify = cert_fingerprint_mismatch_callback(SSL_get_ex_data(ssl, rfbTLSClientIndex), X509_STORE_CTX_get_current_cert(ctx)); + verify = cert_fingerprint_mismatch_callback(client, X509_STORE_CTX_get_current_cert(ctx)); // Cache the user decision to avoid prompting the user multiple times - SSL_set_ex_data(ssl, rfbTLSCertDecisionIndex, (void*)(intptr_t)verify); + if (ssl) + SSL_set_ex_data(ssl, rfbTLSCertDecisionIndex, (void*)(intptr_t)verify); } if(verify) { @@ -342,7 +345,7 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti if (!(ssl_ctx = SSL_CTX_new(SSLv23_client_method()))) { - rfbClientLog("Could not create new SSL context.\n"); + rfbClientLogEx(client, "Could not create new SSL context.\n"); return NULL; } @@ -356,12 +359,12 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti { if (!SSL_CTX_load_verify_locations(ssl_ctx, cred->x509Credential.x509CACertFile, NULL)) { - rfbClientLog("Failed to load CA certificate from %s.\n", + rfbClientLogEx(client, "Failed to load CA certificate from %s.\n", cred->x509Credential.x509CACertFile); goto error_free_ctx; } } else { - rfbClientLog("Using default paths for certificate verification.\n"); + rfbClientLogEx(client, "Using default paths for certificate verification.\n"); SSL_CTX_set_default_verify_paths (ssl_ctx); } @@ -369,7 +372,7 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti { if (!load_crls_from_file(cred->x509Credential.x509CACrlFile, ssl_ctx)) { - rfbClientLog("CRLs could not be loaded.\n"); + rfbClientLogEx(client, "CRLs could not be loaded.\n"); goto error_free_ctx; } if (verify_crls == rfbX509CrlVerifyNone) verify_crls = rfbX509CrlVerifyAll; @@ -379,19 +382,19 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti { if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cred->x509Credential.x509ClientCertFile) != 1) { - rfbClientLog("Client certificate could not be loaded.\n"); + rfbClientLogEx(client, "Client certificate could not be loaded.\n"); goto error_free_ctx; } if (SSL_CTX_use_PrivateKey_file(ssl_ctx, cred->x509Credential.x509ClientKeyFile, SSL_FILETYPE_PEM) != 1) { - rfbClientLog("Client private key could not be loaded.\n"); + rfbClientLogEx(client, "Client private key could not be loaded.\n"); goto error_free_ctx; } if (SSL_CTX_check_private_key(ssl_ctx) == 0) { - rfbClientLog("Client certificate and private key do not match.\n"); + rfbClientLogEx(client, "Client certificate and private key do not match.\n"); goto error_free_ctx; } } @@ -405,7 +408,7 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti if(!X509_VERIFY_PARAM_set1_host(param, client->serverHost, strlen(client->serverHost))) { - rfbClientLog("Could not set server name for verification.\n"); + rfbClientLogEx(client, "Could not set server name for verification.\n"); goto error_free_ctx; } SSL_CTX_set1_param(ssl_ctx, param); @@ -430,7 +433,7 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti if (!(ssl = SSL_new (ssl_ctx))) { - rfbClientLog("Could not create a new SSL session.\n"); + rfbClientLogEx(client, "Could not create a new SSL session.\n"); goto error_free_ctx; } @@ -467,7 +470,7 @@ open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredenti default: verify_res = SSL_get_verify_result(ssl); if (verify_res != X509_V_OK) - rfbClientLog("Could not verify server certificate: %s.\n", + rfbClientLogEx(client, "Could not verify server certificate: %s.\n", X509_verify_cert_error_string(verify_res)); ERR_clear_error(); @@ -505,7 +508,7 @@ InitializeTLSSession(rfbClient* client, rfbBool anonTLS, rfbCredential *cred) INIT_MUTEX(client->tlsRwMutex); - rfbClientLog("TLS session initialized.\n"); + rfbClientLogEx(client, "TLS session initialized.\n"); return TRUE; } @@ -522,7 +525,7 @@ return TRUE; { if (ret != -1) { - rfbClientLog("TLS handshake blocking.\n"); + rfbClientLogEx(client, "TLS handshake blocking.\n"); #ifdef WIN32 Sleep(1000); #else @@ -531,7 +534,7 @@ return TRUE; timeout--; continue; } - rfbClientLog("TLS handshake failed.\n"); + rfbClientLogEx(client, "TLS handshake failed.\n"); FreeTLS(client); return FALSE; @@ -539,12 +542,12 @@ return TRUE; if (timeout <= 0) { - rfbClientLog("TLS handshake timeout.\n"); + rfbClientLogEx(client, "TLS handshake timeout.\n"); FreeTLS(client); return FALSE; } - rfbClientLog("TLS handshake done.\n"); + rfbClientLogEx(client, "TLS handshake done.\n"); return TRUE; } @@ -562,18 +565,18 @@ ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result) if (count==0) { - rfbClientLog("List of security types is ZERO. Giving up.\n"); + rfbClientLogEx(client, "List of security types is ZERO. Giving up.\n"); return FALSE; } - rfbClientLog("We have %d security types to read\n", count); + rfbClientLogEx(client, "We have %d security types to read\n", count); authScheme=0; /* now, we have a list of available security types to read ( uint8_t[] ) */ for (loop=0;loop0 ? ", %d" : "%d"), (int)tAuth[loop]); strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); } - rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n", + rfbClientLogEx(client, "Unknown VeNCrypt authentication scheme from VNC server: %s\n", buf1); return FALSE; } else { - rfbClientLog("Selecting security type %d\n", authScheme); + rfbClientLogEx(client, "Selecting security type %d\n", authScheme); /* send back 4 bytes (in original byte order!) indicating which security type to use */ if (!WriteToRFBServer(client, (char *)&origAuthScheme, 4)) return FALSE; } @@ -660,11 +663,11 @@ HandleVeNCryptAuth(rfbClient* client) { return FALSE; } - rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); + rfbClientLogEx(client, "Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); if (major != 0 && minor != 2) { - rfbClientLog("Unsupported VeNCrypt version.\n"); + rfbClientLogEx(client, "Unsupported VeNCrypt version.\n"); return FALSE; } @@ -677,7 +680,7 @@ HandleVeNCryptAuth(rfbClient* client) if (status != 0) { - rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); + rfbClientLogEx(client, "Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); return FALSE; } @@ -711,7 +714,7 @@ HandleVeNCryptAuth(rfbClient* client) /* Ack is only requred for the encrypted connection */ if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1) { - rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); + rfbClientLogEx(client, "Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); return FALSE; } @@ -723,13 +726,13 @@ HandleVeNCryptAuth(rfbClient* client) if (!client->GetCredential) { - rfbClientLog("GetCredential callback is not set.\n"); + rfbClientLogEx(client, "GetCredential callback is not set.\n"); return FALSE; } cred = client->GetCredential(client, rfbCredentialTypeX509); if (!cred) { - rfbClientLog("Reading credential failed\n"); + rfbClientLogEx(client, "Reading credential failed\n"); return FALSE; } } @@ -764,7 +767,7 @@ ReadFromTLS(rfbClient* client, char *out, unsigned int n) else { errno = ssl_error_to_errno(ssl_error); if (errno != EAGAIN) { - rfbClientLog("Error reading from TLS: -.\n"); + rfbClientLogEx(client, "Error reading from TLS: -.\n"); } } @@ -792,7 +795,7 @@ WriteToTLS(rfbClient* client, const char *buf, unsigned int n) { errno = ssl_error_to_errno(ssl_error); if (errno == EAGAIN || errno == EWOULDBLOCK) continue; - rfbClientLog("Error writing to TLS: -\n"); + rfbClientLogEx(client, "Error writing to TLS: -\n"); return -1; } offset += (unsigned int)ret; diff --git a/src/libvncclient/trle.c b/src/libvncclient/trle.c index cf06c185c..81b4dabc6 100644 --- a/src/libvncclient/trle.c +++ b/src/libvncclient/trle.c @@ -76,7 +76,7 @@ static rfbBool HandleTRLE(rfbClient *client, int rx, int ry, int rw, int rh) { client->raw_buffer = (char *)malloc(client->raw_buffer_size); } - rfbClientLog("Update %d %d %d %d\n", rx, ry, rw, rh); + rfbClientLogEx(client, "Update %d %d %d %d\n", rx, ry, rw, rh); for (y = ry; y < ry + rh; y += 16) { for (x = rx; x < rx + rw; x += 16) { @@ -198,7 +198,7 @@ static rfbBool HandleTRLE(rfbClient *client, int rx, int ry, int rw, int rh) { } } if (length > 0) - rfbClientLog("Warning: possible TRLE corruption\n"); + rfbClientLogEx(client, "Warning: possible TRLE corruption\n"); } type = last_type; @@ -244,7 +244,7 @@ static rfbBool HandleTRLE(rfbClient *client, int rx, int ry, int rw, int rh) { } } if (length > 0) - rfbClientLog("Warning: possible TRLE corruption\n"); + rfbClientLogEx(client, "Warning: possible TRLE corruption\n"); } if (type == 129) { diff --git a/src/libvncclient/ultra.c b/src/libvncclient/ultra.c index 5633b8cbb..b3383f314 100644 --- a/src/libvncclient/ultra.c +++ b/src/libvncclient/ultra.c @@ -46,13 +46,13 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh) if (toRead==0) return TRUE; if (toRead < 0) { - rfbClientErr("ultra error: remote sent negative payload size\n"); + rfbClientErrEx(client, "ultra error: remote sent negative payload size\n"); return FALSE; } if (uncompressedBytes==0) { - rfbClientLog("ultra error: rectangle has 0 uncomressed bytes ((%dw * %dh) * (%d / 8))\n", rw, rh, BPP); + rfbClientLogEx(client, "ultra error: rectangle has 0 uncomressed bytes ((%dw * %dh) * (%d / 8))\n", rw, rh, BPP); return FALSE; } @@ -74,7 +74,7 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh) if(client->raw_buffer == NULL) return FALSE; } - + /* allocate enough space to store the incoming compressed packet */ if ( client->ultra_buffer_size < toRead ) { if ( client->ultra_buffer != NULL ) { @@ -97,19 +97,21 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh) (lzo_byte *)client->ultra_buffer, toRead, (lzo_byte *)client->raw_buffer, (lzo_uintp) &uncompressedBytes, NULL); - + /* Note that uncompressedBytes will be 0 on output overrun */ if ((rw * rh * (BPP / 8)) != uncompressedBytes) - rfbClientLog("Ultra decompressed unexpected amount of data (%d != %d)\n", (rw * rh * (BPP / 8)), uncompressedBytes); - + rfbClientLogEx(client, "Ultra decompressed unexpected amount of data (%lu != %lu)\n", + (unsigned long)(rw * rh * (BPP / 8)), + (unsigned long)uncompressedBytes); + /* Put the uncompressed contents of the update on the screen. */ - if ( inflateResult == LZO_E_OK ) + if ( inflateResult == LZO_E_OK ) { client->GotBitmap(client, (unsigned char *)client->raw_buffer, rx, ry, rw, rh); } else { - rfbClientLog("ultra decompress returned error: %d\n", + rfbClientLogEx(client, "ultra decompress returned error: %d\n", inflateResult); return FALSE; } @@ -138,13 +140,13 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) if (toRead==0) return TRUE; if (toRead < 0) { - rfbClientErr("ultrazip error: remote sent negative payload size\n"); + rfbClientErrEx(client, "ultrazip error: remote sent negative payload size\n"); return FALSE; } if (uncompressedBytes==0) { - rfbClientLog("ultrazip error: rectangle has 0 uncomressed bytes (%dy + (%dw * 65535)) (%d rectangles)\n", ry, rw, rx); + rfbClientLogEx(client, "ultrazip error: rectangle has 0 uncomressed bytes (%dy + (%dw * 65535)) (%d rectangles)\n", ry, rw, rx); return FALSE; } @@ -167,7 +169,7 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) return FALSE; } - + /* allocate enough space to store the incoming compressed packet */ if ( client->ultra_buffer_size < toRead ) { if ( client->ultra_buffer != NULL ) { @@ -186,13 +188,13 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) inflateResult = lzo1x_decompress_safe( (lzo_byte *)client->ultra_buffer, toRead, (lzo_byte *)client->raw_buffer, &uncompressedBytes, NULL); - if ( inflateResult != LZO_E_OK ) + if ( inflateResult != LZO_E_OK ) { - rfbClientLog("ultra decompress returned error: %d\n", + rfbClientLogEx(client, "ultra decompress returned error: %d\n", inflateResult); return FALSE; } - + /* Put the uncompressed contents of the update on the screen. */ ptr = (unsigned char *)client->raw_buffer; ptr_end = ptr + uncompressedBytes; @@ -203,7 +205,7 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* subrect header: sx(2) + sy(2) + sw(2) + sh(2) + se(4) = 12 bytes */ if (ptr + 12 > ptr_end) { - rfbClientLog("UltraZip: subrect %d header exceeds decompressed data bounds\n", i); + rfbClientLogEx(client, "UltraZip: subrect %d header exceeds decompressed data bounds\n", i); return FALSE; } @@ -223,13 +225,13 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) { uint64_t rawBytes = (uint64_t)sw * sh * (BPP / 8); if (rawBytes > (size_t)(ptr_end - ptr)) { - rfbClientLog("UltraZip: subrect %d raw data exceeds decompressed data bounds\n", i); + rfbClientLogEx(client, "UltraZip: subrect %d raw data exceeds decompressed data bounds\n", i); return FALSE; } client->GotBitmap(client, (unsigned char *)ptr, sx, sy, sw, sh); ptr += (size_t)rawBytes; } - } + } return TRUE; } diff --git a/src/libvncclient/vncviewer.c b/src/libvncclient/vncviewer.c index 2af3785e0..b6713f224 100644 --- a/src/libvncclient/vncviewer.c +++ b/src/libvncclient/vncviewer.c @@ -98,14 +98,14 @@ static rfbBool MallocFrameBuffer(rfbClient* client) { allocSize = (uint64_t)client->width * client->height * client->format.bitsPerPixel/8; if (allocSize >= SIZE_MAX) { - rfbClientErr("CRITICAL: cannot allocate frameBuffer, requested size is too large\n"); + rfbClientErrEx(client, "CRITICAL: cannot allocate frameBuffer, requested size is too large\n"); return FALSE; } client->frameBuffer=malloc( (size_t)allocSize ); if (client->frameBuffer == NULL) - rfbClientErr("CRITICAL: frameBuffer allocation failed, requested size too large or not enough memory?\n"); + rfbClientErrEx(client, "CRITICAL: frameBuffer allocation failed, requested size too large or not enough memory?\n"); return client->frameBuffer?TRUE:FALSE; } @@ -124,7 +124,7 @@ static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_ } if (!CheckRect(client, x, y, w, h)) { - rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + rfbClientLogEx(client, "Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); return; } @@ -138,7 +138,7 @@ static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_ case 16: FILL_RECT(16); break; case 32: FILL_RECT(32); break; default: - rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + rfbClientLogEx(client, "Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); } } @@ -150,7 +150,7 @@ static void CopyRectangle(rfbClient* client, const uint8_t* buffer, int x, int y } if (!CheckRect(client, x, y, w, h)) { - rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + rfbClientLogEx(client, "Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); return; } @@ -168,7 +168,7 @@ static void CopyRectangle(rfbClient* client, const uint8_t* buffer, int x, int y case 16: COPY_RECT(16); break; case 32: COPY_RECT(32); break; default: - rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + rfbClientLogEx(client, "Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); } } @@ -181,12 +181,12 @@ static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, } if (!CheckRect(client, src_x, src_y, w, h)) { - rfbClientLog("Source rect out of bounds: %dx%d at (%d, %d)\n", src_x, src_y, w, h); + rfbClientLogEx(client, "Source rect out of bounds: %dx%d at (%d, %d)\n", src_x, src_y, w, h); return; } if (!CheckRect(client, dest_x, dest_y, w, h)) { - rfbClientLog("Dest rect out of bounds: %dx%d at (%d, %d)\n", dest_x, dest_y, w, h); + rfbClientLogEx(client, "Dest rect out of bounds: %dx%d at (%d, %d)\n", dest_x, dest_y, w, h); return; } @@ -225,7 +225,7 @@ static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, case 16: COPY_RECT_FROM_RECT(16); break; case 32: COPY_RECT_FROM_RECT(32); break; default: - rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + rfbClientLogEx(client, "Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); } } @@ -296,12 +296,12 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, #endif rfbClient* client=(rfbClient*)calloc(sizeof(rfbClient),1); if(!client) { - rfbClientErr("Couldn't allocate client structure!\n"); + rfbClientErrEx(client, "Couldn't allocate client structure!\n"); return NULL; } #ifdef WIN32 if((errno = WSAStartup(MAKEWORD(2,0), &unused)) != 0) { - rfbClientErr("Could not init Windows Sockets: %s\n", strerror(errno)); + rfbClientErrEx(client, "Could not init Windows Sockets: %s\n", strerror(errno)); return NULL; } #endif @@ -547,14 +547,14 @@ void rfbClientCleanup(rfbClient* client) { if (client->zlibStreamActive[i] == TRUE ) { if (inflateEnd (&client->zlibStream[i]) != Z_OK && client->zlibStream[i].msg != NULL) - rfbClientLog("inflateEnd: %s\n", client->zlibStream[i].msg); + rfbClientLogEx(client, "inflateEnd: %s\n", client->zlibStream[i].msg); } } if ( client->decompStreamInited == TRUE ) { if (inflateEnd (&client->decompStream) != Z_OK && client->decompStream.msg != NULL) - rfbClientLog("inflateEnd: %s\n", client->decompStream.msg ); + rfbClientLogEx(client, "inflateEnd: %s\n", client->decompStream.msg ); } #ifdef LIBVNCSERVER_HAVE_LIBJPEG @@ -600,7 +600,7 @@ void rfbClientCleanup(rfbClient* client) { #ifdef WIN32 if(WSACleanup() != 0) { errno=WSAGetLastError(); - rfbClientErr("Could not terminate Windows Sockets: %s\n", strerror(errno)); + rfbClientErrEx(client, "Could not terminate Windows Sockets: %s\n", strerror(errno)); } #endif diff --git a/src/libvncclient/zlib.c b/src/libvncclient/zlib.c index fc6f13823..f88567230 100644 --- a/src/libvncclient/zlib.c +++ b/src/libvncclient/zlib.c @@ -77,7 +77,7 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) inflateResult = inflateInit( &client->decompStream ); if ( inflateResult != Z_OK ) { - rfbClientLog( + rfbClientLogEx(client, "inflateInit returned error: %d, msg: %s\n", inflateResult, client->decompStream.msg); @@ -95,7 +95,7 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) */ while (( remaining > 0 ) && ( inflateResult == Z_OK )) { - + if ( remaining > RFB_BUFFER_SIZE ) { toRead = RFB_BUFFER_SIZE; } @@ -115,11 +115,11 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* We never supply a dictionary for compression. */ if ( inflateResult == Z_NEED_DICT ) { - rfbClientLog("zlib inflate needs a dictionary!\n"); + rfbClientLogEx(client, "zlib inflate needs a dictionary!\n"); return FALSE; } if ( inflateResult < 0 ) { - rfbClientLog( + rfbClientLogEx(client, "zlib inflate returned error: %d, msg: %s\n", inflateResult, client->decompStream.msg); @@ -131,7 +131,7 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) */ if (( client->decompStream.avail_in > 0 ) && ( client->decompStream.avail_out <= 0 )) { - rfbClientLog("zlib inflate ran out of space!\n"); + rfbClientLogEx(client, "zlib inflate ran out of space!\n"); return FALSE; } @@ -146,7 +146,7 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) } else { - rfbClientLog( + rfbClientLogEx(client, "zlib inflate returned error: %d, msg: %s\n", inflateResult, client->decompStream.msg); diff --git a/src/libvncclient/zrle.c b/src/libvncclient/zrle.c index 6859519ff..f648b9c25 100644 --- a/src/libvncclient/zrle.c +++ b/src/libvncclient/zrle.c @@ -126,7 +126,7 @@ HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) inflateResult = inflateInit( &client->decompStream ); if ( inflateResult != Z_OK ) { - rfbClientLog( + rfbClientLogEx(client, "inflateInit returned error: %d, msg: %s\n", inflateResult, client->decompStream.msg); @@ -164,11 +164,11 @@ HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) /* We never supply a dictionary for compression. */ if ( inflateResult == Z_NEED_DICT ) { - rfbClientLog("zlib inflate needs a dictionary!\n"); + rfbClientLogEx(client, "zlib inflate needs a dictionary!\n"); return FALSE; } if ( inflateResult < 0 ) { - rfbClientLog( + rfbClientLogEx(client, "zlib inflate returned error: %d, msg: %s\n", inflateResult, client->decompStream.msg); @@ -180,7 +180,7 @@ HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) */ if (( client->decompStream.avail_in > 0 ) && ( client->decompStream.avail_out <= 0 )) { - rfbClientLog("zlib inflate ran out of space!\n"); + rfbClientLogEx(client, "zlib inflate ran out of space!\n"); return FALSE; } @@ -201,7 +201,7 @@ HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) int result=HandleZRLETile(client,(uint8_t *)buf,remaining,rx+i,ry+j,subWidth,subHeight); if(result<0) { - rfbClientLog("ZRLE decoding failed (%d)\n",result); + rfbClientLogEx(client, "ZRLE decoding failed (%d)\n",result); return TRUE; return FALSE; } @@ -212,7 +212,7 @@ return TRUE; } else { - rfbClientLog( + rfbClientLogEx(client, "zlib inflate returned error: %d, msg: %s\n", inflateResult, client->decompStream.msg); @@ -270,7 +270,9 @@ static int HandleZRLETile(rfbClient* client, int i,j; if(1+w*h*REALBPP/8>buffer_length) { - rfbClientLog("expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h); + rfbClientLogEx(client, "expected %lu bytes, got only %lu (%dx%d)\n", + (unsigned long)(1 + w * h * REALBPP / 8), + (unsigned long)buffer_length, w, h); return -3; } @@ -288,7 +290,7 @@ static int HandleZRLETile(rfbClient* client, if(1+REALBPP/8>buffer_length) return -4; - + client->GotFillRect(client, x, y, w, h, color); buffer+=REALBPP/8; @@ -355,7 +357,7 @@ static int HandleZRLETile(rfbClient* client, } } if(length>0) - rfbClientLog("Warning: possible ZRLE corruption\n"); + rfbClientLogEx(client, "Warning: possible ZRLE corruption\n"); } } @@ -407,12 +409,12 @@ static int HandleZRLETile(rfbClient* client, } } if(length>0) - rfbClientLog("Warning: possible ZRLE corruption\n"); + rfbClientLogEx(client, "Warning: possible ZRLE corruption\n"); } } } - return buffer-buffer_copy; + return buffer-buffer_copy; } #undef CARDBPP From ee8a3d16d79815ebae8cfe9641cf10d49445d329 Mon Sep 17 00:00:00 2001 From: Marco Fortina Date: Sun, 17 May 2026 12:32:07 +0000 Subject: [PATCH 3/3] libvncclient: document nullable client logging context --- include/rfb/rfbclient.h | 8 +++++--- src/libvncclient/rfbclient.c | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/rfb/rfbclient.h b/include/rfb/rfbclient.h index 9006a99c6..bc38bf559 100644 --- a/include/rfb/rfbclient.h +++ b/include/rfb/rfbclient.h @@ -530,14 +530,16 @@ typedef void (*rfbClientLogProc)(const char *format, ...); /** * Optional client-aware logging callback used by rfbClientLogEx() and * rfbClientErrEx(). When this callback is NULL, the helpers fall back to the - * legacy global rfbClientLog/rfbClientErr callbacks. + * legacy global rfbClientLog/rfbClientErr callbacks. The client argument may be + * NULL for messages without an available rfbClient context, for example when + * legacy APIs are called directly. */ typedef void (*rfbClientLogProcWithClient)(struct _rfbClient *client, const char *format, va_list args); extern rfbClientLogProc rfbClientLog,rfbClientErr; extern rfbClientLogProcWithClient rfbClientLogWithClient,rfbClientErrWithClient; -/** Log a message with optional rfbClient context. */ +/** Log a message with optional rfbClient context. The client argument may be NULL. */ extern void rfbClientLogEx(rfbClient *client, const char *format, ...); -/** Log an error message with optional rfbClient context. */ +/** Log an error message with optional rfbClient context. The client argument may be NULL. */ extern void rfbClientErrEx(rfbClient *client, const char *format, ...); extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort); diff --git a/src/libvncclient/rfbclient.c b/src/libvncclient/rfbclient.c index 4d3a20365..3898e95a8 100644 --- a/src/libvncclient/rfbclient.c +++ b/src/libvncclient/rfbclient.c @@ -2908,6 +2908,7 @@ PrintPixelFormatForClient(rfbClient *client, rfbPixelFormat *format) void PrintPixelFormat(rfbPixelFormat *format) { + /* Legacy API: no rfbClient context is available here. */ PrintPixelFormatForClient(NULL, format); }