Exemple #1
0
	ClientTest(const QString &_host, int _port, const QString &_proto, const QString &_authzid, const QString &_realm, const QString &_user, const QString &_pass, bool _no_authzid, bool _no_realm) :
		host(_host),
		proto(_proto),
		authzid(_authzid),
		realm(_realm),
		user(_user),
		pass(_pass),
		port(_port),
		no_authzid(_no_authzid),
		no_realm(_no_realm),
		sock_done(false),
		waitCycles(0)
	{
		sock = new QTcpSocket(this);
		connect(sock, SIGNAL(connected()), SLOT(sock_connected()));
		connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
		connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)));

		sasl = new QCA::SASL(this);
		connect(sasl, SIGNAL(clientStarted(bool, const QByteArray &)), SLOT(sasl_clientFirstStep(bool, const QByteArray &)));
		connect(sasl, SIGNAL(nextStep(const QByteArray &)), SLOT(sasl_nextStep(const QByteArray &)));
		connect(sasl, SIGNAL(needParams(const QCA::SASL::Params &)), SLOT(sasl_needParams(const QCA::SASL::Params &)));
		connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
		connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
		connect(sasl, SIGNAL(readyReadOutgoing()), SLOT(sasl_readyReadOutgoing()));
		connect(sasl, SIGNAL(error()), SLOT(sasl_error()));
	}
Exemple #2
0
void CompressionHandler::write(const QByteArray& a)
{
	//qDebug() << (QString("CompressionHandler::write(%1)").arg(a.size()).toAscii());
	errorCode_ = compressor_->write(a);
	if (!errorCode_)
		QTimer::singleShot(0, this, SIGNAL(readyReadOutgoing()));
	else
		QTimer::singleShot(0, this, SIGNAL(error()));
}
Exemple #3
0
	SecureLayer(QCA::SASL *s)
	{
		type = SASL;
		p.sasl = s;
		init();
		connect(p.sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
		connect(p.sasl, SIGNAL(readyReadOutgoing()), SLOT(sasl_readyReadOutgoing()));
		connect(p.sasl, SIGNAL(error()), SLOT(sasl_error()));
	}
Exemple #4
0
	SecureLayer(CompressionHandler *t)
	{
		t->setParent(this); // automatically clean up CompressionHandler when SecureLayer is destroyed
		type = Compression;
		p.compressionHandler = t;
		init();
		connect(p.compressionHandler, SIGNAL(readyRead()), SLOT(compressionHandler_readyRead()));
		connect(p.compressionHandler, SIGNAL(readyReadOutgoing()), SLOT(compressionHandler_readyReadOutgoing()));
		connect(p.compressionHandler, SIGNAL(error()), SLOT(compressionHandler_error()));
	}
Exemple #5
0
void HttpProxyPost::sock_connected()
{
#ifdef PROX_DEBUG
	fprintf(stderr, "HttpProxyPost: Connected\n");
#endif
	if(d->useSsl) {
		d->tls = new QCA::TLS(this);
		connect(d->tls, SIGNAL(readyRead()), SLOT(tls_readyRead()));
		connect(d->tls, SIGNAL(readyReadOutgoing()), SLOT(tls_readyReadOutgoing()));
		connect(d->tls, SIGNAL(error()), SLOT(tls_error()));
		d->tls->startClient();
	}

	d->lastAddress = d->sock.peerAddress();
	d->inHeader = true;
	d->headerLines.clear();

	QUrl u = d->url;

	// connected, now send the request
	QString s;
	s += QString("POST ") + d->url + " HTTP/1.1\r\n";
	if(d->asProxy) {
		if(!d->user.isEmpty()) {
			QString str = d->user + ':' + d->pass;
			s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n";
		}
		s += "Pragma: no-cache\r\n";
		s += QString("Host: ") + u.host() + "\r\n";
	}
	else {
		s += QString("Host: ") + d->host + "\r\n";
	}
	s += "Content-Type: application/x-www-form-urlencoded\r\n";
	s += QString("Content-Length: ") + QString::number(d->postdata.size()) + "\r\n";
	s += "\r\n";

	if(d->useSsl) {
		// write request
		d->tls->write(s.toUtf8());

		// write postdata
		d->tls->write(d->postdata);
	} else {
		// write request
		d->sock.write(s.toUtf8());

		// write postdata
		d->sock.write(d->postdata);
	}
}
Exemple #6
0
void HttpProxyGetStream::sock_connected()
{
#ifdef PROX_DEBUG
	fprintf(stderr, "HttpProxyGetStream: Connected\n");
#endif
	if(d->use_ssl) {
		d->tls = new QCA::TLS(this);
		connect(d->tls, SIGNAL(readyRead()), SLOT(tls_readyRead()));
		connect(d->tls, SIGNAL(readyReadOutgoing()), SLOT(tls_readyReadOutgoing()));
		connect(d->tls, SIGNAL(error()), SLOT(tls_error()));
		d->tls->startClient();
	}

	d->inHeader = true;
	d->headerLines.clear();

	QUrl u = d->url;

	// connected, now send the request
	QString s;
	s += QString("GET ") + d->url + " HTTP/1.0\r\n";
	if(d->asProxy) {
		if(!d->user.isEmpty()) {
			QString str = d->user + ':' + d->pass;
			s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n";
		}
		s += "Pragma: no-cache\r\n";
		s += QString("Host: ") + u.host() + "\r\n";
	}
	else {
		s += QString("Host: ") + d->host + "\r\n";
	}
	s += "\r\n";

	// write request
	if(d->use_ssl)
		d->tls->write(s.toUtf8());
	else
		d->sock.write(s.toUtf8());
}
Exemple #7
0
TLSDataStream::TLSDataStream(QCA::TLS *tls) : m_tls(tls)
{
	connect(m_tls.data(), SIGNAL(readyRead()), SLOT(onReadyRead()));
	connect(m_tls.data(), SIGNAL(readyReadOutgoing()), SLOT(onReadyReadOutgoing()));
	m_offset = 0;
}
void Xmpp::processEvent(Event *event)
{
	/*
	 * WARNING: An event is NOT still the same as before.
	 * Now, an event contains all data from depth = 1 
	 * to depth back to 1.
	 */
	//printf("Elem = %s\n", event->node().localName().toLatin1().constData());
	switch (state)
	{
		case isHandShaking:
			break;
		case PrepareRegistering:
		case waitStream:
			if (event->type() == Event::Stream)
			{
				printf("[XMPP] Ok, received the stream tag.\n");
				if (state != PrepareRegistering)
					state = waitFeatures;
				else
				{
					state = active;
					emit registerReady();
				}
			}
			//else
			//	printf(" ! Didn't receive the stream ! \n");
			break;
		case waitFeatures:
			if (event->node().localName() == "features")
			{
				printf("[XMPP] Ok, received the features tag.\n");
				if (!tlsDone && useTls)
				{
					QDomNode node = event->node().firstChild();
					printf("[XMPP] Next Status : ");
					//state = waitStartTls;
					printf("[XMPP]     %s\n", node.localName().toLatin1().constData());
					if (node.localName() == QString("mechanisms"))
					{
						printf("[XMPP] Must directly switch to SASL authentication\n");
						useTls = false;
						node = node.firstChild();
						// Must directly switch to SASL authentication
						printf("[XMPP]     %s\n", node.localName().toLatin1().constData());
						while(node.localName() == QString("mechanism"))
						{
							printf("[XMPP] Ok, received a mechanism tag.\n");
							if (node.firstChild().toText().data() == QString("PLAIN"))
							{
								plainMech = true;
								printf("[XMPP] Ok, PLAIN mechanism supported\n");

								// Sstartauth method.
								QDomDocument doc("");
								QDomElement e = doc.createElement("auth");
								doc.appendChild(e);
								e.setAttribute(QString("xmlns"), QString("urn:ietf:params:xml:ns:xmpp-sasl"));
								e.setAttribute(QString("mechanism"), QString("PLAIN"));
								QString text = QString("%1%2%3%4").arg('\0').arg(username).arg('\0').arg(password);
								QDomText t = doc.createTextNode(text.toLatin1().toBase64());
								e.appendChild(t);
								QByteArray sData = doc.toString().toLatin1();
								sendData(sData);
								state = waitSuccess;
								
							}
							node = node.nextSibling();
						}
					
					}
					if (node.localName() == QString("starttls"))
					{
						printf("[XMPP] Ok, received the starttls tag.\n");
						// Send starttls tag
						QDomDocument doc("");
						QDomElement e = doc.createElement("starttls");
						doc.appendChild(e);
						e.setAttribute(QString("xmlns"), QString("urn:ietf:params:xml:ns:xmpp-tls"));
						QByteArray sData = doc.toString().toLatin1();
						sendData(sData);
						// Next state
						state = waitProceed;
						// Even if TLS isn't required, I use TLS.
					}
				}
				else
				{
					if (!saslDone)
					{
						//TODO:Must first check that event->node().firstChild() == mechanisms
						QDomNode node = event->node().firstChild().firstChild();
						printf("[XMPP] Tls done or not used. --> sasl\n");
						while(node.localName() == QString("mechanism"))
						{
							printf("[XMPP] Ok, received a mechanism tag.\n");
							if (node.firstChild().toText().data() == QString("PLAIN"))
							{
								plainMech = true;
								printf("[XMPP] Ok, PLAIN mechanism supported\n");

								// Sstartauth method.
								QDomDocument doc("");
								QDomElement e = doc.createElement("auth");
								doc.appendChild(e);
								e.setAttribute(QString("xmlns"), QString("urn:ietf:params:xml:ns:xmpp-sasl"));
								e.setAttribute(QString("mechanism"), QString("PLAIN"));
								QString text = QString("%1%2%3%4").arg('\0').arg(username).arg('\0').arg(password);
								QDomText t = doc.createTextNode(text.toLatin1().toBase64());
								e.appendChild(t);
								QByteArray sData = doc.toString().toLatin1();
								sendData(sData);
								state = waitSuccess;
								
							}
							node = node.nextSibling();
						} //FIXME: this is impemented two times in this function. Another way to do the same ?
					}
					else
					{
				//		printf("Wait Ncessary\n");
				//		state = waitNecessary;
						QDomNode node = event->node().firstChild();
						while(!node.isNull())
						{
							if (node.localName() == QString("bind"))
							{
								printf("[XMPP] Ok, bind needed.\n");
								needBind = true;
							}
							if (node.localName() == QString("session"))
							{
								printf("[XMPP] Ok, session needed.\n");
								needSession = true;
							}
							node = node.nextSibling();
						}
						if (needBind)
						{
							QDomDocument doc("");
							QDomElement e = doc.createElement("iq");
							e.setAttribute("type", "set"); // Trying without id.

							QDomElement e2 = doc.createElement("bind");
							e2.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-bind");
				
							QDomElement e3 = doc.createElement("resource");
							QDomText t = doc.createTextNode(resource);
				
							e3.appendChild(t);
							e2.appendChild(e3);
							e.appendChild(e2);
							doc.appendChild(e);
							QByteArray sData = doc.toString().toLatin1();
							sendData(sData);
				
							state = waitBind;
						}
					}
				}
			}
			break;
		case waitProceed:
			if (event->node().localName() == QString("proceed"))
			{
				//printf(" * Ok, received the proceed tag.\n");
				printf("[XMPP] Proceeding...\n[XMPP] Enabling TLS connection.\n");
				
				state = isHandShaking;
				tls = new TlsHandler();
				connect(tls, SIGNAL(readyRead()), this, SLOT(clearDataReceived()));
				connect(tls, SIGNAL(readyReadOutgoing()), this, SLOT(sendDataFromTls()));
				connect(tls, SIGNAL(connected()), this, SLOT(tlsIsConnected()));
				tls->connect();
				state = isHandShaking;
				isTlsing = true;
			}
			break;
		case waitSuccess:
			if (event->node().localName() == QString("success"))
			{
				printf("[XMPP] Ok, SASL established.\n");
				saslDone = true;
				start();
			}
			if (event->node().localName() == QString("failure"))
			{
				printf("[XMPP]  ! Check Username and password.\n");
				QByteArray sData = "</stream:stream>";
				sendData(sData);
			}
			break;
		case waitBind:
			if (event->node().localName() == QString("iq"))
			{
				if (event->node().toElement().attribute("type") != QString("result"))
				{
					printf("[XMPP] Authentification Error.\n");
					QByteArray sData = "</stream:stream>";
					sendData(sData);
					return;
				}
				if (event->node().firstChild().localName() == QString("bind"))
				{
					QDomNode node = event->node().firstChild();
					if (node.firstChild().localName() == QString("jid"))
					{
						node = node.firstChild().firstChild();
						QString u, r, s;
						if (!node.toText().data().isEmpty())
						{
							u = node.toText().data().split('@')[0]; // Username
							s = node.toText().data().split('@')[1].split('/')[0]; // Server
							r = node.toText().data().split('/')[1]; // Resource
							printf("[XMPP] '%s'@'%s'/'%s'\n", u.toLatin1().constData(), s.toLatin1().constData(), r.toLatin1().constData());
						}
						if (u == username && s == server)
						{
							printf("[XMPP] Jid OK !\n");
							resource = r;
							jidDone = true;
							j.setResource(r);
						}
					}

					if (needSession && jidDone)
					{
						printf("[XMPP] Launching Session...\n");
						QDomDocument doc("");
						QDomElement e = doc.createElement("iq");
						e.setAttribute("to", server);
						e.setAttribute("type", "set");
						e.setAttribute("id", "sess_1");

						QDomElement e2 = doc.createElement("session");
						e2.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-session");

						e.appendChild(e2);
						doc.appendChild(e);

						QByteArray sData = doc.toString().toLatin1();
						sendData(sData);

						state = waitSession;
					}
					
				}
			}
			break;
		case waitSession:
			if (event->node().localName() == QString("iq"))
			{
				if (event->node().toElement().attribute("type") == "result")
				{
					printf("[XMPP] Connection is now active !\n");
					
					/*
					 * Presence must be sent after getting the roster
					 * so we already have the contacts to assign their presence
					 * when receiving presence stanza's wich come after
					 * setting the first presence.
					 */

					state = active;
					emit connected(); 

				}
				else
				{
					if (event->node().toElement().attribute("type") == "error")
					{
						printf("[XMPP] An error occured ! \n");
					}
				}

			}
			break;
		case active:
		{
			Stanza *s = new Stanza(event->node());
			QDomDocument doc = event->node().toDocument();
			printf("[XMPP] Xmpp::processEvent : node = %s\n", doc.toString().toLatin1().constData());
			stanzaList << s;
			emit readyRead();
			break;
		}
		default :
			break;
	}
}