// ========================================================================= // 函数功能:处理客户端对挑战信息的响应 // 输入参数:待交流的客户端cl // 输出参数: // 返回值 : // 说明 :当响应消息失败时,3.7以上的版本会发送失败的原因,而3.7及其以下会直接 // 关闭客户端 // ========================================================================= void rfbAuthProcessClientMessage(rfbClientPtr cl) { char *passwd="123"; int n; u8 response[CHALLENGESIZE]; u32 authResult; if ((n = ReadExact(cl, (char *)response, CHALLENGESIZE)) <= 0) { if (n != 0) debug_printf("rfbAuthProcessClientMessage: read"); rfbCloseClient(cl); return; } rfbEncryptBytes(cl->authChallenge, passwd); if (memcmp(cl->authChallenge, response, CHALLENGESIZE) != 0) { debug_printf("rfbAuthProcessClientMessage: authentication failed from %s\n", cl->host); authResult = Swap32IfLE(rfbVncAuthFailed); if (WriteExact(cl, (char *)&authResult, 4) < 0) { debug_printf("rfbAuthProcessClientMessage: write"); rfbClientSendString(cl,"challengdge failed\n"); } rfbCloseClient(cl); return; } else { debug_printf("challendge success ---cl=%s",cl->host); } authResult = Swap32IfLE(rfbVncAuthOK); if (WriteExact(cl, (char *)&authResult, 4) < 0) { debug_printf("rfbAuthProcessClientMessage: write"); rfbCloseClient(cl); return; } cl->state = RFB_INITIALISATION; }
void rfbProcessClientSecurityType(rfbClientPtr cl) { int n; uint8_t chosenType; rfbSecurityHandler* handler; /* Read the security type. */ n = rfbReadExact(cl, (char *)&chosenType, 1); if (n <= 0) { if (n == 0) rfbLog("rfbProcessClientSecurityType: client gone\n"); else rfbLogPerror("rfbProcessClientSecurityType: read"); rfbCloseClient(cl); return; } /* Make sure it was present in the list sent by the server. */ for (handler = securityHandlers; handler; handler = handler->next) { if (chosenType == handler->type) { rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType); handler->handler(cl); return; } } rfbLog("rfbProcessClientSecurityType: wrong security type (%d) requested\n", chosenType); rfbCloseClient(cl); }
/* * rfbSendFence sends a fence message to a specific client */ Bool rfbSendFence(rfbClientPtr cl, CARD32 flags, unsigned len, const char *data) { rfbFenceMsg f; if (!cl->enableFence) { rfbLog("ERROR in rfbSendFence: Client does not support fence extension\n"); return FALSE; } if (len > 64) { rfbLog("ERROR in rfbSendFence: Fence payload is too large\n"); return FALSE; } if ((flags & ~rfbFenceFlagsSupported) != 0) { rfbLog("ERROR in rfbSendFence: Unknown fence flags\n"); return FALSE; } f.type = rfbFence; f.flags = Swap32IfLE(flags); f.length = len; if (WriteExact(cl, (char *)&f, sz_rfbFenceMsg) < 0) { rfbLogPerror("rfbSendFence: write"); rfbCloseClient(cl); return FALSE; } if (WriteExact(cl, (char *)data, len) < 0) { rfbLogPerror("rfbSendFence: write"); rfbCloseClient(cl); return FALSE; } return TRUE; }
/* * Tell the client what security type will be used (protocol 3.3). */ static void rfbSendSecurityType(rfbClientPtr cl, int32_t securityType) { uint32_t value32; /* Send the value. */ value32 = Swap32IfLE(securityType); if (rfbWriteExact(cl, (char *)&value32, 4) < 0) { rfbLogPerror("rfbSendSecurityType: write"); rfbCloseClient(cl); return; } /* Decide what to do next. */ switch (securityType) { case rfbSecTypeNone: /* Dispatch client input to rfbProcessClientInitMessage. */ cl->state = RFB_INITIALISATION; break; case rfbSecTypeVncAuth: /* Begin the standard VNC authentication procedure. */ rfbVncAuthSendChallenge(cl); break; default: /* Impossible case (hopefully). */ rfbLogPerror("rfbSendSecurityType: assertion failed"); rfbCloseClient(cl); } }
void HandleFileDownloadCancelRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) { int n = 0; char *reason = NULL; rfbClientToServerTightMsg msg; memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadCancelMsg-1)) <= 0) { if (n < 0) rfbLog("File [%s]: Method [%s]: Error while reading " "FileDownloadCancelMsg\n", __FILE__, __FUNCTION__); rfbCloseClient(cl); return; } msg.fdc.reasonLen = Swap16IfLE(msg.fdc.reasonLen); if(msg.fdc.reasonLen == 0) { rfbLog("File [%s]: Method [%s]: reason length received is Zero\n", __FILE__, __FUNCTION__); return; } reason = (char*) calloc(msg.fdc.reasonLen + 1, sizeof(char)); if(reason == NULL) { rfbLog("File [%s]: Method [%s]: Fatal Error: Memory alloc failed\n", __FILE__, __FUNCTION__); return; } if((n = rfbReadExact(cl, reason, msg.fdc.reasonLen)) <= 0) { if (n < 0) rfbLog("File [%s]: Method [%s]: Error while reading " "FileDownloadCancelMsg\n", __FILE__, __FUNCTION__); rfbCloseClient(cl); } rfbLog("File [%s]: Method [%s]: File Download Cancel Request received:" " reason <%s>\n", __FILE__, __FUNCTION__, reason); pthread_mutex_lock(&fileDownloadMutex); CloseUndoneFileTransfer(cl, rtcp); pthread_mutex_unlock(&fileDownloadMutex); if(reason != NULL) { free(reason); reason = NULL; } }
void rfbProcessClientAuthType(rfbClientPtr cl) { uint32_t auth_type; int n, i; rfbTightClientPtr rtcp = rfbGetTightClientData(cl); rfbLog("tightvnc-filetransfer/rfbProcessClientAuthType\n"); if(rtcp == NULL) return; /* Read authentication type selected by the client. */ n = rfbReadExact(cl, (char *)&auth_type, sizeof(auth_type)); if (n <= 0) { if (n == 0) rfbLog("rfbProcessClientAuthType: client gone\n"); else rfbLogPerror("rfbProcessClientAuthType: read"); rfbCloseClient(cl); return; } auth_type = Swap32IfLE(auth_type); /* Make sure it was present in the list sent by the server. */ for (i = 0; i < rtcp->nAuthCaps; i++) { if (auth_type == rtcp->authCaps[i]) break; } if (i >= rtcp->nAuthCaps) { rfbLog("rfbProcessClientAuthType: " "wrong authentication type requested\n"); rfbCloseClient(cl); return; } switch (auth_type) { case rfbAuthNone: /* Dispatch client input to rfbProcessClientInitMessage. */ #ifdef USE_SECTYPE_TIGHT_FOR_RFB_3_8 SECTYPE_TIGHT_FOR_RFB_3_8 #endif cl->state = RFB_INITIALISATION; break; case rfbAuthVNC: rfbVncAuthSendChallenge(cl); break; default: rfbLog("rfbProcessClientAuthType: unknown authentication scheme\n"); rfbCloseClient(cl); } }
// ========================================================================= // 函数功能:处理客户端的安全类型信息 // 输入参数:待交流的客户端cl // 输出参数: // 返回值 : // 说明 : 只有3.7及其以上版本的server才会让cl选择安全类型 // =========================================================================void void rfbProcessClientSecurityType(rfbClientPtr cl) { int n; u8 chosenType; u32 authResult; /* Read the security type. */ n = ReadExact(cl, (char *)&chosenType, 1); if (n <= 0) { if (n == 0) debug_printf("rfbProcessClientSecurityType: client gone\n"); else debug_printf("rfbProcessClientSecurityType: read"); rfbCloseClient(cl); return; } /* Make sure it was present in the list sent by the server. */ switch (chosenType) { case rfbConnFailed: debug_printf("The client %s connfailed!\n",cl->host); cl->state = RFB_INITIALISATION; break; case rfbNoAuth: debug_printf("The client %s need no auth!\n",cl->host); //对于3.8版本仍然需要把结果返还回去 if((cl->protocolMajorVersion==3)&&(cl->protocolMinorVersion>7)) { authResult = Swap32IfLE(rfbVncAuthOK); if (WriteExact(cl, (char *)&authResult, 4) < 0) { debug_printf("rfbAuthProcessClientMessage: write"); rfbCloseClient(cl); break; } } cl->state = RFB_INITIALISATION; break; case rfbVncAuth: debug_printf("The client %s need vncauth!\n",cl->host); rfbVncAuthSendChallenge(cl);//发送挑战信息 break; default: debug_printf("No supported security method--%d\n",chosenType); rfbCloseClient(cl); break; } return; }
void HandleFileCreateDirRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) { int n = 0; char dirName[PATH_MAX]; rfbClientToServerTightMsg msg; memset(dirName, 0, PATH_MAX); memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); if(cl == NULL) { rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n", __FILE__, __FUNCTION__); return; } if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileCreateDirRequestMsg-1)) <= 0) { if (n < 0) rfbLog("File [%s]: Method [%s]: Error while reading FileCreateDirRequestMsg\n", __FILE__, __FUNCTION__); rfbCloseClient(cl); return; } msg.fcdr.dNameLen = Swap16IfLE(msg.fcdr.dNameLen); /* TODO :: chk if the dNameLen is greater than PATH_MAX */ if((n = rfbReadExact(cl, dirName, msg.fcdr.dNameLen)) <= 0) { if (n < 0) rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n", __FILE__, __FUNCTION__); rfbCloseClient(cl); return; } if(ConvertPath(dirName) == NULL) { rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n", __FILE__, __FUNCTION__); return; } CreateDirectory(dirName); }
static rfbBool rfbSetClientColourMapBGR233(rfbClientPtr cl) { char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; uint16_t *rgb = (uint16_t *)(&buf[sz_rfbSetColourMapEntriesMsg]); int i, len; int r, g, b; if (cl->format.bitsPerPixel != 8 ) { ///rfbErr("%s: client not 8 bits per pixel\n", /// "rfbSetClientColourMapBGR233"); rfbCloseClient(cl); return FALSE; } scme->type = rfbSetColourMapEntries; scme->firstColour = Swap16IfLE(0); scme->nColours = Swap16IfLE(256); len = sz_rfbSetColourMapEntriesMsg; i = 0; for (b = 0; b < 4; b++) { for (g = 0; g < 8; g++) { for (r = 0; r < 8; r++) { rgb[i++] = Swap16IfLE(r * 65535 / 7); rgb[i++] = Swap16IfLE(g * 65535 / 7); rgb[i++] = Swap16IfLE(b * 65535 / 3); } } } len += 256 * 3 * 2; if (rfbWriteExact(cl, buf, len) < 0) { ///rfbLogPerror("rfbSetClientColourMapBGR233: write"); rfbCloseClient(cl); return FALSE; } return TRUE; }
//! handle request for a bounding sphere update rfbBool VncServer::handleBoundsMessage(rfbClientPtr cl, void *data, const rfbClientToServerMsg *message) { if (message->type != rfbBounds) return FALSE; if (!cl->clientData) { cl->clientData = new ClientData(); } ClientData *cd = static_cast<ClientData *>(cl->clientData); cd->supportsBounds = true; boundsMsg msg; int n = rfbReadExact(cl, ((char *)&msg)+1, sizeof(msg)-1); if (n <= 0) { if (n!= 0) rfbLogPerror("handleBoundsMessage: read"); rfbCloseClient(cl); return TRUE; } if (msg.sendreply) { std::cout << "SENDING BOUNDS" << std::endl; sendBoundsMessage(cl); } return TRUE; }
void HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize) { char *path = NULL; int n = 0; if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) { rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n", __FILE__, __FUNCTION__); return; } if((n = rfbReadExact(cl, path, fNameSize)) <= 0) { if (n < 0) rfbLog("File [%s]: Method [%s]: Error while reading dir name\n", __FILE__, __FUNCTION__); rfbCloseClient(cl); if(path != NULL) { free(path); path = NULL; } return; } if(path != NULL) { free(path); path = NULL; } SendFileDownloadLengthErrMsg(cl); }
void* RunFileDownloadThread(void* client) { rfbClientPtr cl = (rfbClientPtr) client; rfbTightClientPtr rtcp = rfbGetTightClientData(cl); FileTransferMsg fileDownloadMsg; if(rtcp == NULL) return NULL; memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg)); do { pthread_mutex_lock(&fileDownloadMutex); fileDownloadMsg = GetFileDownloadResponseMsgInBlocks(cl, rtcp); pthread_mutex_unlock(&fileDownloadMutex); if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) { if(rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length) < 0) { rfbLog("File [%s]: Method [%s]: Error while writing to socket \n" , __FILE__, __FUNCTION__); if(cl != NULL) { rfbCloseClient(cl); CloseUndoneFileTransfer(cl, rtcp); } FreeFileTransferMsg(fileDownloadMsg); return NULL; } FreeFileTransferMsg(fileDownloadMsg); } } while(rtcp->rcft.rcfd.downloadInProgress == TRUE); return NULL; }
static void rfbProcessClientInitMessage(rfbClientPtr cl) { rfbClientInitMsg ci; char buf[256]; rfbServerInitMsg *si = (rfbServerInitMsg *)buf; int len, n; if ((n = ReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) { if (n == 0) debug_printf("rfbProcessClientInitMessage: client gone\n"); else debug_printf("rfbProcessClientInitMessage: read"); rfbCloseClient(cl); return; } si->framebufferWidth = Swap16IfLE(cl->screen->width); si->framebufferHeight = Swap16IfLE(cl->screen->height); debug_printf("width=%d hieght=%d\n",cl->screen->width,cl->screen->height); si->format = cl->screen->rfbServerFormat; si->format.redMax = Swap16IfLE(si->format.redMax); si->format.greenMax = Swap16IfLE(si->format.greenMax); si->format.blueMax = Swap16IfLE(si->format.blueMax); if (strlen(cl->screen->desktopName) > 128) /* sanity check on desktop name len */ cl->screen->desktopName[128] = 0; strcpy(buf + sz_rfbServerInitMsg, cl->screen->desktopName); len = strlen(buf + sz_rfbServerInitMsg); si->nameLength = Swap32IfLE(len); if (WriteExact(cl, buf, sz_rfbServerInitMsg + len) < 0) { debug_printf("rfbProcessClientInitMessage: write"); rfbCloseClient(cl); return; } cl->state = RFB_NORMAL; if(ci.shared) { debug_printf("The client permit share!\n"); } else { debug_printf("The client refused share!\n"); } //关于是否共享的问题,以后再谈 }
//! handle light update message rfbBool VncServer::handleLightsMessage(rfbClientPtr cl, void *data, const rfbClientToServerMsg *message) { if (message->type != rfbLights) return FALSE; lightsMsg msg; int n = rfbReadExact(cl, ((char *)&msg)+1, sizeof(msg)-1); if (n <= 0) { if (n!= 0) rfbLogPerror("handleLightsMessage: read"); rfbCloseClient(cl); return TRUE; } if (!cl->clientData) { cl->clientData = new ClientData(); } ClientData *cd = static_cast<ClientData *>(cl->clientData); cd->supportsLights = true; #define SET_VEC(d, dst, src) \ do { \ for (int k=0; k<d; ++k) { \ (dst)[k] = (src)[k]; \ } \ } while(false) std::vector<Light> newLights; for (int i=0; i<lightsMsg::NumLights; ++i) { const auto &cl = msg.lights[i]; newLights.emplace_back(); auto &l = newLights.back(); SET_VEC(4, l.position, cl.position); SET_VEC(4, l.ambient, cl.ambient); SET_VEC(4, l.diffuse, cl.diffuse); SET_VEC(4, l.specular, cl.specular); SET_VEC(3, l.attenuation, cl.attenuation); SET_VEC(3, l.direction, cl.spot_direction); l.spotCutoff = cl.spot_cutoff; l.spotExponent = cl.spot_exponent; l.enabled = cl.enabled; //std::cerr << "Light " << i << ": ambient: " << l.ambient << std::endl; //std::cerr << "Light " << i << ": diffuse: " << l.diffuse << std::endl; } std::swap(plugin->lights, newLights); if (plugin->lights != newLights) { ++plugin->lightsUpdateCount; std::cerr << "handleLightsMessage: lights changed" << std::endl; } //std::cerr << "handleLightsMessage: " << plugin->lights.size() << " lights received" << std::endl; return TRUE; }
void rfbProcessClientTunnelingType(rfbClientPtr cl) { /* If we were called, then something's really wrong. */ rfbLog("rfbProcessClientTunnelingType: not implemented\n"); rfbCloseClient(cl); return; }
static void rfbSendAuthCaps(rfbClientPtr cl) { rfbAuthenticationCapsMsg caps; rfbCapabilityInfo caplist[MAX_AUTH_CAPS]; int count = 0; rfbTightClientPtr rtcp = rfbGetTightClientData(cl); rfbLog("tightvnc-filetransfer/rfbSendAuthCaps\n"); if(rtcp == NULL) return; if (cl->screen->authPasswdData && !cl->reverseConnection) { /* chk if this condition is valid or not. */ SetCapInfo(&caplist[count], rfbAuthVNC, rfbStandardVendor); rtcp->authCaps[count++] = rfbAuthVNC; } rtcp->nAuthCaps = count; caps.nAuthTypes = Swap32IfLE((uint32_t)count); if (rfbWriteExact(cl, (char *)&caps, sz_rfbAuthenticationCapsMsg) < 0) { rfbLogPerror("rfbSendAuthCaps: write"); rfbCloseClient(cl); return; } if (count) { if (rfbWriteExact(cl, (char *)&caplist[0], count * sz_rfbCapabilityInfo) < 0) { rfbLogPerror("rfbSendAuthCaps: write"); rfbCloseClient(cl); return; } /* Dispatch client input to rfbProcessClientAuthType. */ /* Call the function for authentication from here */ rfbProcessClientAuthType(cl); } else { #ifdef USE_SECTYPE_TIGHT_FOR_RFB_3_8 SECTYPE_TIGHT_FOR_RFB_3_8 #endif /* Dispatch client input to rfbProcessClientInitMessage. */ cl->state = RFB_INITIALISATION; } }
static void rfbProcessClientProtocolVersion(rfbClientPtr cl) { rfbProtocolVersionMsg pv; int n, major, minor; char failureReason[256]; if ((n = ReadExact(cl, pv, sz_rfbProtocolVersionMsg)) <= 0) { if (n == 0) debug_printf("rfbProcessClientProtocolVersion: client gone\n"); else debug_printf("rfbProcessClientProtocolVersion: read"); rfbCloseClient(cl); return; } pv[sz_rfbProtocolVersionMsg] = 0; if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { debug_printf("rfbProcessClientProtocolVersion: not a valid RFB client\n"); rfbCloseClient(cl); return; } debug_printf("Protocol version %d.%d\n", major, minor); if (major != rfbProtocolMajorVersion) { /* Major version mismatch - send a ConnFailed message */ debug_printf("Major version mismatch\n"); sprintf(failureReason, "RFB protocol version mismatch - server %d.%d, client %d.%d", rfbProtocolMajorVersion,rfbProtocolMinorVersion,major,minor); rfbClientConnFailed(cl, failureReason); return; } if (minor != rfbProtocolMinorVersion) { /* Minor version mismatch - warn but try to continue */ debug_printf("Ignoring minor version mismatch\n"); } //每个客户端都会发送自己的proto cl->protocolMajorVersion=major; cl->protocolMinorVersion=minor; rfbAuthNewClient(cl); }
//! handle image tile request by client rfbBool VncServer::handleTileMessage(rfbClientPtr cl, void *data, const rfbClientToServerMsg *message) { if (message->type != rfbTile) return FALSE; if (!cl->clientData) { cl->clientData = new ClientData(); } ClientData *cd = static_cast<ClientData *>(cl->clientData); if (!cd->supportsTile) { ++plugin->m_numRhrClients; std::cerr << "VncServer: RHR client connected (#RHR: " << plugin->m_numClients << ", #total: " << plugin->m_numClients << ")" << std::endl; } cd->supportsTile = true; tileMsg msg; int n = rfbReadExact(cl, ((char *)&msg)+1, sizeof(msg)-1); if (n <= 0) { if (n!= 0) rfbLogPerror("handleTileMessage: read"); rfbCloseClient(cl); return TRUE; } cd->tileCompressions = msg.compression; std::vector<char> buf(msg.size); n = rfbReadExact(cl, &buf[0], msg.size); if (n <= 0) { if (n!= 0) rfbLogPerror("handleTileMessage: read data"); rfbCloseClient(cl); return TRUE; } if (msg.flags & rfbTileRequest) { std::cerr << "VncServer: tile request ignored" << std::endl; // FIXME //sendDepthMessage(cl); } return TRUE; }
void rfbAuthProcessClientMessage(rfbClientPtr cl) { int n; uint8_t response[CHALLENGESIZE]; uint32_t authResult; if ((n = rfbReadExact(cl, (char *)response, CHALLENGESIZE)) <= 0) { if (n != 0) rfbLogPerror("rfbAuthProcessClientMessage: read"); rfbCloseClient(cl); return; } //uptill now, we don't chk the passwd, we do it later --TODO // if(!cl->screen->passwordCheck(cl,(const char*)response,CHALLENGESIZE)) { // rfbErr("rfbAuthProcessClientMessage: password check failed\n"); // authResult = Swap32IfLE(rfbVncAuthFailed); // if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) { // rfbLogPerror("rfbAuthProcessClientMessage: write"); // } // /* support RFB 3.8 clients, they expect a reason *why* it was disconnected */ // if (cl->protocolMinorVersion > 7) { // rfbClientSendString(cl, "password check failed!"); // } // else // rfbCloseClient(cl); // return; // } authResult = Swap32IfLE(rfbVncAuthOK); if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); rfbCloseClient(cl); return; } cl->state = RFB_INITIALISATION; }
rfbTightClientPtr rfbGetTightClientData(rfbClientPtr cl) { rfbTightClientPtr rtcp = (rfbTightClientPtr) rfbGetExtensionClientData(cl, &tightVncFileTransferExtension); if(rtcp == NULL) { rfbLog("Extension client data is null, closing the connection !\n"); rfbCloseClient(cl); } return rtcp; }
void rfbShutdownServer(rfbScreenInfoPtr screen,rfbBool disconnectClients) { if(disconnectClients) { rfbClientPtr cl; rfbClientIteratorPtr iter = rfbGetClientIterator(screen); while( (cl = rfbClientIteratorNext(iter)) ) if (cl->sock > -1) /* we don't care about maxfd here, because the server goes away */ rfbCloseClient(cl); rfbReleaseClientIterator(iter); } rfbShutdownSockets(screen); rfbHttpShutdownSockets(screen); }
static void rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) { /* The size of the message is the count of security types +1, * since the first byte is the number of types. */ int size = 1; rfbSecurityHandler* handler; #define MAX_SECURITY_TYPES 255 uint8_t buffer[MAX_SECURITY_TYPES+1]; /* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */ switch (primaryType) { case rfbSecTypeNone: rfbRegisterSecurityHandler(&VncSecurityHandlerNone); break; case rfbSecTypeVncAuth: rfbRegisterSecurityHandler(&VncSecurityHandlerVncAuth); break; } for (handler = securityHandlers; handler && size<MAX_SECURITY_TYPES; handler = handler->next) { buffer[size] = handler->type; size++; } buffer[0] = (unsigned char)size-1; /* Send the list. */ if (rfbWriteExact(cl, (char *)buffer, size) < 0) { rfbLogPerror("rfbSendSecurityTypeList: write"); rfbCloseClient(cl); return; } /* * if count is 0, we need to send the reason and close the connection. */ if(size <= 1) { /* This means total count is Zero and so reason msg should be sent */ /* The execution should never reach here */ char* reason = "No authentication mode is registered!"; rfbClientSendString(cl, reason); return; } /* Dispatch client input to rfbProcessClientSecurityType. */ cl->state = RFB_SECURITY_TYPE; }
rfbTightClientPtr rfbGetTightClientData(rfbClientPtr cl) { rfbExtensionData* data = cl->extensions; while(data && data->extension != &tightVncFileTransferExtension) data = data->next; if(data == NULL) { rfbLog("TightVNC enabled, but client data missing?!\n"); rfbCloseClient(cl); return NULL; } return (rfbTightClientPtr)data->data; }
// ========================================================================= // 函数功能:处理连接失败的善后问题 // 输入参数:待连接的客户cl,连接失败的原因 // 输出参数: // 返回值 : // 说明 :当在协议版本协商或者是认证的时候失败,那么都会调用这个函数进行善后 // ========================================================================= void rfbClientConnFailed(rfbClientPtr cl,char *reason) { char *buf; int len = strlen(reason); buf = (char *)malloc(8 + len); ((u32 *)buf)[0] = Swap32IfLE(rfbConnFailed); ((u32 *)buf)[1] = Swap32IfLE(len); memcpy(buf + 8, reason, len); if (WriteExact(cl, buf, 8 + len) < 0) debug_printf("rfbClientConnFailed: write"); free(buf); rfbCloseClient(cl); }
/* * rfbSendEndOfCU sends an end of Continuous Updates message to a specific * client */ void rfbSendEndOfCU(rfbClientPtr cl) { char type = rfbEndOfContinuousUpdates; if (!cl->enableCU) { rfbLog("ERROR in rfbSendEndOfCU: Client does not support Continuous Updates\n"); return; } if (WriteExact(cl, &type, 1) < 0) { rfbLogPerror("rfbSendEndOfCU: write"); rfbCloseClient(cl); return; } }
static void rfbVncAuthSendChallenge(rfbClientPtr cl) { /* 4 byte header is alreay sent. Which is rfbSecTypeVncAuth (same as rfbVncAuth). Just send the challenge. */ rfbRandomBytes(cl->authChallenge); if (rfbWriteExact(cl, (char *)cl->authChallenge, CHALLENGESIZE) < 0) { rfbLogPerror("rfbAuthNewClient: write"); rfbCloseClient(cl); return; } /* Dispatch client input to rfbVncAuthProcessResponse. */ cl->state = RFB_AUTHENTICATION; }
int rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours) { char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; char *wbuf = buf; rfbSetColourMapEntriesMsg *scme; unsigned short *rgb; int i, len; if (nColours > 256) { /* some rare hardware has, e.g., 4096 colors cells: PseudoColor:12 */ wbuf = (char *) malloc(sz_rfbSetColourMapEntriesMsg + nColours * 3 * 2); } scme = (rfbSetColourMapEntriesMsg *)wbuf; rgb = (u16 *)(&wbuf[sz_rfbSetColourMapEntriesMsg]); scme->type = rfbSetColourMapEntries; scme->firstColour = Swap16IfLE(firstColour); scme->nColours = Swap16IfLE(nColours); len = sz_rfbSetColourMapEntriesMsg; for (i = 0; i < nColours; i++) { rgb[i*3] = Swap16IfLE(i); rgb[i*3+1] = Swap16IfLE(i); rgb[i*3+2] = Swap16IfLE(i); } len += nColours * 3 * 2; if (WriteExact(cl, wbuf, len) < 0) { debug_printf("rfbSendSetColourMapEntries: write"); rfbCloseClient(cl); if (wbuf != buf) free(wbuf); return FALSE; } if (wbuf != buf) free(wbuf); return TRUE; }
static void rfbVncAuthSendChallenge(rfbClientPtr cl) { rfbLog("tightvnc-filetransfer/rfbVncAuthSendChallenge\n"); /* 4 byte header is alreay sent. Which is rfbSecTypeVncAuth (same as rfbVncAuth). Just send the challenge. */ rfbRandomBytes(cl->authChallenge); if (rfbWriteExact(cl, (char *)cl->authChallenge, CHALLENGESIZE) < 0) { rfbLogPerror("rfbAuthNewClient: write"); rfbCloseClient(cl); return; } /* Dispatch client input to rfbVncAuthProcessResponse. */ /* This methos is defined in auth.c file */ rfbAuthProcessClientMessage(cl); }
//! handle matrix update message rfbBool VncServer::handleMatricesMessage(rfbClientPtr cl, void *data, const rfbClientToServerMsg *message) { if (message->type != rfbMatrices) return FALSE; matricesMsg msg; int n = rfbReadExact(cl, ((char *)&msg)+1, sizeof(msg)-1); if (n <= 0) { if (n!= 0) rfbLogPerror("handleMatricesMessage: read"); rfbCloseClient(cl); return TRUE; } size_t viewNum = msg.viewNum >= 0 ? msg.viewNum : 0; if (viewNum >= plugin->m_viewData.size()) { plugin->m_viewData.resize(viewNum+1); } plugin->resize(viewNum, msg.width, msg.height); ViewData &vd = plugin->m_viewData[viewNum]; vd.nparam.matrixTime = msg.time; vd.nparam.requestNumber = msg.requestNumber; for (int i=0; i<16; ++i) { vd.nparam.proj.data()[i] = msg.proj[i]; vd.nparam.view.data()[i] = msg.view[i]; vd.nparam.model.data()[i] = msg.model[i]; } //std::cerr << "handleMatrices: view " << msg.viewNum << ", proj: " << vd.nparam.proj << std::endl; if (msg.last) { for (int i=0; i<plugin->numViews(); ++i) { plugin->m_viewData[i].param = plugin->m_viewData[i].nparam; } } return TRUE; }
static void handle_xrandr_change(int new_x, int new_y) { rfbClientIteratorPtr iter; rfbClientPtr cl; RAWFB_RET_VOID /* assumes no X_LOCK */ /* sanity check xrandr_mode */ if (! xrandr_mode) { xrandr_mode = strdup("default"); } else if (! known_xrandr_mode(xrandr_mode)) { free(xrandr_mode); xrandr_mode = strdup("default"); } rfbLog("xrandr_mode: %s\n", xrandr_mode); if (!strcmp(xrandr_mode, "exit")) { close_all_clients(); rfbLog(" shutting down due to XRANDR event.\n"); clean_up_exit(0); } if (!strcmp(xrandr_mode, "newfbsize") && screen) { iter = rfbGetClientIterator(screen); while( (cl = rfbClientIteratorNext(iter)) ) { if (cl->useNewFBSize) { continue; } rfbLog(" closing client %s (no useNewFBSize" " support).\n", cl->host); rfbCloseClient(cl); rfbClientConnectionGone(cl); } rfbReleaseClientIterator(iter); } /* default, resize, and newfbsize create a new fb: */ rfbLog("check_xrandr_event: trying to create new framebuffer...\n"); if (new_x < wdpy_x || new_y < wdpy_y) { check_black_fb(); } do_new_fb(1); rfbLog("check_xrandr_event: fb WxH: %dx%d\n", wdpy_x, wdpy_y); }