void ExitTunnel::TcpCreateProxy(QSharedPointer<Packet> packet) { TcpStartPacket *sp = dynamic_cast<TcpStartPacket*>(packet.data()); if(!sp) return; QTcpSocket* socket = new QTcpSocket(this); socket->setProxy(_exit_proxy); // Check the verification key if(!_table.SaveConnection(socket, sp->GetConnectionId(), sp->GetVerificationKey())) return; _tcp_buffers[socket] = QByteArray(); connect(socket, SIGNAL(readyRead()), this, SLOT(TcpReadFromProxy())); connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(TcpProxyStateChanged(QAbstractSocket::SocketState))); connect(socket, SIGNAL(disconnected()), this, SLOT(DiscardProxy())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(HandleError(QAbstractSocket::SocketError))); qDebug() << "SOCKS Creating connection" << sp->GetConnectionId(); bool proxy_does_lookups = (socket->proxy().capabilities() & QNetworkProxy::HostNameLookupCapability); qDebug() << "Direct" << proxy_does_lookups; if(sp->GetHostName().IsHostName()) { if(proxy_does_lookups) { // Connect directly to hostname qDebug() << "SOCKS ConnectToHost Direct" << sp->GetHostName().GetName() << ":" << sp->GetHostName().GetPort() << (sp->GetHostName().IsHostName() ? "DNS" : "Address"); socket->connectToHost(sp->GetHostName().GetName(), sp->GetHostName().GetPort()); } else { // Resolve hostname, then connect to IP address qDebug() << "SOCKS Hostname" << sp->GetHostName().GetName(); int lookup_id = QHostInfo::lookupHost(sp->GetHostName().GetName(), this, SLOT(TcpDnsLookupFinished(const QHostInfo &))); TcpPendingDnsData dns_data = {socket, sp->GetHostName().GetPort()}; _tcp_pending_dns[lookup_id] = dns_data; } } else {
//----------------------------------------------------------------------------- void QGCCacheWorker::_lookupReady(QHostInfo info) { #if defined(__android__) Q_UNUSED(info); #else _hostLookupID = 0; if(info.error() == QHostInfo::NoError && info.addresses().size()) { QTcpSocket socket; QNetworkProxy tempProxy; tempProxy.setType(QNetworkProxy::DefaultProxy); socket.setProxy(tempProxy); socket.connectToHost(info.addresses().first(), 80); if (socket.waitForConnected(2000)) { qCDebug(QGCTileCacheLog) << "Yes Internet Access"; emit internetStatus(true); return; } } qWarning() << "No Internet Access"; emit internetStatus(false); #endif }
bool QgsHelp::urlExists( const QString &url ) { QUrl helpUrl( url ); QTcpSocket socket; QgsSettings settings; bool proxyEnabled = settings.value( QStringLiteral( "proxy/proxyEnabled" ), false ).toBool(); if ( proxyEnabled ) { QNetworkProxy proxy; QString proxyHost = settings.value( QStringLiteral( "proxy/proxyHost" ), QString() ).toString(); int proxyPort = settings.value( QStringLiteral( "proxy/proxyPort" ), QString() ).toString().toInt(); QString proxyUser = settings.value( QStringLiteral( "proxy/proxyUser" ), QString() ).toString(); QString proxyPassword = settings.value( QStringLiteral( "proxy/proxyPassword" ), QString() ).toString(); QString proxyTypeString = settings.value( QStringLiteral( "proxy/proxyType" ), QString() ).toString(); if ( proxyTypeString == QLatin1String( "DefaultProxy" ) ) { QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(); if ( !proxies.isEmpty() ) { proxy = proxies.first(); } } else { QNetworkProxy::ProxyType proxyType = QNetworkProxy::DefaultProxy; if ( proxyTypeString == QLatin1String( "Socks5Proxy" ) ) { proxyType = QNetworkProxy::Socks5Proxy; } else if ( proxyTypeString == QLatin1String( "HttpProxy" ) ) { proxyType = QNetworkProxy::HttpProxy; } else if ( proxyTypeString == QLatin1String( "HttpCachingProxy" ) ) { proxyType = QNetworkProxy::HttpCachingProxy; } else if ( proxyTypeString == QLatin1String( "FtpCachingProxy" ) ) { proxyType = QNetworkProxy::FtpCachingProxy; } proxy = QNetworkProxy( proxyType, proxyHost, proxyPort, proxyUser, proxyPassword ); } socket.setProxy( proxy ); } socket.connectToHost( helpUrl.host(), 80 ); if ( socket.waitForConnected() ) { socket.write( "HEAD " + helpUrl.path().toUtf8() + " HTTP/1.1\r\n" "Host: " + helpUrl.host().toUtf8() + "\r\n\r\n" ); if ( socket.waitForReadyRead() ) { QByteArray bytes = socket.readAll(); if ( bytes.contains( "200 OK" ) || bytes.contains( "302 Found" ) ) { return true; } } } return false; }
void HttpProxy::onSocketReadyRead() { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); QTcpSocket *proxySocket = nullptr; QByteArray reqData = socket->readAll(); int pos = reqData.indexOf("\r\n"); QByteArray reqLine = reqData.left(pos); reqData.remove(0, pos + 2); QList<QByteArray> entries = reqLine.split(' '); QByteArray method = entries.value(0); QByteArray address = entries.value(1); QByteArray version = entries.value(2); QString host; quint16 port; QString key; if (method != "CONNECT") { QUrl url = QUrl::fromEncoded(address); if (!url.isValid()) { emit info("Invalid URL: " + url.toString()); socket->disconnectFromHost(); return; } host = url.host(); port = url.port(80); QString req = url.path(); if (url.hasQuery()) { req.append('?').append(url.query()); } reqLine = method + " " + req.toUtf8() + " " + version + "\r\n"; reqData.prepend(reqLine); key = host + ':' + QString::number(port); proxySocket = socket->findChild<QTcpSocket *>(key); if (proxySocket) { proxySocket->write(reqData); return;//if we find an existing socket, then use it and return } } else {//CONNECT method /* * according to http://tools.ietf.org/html/draft-luotonen-ssl-tunneling-03 * the first line would CONNECT HOST:PORT VERSION */ QList<QByteArray> host_port_list = address.split(':'); host = QString(host_port_list.first()); port = host_port_list.last().toUShort(); } proxySocket = new QTcpSocket(socket); proxySocket->setProxy(upstreamProxy); if (method != "CONNECT") { proxySocket->setObjectName(key); proxySocket->setProperty("reqData", reqData); connect (proxySocket, &QTcpSocket::connected, this, &HttpProxy::onProxySocketConnected); connect (proxySocket, &QTcpSocket::readyRead, this, &HttpProxy::onProxySocketReadyRead); } else { connect (proxySocket, &QTcpSocket::connected, this, &HttpProxy::onProxySocketConnectedHttps); } connect (proxySocket, &QTcpSocket::disconnected, proxySocket, &QTcpSocket::deleteLater); connect (proxySocket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), this, &HttpProxy::onSocketError); proxySocket->connectToHost(host, port); }
int main(int argc, char * argv[]) { /* * Before starting main application, need to set 'QT_X11_NO_MITSHM=1' * to make the runtime work with IBM PPC machine. */ #if defined (Q_OS_LINUX) QByteArray val("1"); qputenv("QT_X11_NO_MITSHM", val); #endif // Create the QT application QApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); // Setup the settings management QCoreApplication::setOrganizationName("pgadmin"); QCoreApplication::setOrganizationDomain("pgadmin.org"); QCoreApplication::setApplicationName(PGA_APP_NAME.toLower().replace(" ", "")); #if QT_VERSION >= 0x050000 // Set high DPI pixmap to display icons clear on Qt widget. QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif // Create a hash of the executable path so we can run copies side-by-side QString homeDir = QDir::homePath(); unsigned long exeHash = sdbm((unsigned char *)argv[0]); // Create the address file, that will be used to store the appserver URL for this instance addrFileName = homeDir + (QString("/.%1.%2.addr").arg(PGA_APP_NAME).arg(exeHash)).remove(" "); QFile addrFile(addrFileName); // Create a system-wide semaphore keyed by app name, exe hash and the username // to ensure instances are unique to the user and path QString userName = qgetenv("USER"); // *nix if (userName.isEmpty()) userName = qgetenv("USERNAME"); // Windows QString semaName = QString("%1-%2-%3-sema").arg(PGA_APP_NAME).arg(userName).arg(exeHash); QString shmemName = QString("%1-%2-%3-shmem").arg(PGA_APP_NAME).arg(userName).arg(exeHash); QSystemSemaphore sema(semaName, 1); sema.acquire(); #ifndef Q_OS_WIN32 // We may need to clean up stale shmem segments on *nix. Attaching and detaching // should remove the segment if it is orphaned. QSharedMemory stale_shmem(shmemName); if (stale_shmem.attach()) stale_shmem.detach(); #endif QSharedMemory shmem(shmemName); bool is_running; if (shmem.attach()) { is_running = true; } else { shmem.create(1); is_running = false; } sema.release(); QSettings settings; if (is_running){ addrFile.open(QIODevice::ReadOnly | QIODevice::Text); QTextStream in(&addrFile); QString addr = in.readLine(); QString cmd = settings.value("BrowserCommand").toString(); if (!cmd.isEmpty()) { cmd.replace("%URL%", addr); QProcess::startDetached(cmd); } else { if (!QDesktopServices::openUrl(addr)) { QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?.")); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); exit(1); } } return 0; } atexit(cleanup); // In windows and linux, it is required to set application level proxy // because socket bind logic to find free port gives socket creation error // when system proxy is configured. We are also setting // "setUseSystemConfiguration"=true to use the system proxy which will // override this application level proxy. As this bug is fixed in Qt 5.9 so // need to set application proxy for Qt version < 5.9. // #if defined (Q_OS_WIN) && QT_VERSION <= 0x050800 // Give dummy URL required to find proxy server configured in windows. QNetworkProxyQuery proxyQuery(QUrl("https://www.pgadmin.org")); QNetworkProxy l_proxy; QList<QNetworkProxy> listOfProxies = QNetworkProxyFactory::systemProxyForQuery(proxyQuery); if (listOfProxies.size()) { l_proxy = listOfProxies[0]; // If host name is not empty means proxy server is configured. if (!l_proxy.hostName().isEmpty()) { QNetworkProxy::setApplicationProxy(QNetworkProxy()); } } #endif #if defined (Q_OS_LINUX) && QT_VERSION <= 0x050800 QByteArray proxy_env; proxy_env = qgetenv("http_proxy"); // If http_proxy environment is defined in linux then proxy server is configured. if (!proxy_env.isEmpty()) { QNetworkProxy::setApplicationProxy(QNetworkProxy()); } #endif // Display the spash screen QSplashScreen *splash = new QSplashScreen(); splash->setPixmap(QPixmap(":/splash.png")); splash->show(); app.processEvents(QEventLoop::AllEvents); quint16 port = 0L; // Find an unused port number. Essentially, we're just reserving one // here that Flask will use when we start up the server. // In order to use the socket, we need to free this socket ASAP. // Hence - putting this code in a code block so the scope of the socket // variable vanishes to make that socket available. { #if QT_VERSION >= 0x050000 QTcpSocket socket; #if QT_VERSION >= 0x050900 socket.setProxy(QNetworkProxy::NoProxy); #endif socket.bind(0, QTcpSocket::ShareAddress); #else QUdpSocket socket; socket.bind(0, QUdpSocket::ShareAddress); #endif port = socket.localPort(); } // Generate a random key to authenticate the client to the server QString key = QUuid::createUuid().toString(); key = key.mid(1, key.length() - 2); // Generate the filename for the log logFileName = homeDir + (QString("/.%1.%2.log").arg(PGA_APP_NAME).arg(exeHash)).remove(" "); // Start the tray service TrayIcon *trayicon = new TrayIcon(logFileName); if (!trayicon->Init()) { QString error = QString(QWidget::tr("An error occurred initialising the tray icon")); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); exit(1); } // Fire up the webserver Server *server; bool done = false; while (done != true) { server = new Server(port, key, logFileName); if (!server->Init()) { splash->finish(NULL); qDebug() << server->getError(); QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError()); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); exit(1); } server->start(); // This is a hack to give the server a chance to start and potentially fail. As // the Python interpreter is a synchronous call, we can't check for proper startup // easily in a more robust way - we have to rely on a clean startup not returning. // It should always fail pretty quickly, and take longer to start if it succeeds, so // we don't really get a visible delay here. delay(1000); // Any errors? if (server->isFinished() || server->getError().length() > 0) { splash->finish(NULL); qDebug() << server->getError(); QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError()); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); // Allow the user to tweak the Python Path if needed bool ok; ConfigWindow *dlg = new ConfigWindow(); dlg->setWindowTitle(QWidget::tr("Configuration")); dlg->setBrowserCommand(settings.value("BrowserCommand").toString()); dlg->setPythonPath(settings.value("PythonPath").toString()); dlg->setApplicationPath(settings.value("ApplicationPath").toString()); dlg->setModal(true); ok = dlg->exec(); QString browsercommand = dlg->getBrowserCommand(); QString pythonpath = dlg->getPythonPath(); QString applicationpath = dlg->getApplicationPath(); if (ok) { settings.setValue("BrowserCommand", browsercommand); settings.setValue("PythonPath", pythonpath); settings.setValue("ApplicationPath", applicationpath); settings.sync(); } else { exit(1); } delete server; } else done = true; } // Ensure the server gets cleaned up later QObject::connect(server, SIGNAL(finished()), server, SLOT(deleteLater())); // Generate the app server URL QString appServerUrl = QString("http://127.0.0.1:%1/?key=%2").arg(port).arg(key); // Read the server connection timeout from the registry or set the default timeout. int timeout = settings.value("ConnectionTimeout", 30).toInt(); // Now the server should be up, we'll attempt to connect and get a response. // We'll retry in a loop a few time before aborting if necessary. QTime endTime = QTime::currentTime().addSecs(timeout); bool alive = false; while(QTime::currentTime() <= endTime) { alive = PingServer(QUrl(appServerUrl)); if (alive) { break; } delay(200); } // Attempt to connect one more time in case of a long network timeout while looping if (!alive && !PingServer(QUrl(appServerUrl))) { splash->finish(NULL); QString error(QWidget::tr("The application server could not be contacted.")); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); exit(1); } // Stash the URL for any duplicate processes to open if (addrFile.open(QIODevice::WriteOnly)) { addrFile.setPermissions(QFile::ReadOwner|QFile::WriteOwner); QTextStream out(&addrFile); out << appServerUrl << endl; } // Go! trayicon->setAppServerUrl(appServerUrl); // Enable the shutdown server menu as server started successfully. trayicon->enableShutdownMenu(); QString cmd = settings.value("BrowserCommand").toString(); if (!cmd.isEmpty()) { cmd.replace("%URL%", appServerUrl); QProcess::startDetached(cmd); } else { if (!QDesktopServices::openUrl(appServerUrl)) { QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?.")); QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error); exit(1); } } QObject::connect(trayicon, SIGNAL(shutdownSignal(QUrl)), server, SLOT(shutdown(QUrl))); splash->finish(NULL); return app.exec(); }