initial commit

This commit is contained in:
mikhail "synzr" 2025-12-25 01:37:49 +05:00
commit 9d20827c46
2469 changed files with 470994 additions and 0 deletions

View file

@ -0,0 +1,609 @@
#!/bin/sh
show_usage() {
cat <<EOT
Usage: ./configure [OPTION]...
This script creates necessary configuration files to build/install.
Main options:
--prefix=[path] Base path for build/install. Default: /usr/local
--bindir=[path] Directory for binaries. Default: PREFIX/bin
--qtdir=[path] Directory where Qt is installed.
--debug Enable debug output.
--help This help text.
EOT
}
while [ $# -gt 0 ]; do
case "$1" in
--prefix=*)
PREFIX="${1#--prefix=}"
shift
;;
--bindir=*)
BINDIR="${1#--bindir=}"
shift
;;
--qtdir=*)
QTDIR="${1#--qtdir=}"
shift
;;
--debug)
QC_DEBUG="Y"
shift
;;
--help) show_usage; exit ;;
*) show_usage; exit ;;
esac
done
PREFIX=${PREFIX:-/usr/local}
BINDIR=${BINDIR:-$PREFIX/bin}
echo "Configuring Iris Conntest ..."
if [ "$QC_DEBUG" = "Y" ]; then
echo
echo PREFIX=$PREFIX
echo BINDIR=$BINDIR
echo QTDIR=$QTDIR
echo
fi
printf "Verifying Qt 3.x Multithreaded (MT) build environment ... "
if [ -z "$QTDIR" ]; then
if [ "$QC_DEBUG" = "Y" ]; then
echo \$QTDIR not set... trying to find Qt manually
fi
for p in /usr/lib/qt /usr/share/qt /usr/share/qt3 /usr/local/lib/qt /usr/local/share/qt /usr/lib/qt3 /usr/local/lib/qt3 /usr/X11R6/share/qt /usr/qt/3 ; do
if [ -d "$p/mkspecs" ]; then
QTDIR=$p
break;
fi;
done
if [ -z "$QTDIR" ]; then
echo fail
echo
echo "Unable to find Qt 'mkspecs'. Perhaps you need to"
echo "install the Qt 3 development utilities. You may download"
echo "them either from the vendor of your operating system"
echo "or from http://www.trolltech.com/"
echo
echo "If you're sure you have the Qt development utilities"
echo "installed, you might try using the --qtdir option."
echo
exit 1;
fi
if [ ! -x "$QTDIR/bin/moc" ]; then
m=`which moc 2>/dev/null`
if [ ! -x "$m" ]; then
echo fail
echo
echo "We found Qt in $QTDIR, but we were unable to locate"
echo "the moc utility. It was not found in $QTDIR/bin"
echo "nor in PATH. This seems to be a very unusual setup."
echo "You might try using the --qtdir option."
echo
exit 1;
fi
qtpre=`echo $m | awk '{ n = index($0, "/bin/moc"); if (!n) { exit 1; } print substr($0, 0, n-1); exit 0; }' 2>/dev/null`
ret="$?"
if [ "$ret" != "0" ]; then
echo fail
echo
echo "We found Qt in $QTDIR, but the location of moc"
echo "($m) is not suitable for use with this build system."
echo "This is a VERY unusual and likely-broken setup. You"
echo "should contact the maintainer of your Qt package."
echo
exit 1;
fi
QTDIR=$qtpre
fi
fi
if [ ! -x "$QTDIR/bin/qmake" ]; then
if [ "$QC_DEBUG" = "Y" ]; then
echo Warning: qmake not in \$QTDIR/bin/qmake
echo trying to find it in \$PATH
fi
qm=`which qmake 2>/dev/null`
if [ -x "$qm" ]; then
if [ "$QC_DEBUG" = "Y" ]; then
echo qmake found in $qm
fi
else
echo fail
echo
echo Sorry, you seem to have a very unusual setup,
echo or I missdetected \$QTDIR=$QTDIR
echo
echo Please set \$QTDIR manually and make sure that
echo \$QTDIR/bin/qmake exists.
echo
exit 1;
fi
else
qm=$QTDIR/bin/qmake
fi
gen_files() {
cat >$1/modules.cpp <<EOT
EOT
cat >$1/modules_new.cpp <<EOT
EOT
cat >$1/conf.cpp <<EOT
#include<stdio.h>
#include<stdlib.h>
#include<qstring.h>
#include<qdict.h>
#include<qptrlist.h>
#include<qfileinfo.h>
#include<qfile.h>
#include<qdir.h>
#include<qstringlist.h>
#include<qobject.h>
class MocTestObject : public QObject
{
Q_OBJECT
public:
MocTestObject() {}
};
class Conf;
class ConfObj
{
public:
ConfObj(Conf *c);
virtual ~ConfObj();
virtual QString name() const=0;
virtual QString shortname() const=0;
virtual QString checkString() const;
virtual QString resultString() const;
virtual bool exec()=0;
Conf *conf;
bool required;
bool disabled;
};
typedef QPtrList<ConfObj> ConfObjList;
typedef QPtrListIterator<ConfObj> ConfObjListIt;
class Conf
{
public:
Conf() : vars(17)
{
list.setAutoDelete(true);
vars.setAutoDelete(true);
vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC));
vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR));
vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB));
vars.insert("QMAKE_CC", new QString(CC));
do_debug = false;
done_debug = false;
}
~Conf()
{
}
void added(ConfObj *o)
{
list.append(o);
}
QString getenv(const QString &var)
{
char *p = ::getenv(var.latin1());
if(!p)
return QString::null;
return QString(p);
}
void debug(const QString &s)
{
if(do_debug) {
if(!done_debug)
printf("\n");
done_debug = true;
printf(" * %s\n", s.latin1());
}
}
bool exec()
{
if(getenv("QC_DEBUG") == "Y")
do_debug = true;
ConfObjListIt it(list);
for(ConfObj *o; (o = it.current()); ++it) {
// if this was a disabled-by-default option, check if it was enabled
if(o->disabled) {
QString v = QString("QC_ENABLE_") + o->shortname();
if(getenv(v) != "Y")
continue;
}
// and the opposite?
else {
QString v = QString("QC_DISABLE_") + o->shortname();
if(getenv(v) == "Y")
continue;
}
QString check = o->checkString();
if(check.isEmpty())
check = QString("Checking for %1 ...").arg(o->name());
printf("%s", check.latin1());
fflush(stdout);
done_debug = false;
bool ok = o->exec();
QString result = o->resultString();
if(result.isEmpty()) {
if(ok)
result = "yes";
else
result = "no";
}
if(done_debug)
printf(" -> %s\n", result.latin1());
else
printf(" %s\n", result.latin1());
if(!ok && o->required) {
printf("\nError: need %s!\n", o->name().latin1());
return false;
}
}
return true;
}
const QString & qvar(const QString &s)
{
QString *p = vars.find(s);
if(p)
return *p;
else
return blank;
}
QString expandIncludes(const QString &inc)
{
return QString("-I") + inc;
}
QString expandLibs(const QString &lib)
{
return QString("-L") + lib;
}
int doCommand(const QString &s)
{
debug(QString("[%1]").arg(s));
QString fullcmd;
if(do_debug)
fullcmd = s;
else
fullcmd = s + " 1>/dev/null 2>/dev/null";
int r = system(fullcmd.latin1());
debug(QString("returned: %1").arg(r));
return r;
}
bool doCompileAndLink(const QString &filedata, const QString &flags, int *retcode=0)
{
QDir dir(".");
QString fname = "atest.c";
QString out = "atest";
QFile f(fname);
QCString cs = filedata.latin1();
if(!f.open(IO_WriteOnly | IO_Truncate)) {
debug("unable to open atest.c for writing");
return false;
}
if(f.writeBlock(cs.data(), cs.length()) == -1) {
debug("error writing to atest.c");
return false;
}
f.close();
debug(QString("Wrote atest.c:\n%1").arg(filedata));
QString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out;
if(!flags.isEmpty()) {
str += ' ';
str += flags;
}
int r = doCommand(str);
if(r == 0 && retcode)
*retcode = doCommand(QString("./") + out);
dir.remove(fname);
dir.remove(out);
if(r != 0)
return false;
return true;
}
bool checkHeader(const QString &path, const QString &h)
{
QFileInfo fi(path + '/' + h);
if(fi.exists())
return true;
return false;
}
bool findHeader(const QString &h, const QStringList &ext, QString *inc)
{
if(checkHeader("/usr/include", h)) {
*inc = "";
return true;
}
QStringList dirs;
dirs += "/usr/local/include";
dirs += ext;
for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
if(checkHeader(*it, h)) {
*inc = *it;
return true;
}
}
return false;
}
bool checkLibrary(const QString &path, const QString &name)
{
QString str =
"int main()\n"
"{\n"
" return 0;\n"
"}\n";
QString extra;
if(!path.isEmpty())
extra += QString("-L") + path + ' ';
extra += QString("-l") + name;
if(!doCompileAndLink(str, extra))
return false;
return true;
}
bool findLibrary(const QString &name, QString *lib)
{
if(checkLibrary("", name)) {
*lib = "";
return true;
}
if(checkLibrary("/usr/local/lib", name)) {
*lib = "/usr/local/lib";
return true;
}
return false;
}
void addDefine(const QString &str)
{
if(DEFINES.isEmpty())
DEFINES = str;
else
DEFINES += QString(" ") + str;
debug(QString("DEFINES += %1").arg(str));
}
void addLib(const QString &str)
{
if(LIBS.isEmpty())
LIBS = str;
else
LIBS += QString(" ") + str;
debug(QString("LIBS += %1").arg(str));
}
void addIncludePath(const QString &str)
{
if(INCLUDEPATH.isEmpty())
INCLUDEPATH = str;
else
INCLUDEPATH += QString(" ") + str;
debug(QString("INCLUDEPATH += %1").arg(str));
}
void addExtra(const QString &str)
{
extra += str + '\n';
debug(QString("extra += %1").arg(str));
}
QString DEFINES;
QString INCLUDEPATH;
QString LIBS;
QString extra;
private:
ConfObjList list;
QDict<QString> vars;
QString blank;
bool do_debug, done_debug;
};
ConfObj::ConfObj(Conf *c)
{
conf = c;
conf->added(this);
required = false;
disabled = false;
}
ConfObj::~ConfObj()
{
}
QString ConfObj::checkString() const
{
return QString();
}
QString ConfObj::resultString() const
{
return QString();
}
#include"modules.cpp"
//----------------------------------------------------------------------------
// main
//----------------------------------------------------------------------------
int main()
{
Conf *conf = new Conf;
ConfObj *o;
o = 0;
#include"modules_new.cpp"
printf("ok\n");
bool success = false;
if(conf->exec()) {
QFile f("conf.pri");
if(!f.open(IO_WriteOnly | IO_Truncate)) {
printf("Error writing %s\n", f.name().latin1());
return 1;
}
QString str;
str += "# qconf\n";
str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n';
if(!conf->DEFINES.isEmpty())
str += "DEFINES += " + conf->DEFINES + '\n';
if(!conf->INCLUDEPATH.isEmpty())
str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n';
if(!conf->LIBS.isEmpty())
str += "LIBS += " + conf->LIBS + '\n';
if(!conf->extra.isEmpty())
str += conf->extra;
str += '\n';
char *p = getenv("BINDIR");
if(p) {
str += QString("target.path = ") + p + '\n';
str += "INSTALLS += target\n";
}
QCString cs = str.latin1();
f.writeBlock(cs.data(), cs.length());
f.close();
success = true;
}
delete conf;
if(success)
return 0;
else
return 1;
}
#include"conf.moc"
EOT
cat >$1/conf.pro <<EOT
TEMPLATE = app
CONFIG += qt x11 thread console
TARGET = conf
DEFINES += X11_INC='"\$\$QMAKE_INCDIR_X11"'
DEFINES += X11_LIBDIR='"\$\$QMAKE_LIBDIR_X11"'
DEFINES += X11_LIB='"\$\$QMAKE_LIBS_X11"'
DEFINES += CC='"\$\$QMAKE_CC"'
SOURCES += conf.cpp
EOT
}
export PREFIX
export BINDIR
export QTDIR
export QC_DEBUG
rm -rf .qconftemp
(
mkdir .qconftemp
gen_files .qconftemp
cd .qconftemp
$qm conf.pro >/dev/null
QTDIR=$QTDIR make clean >/dev/null 2>&1
QTDIR=$QTDIR make >../conf.log 2>&1
)
if [ "$?" != "0" ]; then
rm -rf .qconftemp
echo fail
echo
echo "There was an error compiling 'conf'. Be sure you have a proper"
echo "Qt 3.x Multithreaded (MT) build environment set up. This"
echo "means not just Qt, but also a C++ compiler, the 'make' command,"
echo "and any other packages necessary to compile C++ programs."
echo "See conf.log for details."
if [ ! -f "$QTDIR/lib/libqt-mt.so.3" ]; then
echo
echo "One possible reason is that you don't have"
echo "libqt-mt.so.3 installed in $QTDIR/lib/."
fi
echo
exit 1;
fi
.qconftemp/conf
ret="$?"
if [ "$ret" = "1" ]; then
rm -rf .qconftemp
echo
exit 1;
else
if [ "$ret" != "0" ]; then
rm -rf .qconftemp
echo fail
echo
echo Unexpected error launching 'conf'
echo
exit 1;
fi
fi
rm -rf .qconftemp
if [ -x "./qcextra" ]; then
./qcextra
fi
# run qmake
$qm conntest.pro
if [ "$?" != "0" ]; then
echo
exit 1;
fi
cat >Makefile.tmp <<EOT
export QTDIR = $QTDIR
export PATH = $QTDIR/bin:$PATH
EOT
cat Makefile >> Makefile.tmp
rm -f Makefile
cp -f Makefile.tmp Makefile
rm -f Makefile.tmp
echo
echo Good, your configure finished. Now run \'make\'.
echo

View file

@ -0,0 +1,578 @@
#include <qapplication.h>
#include "bconsole.h"
#include <QtCrypto>
#include "xmpp.h"
#include <stdio.h>
#define ROOTCERT_PATH "/usr/local/share/psi/certs/rootcert.xml"
QCA::Cert readCertXml(const QDomElement &e)
{
QCA::Cert cert;
// there should be one child data tag
QDomElement data = e.elementsByTagName("data").item(0).toElement();
if(!data.isNull())
cert.fromDER(Base64::stringToArray(data.text()));
return cert;
}
QPtrList<QCA::Cert> getRootCerts(const QString &store)
{
QPtrList<QCA::Cert> list;
// open the Psi rootcerts file
QFile f(store);
if(!f.open(IO_ReadOnly)) {
printf("unable to open %s\n", f.name().latin1());
return list;
}
QDomDocument doc;
doc.setContent(&f);
f.close();
QDomElement base = doc.documentElement();
if(base.tagName() != "store") {
printf("wrong format of %s\n", f.name().latin1());
return list;
}
QDomNodeList cl = base.elementsByTagName("certificate");
if(cl.count() == 0) {
printf("no certs found in %s\n", f.name().latin1());
return list;
}
int num = 0;
for(int n = 0; n < (int)cl.count(); ++n) {
QCA::Cert *cert = new QCA::Cert(readCertXml(cl.item(n).toElement()));
if(cert->isNull()) {
printf("error reading cert\n");
delete cert;
continue;
}
++num;
list.append(cert);
}
printf("imported %d root certs\n", num);
return list;
}
static QString prompt(const QString &s)
{
printf("* %s ", s.latin1());
fflush(stdout);
char line[256];
fgets(line, 255, stdin);
QString result = line;
if(result[result.length()-1] == '\n')
result.truncate(result.length()-1);
return result;
}
static void showCertInfo(const QCA::Cert &cert)
{
fprintf(stderr, "-- Cert --\n");
fprintf(stderr, " CN: %s\n", cert.subject()["CN"].latin1());
fprintf(stderr, " Valid from: %s, until %s\n",
cert.notBefore().toString().latin1(),
cert.notAfter().toString().latin1());
fprintf(stderr, " PEM:\n%s\n", cert.toPEM().latin1());
}
static QString resultToString(int result)
{
QString s;
switch(result) {
case QCA::TLS::NoCert:
s = QObject::tr("No certificate presented.");
break;
case QCA::TLS::Valid:
break;
case QCA::TLS::HostMismatch:
s = QObject::tr("Hostname mismatch.");
break;
case QCA::TLS::Rejected:
s = QObject::tr("Root CA rejects the specified purpose.");
break;
case QCA::TLS::Untrusted:
s = QObject::tr("Not trusted for the specified purpose.");
break;
case QCA::TLS::SignatureFailed:
s = QObject::tr("Invalid signature.");
break;
case QCA::TLS::InvalidCA:
s = QObject::tr("Invalid CA certificate.");
break;
case QCA::TLS::InvalidPurpose:
s = QObject::tr("Invalid certificate purpose.");
break;
case QCA::TLS::SelfSigned:
s = QObject::tr("Certificate is self-signed.");
break;
case QCA::TLS::Revoked:
s = QObject::tr("Certificate has been revoked.");
break;
case QCA::TLS::PathLengthExceeded:
s = QObject::tr("Maximum cert chain length exceeded.");
break;
case QCA::TLS::Expired:
s = QObject::tr("Certificate has expired.");
break;
case QCA::TLS::Unknown:
default:
s = QObject::tr("General validation error.");
break;
}
return s;
}
class App : public QObject
{
Q_OBJECT
public:
XMPP::AdvancedConnector *conn;
QCA::TLS *tls;
XMPP::QCATLSHandler *tlsHandler;
XMPP::ClientStream *stream;
BConsole *c;
XMPP::Jid jid;
QPtrList<QCA::Cert> rootCerts;
App(const XMPP::Jid &_jid, const XMPP::AdvancedConnector::Proxy &proxy, const QString &host, int port, bool opt_ssl, bool opt_probe)
:QObject(0)
{
c = 0;
jid = _jid;
// Connector
conn = new XMPP::AdvancedConnector;
conn->setProxy(proxy);
if(!host.isEmpty())
conn->setOptHostPort(host, port);
conn->setOptProbe(opt_probe);
conn->setOptSSL(opt_ssl);
// TLSHandler
tls = 0;
tlsHandler = 0;
rootCerts.setAutoDelete(true);
if(QCA::isSupported(QCA::CAP_TLS)) {
rootCerts = getRootCerts(ROOTCERT_PATH);
tls = new QCA::TLS;
tls->setCertificateStore(rootCerts);
tlsHandler = new XMPP::QCATLSHandler(tls);
connect(tlsHandler, SIGNAL(tlsHandshaken()), SLOT(tls_handshaken()));
}
// Stream
stream = new XMPP::ClientStream(conn, tlsHandler);
connect(stream, SIGNAL(connected()), SLOT(cs_connected()));
connect(stream, SIGNAL(securityLayerActivated(int)), SLOT(cs_securityLayerActivated()));
connect(stream, SIGNAL(needAuthParams(bool, bool, bool)), SLOT(cs_needAuthParams(bool, bool, bool)));
connect(stream, SIGNAL(authenticated()), SLOT(cs_authenticated()));
connect(stream, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed()));
connect(stream, SIGNAL(readyRead()), SLOT(cs_readyRead()));
connect(stream, SIGNAL(stanzaWritten()), SLOT(cs_stanzaWritten()));
connect(stream, SIGNAL(warning(int)), SLOT(cs_warning(int)));
connect(stream, SIGNAL(error(int)), SLOT(cs_error(int)));
fprintf(stderr, "conntest: Connecting ...\n");
stream->setSSFRange(0, 256);
stream->connectToServer(jid);
}
~App()
{
delete stream;
delete tls; // this destroys the TLSHandler also
delete conn;
delete c;
}
signals:
void quit();
private slots:
void tls_handshaken()
{
QCA::Cert cert = tls->peerCertificate();
int vr = tls->certificateValidityResult();
fprintf(stderr, "conntest: Successful TLS handshake.\n");
if(!cert.isNull())
showCertInfo(cert);
if(vr == QCA::TLS::Valid)
fprintf(stderr, "conntest: Valid certificate.\n");
else
fprintf(stderr, "conntest: Invalid certificate: %s\n", resultToString(vr).latin1());
tlsHandler->continueAfterHandshake();
}
void cs_connected()
{
fprintf(stderr, "conntest: Connected\n");
}
void cs_securityLayerActivated()
{
fprintf(stderr, "conntest: Security layer activated (%s)\n", tls->isHandshaken() ? "TLS": "SASL");
}
void cs_needAuthParams(bool user, bool pass, bool realm)
{
fprintf(stderr, "conntest: need auth params -");
if(user)
fprintf(stderr, " (user)");
if(pass)
fprintf(stderr, " (pass)");
if(realm)
fprintf(stderr, " (realm)");
fprintf(stderr, "\n");
if(user)
stream->setUsername(jid.node());
if(pass)
stream->setPassword(prompt("Password (not hidden!) :"));
stream->continueAfterParams();
}
void cs_authenticated()
{
fprintf(stderr, "conntest: <<< Authenticated >>>\n");
// console
c = new BConsole;
connect(c, SIGNAL(connectionClosed()), SLOT(con_connectionClosed()));
connect(c, SIGNAL(readyRead()), SLOT(con_readyRead()));
}
void cs_connectionClosed()
{
fprintf(stderr, "conntest: Disconnected by peer\n");
quit();
}
void cs_readyRead()
{
for(XMPP::Stanza s; !(s = stream->read()).isNull();) {
QString str = s.toString();
printf("%s\n", str.local8Bit().data());
}
}
void cs_stanzaWritten()
{
fprintf(stderr, "conntest: Stanza written\n");
}
void cs_warning(int warn)
{
if(warn == XMPP::ClientStream::WarnOldVersion) {
fprintf(stderr, "conntest: Warning: pre-1.0 protocol server\n");
}
else if(warn == XMPP::ClientStream::WarnNoTLS) {
fprintf(stderr, "conntest: Warning: TLS not available!\n");
}
stream->continueAfterWarning();
}
void cs_error(int err)
{
if(err == XMPP::ClientStream::ErrParse) {
fprintf(stderr, "conntest: XML parsing error\n");
}
else if(err == XMPP::ClientStream::ErrProtocol) {
fprintf(stderr, "conntest: XMPP protocol error\n");
}
else if(err == XMPP::ClientStream::ErrStream) {
int x = stream->errorCondition();
QString s;
if(x == XMPP::Stream::GenericStreamError)
s = "generic stream error";
else if(x == XMPP::ClientStream::Conflict)
s = "conflict (remote login replacing this one)";
else if(x == XMPP::ClientStream::ConnectionTimeout)
s = "timed out from inactivity";
else if(x == XMPP::ClientStream::InternalServerError)
s = "internal server error";
else if(x == XMPP::ClientStream::InvalidXml)
s = "invalid XML";
else if(x == XMPP::ClientStream::PolicyViolation)
s = "policy violation. go to jail!";
else if(x == XMPP::ClientStream::ResourceConstraint)
s = "server out of resources";
else if(x == XMPP::ClientStream::SystemShutdown)
s = "system is shutting down NOW";
fprintf(stderr, "conntest: XMPP stream error: %s\n", s.latin1());
}
else if(err == XMPP::ClientStream::ErrConnection) {
int x = conn->errorCode();
QString s;
if(x == XMPP::AdvancedConnector::ErrConnectionRefused)
s = "unable to connect to server";
else if(x == XMPP::AdvancedConnector::ErrHostNotFound)
s = "host not found";
else if(x == XMPP::AdvancedConnector::ErrProxyConnect)
s = "proxy connect";
else if(x == XMPP::AdvancedConnector::ErrProxyNeg)
s = "proxy negotiating";
else if(x == XMPP::AdvancedConnector::ErrProxyAuth)
s = "proxy authorization";
else if(x == XMPP::AdvancedConnector::ErrStream)
s = "stream error";
fprintf(stderr, "conntest: connection error: %s\n", s.latin1());
}
else if(err == XMPP::ClientStream::ErrNeg) {
int x = stream->errorCondition();
QString s;
if(x == XMPP::ClientStream::HostGone)
s = "host no longer hosted";
else if(x == XMPP::ClientStream::HostUnknown)
s = "host unknown";
else if(x == XMPP::ClientStream::RemoteConnectionFailed)
s = "a required remote connection failed";
else if(x == XMPP::ClientStream::SeeOtherHost)
s = QString("see other host: [%1]").arg(stream->errorText());
else if(x == XMPP::ClientStream::UnsupportedVersion)
s = "server does not support proper xmpp version";
fprintf(stderr, "conntest: stream negotiation error: %s\n", s.latin1());
}
else if(err == XMPP::ClientStream::ErrTLS) {
int x = stream->errorCondition();
QString s;
if(x == XMPP::ClientStream::TLSStart)
s = "server rejected STARTTLS";
else if(x == XMPP::ClientStream::TLSFail) {
int t = tlsHandler->tlsError();
if(t == QCA::TLS::ErrHandshake)
s = "TLS handshake error";
else
s = "broken security layer (TLS)";
}
fprintf(stderr, "conntest: %s\n", s.latin1());
}
else if(err == XMPP::ClientStream::ErrAuth) {
int x = stream->errorCondition();
QString s;
if(x == XMPP::ClientStream::GenericAuthError)
s = "unable to login";
else if(x == XMPP::ClientStream::NoMech)
s = "no appropriate auth mechanism available for given security settings";
else if(x == XMPP::ClientStream::BadProto)
s = "bad server response";
else if(x == XMPP::ClientStream::BadServ)
s = "server failed mutual authentication";
else if(x == XMPP::ClientStream::EncryptionRequired)
s = "encryption required for chosen SASL mechanism";
else if(x == XMPP::ClientStream::InvalidAuthzid)
s = "invalid authzid";
else if(x == XMPP::ClientStream::InvalidMech)
s = "invalid SASL mechanism";
else if(x == XMPP::ClientStream::InvalidRealm)
s = "invalid realm";
else if(x == XMPP::ClientStream::MechTooWeak)
s = "SASL mechanism too weak for authzid";
else if(x == XMPP::ClientStream::NotAuthorized)
s = "not authorized";
else if(x == XMPP::ClientStream::TemporaryAuthFailure)
s = "temporary auth failure";
fprintf(stderr, "conntest: auth error: %s\n", s.latin1());
}
else if(err == XMPP::ClientStream::ErrSecurityLayer)
fprintf(stderr, "conntest: broken security layer (SASL)\n");
quit();
}
void con_connectionClosed()
{
fprintf(stderr, "conntest: Closing.\n");
stream->close();
quit();
}
void con_readyRead()
{
QByteArray a = c->read();
QCString cs;
cs.resize(a.size()+1);
memcpy(cs.data(), a.data(), a.size());
QString s = QString::fromLocal8Bit(cs);
stream->writeDirect(s);
}
};
#include "conntest.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv, false);
if(argc < 2) {
printf("usage: conntest [options] [jid]\n");
printf(" Options:\n");
printf(" --host=host:port\n");
printf(" --sslhost=host:port\n");
printf(" --probe\n");
printf(" --proxy=[https|poll|socks],host:port,url\n");
printf(" --proxy-auth=user,pass\n");
printf("\n");
return 0;
}
bool have_tls = QCA::isSupported(QCA::CAP_TLS);
XMPP::Jid jid;
XMPP::AdvancedConnector::Proxy proxy;
QString host;
int port = 0;
bool opt_ssl = false;
bool opt_probe = false;
for(int at = 1; at < argc; ++at) {
QString s = argv[at];
// is it an option?
if(s.left(2) == "--") {
QString name;
QStringList args;
int n = s.find('=', 2);
if(n != -1) {
name = s.mid(2, n-2);
++n;
args = QStringList::split(',', s.mid(n), true);
}
else {
name = s.mid(2);
args.clear();
}
// eat the arg
--argc;
for(int x = at; x < argc; ++x)
argv[x] = argv[x+1];
--at; // don't advance
// process option
if(name == "proxy") {
QString proxy_host;
int proxy_port = 0;
QString type = args[0];
QString s = args[1];
int n = s.find(':');
if(n == -1) {
if(type != "poll") {
printf("Invalid host:port for proxy\n");
return 0;
}
}
else {
proxy_host = s.mid(0, n);
++n;
proxy_port = s.mid(n).toInt();
}
if(type == "https") {
proxy.setHttpConnect(proxy_host, proxy_port);
}
else if(type == "poll") {
if(args.count() < 3) {
printf("poll needs more args\n");
return 0;
}
QString proxy_url = args[2];
proxy.setHttpPoll(proxy_host, proxy_port, proxy_url);
}
else if(type == "socks") {
proxy.setSocks(proxy_host, proxy_port);
}
else {
printf("No such proxy type '%s'\n", type.latin1());
return 0;
}
}
else if(name == "proxy-auth") {
proxy.setUserPass(args[0], args[1]);
}
else if(name == "host") {
QString s = args[0];
int n = s.find(':');
if(n == -1) {
printf("Invalid host:port for host\n");
return 0;
}
host = s.mid(0, n);
++n;
port = s.mid(n).toInt();
}
else if(name == "sslhost") {
QString s = args[0];
int n = s.find(':');
if(n == -1) {
printf("Invalid host:port for host\n");
return 0;
}
host = s.mid(0, n);
++n;
port = s.mid(n).toInt();
opt_ssl = true;
}
else if(name == "probe") {
opt_probe = true;
}
else {
printf("Unknown option '%s'\n", name.latin1());
return 0;
}
}
}
if(argc < 2) {
printf("No host specified!\n");
return 0;
}
jid = argv[1];
if((opt_ssl || opt_probe) && !have_tls) {
printf("TLS not supported, so the sslhost and probe options are not allowed.\n");
return 0;
}
printf("JID: %s\n", jid.full().latin1());
if(proxy.type() != XMPP::AdvancedConnector::Proxy::None) {
printf("Proxy: ");
if(proxy.type() == XMPP::AdvancedConnector::Proxy::HttpConnect)
printf("HttpConnect (%s:%d)", proxy.host().latin1(), proxy.port());
else if(proxy.type() == XMPP::AdvancedConnector::Proxy::HttpPoll) {
printf("HttpPoll {%s}", proxy.url().latin1());
if(!proxy.host().isEmpty()) {
printf(" (%s:%d)", proxy.host().latin1(), proxy.port());
}
}
else if(proxy.type() == XMPP::AdvancedConnector::Proxy::Socks)
printf("Socks (%s:%d)", proxy.host().latin1(), proxy.port());
printf("\n");
}
if(proxy.type() != XMPP::AdvancedConnector::Proxy::HttpPoll) {
if(!host.isEmpty()) {
printf("Host: %s:%d", host.latin1(), port);
if(opt_ssl)
printf(" (ssl)");
printf("\n");
}
else {
if(opt_probe)
printf("Probe active\n");
}
}
printf("----------\n");
App *a = new App(jid, proxy, host, port, opt_ssl, opt_probe);
QObject::connect(a, SIGNAL(quit()), &app, SLOT(quit()));
app.exec();
delete a;
return 0;
}

View file

@ -0,0 +1,15 @@
TEMPLATE = app
CONFIG += qt thread console
TARGET = conntest
QT += qt3support network xml
# Dependencies
CONFIG += crypto
include(../../../cutestuff/cutestuff.pri)
include(../../iris.pri)
irisnet {
include(../../irisnet/irisnet.pri)
}
SOURCES += conntest.cpp

View file

@ -0,0 +1,4 @@
<qconf>
<name>Iris Conntest</name>
<profile>conntest.pro</profile>
</qconf>

View file

@ -0,0 +1,30 @@
#!/bin/sh
CS_BASE=../../../cutestuff
QCA_BASE=../../../qca
IRIS_BASE=../..
# import cutestuff
mkdir cutestuff
cp -a $CS_BASE/util cutestuff
cp -a $CS_BASE/network cutestuff
# import qca
mkdir qca
cp -a $QCA_BASE/src/* qca
# import iris
mkdir iris
cp -a $IRIS_BASE/libidn iris
cp -a $IRIS_BASE/libidn.pri iris
cp -a $IRIS_BASE/include iris
cp -a $IRIS_BASE/xmpp-core iris
cp -a $IRIS_BASE/xmpp-im iris
cp -a $IRIS_BASE/jabber iris
cp -a $IRIS_BASE/iris.pri iris
# other stuff
cp -a $IRIS_BASE/cs.pri .
cp -a $IRIS_BASE/example/example.pri .
cp -a $IRIS_BASE/COPYING .