rfbBool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w, int h) { rfbFramebufferUpdateRectHeader rect; if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { if (!rfbSendUpdateBuf(cl)) return FALSE; } rect.r.x = Swap16IfLE(x); rect.r.y = Swap16IfLE(y); rect.r.w = Swap16IfLE(w); rect.r.h = Swap16IfLE(h); rect.encoding = Swap32IfLE(rfbEncodingHextile); memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; rfbStatRecordEncodingSent(cl, rfbEncodingHextile, sz_rfbFramebufferUpdateRectHeader, sz_rfbFramebufferUpdateRectHeader + w * (cl->format.bitsPerPixel / 8) * h); switch (cl->format.bitsPerPixel) { case 8: return sendHextiles8(cl, x, y, w, h); case 16: return sendHextiles16(cl, x, y, w, h); case 32: return sendHextiles32(cl, x, y, w, h); } rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel); return FALSE; }
//------------------------------------------------------------------------------ // FUNCTION // // // DESCRIPTION // // // PARAMETERS // // // RETURN // // //------------------------------------------------------------------------------ int netarpcmd(int cmd, int ip, char *hwaddr, int *pflags, struct ifnet *ifp) { struct arpreq arpRequest; int rc; #if 0 //Eddy6 no arpioctl // fill in arp request structure bzero ((caddr_t) &arpRequest, sizeof (struct arpreq)); arpRequest.arp_pa.sa_family = AF_INET; ip = Swap32IfLE(ip); ((struct sockaddr_in *)&(arpRequest.arp_pa))->sin_addr.s_addr = htonl(ip); arpRequest.arp_ha.sa_family = AF_UNSPEC; if (hwaddr != NULL) { bcopy ((caddr_t) hwaddr ,(caddr_t) arpRequest.arp_ha.sa_data, 6); } if(pflags) arpRequest.arp_flags = *pflags; if (ifp != NULL) arpRequest.ifp = ifp; if((rc = arpioctl(cmd, (caddr_t)(&arpRequest))) == 0) { if(hwaddr != NULL) { bcopy ((caddr_t) arpRequest.arp_ha.sa_data, (caddr_t) hwaddr, 6); } if(pflags != NULL) { *pflags = arpRequest.arp_flags; } } #endif return rc; }
// Encode a rectangle inline UINT vncEncoder::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) { // Create the header for the update in the destination area rfbFramebufferUpdateRectHeader *surh = (rfbFramebufferUpdateRectHeader *)dest; surh->r.x = (CARD16) (rect.tl.x-m_SWOffsetx); surh->r.y = (CARD16) (rect.tl.y-m_SWOffsety); surh->r.w = (CARD16) (rect.br.x-rect.tl.x); surh->r.h = (CARD16) (rect.br.y-rect.tl.y); surh->r.x = Swap16IfLE(surh->r.x); surh->r.y = Swap16IfLE(surh->r.y); surh->r.w = Swap16IfLE(surh->r.w); surh->r.h = Swap16IfLE(surh->r.h); surh->encoding = Swap32IfLE(rfbEncodingRaw); // Translate the data in place in the output buffer Translate(source, dest + sz_rfbFramebufferUpdateRectHeader, rect); // Return the buffer size return sz_rfbFramebufferUpdateRectHeader + ((rect.br.x-rect.tl.x)*(rect.br.y-rect.tl.y)*m_remoteformat.bitsPerPixel) / 8; }
UINT vncEncodeZlibHex::EncodeRect(BYTE *source, VSocket *outConn, BYTE *dest, const RECT &rect, int offx, int offy) { const int rectW = rect.right - rect.left; const int rectH = rect.bottom - rect.top; // Create the rectangle header rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; surh->r.x = (CARD16) (rect.left - offx); surh->r.y = (CARD16) (rect.top - offy); surh->r.w = (CARD16) (rectW); surh->r.h = (CARD16) (rectH); surh->r.x = Swap16IfLE(surh->r.x); surh->r.y = Swap16IfLE(surh->r.y); surh->r.w = Swap16IfLE(surh->r.w); surh->r.h = Swap16IfLE(surh->r.h); surh->encoding = Swap32IfLE(rfbEncodingZlibHex); rectangleOverhead += sz_rfbFramebufferUpdateRectHeader; dataSize += ( rectW * rectH * m_remoteformat.bitsPerPixel) / 8; // Go ahead and send the RFB update header, in case partial updates // are send in EncodeHextiles#() below. outConn->SendQueued( (char *)dest, sz_rfbFramebufferUpdateRectHeader ); transmittedSize += sz_rfbFramebufferUpdateRectHeader; // Do the encoding switch (m_remoteformat.bitsPerPixel) { case 8: return EncodeHextiles8(source, dest, outConn, rect.left, rect.top, rectW, rectH); case 16: return EncodeHextiles16(source, dest, outConn, rect.left, rect.top, rectW, rectH); case 32: return EncodeHextiles32(source, dest, outConn, rect.left, rect.top, rectW, rectH); } return vncEncoder::EncodeRect(source, dest, rect, offx, offy); }
static void rfbSendTunnelingCaps(rfbClientPtr cl) { rfbTunnelingCapsMsg caps; uint32_t nTypes = 0; /* we don't support tunneling yet */ rfbLog("tightvnc-filetransfer/rfbSendTunnelingCaps\n"); caps.nTunnelTypes = Swap32IfLE(nTypes); if (rfbWriteExact(cl, (char *)&caps, sz_rfbTunnelingCapsMsg) < 0) { rfbLogPerror("rfbSendTunnelingCaps: write"); rfbCloseClient(cl); return; } if (nTypes) { /* Dispatch client input to rfbProcessClientTunnelingType(). */ /* The flow should not reach here as tunneling is not implemented. */ rfbProcessClientTunnelingType(cl); } else { rfbSendAuthCaps(cl); } }
UINT vncEncodeHexT::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) { const UINT rectW = rect.br.x - rect.tl.x; const UINT rectH = rect.br.y - rect.tl.y; // Create the rectangle header rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; surh->r.x = (CARD16) rect.tl.x; surh->r.y = (CARD16) rect.tl.y; surh->r.w = (CARD16) (rectW); surh->r.h = (CARD16) (rectH); surh->r.x = Swap16IfLE(surh->r.x); surh->r.y = Swap16IfLE(surh->r.y); surh->r.w = Swap16IfLE(surh->r.w); surh->r.h = Swap16IfLE(surh->r.h); surh->encoding = Swap32IfLE(rfbEncodingHextile); // Do the encoding switch (m_remoteformat.bitsPerPixel) { case 8: return sz_rfbFramebufferUpdateRectHeader + EncodeHextiles8(source, dest + sz_rfbFramebufferUpdateRectHeader, rect.tl.x, rect.tl.y, rectW, rectH); case 16: return sz_rfbFramebufferUpdateRectHeader + EncodeHextiles16(source, dest + sz_rfbFramebufferUpdateRectHeader, rect.tl.x, rect.tl.y, rectW, rectH); case 32: return sz_rfbFramebufferUpdateRectHeader + EncodeHextiles32(source, dest + sz_rfbFramebufferUpdateRectHeader, rect.tl.x, rect.tl.y, rectW, rectH); } return vncEncoder::EncodeRect(source, dest, rect); }
// Send a single CopyRect message BOOL vncClient::SendCopyRect(const rfb::Rect &dest, const rfb::Point &source) { // Create the message header rfbFramebufferUpdateRectHeader copyrecthdr; copyrecthdr.r.x = Swap16IfLE(dest.tl.x); copyrecthdr.r.y = Swap16IfLE(dest.tl.y); copyrecthdr.r.w = Swap16IfLE(dest.br.x-dest.tl.x); copyrecthdr.r.h = Swap16IfLE(dest.br.y-dest.tl.y); copyrecthdr.encoding = Swap32IfLE(rfbEncodingCopyRect); // Create the CopyRect-specific section rfbCopyRect copyrectbody; copyrectbody.srcX = Swap16IfLE(source.x); copyrectbody.srcY = Swap16IfLE(source.y); // Now send the message; if (!m_socket->SendExact((char *)©recthdr, sizeof(copyrecthdr))) return FALSE; if (!m_socket->SendExact((char *)©rectbody, sizeof(copyrectbody))) return FALSE; return TRUE; }
static void rfbVncAuthNone(rfbClientPtr cl) { /* The built-in Mac OS X VNC client behaves in a non-conforming fashion * when the server version is 3.7 or later AND the list of security types * sent to the OS X client contains the 'None' authentication type AND * the OS X client sends back the 'None' type as its choice. In this case, * and this case ONLY, the built-in Mac OS X VNC client will NOT send the * ClientInit message and instead will behave as though an implicit * ClientInit message containing a shared-flag of true has been sent. * The special state RFB_INITIALISATION_SHARED represents this case. * The Mac OS X VNC client can be detected by checking protocolMinorVersion * for a value of 889. No other VNC client is known to use this value * for protocolMinorVersion. */ uint32_t authResult; /* The built-in Mac OS X VNC client expects to NOT receive a SecurityResult * message for authentication type 'None'. Since its protocolMinorVersion * is greater than 7 (it is 889) this case must be tested for specially. */ if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion > 7 && cl->protocolMinorVersion != 889) { rfbLog("rfbProcessClientSecurityType: returning securityResult for client rfb version >= 3.8\n"); authResult = Swap32IfLE(rfbVncAuthOK); if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); rfbCloseClient(cl); return; } } cl->state = cl->protocolMinorVersion == 889 ? RFB_INITIALISATION_SHARED : RFB_INITIALISATION; if (cl->state == RFB_INITIALISATION_SHARED) /* In this case we must call rfbProcessClientMessage now because * otherwise we would hang waiting for data to be received from the * client (the ClientInit message which will never come). */ rfbProcessClientMessage(cl); return; }
static int ReadSecurityType(void) { CARD32 secType; /* Read the security type */ if (!ReadFromRFBServer((char *)&secType, sizeof(secType))) return rfbSecTypeInvalid; secType = Swap32IfLE(secType); if (secType == rfbSecTypeInvalid) { ReadConnFailedReason(); return rfbSecTypeInvalid; } if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) { fprintf(stderr, "Unknown security type from RFB server: %d\n", (int)secType); return rfbSecTypeInvalid; } return (int)secType; }
Bool VNCViewer::HandleRREBPP (sgVNCViewer *ct, int rx, int ry, int rw, int rh) { rfbRREHeader hdr; int i; CARDBPP pix; rfbRectangle subrect; if (!ReadFromRFBServer((char *)&hdr, sz_rfbRREHeader)) return False; hdr.nSubrects = Swap32IfLE(hdr.nSubrects); if (!ReadFromRFBServer((char *)&pix, sizeof(pix))) return False; ct->FillToScreen(pix, rx, ry, rw, rh); for (i = 0; i < hdr.nSubrects; i++) { if (!ReadFromRFBServer((char *)&pix, sizeof(pix))) return False; if (!ReadFromRFBServer((char *)&subrect, sz_rfbRectangle)) return False; subrect.x = Swap16IfLE(subrect.x); subrect.y = Swap16IfLE(subrect.y); subrect.w = Swap16IfLE(subrect.w); subrect.h = Swap16IfLE(subrect.h); ct->FillToScreen(pix, rx + subrect.x, ry + subrect.y, subrect.w, subrect.h); } return True; }
static Bool AuthenticateUnixLogin(void) { CARD32 loginLen, passwdLen, authResult; char *login; char *passwd; struct passwd *ps; fprintf(stderr, "Performing Unix login-style authentication\n"); if (appData.userLogin) { login = appData.userLogin; } else { ps = getpwuid(getuid()); login = ps->pw_name; } fprintf(stderr, "Using user name \"%s\"\n", login); if (appData.passwordDialog) { passwd = DoPasswordDialog(); } else { passwd = getpass("Password: "******"Reading password failed\n"); return False; } loginLen = Swap32IfLE((CARD32)strlen(login)); passwdLen = Swap32IfLE((CARD32)strlen(passwd)); if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) || !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen))) return False; if (!WriteExact(rfbsock, login, strlen(login)) || !WriteExact(rfbsock, passwd, strlen(passwd))) return False; /* Lose the password from memory */ memset(passwd, '\0', strlen(passwd)); if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult))) return False; authResult = Swap32IfLE(authResult); switch (authResult) { case rfbVncAuthOK: fprintf(stderr, "Authentication succeeded\n"); break; case rfbVncAuthFailed: fprintf(stderr, "Authentication failed\n"); return False; case rfbVncAuthTooMany: fprintf(stderr, "Authentication failed - too many tries\n"); return False; default: fprintf(stderr, "Unknown authentication result: %d\n", (int)authResult); return False; } return True; }
static Bool AuthenticateVNC(void) { CARD32 authScheme, authResult; CARD8 challenge[CHALLENGESIZE]; char *passwd; char buffer[64]; char* cstatus; int len; fprintf(stderr, "Performing standard VNC authentication\n"); if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) return False; if (appData.passwordFile) { passwd = vncDecryptPasswdFromFile(appData.passwordFile); if (!passwd) { fprintf(stderr, "Cannot read valid password from file \"%s\"\n", appData.passwordFile); return False; } } else if (appData.autoPass) { passwd = buffer; cstatus = fgets(buffer, sizeof buffer, stdin); if (cstatus == NULL) buffer[0] = '\0'; else { len = strlen(buffer); if (len > 0 && buffer[len - 1] == '\n') buffer[len - 1] = '\0'; } } else if (appData.passwordDialog) { passwd = DoPasswordDialog(); } else { passwd = getpass("Password: "******"Reading password failed\n"); return False; } if (strlen(passwd) > 8) { passwd[8] = '\0'; } vncEncryptBytes(challenge, passwd); /* Lose the password from memory */ memset(passwd, '\0', strlen(passwd)); if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) return False; if (!ReadFromRFBServer((char *)&authResult, 4)) return False; authResult = Swap32IfLE(authResult); switch (authResult) { case rfbVncAuthOK: fprintf(stderr, "VNC authentication succeeded\n"); break; case rfbVncAuthFailed: fprintf(stderr, "VNC authentication failed\n"); return False; case rfbVncAuthTooMany: fprintf(stderr, "VNC authentication failed - too many tries\n"); return False; default: fprintf(stderr, "Unknown VNC authentication result: %d\n", (int)authResult); return False; } return True; }
Bool InitialiseRFBConnection(void) { rfbProtocolVersionMsg pv; int server_major, server_minor; int viewer_major, viewer_minor; rfbClientInitMsg ci; int secType; /* if the connection is immediately closed, don't report anything, so that pmw's monitor can make test connections */ if (listenSpecified) errorMessageOnReadFailure = False; if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) return False; errorMessageOnReadFailure = True; pv[sz_rfbProtocolVersionMsg] = 0; if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) { fprintf(stderr,"Not a valid VNC server\n"); return False; } viewer_major = rfbProtocolMajorVersion; if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) { /* the server supports at least the standard protocol 3.7 */ viewer_minor = rfbProtocolMinorVersion; } else { /* any other server version, request the standard 3.3 */ viewer_minor = rfbProtocolFallbackMinorVersion; } fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n", viewer_major, viewer_minor); sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor); if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) return False; /* Read or select the security type. */ if (viewer_minor == rfbProtocolMinorVersion) { secType = SelectSecurityType(); } else { secType = ReadSecurityType(); } if (secType == rfbSecTypeInvalid) return False; switch (secType) { case rfbSecTypeNone: fprintf(stderr, "No authentication needed\n"); break; case rfbSecTypeVncAuth: if (!AuthenticateVNC()) return False; break; case rfbSecTypeTight: tightVncProtocol = True; InitCapabilities(); if (!SetupTunneling()) return False; if (!PerformAuthenticationTight()) return False; break; default: /* should never happen */ fprintf(stderr, "Internal error: Invalid security type\n"); return False; } ci.shared = (appData.shareDesktop ? 1 : 0); if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) return False; if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) return False; si.framebufferWidth = Swap16IfLE(si.framebufferWidth); si.framebufferHeight = Swap16IfLE(si.framebufferHeight); si.format.redMax = Swap16IfLE(si.format.redMax); si.format.greenMax = Swap16IfLE(si.format.greenMax); si.format.blueMax = Swap16IfLE(si.format.blueMax); si.nameLength = Swap32IfLE(si.nameLength); /* FIXME: Check arguments to malloc() calls. */ desktopName = malloc(si.nameLength + 1); if (!desktopName) { fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n", (unsigned long)si.nameLength); return False; } if (!ReadFromRFBServer(desktopName, si.nameLength)) return False; desktopName[si.nameLength] = 0; fprintf(stderr,"Desktop name \"%s\"\n",desktopName); fprintf(stderr,"VNC server default format:\n"); PrintPixelFormat(&si.format); if (tightVncProtocol) { /* Read interaction capabilities (protocol 3.7t) */ if (!ReadInteractionCaps()) return False; } return True; }
void FileTransfer::FileTransferUpload() { int numOfFilesToUpload = 0, currentUploadIndex = -1; DWORD sz_rfbFileSize; DWORD sz_rfbBlockSize= 8192; DWORD dwNumberOfBytesRead = 0; unsigned int mTime = 0; char path[rfbMAX_PATH + rfbMAX_PATH + 2]; BOOL bResult; numOfFilesToUpload = ListView_GetSelectedCount(m_hwndFTClientList); if (numOfFilesToUpload < 0) { SetWindowText(m_hwndFTStatus, "No file selected, nothing to upload."); BlockingFileTransferDialog(TRUE); EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE); return; } for (int i = 0; i < numOfFilesToUpload; i++) { BlockingFileTransferDialog(FALSE); EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), TRUE); int index = ListView_GetNextItem(m_hwndFTClientList, currentUploadIndex, LVNI_SELECTED); if (index < 0) { SetWindowText(m_hwndFTStatus, "No file is selected, nothing to download."); return; } currentUploadIndex = index; ListView_GetItemText(m_hwndFTClientList, currentUploadIndex, 0, m_ClientFilename, rfbMAX_PATH); sprintf(path, "%s\\%s", m_ClientPath, m_ClientFilename); strcpy(m_UploadFilename, path); WIN32_FIND_DATA FindFileData; SetErrorMode(SEM_FAILCRITICALERRORS); HANDLE hFile = FindFirstFile(path, &FindFileData); SetErrorMode(0); if (hFile == INVALID_HANDLE_VALUE) { SetWindowText(m_hwndFTStatus, "Could not find selected file, can't upload"); // Continue with upload of other files. continue; } else if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { SetWindowText(m_hwndFTStatus, "Cannot upload a directory"); // Continue with upload of other files. continue; } else { sz_rfbFileSize = FindFileData.nFileSizeLow; mTime = FiletimeToTime70(FindFileData.ftLastWriteTime); strcpy(m_ServerFilename, FindFileData.cFileName); } FindClose(hFile); if ((sz_rfbFileSize != 0) && (sz_rfbFileSize <= sz_rfbBlockSize)) sz_rfbBlockSize = sz_rfbFileSize; m_hFiletoRead = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (m_hFiletoRead == INVALID_HANDLE_VALUE) { SetWindowText(m_hwndFTStatus, "Upload failed: could not open selected file"); BlockingFileTransferDialog(TRUE); EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE); return; } char buffer[rfbMAX_PATH + rfbMAX_PATH + rfbMAX_PATH + rfbMAX_PATH + 20]; sprintf(buffer, "Uploading: %s\\%s -> %s\\%s ...", m_ClientPath, m_ClientFilename, m_ServerPath, m_ServerFilename); SetWindowText(m_hwndFTStatus, buffer); sprintf(path, "%s\\%s", m_ServerPath, m_ClientFilename); ConvertPath(path); int pathLen = strlen(path); char *pAllFURMessage = new char[sz_rfbFileUploadRequestMsg + pathLen]; rfbFileUploadRequestMsg *pFUR = (rfbFileUploadRequestMsg *) pAllFURMessage; char *pFollowMsg = &pAllFURMessage[sz_rfbFileUploadRequestMsg]; pFUR->type = rfbFileUploadRequest; pFUR->compressedLevel = 0; pFUR->fNameSize = Swap16IfLE(pathLen); pFUR->position = Swap32IfLE(0); memcpy(pFollowMsg, path, pathLen); m_clientconn->WriteExact(pAllFURMessage, sz_rfbFileUploadRequestMsg + pathLen); delete [] pAllFURMessage; if (sz_rfbFileSize == 0) { SendFileUploadDataMessage(mTime); } else { int amount = sz_rfbFileSize / (sz_rfbBlockSize * 10); InitProgressBar(0, 0, amount, 1); DWORD dwPortionRead = 0; char *pBuff = new char [sz_rfbBlockSize]; m_bUploadStarted = TRUE; while(m_bUploadStarted) { ProcessDlgMessage(m_hwndFileTransfer); if (m_bTransferEnable == FALSE) { SetWindowText(m_hwndFTStatus, "File transfer canceled"); EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE); BlockingFileTransferDialog(TRUE); char reason[] = "File transfer canceled by user"; int reasonLen = strlen(reason); char *pFUFMessage = new char[sz_rfbFileUploadFailedMsg + reasonLen]; rfbFileUploadFailedMsg *pFUF = (rfbFileUploadFailedMsg *) pFUFMessage; char *pReason = &pFUFMessage[sz_rfbFileUploadFailedMsg]; pFUF->type = rfbFileUploadFailed; pFUF->reasonLen = Swap16IfLE(reasonLen); memcpy(pReason, reason, reasonLen); m_clientconn->WriteExact(pFUFMessage, sz_rfbFileUploadFailedMsg + reasonLen); delete [] pFUFMessage; break; } bResult = ReadFile(m_hFiletoRead, pBuff, sz_rfbBlockSize, &dwNumberOfBytesRead, NULL); if (bResult && dwNumberOfBytesRead == 0) { /* This is the end of the file. */ SendFileUploadDataMessage(mTime); break; } SendFileUploadDataMessage((unsigned short)dwNumberOfBytesRead, pBuff); dwPortionRead += dwNumberOfBytesRead; if (dwPortionRead >= (10 * sz_rfbBlockSize)) { dwPortionRead = 0; SendMessage(m_hwndFTProgress, PBM_STEPIT, 0, 0); } } if (m_bTransferEnable == FALSE) break; m_bUploadStarted = FALSE; delete [] pBuff; } SendMessage(m_hwndFTProgress, PBM_SETPOS, 0, 0); SetWindowText(m_hwndFTStatus, ""); CloseHandle(m_hFiletoRead); } EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE); BlockingFileTransferDialog(TRUE); SendFileListRequestMessage(m_ServerPath, 0); }
void ClientConnection::ReadCoRRERect(rfbFramebufferUpdateRectHeader *pfburh) { // An RRE rect is always followed by a background color // For speed's sake we read them together into a buffer. char tmpbuf[sz_rfbRREHeader+4]; // biggest pixel is 4 bytes long rfbRREHeader *prreh = (rfbRREHeader *) tmpbuf; CARD8 *pcolor = (CARD8 *) tmpbuf + sz_rfbRREHeader; ReadExact(tmpbuf, sz_rfbRREHeader + m_minPixelBytes); prreh->nSubrects = Swap32IfLE(prreh->nSubrects); SETUP_COLOR_SHORTCUTS; COLORREF color; switch (m_myFormat.bitsPerPixel) { case 8: color = COLOR_FROM_PIXEL8_ADDRESS(pcolor); break; case 16: color = COLOR_FROM_PIXEL16_ADDRESS(pcolor); break; case 24: case 32: color = COLOR_FROM_PIXEL32_ADDRESS(pcolor); break; } // Draw the background of the rectangle FillSolidRect(pfburh->r.x, pfburh->r.y, pfburh->r.w, pfburh->r.h, color); if (prreh->nSubrects == 0) return; // Draw the sub-rectangles rfbCoRRERectangle *pRect; rfbRectangle rect; // The size of an CoRRE subrect including color info int subRectSize = m_minPixelBytes + sz_rfbCoRRERectangle; // Read subrects into the buffer CheckBufferSize(subRectSize * prreh->nSubrects); ReadExact(m_netbuf, subRectSize * prreh->nSubrects); BYTE *p = (BYTE *) m_netbuf; { boost::recursive_mutex::scoped_lock l(m_bitmapdcMutex); \ ObjectSelector b(m_hBitmapDC, m_hBitmap); \ PaletteSelector ps(m_hBitmapDC, m_hPalette); \ for (CARD32 i = 0; i < prreh->nSubrects; i++) { pRect = (rfbCoRRERectangle *) (p + m_minPixelBytes); switch (m_myFormat.bitsPerPixel) { case 8: color = COLOR_FROM_PIXEL8_ADDRESS(p); break; case 16: color = COLOR_FROM_PIXEL16_ADDRESS(p); break; case 32: color = COLOR_FROM_PIXEL32_ADDRESS(p); break; }; // color = COLOR_FROM_PIXEL8_ADDRESS(netbuf); rect.x = pRect->x + pfburh->r.x; rect.y = pRect->y + pfburh->r.y; rect.w = pRect->w; rect.h = pRect->h; FillSolidRect(rect.x, rect.y, rect.w, rect.h, color); p+=subRectSize; } } }
rfbBool rfbSendRectEncodingRRE(rfbClientPtr cl, int x, int y, int w, int h) { rfbFramebufferUpdateRectHeader rect; rfbRREHeader hdr; int nSubrects; int i; char *fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y) + (x * (cl->scaledScreen->bitsPerPixel / 8))); int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height * (cl->format.bitsPerPixel / 8)); if (cl->beforeEncBufSize < maxRawSize) { cl->beforeEncBufSize = maxRawSize; if (cl->beforeEncBuf == NULL) cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize); else cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize); } if (cl->afterEncBufSize < maxRawSize) { cl->afterEncBufSize = maxRawSize; if (cl->afterEncBuf == NULL) cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize); else cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize); } (*cl->translateFn)(cl->translateLookupTable, &(cl->screen->serverFormat), &cl->format, fbptr, cl->beforeEncBuf, cl->scaledScreen->paddedWidthInBytes, w, h); switch (cl->format.bitsPerPixel) { case 8: nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h); break; case 16: nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h); break; case 32: nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h); break; default: rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); return FALSE; } if (nSubrects < 0) { /* RRE encoding was too large, use raw */ return rfbSendRectEncodingRaw(cl, x, y, w, h); } rfbStatRecordEncodingSent(cl, rfbEncodingRRE, sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen, sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8)); if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader > UPDATE_BUF_SIZE) { if (!rfbSendUpdateBuf(cl)) return FALSE; } rect.r.x = Swap16IfLE(x); rect.r.y = Swap16IfLE(y); rect.r.w = Swap16IfLE(w); rect.r.h = Swap16IfLE(h); rect.encoding = Swap32IfLE(rfbEncodingRRE); memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; hdr.nSubrects = Swap32IfLE(nSubrects); memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader); cl->ublen += sz_rfbRREHeader; for (i = 0; i < cl->afterEncBufLen;) { int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; if (i + bytesToCopy > cl->afterEncBufLen) { bytesToCopy = cl->afterEncBufLen - i; } memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy); cl->ublen += bytesToCopy; i += bytesToCopy; if (cl->ublen == UPDATE_BUF_SIZE) { if (!rfbSendUpdateBuf(cl)) return FALSE; } } return TRUE; }
THREAD_CALL server_listen(LPVOID lpParam) { listener_thread_params *thread_params = (listener_thread_params *)lpParam; SOCKET conn; struct sockaddr_in client; socklen_t socklen = sizeof(client); rfbProtocolVersionMsg protocol_version; char host_id[MAX_HOST_NAME_LEN + 1]; char phost[MAX_HOST_NAME_LEN + 1]; CARD32 auth_type; unsigned char challenge[CHALLENGESIZE]; uint32_t code; char *ip_addr; thread_params->sock = create_listener_socket( thread_params->port ); if (thread_params->sock == INVALID_SOCKET) notstopped = false; else logp(DEBUG, "Listening for incoming server connections on port %d.", thread_params->port); while(notstopped) { conn = socket_accept(thread_params->sock, (struct sockaddr *)&client, &socklen); if (conn == INVALID_SOCKET) { if (notstopped) logp(ERROR, "server_listen(): accept() failed, errno=%d", getLastErrNo()); } else { ip_addr = inet_ntoa(client.sin_addr); /* IP Address for monitoring purposes */ logp(INFO, "Server (socket=%d) connection accepted from %s.", conn, ip_addr); // First thing is first: Get the repeater ID... if( socket_recv(conn, host_id, MAX_HOST_NAME_LEN, "hostid from server") ) { // Check and cypher the ID if( ParseDisplay(host_id, phost, MAX_HOST_NAME_LEN, (int *)&code, challenge) ) { logp(DEBUG, "Server (socket=%d) sent the host ID:%d.", conn, code); // Continue with the handshake until ClientInit. Read the Protocol Version. if( socket_recv(conn, protocol_version, sz_rfbProtocolVersionMsg, "protocol version from server") ) { // ToDo: Make sure the version is OK! logp(DEBUG, "Server (socket=%d) sent protocol version.", conn); // Tell the server we are using Protocol Version 3.3 sprintf(protocol_version, rfbProtocolVersionFormat, rfbProtocolMajorVersion, rfbProtocolMinorVersion); if( socket_send(conn, protocol_version, sz_rfbProtocolVersionMsg, "protocol version to server") ) { logp(DEBUG, "Protocol version sent to server (socket=%d).", conn); // The server should send the authentication type it whises to use. // ToDo: We could add a password this would restrict other servers from connecting to our repeater, // in the meanwhile, assume no auth is the only scheme allowed. if( socket_recv(conn, (char *)&auth_type, sizeof(auth_type), "auth type from server") ) { logp(DEBUG, "Server (socket=%d) sent authentication scheme.", conn); if( Swap32IfLE(auth_type) != rfbNoAuth ) { logp(ERROR, "Invalid authentication scheme sent by server (socket=%d).", conn); socket_close(conn); } else add_new_slot(conn, INVALID_SOCKET, challenge, code); } } } } else logp(ERROR, "server_listen(): Reading Proxy settings error %s", host_id); } } } notstopped = false; socket_close(thread_params->sock); log(INFO, "Server listening thread has exited.\n"); return 0; }
BOOL VNCScanner(EXINFO exinfo) { char buffer[IRCLINE]; char szClientPacket[] = "\x01"; struct sockaddr_in thataddr; int res; SOCKET m_sock; m_sock = fsocket(PF_INET, SOCK_STREAM, 0); if (m_sock == INVALID_SOCKET) { fclosesocket(m_sock); return FALSE; } thataddr.sin_addr.s_addr = finet_addr(exinfo.ip); thataddr.sin_family = AF_INET; thataddr.sin_port = fhtons((unsigned short)exinfo.port); res = fconnect(m_sock, (LPSOCKADDR) &thataddr, sizeof(thataddr)); if (res == SOCKET_ERROR) { fclosesocket(m_sock); return FALSE; } //connected //now lets negotiate protocol rfbProtocolVersionMsg pv; if (!ReadExact(m_sock, pv, sz_rfbProtocolVersionMsg)) { closesocket(m_sock); return FALSE; } pv[sz_rfbProtocolVersionMsg] = 0; int m_majorVersion, m_minorVersion; if (sscanf(pv,rfbProtocolVersionFormat,&m_majorVersion,&m_minorVersion) != 2) { closesocket(m_sock); return FALSE; } if (!(m_majorVersion == 3) && !(m_minorVersion == 8)) { //Server is not 3.8 closesocket(m_sock); return FALSE; } if (!WriteExact(m_sock, pv, sz_rfbProtocolVersionMsg)) { closesocket(m_sock); return FALSE; } //auth part CARD32 authScheme, authResult; // CARD8 challenge[CHALLENGESIZE]; //we expect to get 2 bytes if (!ReadExact(m_sock, (char *)&authScheme, 2)) { closesocket(m_sock); return FALSE; } //return clientpacket if (!WriteExact(m_sock, szClientPacket, 1)) { closesocket(m_sock); return FALSE; } if (ReadExact(m_sock, (char *) &authResult, 4)) { authResult = Swap32IfLE(authResult); switch (authResult) { case rfbVncAuthOK: { rfbServerInitMsg m_si; //send non-shared session request and receive data if (WriteExact(m_sock, (char *) useShared, sz_rfbClientInitMsg) && ReadExact(m_sock, (char *) &m_si, sz_rfbServerInitMsg)) { //lets get desktop name m_si.framebufferWidth = Swap16IfLE(m_si.framebufferWidth); m_si.framebufferHeight = Swap16IfLE(m_si.framebufferHeight); m_si.format.redMax = Swap16IfLE(m_si.format.redMax); m_si.format.greenMax = Swap16IfLE(m_si.format.greenMax); m_si.format.blueMax = Swap16IfLE(m_si.format.blueMax); m_si.nameLength = Swap32IfLE(m_si.nameLength); TCHAR *m_desktopName; m_desktopName = new TCHAR[m_si.nameLength + 2]; ReadString(m_sock, m_desktopName, m_si.nameLength); _snprintf(buffer, sizeof(buffer), "VNC%d.%d %s: %s - [AuthBypass]", m_majorVersion, m_minorVersion, m_desktopName, exinfo.ip); irc_privmsg(exinfo.sock, exinfo.chan, buffer, exinfo.notice); addlog(buffer); exploit[exinfo.exploit].stats++; closesocket(m_sock); return TRUE; } break; } default: { break; } } } closesocket(m_sock); return FALSE; }
static void AuthPAMUserPwdRspFunc(rfbClientPtr cl) { CARD32 userLen; CARD32 pwdLen; char userBuf[MAX_USER_LEN + 1]; char pwdBuf[MAX_PWD_LEN + 1]; int n; const char* emsg; n = ReadExact(cl->sock, (char*) &userLen, sizeof(userLen)); if (n <= 0) { if (n != 0) rfbLogPerror("AuthPAMUserPwdRspFunc: read error"); rfbCloseSock(cl->sock); return; } userLen = Swap32IfLE(userLen); n = ReadExact(cl->sock, (char*) &pwdLen, sizeof(pwdLen)); if (n <= 0) { if (n != 0) rfbLogPerror("AuthPAMUserPwdRspFunc: read error"); rfbCloseSock(cl->sock); return; } pwdLen = Swap32IfLE(pwdLen); if ((userLen > MAX_USER_LEN) || (pwdLen > MAX_PWD_LEN)) { rfbLogPerror("AuthPAMUserPwdRspFunc: excessively large user name or password in response"); rfbCloseSock(cl->sock); return; } n = ReadExact(cl->sock, userBuf, userLen); if (n <= 0) { if (n != 0) rfbLogPerror("AuthPAMUserPwdRspFunc: error reading user name"); rfbCloseSock(cl->sock); return; } userBuf[userLen] = '\0'; n = ReadExact(cl->sock, pwdBuf, pwdLen); if (n <= 0) { if (n != 0) rfbLogPerror("AuthPAMUserPwdRspFunc: error reading password"); rfbCloseSock(cl->sock); return; } pwdBuf[pwdLen] = '\0'; if (rfbAuthUserACL) { UserList* p = userACL; if (p == NULL) rfbLog("WARNING: User ACL is empty. No users will be allowed to log in with Unix login authentication.\n"); while (p != NULL) { if (!strcmp(p->name, userBuf)) break; p = p->next; } if (p == NULL) { rfbLog("User '%s' is not in the ACL and has been denied access\n", userBuf); rfbClientAuthFailed(cl, "User denied access"); return; } cl->viewOnly = p->viewOnly; } if (rfbPAMAuthenticate(pamServiceName, cl->host, userBuf, pwdBuf, &emsg)) { rfbClientAuthSucceeded(cl, rfbAuthUnixLogin); } else { rfbClientAuthFailed(cl, (char*)emsg); } }
// Encode the rectangle using RRE inline UINT vncEncodeRRE::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) { int subrects = -1; const UINT rectW = rect.br.x - rect.tl.x; const UINT rectH = rect.br.y - rect.tl.y; // Create the rectangle header rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; surh->r.x = (CARD16) rect.tl.x; surh->r.y = (CARD16) rect.tl.y; surh->r.w = (CARD16) (rectW); surh->r.h = (CARD16) (rectH); surh->r.x = Swap16IfLE(surh->r.x); surh->r.y = Swap16IfLE(surh->r.y); surh->r.w = Swap16IfLE(surh->r.w); surh->r.h = Swap16IfLE(surh->r.h); surh->encoding = Swap32IfLE(rfbEncodingRRE); // create a space big enough for the RRE encoded pixels if (m_bufflen < (rectW*rectH*m_remoteformat.bitsPerPixel / 8)) { if (m_buffer != NULL) { delete [] m_buffer; m_buffer = NULL; } m_buffer = new BYTE [rectW*rectH*m_remoteformat.bitsPerPixel/8+1]; if (m_buffer == NULL) return vncEncoder::EncodeRect(source, dest, rect); m_bufflen = rectW*rectH*m_remoteformat.bitsPerPixel/8; } // Translate the data into our new buffer Translate(source, m_buffer, rect); // Choose the appropriate encoding routine (for speed...) switch(m_remoteformat.bitsPerPixel) { case 8: subrects = subrectEncode8( m_buffer, dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader, rectW, rectH, m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader ); break; case 16: subrects = subrectEncode16( (CARD16 *)m_buffer, (CARD8 *)(dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader), rectW, rectH, m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader ); break; case 32: subrects = subrectEncode32( (CARD32 *)m_buffer, (CARD8 *)(dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader), rectW, rectH, m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader ); break; } // If we couldn't encode the rectangles then just send the data raw if (subrects < 0) return vncEncoder::EncodeRect(source, dest, rect); // Send the RREHeader rfbRREHeader *rreh=(rfbRREHeader *)(dest+sz_rfbFramebufferUpdateRectHeader); rreh->nSubrects = Swap32IfLE(subrects); // Return the amount of data sent return sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + (m_remoteformat.bitsPerPixel / 8) + (subrects * (sz_rfbRectangle + m_remoteformat.bitsPerPixel / 8)); }
rfbBool rfbSendCursorShape(rfbClientPtr cl) { rfbCursorPtr pCursor; rfbFramebufferUpdateRectHeader rect; rfbXCursorColors colors; int saved_ublen; int bitmapRowBytes, maskBytes, dataBytes; int i, j; uint8_t *bitmapData; uint8_t bitmapByte; /* TODO: scale the cursor data to the correct size */ pCursor = cl->screen->getCursorPtr(cl); /*if(!pCursor) return TRUE;*/ if (cl->useRichCursorEncoding) { if(pCursor && !pCursor->richSource) rfbMakeRichCursorFromXCursor(cl->screen,pCursor); rect.encoding = Swap32IfLE(rfbEncodingRichCursor); } else { if(pCursor && !pCursor->source) rfbMakeXCursorFromRichCursor(cl->screen,pCursor); rect.encoding = Swap32IfLE(rfbEncodingXCursor); } /* If there is no cursor, send update with empty cursor data. */ if ( pCursor && pCursor->width == 1 && pCursor->height == 1 && pCursor->mask[0] == 0 ) { pCursor = NULL; } if (pCursor == NULL) { if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE ) { if (!rfbSendUpdateBuf(cl)) return FALSE; } rect.r.x = rect.r.y = 0; rect.r.w = rect.r.h = 0; memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; if (!rfbSendUpdateBuf(cl)) return FALSE; return TRUE; } /* Calculate data sizes. */ bitmapRowBytes = (pCursor->width + 7) / 8; maskBytes = bitmapRowBytes * pCursor->height; dataBytes = (cl->useRichCursorEncoding) ? (pCursor->width * pCursor->height * (cl->format.bitsPerPixel / 8)) : maskBytes; /* Send buffer contents if needed. */ if ( cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) { if (!rfbSendUpdateBuf(cl)) return FALSE; } if ( cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) { return FALSE; /* FIXME. */ } saved_ublen = cl->ublen; /* Prepare rectangle header. */ rect.r.x = Swap16IfLE(pCursor->xhot); rect.r.y = Swap16IfLE(pCursor->yhot); rect.r.w = Swap16IfLE(pCursor->width); rect.r.h = Swap16IfLE(pCursor->height); memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; /* Prepare actual cursor data (depends on encoding used). */ if (!cl->useRichCursorEncoding) { /* XCursor encoding. */ colors.foreRed = (char)(pCursor->foreRed >> 8); colors.foreGreen = (char)(pCursor->foreGreen >> 8); colors.foreBlue = (char)(pCursor->foreBlue >> 8); colors.backRed = (char)(pCursor->backRed >> 8); colors.backGreen = (char)(pCursor->backGreen >> 8); colors.backBlue = (char)(pCursor->backBlue >> 8); memcpy(&cl->updateBuf[cl->ublen], (char *)&colors, sz_rfbXCursorColors); cl->ublen += sz_rfbXCursorColors; bitmapData = (uint8_t *)pCursor->source; for (i = 0; i < pCursor->height; i++) { for (j = 0; j < bitmapRowBytes; j++) { bitmapByte = bitmapData[i * bitmapRowBytes + j]; cl->updateBuf[cl->ublen++] = (char)bitmapByte; } } }
UINT vncEncodeZRLE::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) { int x = rect.tl.x; int y = rect.tl.y; int w = rect.br.x - x; int h = rect.br.y - y; mos->clear(); if( m_use_zywrle ){ if( m_qualitylevel < 0 ){ zywrle_level = 1; }else if( m_qualitylevel < 3 ){ zywrle_level = 3; }else if( m_qualitylevel < 6 ){ zywrle_level = 2; }else{ zywrle_level = 1; } }else{ zywrle_level = 0; } switch (m_remoteformat.bitsPerPixel) { case 8: zrleEncode8NE( x, y, w, h, mos, zos, beforeBuf, source, this); break; case 16: if( m_remoteformat.greenMax > 0x1F ){ if( m_remoteformat.bigEndian ){ zrleEncode16BE(x, y, w, h, mos, zos, beforeBuf, source, this); }else{ zrleEncode16LE(x, y, w, h, mos, zos, beforeBuf, source, this); } }else{ if( m_remoteformat.bigEndian ){ zrleEncode15BE(x, y, w, h, mos, zos, beforeBuf, source, this); }else{ zrleEncode15LE(x, y, w, h, mos, zos, beforeBuf, source, this); } } break; case 32: bool fitsInLS3Bytes = ((m_remoteformat.redMax << m_remoteformat.redShift) < (1<<24) && (m_remoteformat.greenMax << m_remoteformat.greenShift) < (1<<24) && (m_remoteformat.blueMax << m_remoteformat.blueShift) < (1<<24)); bool fitsInMS3Bytes = (m_remoteformat.redShift > 7 && m_remoteformat.greenShift > 7 && m_remoteformat.blueShift > 7); if ((fitsInLS3Bytes && !m_remoteformat.bigEndian) || (fitsInMS3Bytes && m_remoteformat.bigEndian)) { if( m_remoteformat.bigEndian ){ zrleEncode24ABE(x, y, w, h, mos, zos, beforeBuf, source, this); }else{ zrleEncode24ALE(x, y, w, h, mos, zos, beforeBuf, source, this); } } else if ((fitsInLS3Bytes && m_remoteformat.bigEndian) || (fitsInMS3Bytes && !m_remoteformat.bigEndian)) { if( m_remoteformat.bigEndian ){ zrleEncode24BBE(x, y, w, h, mos, zos, beforeBuf, source, this); }else{ zrleEncode24BLE(x, y, w, h, mos, zos, beforeBuf, source, this); } } else { if( m_remoteformat.bigEndian ){ zrleEncode32BE(x, y, w, h, mos, zos, beforeBuf, source, this); }else{ zrleEncode32LE(x, y, w, h, mos, zos, beforeBuf, source, this); } } break; } rfbFramebufferUpdateRectHeader* surh = (rfbFramebufferUpdateRectHeader*)dest; surh->r.x = Swap16IfLE(x-m_SWOffsetx); surh->r.y = Swap16IfLE(y-m_SWOffsety); surh->r.w = Swap16IfLE(w); surh->r.h = Swap16IfLE(h); if( m_use_zywrle ){ surh->encoding = Swap32IfLE(rfbEncodingZYWRLE); }else{ surh->encoding = Swap32IfLE(rfbEncodingZRLE); } rfbZRLEHeader* hdr = (rfbZRLEHeader*)(dest + sz_rfbFramebufferUpdateRectHeader); hdr->length = Swap32IfLE(mos->length()); memcpy(dest + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader, (rdr::U8*)mos->data(), mos->length()); return sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader + mos->length(); }
Bool SetFormatAndEncodings() { rfbSetPixelFormatMsg spf; char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4]; rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf; CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]); int len = 0; Bool requestCompressLevel = False; Bool requestQualityLevel = False; Bool requestLastRectEncoding = False; spf.type = rfbSetPixelFormat; spf.format = myFormat; spf.format.redMax = Swap16IfLE(spf.format.redMax); spf.format.greenMax = Swap16IfLE(spf.format.greenMax); spf.format.blueMax = Swap16IfLE(spf.format.blueMax); if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg)) return False; se->type = rfbSetEncodings; se->nEncodings = 0; if (appData.encodingsString) { char *encStr = appData.encodingsString; int encStrLen; do { char *nextEncStr = strchr(encStr, ' '); if (nextEncStr) { encStrLen = nextEncStr - encStr; nextEncStr++; } else { encStrLen = strlen(encStr); } if (strncasecmp(encStr,"raw",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); } else if (strncasecmp(encStr,"tight",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); requestLastRectEncoding = True; if (appData.compressLevel >= 0 && appData.compressLevel <= 9) requestCompressLevel = True; if (appData.enableJPEG) requestQualityLevel = True; } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); if (appData.compressLevel >= 0 && appData.compressLevel <= 9) requestCompressLevel = True; } else if (strncasecmp(encStr,"corre",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); } else if (strncasecmp(encStr,"rre",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE); } else { fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr); } encStr = nextEncStr; } while (encStr && se->nEncodings < MAX_ENCODINGS); if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) { encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0); } if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) { if (appData.qualityLevel < 0 || appData.qualityLevel > 9) appData.qualityLevel = 5; encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbEncodingQualityLevel0); } if (appData.useRemoteCursor) { if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos); } if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); } } else { if (SameMachine(rfbsock)) { if (!tunnelSpecified) { fprintf(stderr,"Same machine: preferring raw encoding\n"); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); } else { fprintf(stderr,"Tunneling active: preferring tight encoding\n"); } } encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE); if (appData.compressLevel >= 0 && appData.compressLevel <= 9) { encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0); } else if (!tunnelSpecified) { /* If -tunnel option was provided, we assume that server machine is not in the local network so we use default compression level for tight encoding instead of fast compression. Thus we are requesting level 1 compression only if tunneling is not used. */ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCompressLevel1); } if (appData.enableJPEG) { if (appData.qualityLevel < 0 || appData.qualityLevel > 9) appData.qualityLevel = 5; encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbEncodingQualityLevel0); } if (appData.useRemoteCursor) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos); } encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); } len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; se->nEncodings = Swap16IfLE(se->nEncodings); if (!WriteExact(rfbsock, buf, len)) return False; return True; }
static void rfbProcessClientNormalMessage(rfbClientPtr cl) { int n=0; rfbClientToServerMsg msg; char *str; int i; // unsigned char keyvalue; u32 enc; // debug_printf("--In the NormalMessadge process!\n"); if ((n = ReadExact(cl, (char *)&msg, 1)) <= 0) { debug_printf("rfbProcessClientNormalMessage: read--type-error,shutdown clien!\n"); // delay(10); rfbCloseClient(cl); return; } // debug_printf("--In the NormalMessadge process!--has read msg type=%d \n",msg.type); switch (msg.type) //根据收到的消息来对应的处理各种情况 { case rfbSetPixelFormat://目前已经处理完备 debug_printf("SetPixelFormat!\n"); if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbSetPixelFormatMsg - 1)) <= 0) { debug_printf("rfbProcessClientNormalMessage: read--setpixelmessage-error,shutdown client!\n"); // delay(10000); rfbCloseClient(cl); return; } cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel; cl->format.depth = msg.spf.format.depth; cl->format.bigEndian = (msg.spf.format.bigEndian ? 1 : 0); cl->format.trueColour = (msg.spf.format.trueColour ? 1 : 0); cl->format.redMax = Swap16IfLE(msg.spf.format.redMax); cl->format.greenMax = Swap16IfLE(msg.spf.format.greenMax); cl->format.blueMax = Swap16IfLE(msg.spf.format.blueMax); cl->format.redShift = msg.spf.format.redShift; cl->format.greenShift = msg.spf.format.greenShift; cl->format.blueShift = msg.spf.format.blueShift; cl->readyForSetColourMapEntries = TRUE; //这个是必须要处理的,因为当客户端发送的信息是颜色不是真彩色的话,必须要发送服务器的映射方法。 debug_printf("got the client set pixformat=%s\n",cl->host); showPixelFormat(&(cl->format)); // deug_printf("--set the client color translate begin!\n"); rfbSetTranslateFunction(cl); // debug_printf("--set the client color end!\n"); return; case rfbFixColourMapEntries: debug_printf("rfbFixColourMapEntries!\n"); if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbFixColourMapEntriesMsg - 1)) <= 0) { debug_printf("rfbProcessClientNormalMessage: read--fixpixelmessage-error,shutdown client!\n"); delay(10000); rfbCloseClient(cl); return; } debug_printf("FixColourMapEntries unsupported\n"); rfbCloseClient(cl); return; case rfbSetEncodings://目前已经处理完备 { //debug_printf("rfbSetEncodings!\n"); if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbSetEncodingsMsg - 1)) <= 0) { debug_printf("rfbProcessClientNormalMessage: read--rfbSetEncodings-error,shutdown client!\n"); delay(10000); rfbCloseClient(cl); return; } msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings); cl->preferredEncoding = -1; cl->useCopyRect = FALSE; cl->enableCursorShapeUpdates = FALSE; cl->enableLastRectEncoding = FALSE; for (i = 0; i < msg.se.nEncodings; i++) { if ((n = ReadExact(cl, (char *)&enc, 4)) <= 0) { debug_printf("rfbProcessClientNormalMessage: read--rfbSetEncodings-error,shutdown client!\n"); delay(10000); rfbCloseClient(cl); return; } enc = Swap32IfLE(enc); switch (enc) { case rfbEncodingCopyRect: debug_printf("client %s supported rfbEncodingCopyRect\n",cl->host); cl->useCopyRect = TRUE; break; case rfbEncodingRaw: debug_printf("client %s supported rfbEncodingRaw\n",cl->host); if (cl->preferredEncoding == -1) { cl->preferredEncoding = enc; debug_printf("Using raw encoding for client %s\n", cl->host); } break; case rfbEncodingRRE: debug_printf("client %s supported rfbEncodingRRE\n",cl->host); if (cl->preferredEncoding == -1) { cl->preferredEncoding = enc; debug_printf("Using rre encoding for client %s\n", cl->host); } break; case rfbEncodingCoRRE: debug_printf("client %s supported rfbEncodingCoRRE\n",cl->host); if (cl->preferredEncoding == -1) { cl->preferredEncoding = enc; debug_printf("Using CoRRE encoding for client %s\n", cl->host); } break; case rfbEncodingHextile: debug_printf("client %s supported rfbEncodingHextile\n",cl->host); if (cl->preferredEncoding == -1) { cl->preferredEncoding = enc; debug_printf("Using hextile encoding for client %s\n", cl->host); } break; case rfbEncodingZlib: debug_printf("client %s supported rfbEncodingZlib\n",cl->host); if (cl->preferredEncoding == -1) { cl->preferredEncoding = enc; debug_printf("Using zlib encoding for client %s\n", cl->host); } break; case rfbEncodingTight: debug_printf("client %s supported rfbEncodingHextile\n",cl->host); if (cl->preferredEncoding == -1) { cl->preferredEncoding = enc; debug_printf("Using tight encoding for client %s\n", cl->host); } break; case rfbEncodingXCursor: debug_printf("Enabling X-style cursor updates for client %s\n", cl->host); cl->enableCursorShapeUpdates = TRUE; cl->useRichCursorEncoding = FALSE; cl->cursorWasChanged = TRUE; break; case rfbEncodingRichCursor: if (!cl->enableCursorShapeUpdates) { debug_printf("Enabling full-color cursor updates for client " "%s\n", cl->host); cl->enableCursorShapeUpdates = TRUE; cl->useRichCursorEncoding = TRUE; cl->cursorWasChanged = TRUE; } break; case rfbEncodingLastRect: debug_printf("client %s supported rfbEncodingLastRect\n",cl->host); if (!cl->enableLastRectEncoding) { debug_printf("Enabling LastRect protocol extension for client " "%s\n", cl->host); cl->enableLastRectEncoding = TRUE; } break; default: if ( enc >= (u32)rfbEncodingCompressLevel0 && enc <= (u32)rfbEncodingCompressLevel9 ) { cl->zlibCompressLevel = enc & 0x0F; cl->tightCompressLevel = enc & 0x0F; debug_printf("Using compression level %d for client %s\n", cl->tightCompressLevel, cl->host); } else if ( enc >= (u32)rfbEncodingQualityLevel0 && enc <= (u32)rfbEncodingQualityLevel9 ) { cl->tightQualityLevel = enc & 0x0F; debug_printf("Using image quality level %d for client %s\n", cl->tightQualityLevel, cl->host); } else debug_printf("rfbProcessClientNormalMessage: ignoring unknown " "encoding type %d\n", (int)enc); } } if (cl->preferredEncoding == -1) { cl->preferredEncoding = rfbEncodingRaw; } return; } case rfbFramebufferUpdateRequest: { //debug_printf("rfbSetEncodings!\n"); if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) { if (n != 0) debug_printf("rfbProcessClientNormalMessage: read"); rfbCloseClient(cl); return; } if(msg.fur.incremental==FALSE)//客户端请求整幅数据,出现了某些数据的丢失 { cl->InitDone=FALSE; cl->modifiedregion.x=Swap16IfLE(msg.fur.x); cl->modifiedregion.y=Swap16IfLE(msg.fur.y); cl->modifiedregion.w=Swap16IfLE(msg.fur.w); cl->modifiedregion.h=Swap16IfLE(msg.fur.h); } else { cl->InitDone=TRUE; } if (!cl->readyForSetColourMapEntries) { /* client hasn't sent a SetPixelFormat so is using server's */ cl->readyForSetColourMapEntries = TRUE; if (!cl->format.trueColour) { if (!rfbSendSetColourMapEntries(cl, 0, 256)) { // sraRgnDestroy(tmpRegion); // TSIGNAL(cl->updateCond); // UNLOCK(cl->updateMutex); debug_printf("failed to send the color map!"); return; } } } cl->HasRequest = 1; return; } case rfbKeyEvent: debug_printf("rfbKeyEvent!\n"); cl->rfbKeyEventsRcvd++; if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbKeyEventMsg - 1)) <= 0) { if (n != 0) debug_printf("rfbProcessClientNormalMessage: read"); rfbCloseClient(cl); return; } //打印接受到的键盘值 msg.ke.key=Swap32IfLE(msg.ke.key); #if CN_CFG_KEYBOARD == 1 vncclient_keyevent(cl->screen, msg); #endif return; case rfbPointerEvent: cl->rfbPointerEventsRcvd++; if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbPointerEventMsg - 1)) <= 0) { if (n != 0)//等于0应该是客户端主动关闭了 debug_printf("rfbProcessClientNormalMessage: read"); rfbCloseClient(cl); return; } //输入touch message msg.pe.x = Swap16IfLE(msg.pe.x); msg.pe.y = Swap16IfLE(msg.pe.y); // debug_printf("rfbPointerEvent!----x=%d y=%d\n", msg.pe.x,msg.pe.y); #if CN_CFG_KEYBOARD == 1 vncclient_pointevent(cl->screen, msg); #endif return; case rfbClientCutText: debug_printf("rfbClientCutText!\n"); if ((n = ReadExact(cl, ((char *)&msg) + 1, sz_rfbClientCutTextMsg - 1)) <= 0) { if (n != 0) debug_printf("rfbProcessClientNormalMessage: read"); rfbCloseClient(cl); return; } msg.cct.length = Swap32IfLE(msg.cct.length); str = (char *)M_MallocLc(msg.cct.length+1, 0); if ((n = ReadExact(cl, str, msg.cct.length)) <= 0) { if (n != 0) debug_printf("rfbProcessClientNormalMessage: read"); free(str); rfbCloseClient(cl); return; } // cl->screen->setXCutText(str, msg.cct.length, cl); str[msg.cct.length]= 0; debug_printf(" the cut messaged=%s\n",str); free(str); return; default: debug_printf("rfbProcessClientNormalMessage: unknown message type %d\n", msg.type); debug_printf(" ... closing connection\n"); rfbCloseClient(cl); return; } }
Bool HandleRFBServerMessage() { rfbServerToClientMsg msg; if (!ReadFromRFBServer((char *)&msg, 1)) return False; switch (msg.type) { case rfbSetColourMapEntries: { int i; CARD16 rgb[3]; XColor xc; if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbSetColourMapEntriesMsg - 1)) return False; msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); msg.scme.nColours = Swap16IfLE(msg.scme.nColours); for (i = 0; i < msg.scme.nColours; i++) { if (!ReadFromRFBServer((char *)rgb, 6)) return False; xc.pixel = msg.scme.firstColour + i; xc.red = Swap16IfLE(rgb[0]); xc.green = Swap16IfLE(rgb[1]); xc.blue = Swap16IfLE(rgb[2]); xc.flags = DoRed|DoGreen|DoBlue; XStoreColor(dpy, cmap, &xc); } break; } case rfbFramebufferUpdate: { rfbFramebufferUpdateRectHeader rect; int linesToRead; int bytesPerLine; int i; int usecs; if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) return False; msg.fu.nRects = Swap16IfLE(msg.fu.nRects); for (i = 0; i < msg.fu.nRects; i++) { if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) return False; rect.encoding = Swap32IfLE(rect.encoding); if (rect.encoding == rfbEncodingLastRect) break; rect.r.x = Swap16IfLE(rect.r.x); rect.r.y = Swap16IfLE(rect.r.y); rect.r.w = Swap16IfLE(rect.r.w); rect.r.h = Swap16IfLE(rect.r.h); if (rect.encoding == rfbEncodingXCursor || rect.encoding == rfbEncodingRichCursor) { if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rect.encoding)) { return False; } continue; } if (rect.encoding == rfbEncodingPointerPos) { if (!HandleCursorPos(rect.r.x, rect.r.y)) { return False; } continue; } if ((rect.r.x + rect.r.w > si.framebufferWidth) || (rect.r.y + rect.r.h > si.framebufferHeight)) { fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); return False; } if (rect.r.h * rect.r.w == 0) { fprintf(stderr,"Zero size rect - ignoring\n"); continue; } /* If RichCursor encoding is used, we should prevent collisions between framebuffer updates and cursor drawing operations. */ SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h); switch (rect.encoding) { case rfbEncodingRaw: bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; linesToRead = BUFFER_SIZE / bytesPerLine; while (rect.r.h > 0) { if (linesToRead > rect.r.h) linesToRead = rect.r.h; if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) return False; CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, linesToRead); rect.r.h -= linesToRead; rect.r.y += linesToRead; } break; case rfbEncodingCopyRect: { rfbCopyRect cr; if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) return False; cr.srcX = Swap16IfLE(cr.srcX); cr.srcY = Swap16IfLE(cr.srcY); /* If RichCursor encoding is used, we should extend our "cursor lock area" (previously set to destination rectangle) to the source rectangle as well. */ SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h); if (appData.copyRectDelay != 0) { XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); #if VNC_CAPTURE myxfillrec(dpy, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); #endif XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h); #if VNC_CAPTURE myxfillrec(dpy, dstGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); #endif XSync(dpy,False); usleep(appData.copyRectDelay * 1000); XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h); #if VNC_CAPTURE myxfillrec(dpy, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h); #endif XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); #if VNC_CAPTURE myxfillrec(dpy, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); #endif } XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY, rect.r.w, rect.r.h, rect.r.x, rect.r.y); #if VNC_CAPTURE myxcparea(dpy, gc, cr.srcX, cr.srcY, rect.r.w, rect.r.h,rect.r.x,rect.r.y); #endif break; } case rfbEncodingRRE: { switch (myFormat.bitsPerPixel) { case 8: if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 16: if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 32: if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } break; } case rfbEncodingCoRRE: { switch (myFormat.bitsPerPixel) { case 8: if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 16: if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 32: if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } break; } case rfbEncodingHextile: { switch (myFormat.bitsPerPixel) { case 8: if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 16: if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 32: if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } break; } case rfbEncodingZlib: { switch (myFormat.bitsPerPixel) { case 8: if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 16: if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 32: if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } break; } case rfbEncodingTight: { switch (myFormat.bitsPerPixel) { case 8: if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 16: if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; case 32: if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } break; } default: fprintf(stderr,"Unknown rect encoding %d\n", (int)rect.encoding); return False; } /* Now we may discard "soft cursor locks". */ SoftCursorUnlockScreen(); } #ifdef MITSHM /* if using shared memory PutImage, make sure that the X server has updated its framebuffer before we reuse the shared memory. This is mainly to avoid copyrect using invalid screen contents - not sure if we'd need it otherwise. */ if (appData.useShm) XSync(dpy, False); #endif if (!SendIncrementalFramebufferUpdateRequest()) return False; break; } case rfbBell: { Window toplevelWin; XBell(dpy, 0); if (appData.raiseOnBeep) { toplevelWin = XtWindow(toplevel); XMapRaised(dpy, toplevelWin); } break; } case rfbServerCutText: { if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbServerCutTextMsg - 1)) return False; msg.sct.length = Swap32IfLE(msg.sct.length); if (serverCutText) free(serverCutText); serverCutText = malloc(msg.sct.length+1); if (!ReadFromRFBServer(serverCutText, msg.sct.length)) return False; serverCutText[msg.sct.length] = 0; newServerCutText = True; break; } default: fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); return False; } return True; }
int WriteOutDTD(struct DTDesc *TheDTDesc) { struct IFFHandle *IH; struct FileDataTypeHeader FileDTH; int i; if(!TheDTDesc) { return(FALSE); } if(strlen(TheDTDesc->Name)==0) { return(FALSE); } if(strlen(TheDTDesc->BaseName)==0) { return(FALSE); } #if 0 if(TheDTDesc->DTH.dth_MaskLen==0) { return(FALSE); } #endif if(strlen(TheDTDesc->Pattern)==0) { TheDTDesc->Pattern[0]='#'; TheDTDesc->Pattern[1]='?'; TheDTDesc->Pattern[2]='\0'; } IH=NewIFF(TheDTDesc->OutputName, MAKE_ID('D','T','Y','P')); if(!IH) { return(FALSE); } if(!NewChunk(IH, MAKE_ID('N','A','M','E'))) { CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->Name, (strlen(TheDTDesc->Name)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } EndChunk(IH); if(strlen(TheDTDesc->Version) > 0) { if(!NewChunk(IH, MAKE_ID('F','V','E','R'))) { CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->Version, (strlen(TheDTDesc->Version)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } EndChunk(IH); } if(!NewChunk(IH, MAKE_ID('D','T','H','D'))) { CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } FileDTH.dth_Name = (((unsigned int) sizeof(struct FileDataTypeHeader))); FileDTH.dth_BaseName = (((unsigned int) FileDTH.dth_Name) + strlen(TheDTDesc->DTH.dth_Name) + 1); FileDTH.dth_Pattern = (((unsigned int) FileDTH.dth_BaseName) + strlen(TheDTDesc->DTH.dth_BaseName) + 1); FileDTH.dth_Mask = (((unsigned int) FileDTH.dth_Pattern) + strlen(TheDTDesc->DTH.dth_Pattern) + 1); FileDTH.dth_GroupID = TheDTDesc->DTH.dth_GroupID; FileDTH.dth_ID = TheDTDesc->DTH.dth_ID; FileDTH.dth_MaskLen = TheDTDesc->DTH.dth_MaskLen; FileDTH.dth_Pad = TheDTDesc->DTH.dth_Pad; FileDTH.dth_Flags = TheDTDesc->DTH.dth_Flags; FileDTH.dth_Priority = TheDTDesc->DTH.dth_Priority; FileDTH.dth_Name = Swap32IfLE(((uint32_t) FileDTH.dth_Name)); FileDTH.dth_BaseName = Swap32IfLE(((uint32_t) FileDTH.dth_BaseName)); FileDTH.dth_Pattern = Swap32IfLE(((uint32_t) FileDTH.dth_Pattern)); FileDTH.dth_Mask = Swap32IfLE(((uint32_t) FileDTH.dth_Mask)); FileDTH.dth_GroupID = Swap32IfLE(FileDTH.dth_GroupID); FileDTH.dth_ID = Swap32IfLE(FileDTH.dth_ID); FileDTH.dth_MaskLen = Swap16IfLE(FileDTH.dth_MaskLen); FileDTH.dth_Pad = Swap16IfLE(FileDTH.dth_Pad); FileDTH.dth_Flags = Swap16IfLE(FileDTH.dth_Flags); FileDTH.dth_Priority = Swap16IfLE(FileDTH.dth_Priority); if(WriteChunkData(IH, (char *) &FileDTH, sizeof(struct FileDataTypeHeader))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->DTH.dth_Name, (strlen(TheDTDesc->DTH.dth_Name)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->DTH.dth_BaseName, (strlen(TheDTDesc->DTH.dth_BaseName)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->DTH.dth_Pattern, (strlen(TheDTDesc->DTH.dth_Pattern)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } for(i=0; i<TheDTDesc->DTH.dth_MaskLen; i++) { TheDTDesc->DTH.dth_Mask[i]=Swap16IfLE(TheDTDesc->DTH.dth_Mask[i]); } if (TheDTDesc->DTH.dth_MaskLen) { if(WriteChunkData(IH, (char *) TheDTDesc->DTH.dth_Mask, TheDTDesc->DTH.dth_MaskLen*sizeof(uint16_t))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } } EndChunk(IH); CloseIFF(IH); return(TRUE); }
THREAD_CALL viewer_listen(LPVOID lpParam) { listener_thread_params *thread_params = (listener_thread_params *)lpParam; SOCKET conn; struct sockaddr_in client; socklen_t socklen = sizeof(client); rfbProtocolVersionMsg protocol_version; CARD32 auth_type; CARD32 auth_response; CARD8 client_init; unsigned char challenge[CHALLENGESIZE]; char *ip_addr; thread_params->sock = create_listener_socket( thread_params->port ); if (thread_params->sock == INVALID_SOCKET) notstopped = false; else logp(DEBUG, "Listening for incoming viewer connections on port %d.", thread_params->port); while(notstopped) { conn = socket_accept(thread_params->sock, (struct sockaddr *)&client, &socklen); if (conn == INVALID_SOCKET) { if (notstopped) logp(ERROR, "viewer_listen(): accept() failed, errno=%d", getLastErrNo()); } else { ip_addr = inet_ntoa(client.sin_addr); /* IP Address for monitoring purposes */ logp(INFO, "Viewer (socket=%d) connection accepted from %s.", conn, ip_addr); // Act like a server until the authentication phase is over. Send the protocol version. sprintf(protocol_version, rfbProtocolVersionFormat, rfbProtocolMajorVersion, rfbProtocolMinorVersion); if( socket_send(conn, protocol_version, sz_rfbProtocolVersionMsg, "protocol version to viewer") ) { logp(DEBUG, "Protocol version sent to viewer (socket=%d).", conn); // Read the protocol version the client suggests (Must be 3.3) if( socket_recv(conn, protocol_version, sz_rfbProtocolVersionMsg, "protocol version from viewer") ) { logp(DEBUG, "Viewer (socket=%d) sent protocol version.", conn); // Send Authentication Type (VNC Authentication to keep it standard) auth_type = Swap32IfLE(rfbVncAuth); if( socket_send(conn, (char *)&auth_type, sizeof(auth_type), "auth type to viewer") ) { logp(DEBUG, "Authentication scheme sent to viewer (socket=%d).", conn); // We must send the 16 bytes challenge key. In order for this to work the challenge must be always the same. if( socket_send(conn, (char *)challenge_key, CHALLENGESIZE, "challenge key to viewer") ) { logp(DEBUG, "Challenge sent to viewer (socket=%d).", conn); // Read the password. It will be treated as the repeater IDentifier. memset(challenge, 0, CHALLENGESIZE); if( socket_recv(conn, (char *)challenge, CHALLENGESIZE, "challenge response from viewer") ) { logp(DEBUG, "Viewer (socket=%d) sent challenge response.", conn); // Send Authentication response auth_response = Swap32IfLE(rfbVncAuthOK); if( socket_send(conn, (char *)&auth_response, sizeof(auth_response), "auth response to viewer") ) { logp(DEBUG, "Authentication response sent to viewer (socket=%d).", conn); // Retrieve ClientInit and save it inside the structure. if( socket_recv(conn, (char *)&client_init, sizeof(client_init), "ClientInit from viewer") ) { logp(DEBUG, "Viewer (socket=%d) sent ClientInit message.", conn); add_new_slot(INVALID_SOCKET, conn, challenge, -1); } } } } } } } } } notstopped = false; socket_close(thread_params->sock); log(INFO, "Viewer listening thread has exited."); return 0; }
rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w, int h) { zrleOutStream* zos; rfbFramebufferUpdateRectHeader rect; rfbZRLEHeader hdr; int i; if (cl->preferredEncoding == rfbEncodingZYWRLE) { if (cl->tightQualityLevel < 0) { cl->zywrleLevel = 1; } else if (cl->tightQualityLevel < 3) { cl->zywrleLevel = 3; } else if (cl->tightQualityLevel < 6) { cl->zywrleLevel = 2; } else { cl->zywrleLevel = 1; } } else cl->zywrleLevel = 0; if (!cl->zrleData) cl->zrleData = zrleOutStreamNew(); zos = cl->zrleData; zos->in.ptr = zos->in.start; zos->out.ptr = zos->out.start; switch (cl->format.bitsPerPixel) { case 8: zrleEncode8NE(x, y, w, h, zos, zrleBeforeBuf, cl); break; case 16: if (cl->format.greenMax > 0x1F) { if (cl->format.bigEndian) zrleEncode16BE(x, y, w, h, zos, zrleBeforeBuf, cl); else zrleEncode16LE(x, y, w, h, zos, zrleBeforeBuf, cl); } else { if (cl->format.bigEndian) zrleEncode15BE(x, y, w, h, zos, zrleBeforeBuf, cl); else zrleEncode15LE(x, y, w, h, zos, zrleBeforeBuf, cl); } break; case 32: { rfbBool fitsInLS3Bytes = ((cl->format.redMax << cl->format.redShift) < (1<<24) && (cl->format.greenMax << cl->format.greenShift) < (1<<24) && (cl->format.blueMax << cl->format.blueShift) < (1<<24)); rfbBool fitsInMS3Bytes = (cl->format.redShift > 7 && cl->format.greenShift > 7 && cl->format.blueShift > 7); if ((fitsInLS3Bytes && !cl->format.bigEndian) || (fitsInMS3Bytes && cl->format.bigEndian)) { if (cl->format.bigEndian) zrleEncode24ABE(x, y, w, h, zos, zrleBeforeBuf, cl); else zrleEncode24ALE(x, y, w, h, zos, zrleBeforeBuf, cl); } else if ((fitsInLS3Bytes && cl->format.bigEndian) || (fitsInMS3Bytes && !cl->format.bigEndian)) { if (cl->format.bigEndian) zrleEncode24BBE(x, y, w, h, zos, zrleBeforeBuf, cl); else zrleEncode24BLE(x, y, w, h, zos, zrleBeforeBuf, cl); } else { if (cl->format.bigEndian) zrleEncode32BE(x, y, w, h, zos, zrleBeforeBuf, cl); else zrleEncode32LE(x, y, w, h, zos, zrleBeforeBuf, cl); } } break; } rfbStatRecordEncodingSent(cl, rfbEncodingZRLE, sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader + ZRLE_BUFFER_LENGTH(&zos->out), + w * (cl->format.bitsPerPixel / 8) * h); if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader > UPDATE_BUF_SIZE) { if (!rfbSendUpdateBuf(cl)) return FALSE; } rect.r.x = Swap16IfLE(x); rect.r.y = Swap16IfLE(y); rect.r.w = Swap16IfLE(w); rect.r.h = Swap16IfLE(h); rect.encoding = Swap32IfLE(cl->preferredEncoding); memcpy(cl->updateBuf+cl->ublen, (char *)&rect, sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; hdr.length = Swap32IfLE(ZRLE_BUFFER_LENGTH(&zos->out)); memcpy(cl->updateBuf+cl->ublen, (char *)&hdr, sz_rfbZRLEHeader); cl->ublen += sz_rfbZRLEHeader; /* copy into updateBuf and send from there. Maybe should send directly? */ for (i = 0; i < ZRLE_BUFFER_LENGTH(&zos->out);) { int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; if (i + bytesToCopy > ZRLE_BUFFER_LENGTH(&zos->out)) { bytesToCopy = ZRLE_BUFFER_LENGTH(&zos->out) - i; } memcpy(cl->updateBuf+cl->ublen, (uint8_t*)zos->out.start + i, bytesToCopy); cl->ublen += bytesToCopy; i += bytesToCopy; if (cl->ublen == UPDATE_BUF_SIZE) { if (!rfbSendUpdateBuf(cl)) return FALSE; } } return TRUE; }
UINT vncEncodeXZ::EncodeBulkRects(const rfb::RectVector &allRects, BYTE *source, BYTE *dest, VSocket *outConn) { if (allRects.empty()) { return TRUE; } xzos->SetCompressLevel(m_compresslevel); mos->clear(); xzos->setUnderlying(mos); int nAllRects = allRects.size(); rfb::RectVector::const_iterator i; for (i=allRects.begin();i!=allRects.end();i++) { const rfb::Rect& rect(*i); rfbRectangle rectangle; rectangle.x = Swap16IfLE(rect.tl.x-m_SWOffsetx); rectangle.y = Swap16IfLE(rect.tl.y-m_SWOffsety); rectangle.w = Swap16IfLE(rect.br.x - rect.tl.x); rectangle.h = Swap16IfLE(rect.br.y - rect.tl.y); xzos->writeBytes((const void*)&rectangle, sz_rfbRectangle); } for (i=allRects.begin();i!=allRects.end();i++) { const rfb::Rect& rect(*i); int x = rect.tl.x; int y = rect.tl.y; int w = rect.br.x - x; int h = rect.br.y - y; EncodeRect_Internal(source, x, y, w, h); } xzos->flush(); const void* pDataBytes = mos->data(); int nDataLength = mos->length(); assert(nDataLength > 0); rfbFramebufferUpdateRectHeader surh; if( m_use_xzyw ){ surh.encoding = Swap32IfLE(rfbEncodingXZYW); }else{ surh.encoding = Swap32IfLE(rfbEncodingXZ); } int nAllRectsHigh = (nAllRects & 0xFFFF0000) >> 16; int nAllRectsLow = (nAllRects & 0x0000FFFF); int nDataLengthHigh = (nDataLength & 0xFFFF0000) >> 16; int nDataLengthLow = (nDataLength & 0x0000FFFF); surh.r.x = Swap16IfLE(nAllRectsHigh); surh.r.y = Swap16IfLE(nAllRectsLow); surh.r.w = Swap16IfLE(nDataLengthHigh); surh.r.h = Swap16IfLE(nDataLengthLow); UINT nTotalLength = 0; if (!outConn->SendExact((const char*)&surh, sz_rfbFramebufferUpdateRectHeader)) { return FALSE; } nTotalLength += sz_rfbFramebufferUpdateRectHeader; if (!outConn->SendExact((const char*)pDataBytes, nDataLength)) { return FALSE; } nTotalLength += nDataLength; return nDataLength > 0 ? TRUE : FALSE; }
// Encode the rectangle using zlib compression inline UINT vncEncodeUltra::EncodeOneRect(BYTE *source, BYTE *dest, const RECT &rect,VSocket *outConn) { const int rectW = rect.right - rect.left; const int rectH = rect.bottom - rect.top; const int rawDataSize = (rectW*rectH*m_remoteformat.bitsPerPixel / 8); const int maxCompSize = (rawDataSize + (rawDataSize/100) + 8); // Create the rectangle header rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; // Modif rdv@2002 - v1.1.x - Application Resize surh->r.x = (CARD16) rect.left-m_SWOffsetx; surh->r.y = (CARD16) rect.top-m_SWOffsety; surh->r.w = (CARD16) (rectW); surh->r.h = (CARD16) (rectH); surh->r.x = Swap16IfLE(surh->r.x); surh->r.y = Swap16IfLE(surh->r.y); surh->r.w = Swap16IfLE(surh->r.w); surh->r.h = Swap16IfLE(surh->r.h); surh->encoding = Swap32IfLE(rfbEncodingUltra); dataSize += ( rectW * rectH * m_remoteformat.bitsPerPixel) / 8; rectangleOverhead += sz_rfbFramebufferUpdateRectHeader; // create a space big enough for the Zlib encoded pixels if (m_bufflen < rawDataSize) { if (m_buffer != NULL) { delete [] m_buffer; m_buffer = NULL; } m_buffer = new BYTE [rawDataSize+1]; if (m_buffer == NULL) return vncEncoder::EncodeRect(source, dest, rect); m_bufflen = rawDataSize; } // Translate the data into our new buffer Translate(source, m_buffer, rect); // Perhaps we can queue the small updates and compress them combined if (rawDataSize < VNC_ENCODE_ULTRA_MIN_COMP_SIZE) { if (m_queueEnable) { surh->encoding = Swap32IfLE(rfbEncodingRaw); memcpy(dest+sz_rfbFramebufferUpdateRectHeader,m_buffer,rawDataSize); AddToQueu(dest,sz_rfbFramebufferUpdateRectHeader +rawDataSize,outConn,0); return 0; } else return vncEncoder::EncodeRect(source, dest, rect); } if (rawDataSize<1000 && m_queueEnable) { surh->encoding = Swap32IfLE(rfbEncodingRaw); memcpy(dest+sz_rfbFramebufferUpdateRectHeader,m_buffer,rawDataSize); AddToQueu(dest,sz_rfbFramebufferUpdateRectHeader +rawDataSize,outConn,1); return 0; } surh->encoding = Swap32IfLE(rfbEncodingUltra); if (lzo==false) { if (lzo_init() == LZO_E_OK) lzo=true; } lzo1x_1_compress(m_buffer,rawDataSize,dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbZlibHeader,&out_len,wrkmem); if (out_len > (lzo_uint)rawDataSize) { return vncEncoder::EncodeRect(source, dest, rect); } // Format the ZlibHeader rfbZlibHeader *zlibh=(rfbZlibHeader *)(dest+sz_rfbFramebufferUpdateRectHeader); zlibh->nBytes = Swap32IfLE(out_len); // Update statistics encodedSize += sz_rfbZlibHeader + out_len; rectangleOverhead += sz_rfbFramebufferUpdateRectHeader; // Return the amount of data sent return sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + out_len; }