Exemple #1
0
// ****************************************************************************
// Method: SharedDaemon::handleConnection
//
// Purpose:
//  Handle the incomming connection..
//
// Arguments:
//
// Returns:
//
// Note:
//
// Programmer: Hari Krishnan
// Creation:   Oct 13, 2012
//
// Modifications:
//   Kathleen Biagas, Mon Dec 3 12:01:15 PST 2012
//   Use operator[] instead of 'at' to support older MSVC compiler.
//
// ****************************************************************************
bool
SharedDaemon::ParseInput(const QString& input, std::string& lpasswd, bool& canRender)
{
    if(input.startsWith("{"))
    {
        JSONNode node;
        node.Parse(input.toStdString());

        if(node.GetType() != JSONNode::JSONOBJECT ||
           !node.HasKey("password") ||
            node.GetJsonObject()["password"].GetString() != password)
            return false;

        lpasswd = node.GetJsonObject()["password"].GetString();

        if(node.HasKey("canRender") == true &&
           node.GetJsonObject()["canRender"].GetType() == JSONNode::JSONBOOL)
            canRender = node.GetJsonObject()["canRender"].GetBool();

        return true;
    }

    return false;
}
// ****************************************************************************
// Method: SharedDaemon::handleConnection
//
// Purpose:
//  Handle the incomming connection..
//
// Arguments:
//
// Returns:
//
// Note:
//
// Programmer: Hari Krishnan
// Creation:   Oct 13, 2012
//
// Modifications:
//   Kathleen Biagas, Mon Dec 3 12:01:15 PST 2012
//   Use operator[] instead of 'at' to support older MSVC compiler.
//
// ****************************************************************************
bool
SharedDaemon::ParseInput(const QString& input, JSONNode& output)
{
    if(input.startsWith("{"))
    {
        JSONNode node;
        node.Parse(input.toStdString());
        //std::cout << node.ToString() << std::endl;
        /// also check to make sure password is coorect..
        if(node.GetType() != JSONNode::JSONOBJECT ||
           !node.HasKey("password") ||
            node.GetJsonObject()["password"].GetString() != password.toStdString())
            return false;

        output = node;
        return true;
    }

    return false;
}
bool
ProgrammableOpAttributes::SetupPipeline(const JSONNode& atts, stringVector& args, const std::string& parent)
{
    if(atts.GetType() != JSONNode::JSONARRAY)
        return false;

    const JSONNode::JSONArray& array = atts.GetArray();

    for(int i = 0; i < array.size(); ++i)
    {
        /// need key, value pair
        /// this can be in the form of a dictionary, "a = b", pair tuple (a,b), or a pair array [a,b]
        JSONNode node = array[i];
        JSONNode key,value;
        if(node.GetType() == JSONNode::JSONARRAY)
        {
            if(node.GetArray().size() != 2) continue;

            key = node.GetArray()[0];
            value = node.GetArray()[1];
        }
        else if(node.GetType() == JSONNode::JSONOBJECT)
        {
            /// parse through dictionary and compute arguments from names..
            const JSONNode::JSONObject& obj = node.GetJsonObject();
            if(obj.size() != 1) continue;

            const JSONNode::JSONObject::const_iterator itr = obj.begin();
            key = itr->first;
            value = itr->second;
        }
        else if(node.GetType() == JSONNode::JSONSTRING)
        {
            std::string pair = node.GetString();
            int index = pair.find("=");
            if(index == std::string::npos) continue;
            key = pair.substr(0,index);

            value = trim(pair.substr(index+1));
         }

        if(key.GetType() != JSONNode::JSONSTRING) continue;

        std::string keystr = trim(key.GetString());

        std::ostringstream str;
        str << "import json\n";
        if(value.GetType() == JSONNode::JSONSTRING)
        {
            std::string v = trim(value.GetString());

            ///character at 0 and has :
            if(v.find(":") != std::string::npos && v.find(":") == 0)
            {
                /// optionally handle whether it can be as_vtkarray, as_ndarray, or as_rarray

                size_t index = v.find(":as_ndarray");

                if(index == std::string::npos)
                    index = v.find(":as_rarray");

                if(index != std::string::npos)
                {
                    std::string newName = getNextName();
                    v = v.substr(0,index);
                    AddNode(newName, "as_ndarray");
                    AddConnection(v, newName, "in");
                    AddConnection(newName,parent,keystr);
                }
                else
                {
                    index = v.find(":as_vtkarray");
                    if(index != std::string::npos)
                        v = v.substr(0,index);
                    AddConnection(v,parent,keystr);
                }
            }
            else
            {
                std::string escapedCode = trim(value.GetString());
                replace(escapedCode,"\n","\\\n");
                replace(escapedCode,"'","\"");
                escapedCode = "'" + escapedCode + "'";

                str << "try:\n"
                    << " a = json.loads(" << escapedCode << ")\n"
                    << "except:\n"
                    << " a = " << escapedCode << "\n"
                    << "setout(a)\n";

                AddPythonScript(keystr,stringVector(),str.str());
                AddNode(keystr,keystr);
                AddConnection(keystr,parent,keystr);
            }
        }
        else
        {
            str << "setout(json.loads('" << trim(value.ToString()) << "'))\n";

            AddPythonScript(keystr,stringVector(),str.str());
            AddNode(keystr,keystr);
            AddConnection(keystr,parent,keystr);
        }
        args.push_back(keystr);
    }
    return true;
}
Exemple #4
0
bool ViewerProxy::ConnectToExistingViewer(const std::string& host, const int& port, const std::string& password)
{

    //Step 1: Check and see if connection can be made..
    int testSocket = socket(AF_INET, SOCK_STREAM, 0);
    if( testSocket < 0 )
    {
        std::cerr << "Socket not created (ERROR)" << std::endl;
        return false;
    }

    std::cout << "connecting to host: " << host << " port " << port << std::endl;
    struct sockaddr_in sin;
    struct hostent *server = gethostbyname(host.c_str());
    memset(&sin, 0, sizeof(sin));
    memcpy(&(sin.sin_addr), server->h_addr, server->h_length);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);

    if (connect(testSocket,(struct sockaddr*) &sin,sizeof(sin)) < 0)
    {
        std::cerr << "Unable to connect to Viewer" << std::endl;
        CloseSocket(testSocket);
        return false;
    }

    //Step 2: Send password to verify that you should be added
    std::ostringstream handshake;
    handshake << "{ \"password\" : \"" << password << "\" }";

#ifndef _WIN32
    int nwrite = write(testSocket,handshake.str().c_str(),handshake.str().length());
#else
    int nwrite = _write(testSocket,handshake.str().c_str(),(unsigned int)handshake.str().length());
#endif
    if(nwrite < 0)
    {
        std::cerr << "Error writing to Viewer" << std::endl;
        CloseSocket(testSocket);
        return false;
    }

    //Step 3: receive arguments to establish reverse connection

    char buffer[1024];

#ifndef _WIN32
    int bytes = read(testSocket,buffer,1024);
#else
    int bytes = _read(testSocket,buffer,1024);
#endif
    buffer[bytes] = '\0';
    //std::cout << "bytes read: " << bytes << " " << buffer << std::endl;

    CloseSocket(testSocket);
    //Step 4: reverse connect same as if it was originally intented..

    //parse message and create new reverse connect

    std::string message = buffer;

    JSONNode node;
    node.Parse(message);

    stringVector args;

    args.push_back("-v");
    args.push_back(node.GetJsonObject()["version"].GetString());

    args.push_back("-host");
    args.push_back(node.GetJsonObject()["host"].GetString());

    args.push_back("-port");
    args.push_back(node.GetJsonObject()["port"].GetString());

    args.push_back("-key");
    args.push_back(node.GetJsonObject()["securityKey"].GetString());

    args.push_back("-reverse_launch");

    int inputArgc = args.size();

    char** inputArgv = new char* [inputArgc+1];

    for(size_t i = 0; i < args.size(); ++i)
    {
        inputArgv[i] = new char [args[i].length()+1];
        strcpy(inputArgv[i],args[i].c_str());
        inputArgv[i][args[i].length()] = '\0';
    }

    inputArgv[inputArgc] = NULL;

    // Connect to the viewer process. Our command line arguments
    // should contain  The viewer is executed using
    // "visit -viewer".
    //

    viewerP = new ParentProcess;
    viewerP->Connect(1, 1, &inputArgc, &inputArgv, true);

    // Use viewerP's connections for xfer.
    xfer->SetInputConnection(viewerP->GetWriteConnection());
    xfer->SetOutputConnection(viewerP->GetReadConnection());
    return true;
}
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..
}