void SharedDaemon::AddNewClient(const std::string &host, const stringVector &args, void *cbdata) { /// Send appropriate message for TCP or WebConnection void** data = (void**)cbdata; ConnectionType typeOfConnection = *((ConnectionType*)(data[0])); QAbstractSocket* socket = static_cast<QAbstractSocket*>(data[1]); ViewerState* viewerState = static_cast<ViewerState*>(data[2]); JSONNode node; QString hostname = typeOfConnection == TcpConnection ? socket->localAddress().toString(): dynamic_cast<QWsSocket*>(socket)->internalSocket()->localAddress().toString(); if(hostMap.contains(hostname)) hostname = hostMap[hostname]; node["host"] = hostname.toStdString(); //host node["port"] = args[7]; //port node["version"] = args[2]; //version node["securityKey"] = args[9]; //key node["numStates"] = viewerState->GetNumStateObjects(); //number of states JSONNode::JSONArray rpc_array = JSONNode::JSONArray(); for(size_t i = 0; i < ViewerRPC::MaxRPC; ++i) { rpc_array.push_back(ViewerRPC::ViewerRPCType_ToString((ViewerRPC::ViewerRPCType)i)); } node["rpc_array"] = rpc_array; if(typeOfConnection == TcpConnection) { QTcpSocket *tsocket = dynamic_cast<QTcpSocket*>(socket); std::string message = node.ToString(); tsocket->write(message.c_str(),message.length()); if(tsocket->state() != QAbstractSocket::UnconnectedState) tsocket->waitForBytesWritten(); tsocket->disconnectFromHost(); if(tsocket->state() != QAbstractSocket::UnconnectedState) tsocket->waitForDisconnected(); //HKTODO: Do not delete connection (test fix for ORNL machines) //tsocket->deleteLater(); } else { QWsSocket *wsocket = dynamic_cast<QWsSocket*>(socket); wsocket->write(QString(node.ToString().c_str())); wsocket->flush(); if(wsocket->internalSocket()->state() != QAbstractSocket::UnconnectedState) wsocket->internalSocket()->waitForBytesWritten(); wsocket->close(""); wsocket->internalSocket()->disconnectFromHost(); if(wsocket->internalSocket()->state() != QAbstractSocket::UnconnectedState) wsocket->internalSocket()->waitForDisconnected(); wsocket->deleteLater(); } }
void SharedDaemon::AddNewClient(const std::string &host, const stringVector &args, void *cbdata) { /// Send appropriate message for TCP or WebConnection void** data = (void**)cbdata; ConnectionType typeOfConnection = *((ConnectionType*)(data[0])); QAbstractSocket* socket = static_cast<QAbstractSocket*>(data[1]); JSONNode node; node["host"] = args[5]; //host node["port"] = args[7]; //port node["version"] = args[2]; //version node["securityKey"] = args[9]; //key if(typeOfConnection == TcpConnection) { QTcpSocket *tsocket = dynamic_cast<QTcpSocket*>(socket); std::string message = node.ToString(); tsocket->write(message.c_str(),message.length()); tsocket->waitForBytesWritten(); tsocket->disconnectFromHost(); tsocket->waitForDisconnected(); tsocket->deleteLater(); } else { QWsSocket *wsocket = dynamic_cast<QWsSocket*>(socket); wsocket->write(QString(node.ToString().c_str())); wsocket->flush(); wsocket->internalSocket()->waitForBytesWritten(); wsocket->close(); wsocket->internalSocket()->disconnectFromHost(); wsocket->internalSocket()->waitForDisconnected(); wsocket->deleteLater(); } }
void SharedDaemon::handleConnection() { QTcpSocket *socket = nextPendingConnection(); if ( !socket ) return; //the connecting socket should have sent password.. //the client should be sending a password.. socket->waitForReadyRead(); if (!socket->bytesAvailable()) { //std::cout << "no bytes available to read" << std::endl; socket->close(); return; } QAbstractSocket* finalSocket = NULL; ConnectionType typeOfConnection = TcpConnection; QByteArray result = socket->readAll(); QString input(result); /// initial connection must pass password, but can optionally pass /// whether the client canRender and what the threshold value should be.. std::string lpasswd = ""; bool canRender = false; /// check if this is a WebSocketConnection QString response = ""; if(input.startsWith("{") && ParseInput(input,lpasswd,canRender)) { finalSocket = socket; typeOfConnection = TcpConnection; } /// check if this is a WebSocketConnection.. else if(QWsSocket::initializeWebSocket(result,response)) { /// this is a websocket connection, respond and get frame.. socket->write(response.toAscii()); socket->flush(); QEventLoop loop; matched_input = ""; QWsSocket* wssocket = new QWsSocket(socket); connect(wssocket,SIGNAL(frameReceived(QString)), this,SLOT(getPasswordMessage(QString))); connect(wssocket,SIGNAL(frameReceived(QString)), &loop,SLOT(quit())); /// wait for password to be sent .. /// std::cout << "waiting for password from websocket" << std::endl; loop.exec(); disconnect(wssocket,SIGNAL(frameReceived(QString)), this,SLOT(getPasswordMessage(QString))); disconnect(wssocket,SIGNAL(frameReceived(QString)), &loop,SLOT(quit())); //std::cout << matched_input.toStdString() << std::endl; if( !ParseInput(matched_input,lpasswd,canRender) ) { //std::cout << "passwords do not match: " // << matched_password.toStdString() // << " " << password << std::endl; disconnect(wssocket,SIGNAL(frameReceived(QString)), this,SLOT(getPasswordMessage(QString))); wssocket->close("passwords do not match or operation timed out"); socket->waitForDisconnected(); wssocket->deleteLater(); return; } finalSocket = wssocket; typeOfConnection = WSocketConnection; } /// not sure what connection this is, reject it.. else { //send rejection notice.. std::string errorString = "Unknown connection.."; socket->write(errorString.c_str(),errorString.length()); socket->disconnectFromHost(); socket->waitForDisconnected(); return; } //passwords match enable RemoteProcess and get port remote Process is listening to. //send host,port,security_key and whatever else so that remote machine can successfully reverse connect std::string program = "remoteApp"; std::string clientName = "newclient1"; ViewerClientConnection *newClient = new ViewerClientConnection(subject->GetViewerState(), this, clientName.c_str(), true); newClient->SetExternalClient(true); newClient->SetAdvancedRendering(canRender); stringVector args; /// assign whether connection is of type WebSocket or TCPConnection /// Register Type & Register Callback RemoteProcess::SetCustomConnectionCallback(createCustomConnection,&typeOfConnection); void* data[2]; data[0] = &typeOfConnection; data[1] = (void*)finalSocket; newClient->LaunchClient(program,args,AddNewClient,data,0,0); RemoteProcess::SetCustomConnectionCallback(0,0); /// reset connection.. /// Now that client has launched RemoveCallback.. subject->AddNewViewerClientConnection(newClient); }
void SharedDaemon::handleConnection() { QTcpSocket *socket = nextPendingConnection(); if ( !socket ) return; //the connecting socket should have sent password.. //the client should be sending a password.. socket->waitForReadyRead(); if (!socket->bytesAvailable()) { //std::cout << "no bytes available to read" << std::endl; socket->close(); return; } std::cout << "user: "******" is attempting to connect" << std::endl; QAbstractSocket* finalSocket = NULL; ConnectionType typeOfConnection = TcpConnection; QByteArray result = socket->readAll(); QString input(result); /// initial connection must pass password, but can optionally pass /// whether the client canRender and what the threshold value should be.. JSONNode output; /// check if this is a WebSocketConnection QString response = ""; if(input.startsWith("{") && ParseInput(input,output)) { finalSocket = socket; typeOfConnection = TcpConnection; } /// check if this is a WebSocketConnection.. else if(QWsSocket::initializeWebSocket(result,response)) { /// this is a websocket connection, respond and get frame.. socket->write(response.toLatin1()); socket->flush(); QEventLoop loop; matched_input = ""; QWsSocket* wssocket = new QWsSocket(socket); connect(wssocket,SIGNAL(frameReceived(QString)), this,SLOT(getPasswordMessage(QString))); connect(wssocket,SIGNAL(frameReceived(QString)), &loop,SLOT(quit())); /// wait for password to be sent .. /// std::cout << "waiting for password from websocket" << std::endl; loop.exec(); disconnect(wssocket,SIGNAL(frameReceived(QString)), this,SLOT(getPasswordMessage(QString))); disconnect(wssocket,SIGNAL(frameReceived(QString)), &loop,SLOT(quit())); //std::cout << matched_input.toStdString() << std::endl; if( !ParseInput(matched_input,output) ) { //std::cout << "passwords do not match: " // << matched_password.toStdString() // << " " << password << std::endl; wssocket->close("passwords do not match or operation timed out"); if(socket->state() != QAbstractSocket::UnconnectedState) socket->waitForDisconnected(); wssocket->deleteLater(); return; } finalSocket = wssocket; typeOfConnection = WSocketConnection; } /// not sure what connection this is, reject it.. else { //send rejection notice.. std::string errorString = "Unknown connection.."; socket->write(errorString.c_str(),errorString.length()); socket->disconnectFromHost(); socket->waitForDisconnected(); return; } //passwords match enable RemoteProcess and get port remote Process is listening to. //send host,port,security_key and whatever else so that remote machine can successfully reverse connect std::string program = "remoteApp"; std::string clientName = "newclient1"; ViewerClientConnection *newClient = new ViewerClientConnection(subject->GetViewerState(), this, clientName.c_str(), true); ViewerClientAttributes& clientAtts = newClient->GetViewerClientAttributes(); JSONNode::JSONObject jo = output.GetJsonObject(); clientAtts.SetExternalClient(true); if(jo.count("name") == 0 || jo["name"].GetString().size() == 0) clientAtts.SetTitle(socket->peerAddress().toString().toStdString()); else clientAtts.SetTitle(jo["name"].GetString()); if(jo.count("windowIds") > 0 && jo["windowIds"].GetType() == JSONNode::JSONARRAY) { const JSONNode::JSONArray& array = jo["windowIds"].GetArray(); for(size_t i = 0; i < array.size(); ++i) { const JSONNode& node = array[i]; if(node.GetType() != JSONNode::JSONINTEGER) continue; std::cout << clientAtts.GetTitle() << " requesting window: " << node.GetInt() << " " << std::endl; clientAtts.GetWindowIds().push_back(node.GetInt()); } } if(jo.count("geometry") > 0) { std::string geometry = jo["geometry"].GetString(); /// split into width & height... size_t index = geometry.find("x"); if(index != std::string::npos && index != 0 && index != geometry.size()-1) { int geometryWidth = atoi(geometry.substr(0,index).c_str()); int geometryHeight = atoi(geometry.substr(index+1).c_str()); clientAtts.SetImageWidth(geometryWidth); clientAtts.SetImageHeight(geometryHeight); //std::cout << "geometry: " << clientAtts.clientWidth << " " << clientAtts.clientHeight << std::endl; } } /// advanced rendering can be true or false (image only), or string none,image,data if(jo.count("canRender") == 0) { clientAtts.SetRenderingType(ViewerClientAttributes::None); clientAtts.GetRenderingTypes().push_back(ViewerClientAttributes::None); } else { const JSONNode& node = jo["canRender"]; QString type = node.GetString().c_str(); type = type.toLower(); /// TODO: remove the boolean check and make all current clients comply.. if(node.GetType() == JSONNode::JSONBOOL) { clientAtts.SetRenderingType( node.GetBool() ? ViewerClientAttributes::Image : ViewerClientAttributes::None); clientAtts.GetRenderingTypes().push_back(node.GetBool() ? ViewerClientAttributes::Image : ViewerClientAttributes::None); } else if(node.GetType() == JSONNode::JSONSTRING) { if(type == "image") { clientAtts.SetRenderingType(ViewerClientAttributes::Image); clientAtts.GetRenderingTypes().push_back((int)ViewerClientAttributes::Image); } else if(type == "data") { clientAtts.SetRenderingType(ViewerClientAttributes::Data); clientAtts.GetRenderingTypes().push_back((int)ViewerClientAttributes::Data); } else { clientAtts.SetRenderingType(ViewerClientAttributes::None); clientAtts.GetRenderingTypes().push_back((int)ViewerClientAttributes::None); } } else { clientAtts.SetRenderingType(ViewerClientAttributes::None); clientAtts.GetRenderingTypes().push_back((int)ViewerClientAttributes::None); } } stringVector args; /// assign whether connection is of type WebSocket or TCPConnection /// Register Type & Register Callback RemoteProcess::SetCustomConnectionCallback(createCustomConnection,&typeOfConnection); TRY { void* data[3]; data[0] = &typeOfConnection; data[1] = (void*)finalSocket; data[2] = (void*)subject->GetViewerState(); newClient->LaunchClient(program,args,AddNewClient,data,0,0); /// Now that client has launched RemoveCallback.. subject->AddNewViewerClientConnection(newClient); std::cout << "user: "******" successfully connected" << std::endl; } CATCHALL { std::cout << "user: "******" failed to connected" << std::endl; delete newClient; } ENDTRY RemoteProcess::SetCustomConnectionCallback(0,0); /// reset connection.. }