fix tests (TODO filetransfer)

This commit is contained in:
Vitaly Takmazov 2015-10-15 15:41:16 +03:00
parent b9d0590c67
commit 20d8dd690e
73 changed files with 18140 additions and 18267 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +1,61 @@
Prerequisites
=============
1. Microsoft Visual C++ 2010 Express or higher edition (http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express)
2. Git for Windows (http://code.google.com/p/msysgit/downloads/list)
3. CMake 2.8 or newer (http://www.cmake.org/cmake/resources/software.html)
4. Python 2.x for Swiften build scripts (scons) (http://www.python.org)
Libraries
=========
3. Swiften library (http://swift.im/git/swift)
4. Boost 1.48 or newer (http://sourceforge.net/projects/boost/files/boost/1.49.0/)
5. Google ProtoBuf library (http://code.google.com/p/protobuf/downloads/list)
Environment
===========
To create spectrum build environment do:
0. Create directory where we'll install all dependencies, e.g. C:\env-msvc-x64.
Create C:\env-msvc-x64\bin and add it to %PATH%.
Assuming you have git, python and cmake in %PATH%,
launch "Visual Studio 2010 command prompt" or
"Visual Studio 2010(x64) command prompt", depends on your target (Windows x86 or Windows x86_64).
1. unpack and build boost libraries:
bootstrap.bat
b2.exe --without-mpi --without-python
b2.exe --without-mpi --without-python install --prefix=C:\env-msvc-x64 release
2. clone swift repository and build it. Don't forget to point it to our env directory:
git clone git://swift.im/swift
cd swift
echo boost_includedir="c:/env-msvc-x64/include/boost-1_49" > config.py
echo boost_libdir="c:/env-msvc-x64/lib" >> config.py
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 force_configure=1
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 C:\env-msvc-x64
3. unpack and compile protobuf as described in its documentation.
Run extract_includes.bat in vsprojects/ directory and move resulting vsprojects/include/google/ directory to our C:\env-msvc-x64\include
Move protoc.exe to C:\env-msvc-x64\bin\ and libprotobuf.lib to C:\env-msvc-x64\lib
4. Install gtkmm
Download installer from https://live.gnome.org/gtkmm/MSWindows and install gtkmm into C:\env-msvc-x64\
5. Install libpurple headers
Download http://www.pidgin.im/download/source/ , extract it and copy libpurple directory in C:\env-msvc-x64\include
6. You're ready! :) Clone libtransport into C:\env-msvc-x64\libtransport (You *must* clone it into this directory, because libtransport will try to find the dependencies in ../lib and ../include)
Compile it as:
set CMAKE_INCLUDE_PATH=C:\env-msvc-x64\include
cmake . -G "NMake Makefiles" -DBOOST_INCLUDEDIR=../include/boost-1_49 -DBOOST_LIBRARYDIR=../lib -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=C:\env-msvc-x64 -DGIT_EXECUTABLE="c:\Program Files (x86)\git\bin\git.exe"
nmake
Prerequisites
=============
1. Microsoft Visual C++ 2010 Express or higher edition (http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express)
2. Git for Windows (http://code.google.com/p/msysgit/downloads/list)
3. CMake 2.8 or newer (http://www.cmake.org/cmake/resources/software.html)
4. Python 2.x for Swiften build scripts (scons) (http://www.python.org)
Libraries
=========
3. Swiften library (http://swift.im/git/swift)
4. Boost 1.48 or newer (http://sourceforge.net/projects/boost/files/boost/1.49.0/)
5. Google ProtoBuf library (http://code.google.com/p/protobuf/downloads/list)
Environment
===========
To create spectrum build environment do:
0. Create directory where we'll install all dependencies, e.g. C:\env-msvc-x64.
Create C:\env-msvc-x64\bin and add it to %PATH%.
Assuming you have git, python and cmake in %PATH%,
launch "Visual Studio 2010 command prompt" or
"Visual Studio 2010(x64) command prompt", depends on your target (Windows x86 or Windows x86_64).
1. unpack and build boost libraries:
bootstrap.bat
b2.exe --without-mpi --without-python
b2.exe --without-mpi --without-python install --prefix=C:\env-msvc-x64 release
2. clone swift repository and build it. Don't forget to point it to our env directory:
git clone git://swift.im/swift
cd swift
echo boost_includedir="c:/env-msvc-x64/include/boost-1_49" > config.py
echo boost_libdir="c:/env-msvc-x64/lib" >> config.py
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 force_configure=1
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 C:\env-msvc-x64
3. unpack and compile protobuf as described in its documentation.
Run extract_includes.bat in vsprojects/ directory and move resulting vsprojects/include/google/ directory to our C:\env-msvc-x64\include
Move protoc.exe to C:\env-msvc-x64\bin\ and libprotobuf.lib to C:\env-msvc-x64\lib
4. Install gtkmm
Download installer from https://live.gnome.org/gtkmm/MSWindows and install gtkmm into C:\env-msvc-x64\
5. Install libpurple headers
Download http://www.pidgin.im/download/source/ , extract it and copy libpurple directory in C:\env-msvc-x64\include
6. You're ready! :) Clone libtransport into C:\env-msvc-x64\libtransport (You *must* clone it into this directory, because libtransport will try to find the dependencies in ../lib and ../include)
Compile it as:
set CMAKE_INCLUDE_PATH=C:\env-msvc-x64\include
cmake . -G "NMake Makefiles" -DBOOST_INCLUDEDIR=../include/boost-1_49 -DBOOST_LIBRARYDIR=../lib -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=C:\env-msvc-x64 -DGIT_EXECUTABLE="c:\Program Files (x86)\git\bin\git.exe"
nmake

View File

@ -1,12 +1,12 @@
cmake_minimum_required(VERSION 2.6)
ADD_SUBDIRECTORY(dfrotz)
FILE(GLOB SRC *.c *.cpp)
ADD_EXECUTABLE(spectrum2_frotz_backend ${SRC})
target_link_libraries(spectrum2_frotz_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
INSTALL(TARGETS spectrum2_frotz_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
ADD_SUBDIRECTORY(dfrotz)
FILE(GLOB SRC *.c *.cpp)
ADD_EXECUTABLE(spectrum2_frotz_backend ${SRC})
target_link_libraries(spectrum2_frotz_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
INSTALL(TARGETS spectrum2_frotz_backend RUNTIME DESTINATION bin)

View File

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC common/*.c dumb/*.c)
ADD_EXECUTABLE(dfrotz ${SRC})
# target_link_libraries(dfrotz)
INSTALL(TARGETS dfrotz RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC common/*.c dumb/*.c)
ADD_EXECUTABLE(dfrotz ${SRC})
# target_link_libraries(dfrotz)
INSTALL(TARGETS dfrotz RUNTIME DESTINATION bin)

View File

@ -1,13 +1,13 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
FILE(GLOB HEADERS *.h)
QT4_WRAP_CPP(SRC ${HEADERS} OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
ADD_EXECUTABLE(spectrum2_libcommuni_backend ${SRC})
if (NOT WIN32)
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport pthread)
else ()
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport)
endif()
INSTALL(TARGETS spectrum2_libcommuni_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
FILE(GLOB HEADERS *.h)
QT4_WRAP_CPP(SRC ${HEADERS} OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
ADD_EXECUTABLE(spectrum2_libcommuni_backend ${SRC})
if (NOT WIN32)
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport pthread)
else ()
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport)
endif()
INSTALL(TARGETS spectrum2_libcommuni_backend RUNTIME DESTINATION bin)

View File

@ -1,17 +1,17 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2_libpurple_backend ${SRC})
if(CMAKE_COMPILER_IS_GNUCXX)
if (NOT WIN32)
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
else()
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
endif()
else()
target_link_libraries(spectrum2_libpurple_backend sqlite3 ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin ${PROTOBUF_LIBRARY})
endif()
INSTALL(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2_libpurple_backend ${SRC})
if(CMAKE_COMPILER_IS_GNUCXX)
if (NOT WIN32)
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
else()
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
endif()
else()
target_link_libraries(spectrum2_libpurple_backend sqlite3 ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin ${PROTOBUF_LIBRARY})
endif()
INSTALL(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin)

View File

@ -1,14 +1,14 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB_RECURSE SRC *.c *.cpp)
ADD_DEFINITIONS(-DHAVE_STDINT_H=1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/yahoo)
ADD_EXECUTABLE(spectrum2_libyahoo2_backend ${SRC})
target_link_libraries(spectrum2_libyahoo2_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
INSTALL(TARGETS spectrum2_libyahoo2_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB_RECURSE SRC *.c *.cpp)
ADD_DEFINITIONS(-DHAVE_STDINT_H=1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/yahoo)
ADD_EXECUTABLE(spectrum2_libyahoo2_backend ${SRC})
target_link_libraries(spectrum2_libyahoo2_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
INSTALL(TARGETS spectrum2_libyahoo2_backend RUNTIME DESTINATION bin)

View File

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2_skype_backend ${SRC})
target_link_libraries(spectrum2_skype_backend ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport pthread ${LIBDBUSGLIB_LIBRARIES})
INSTALL(TARGETS spectrum2_skype_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2_skype_backend ${SRC})
target_link_libraries(spectrum2_skype_backend ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport pthread ${LIBDBUSGLIB_LIBRARIES})
INSTALL(TARGETS spectrum2_skype_backend RUNTIME DESTINATION bin)

View File

@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.c *.cpp)
ADD_EXECUTABLE(spectrum2_smstools3_backend ${SRC})
target_link_libraries(spectrum2_smstools3_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
INSTALL(TARGETS spectrum2_smstools3_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.c *.cpp)
ADD_EXECUTABLE(spectrum2_smstools3_backend ${SRC})
target_link_libraries(spectrum2_smstools3_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
INSTALL(TARGETS spectrum2_smstools3_backend RUNTIME DESTINATION bin)

View File

@ -1,14 +1,14 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2_swiften_backend ${SRC})
IF (NOT WIN32)
target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
else()
target_link_libraries(spectrum2_swiften_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
endif()
INSTALL(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2_swiften_backend ${SRC})
IF (NOT WIN32)
target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
else()
target_link_libraries(spectrum2_swiften_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
endif()
INSTALL(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION bin)

View File

@ -1,455 +1,455 @@
// Transport includes
#include "transport/config.h"
#include "transport/networkplugin.h"
#include "transport/logging.h"
#include "boost/date_time/posix_time/posix_time.hpp"
// Swiften
#include "Swiften/Swiften.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#ifndef WIN32
// for signal handler
#include "unistd.h"
#include "signal.h"
#include "sys/wait.h"
#include "sys/signal.h"
#endif
#ifndef __FreeBSD__
#ifndef __MACH__
// malloc_trim
#include "malloc.h"
#endif
#endif
// Boost
#include <boost/algorithm/string.hpp>
using namespace boost::filesystem;
using namespace boost::program_options;
using namespace Transport;
DEFINE_LOGGER(logger, "Swiften");
DEFINE_LOGGER(logger_xml, "backend.xml");
// eventloop
Swift::SimpleEventLoop *loop_;
// Plugins
class SwiftenPlugin;
NetworkPlugin *np = NULL;
Swift::XMPPSerializer *serializer;
class ForwardIQHandler : public Swift::IQHandler {
public:
std::map <std::string, std::string> m_id2resource;
ForwardIQHandler(NetworkPlugin *np, const std::string &user) {
m_np = np;
m_user = user;
}
bool handleIQ(boost::shared_ptr<Swift::IQ> iq) {
if (iq->getPayload<Swift::RosterPayload>() != NULL) {
return false;
}
if (iq->getType() == Swift::IQ::Get) {
m_id2resource[iq->getID()] = iq->getFrom().getResource();
}
iq->setTo(m_user);
std::string xml = safeByteArrayToString(serializer->serializeElement(iq));
m_np->sendRawXML(xml);
return true;
}
private:
NetworkPlugin *m_np;
std::string m_user;
};
class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient {
public:
Swift::BoostNetworkFactories *m_factories;
Swift::BoostIOServiceThread m_boostIOServiceThread;
boost::shared_ptr<Swift::Connection> m_conn;
bool m_firstPing;
Swift::FullPayloadSerializerCollection collection;
Swift::XMPPParser *m_xmppParser;
Swift::FullPayloadParserFactoryCollection m_collection2;
SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
this->config = config;
m_firstPing = true;
m_factories = new Swift::BoostNetworkFactories(loop);
m_conn = m_factories->getConnectionFactory()->createConnection();
m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1));
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
#if HAVE_SWIFTEN_3
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType, false);
#else
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType);
#endif
m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory());
m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
LOG4CXX_INFO(logger, "Starting the plugin.");
}
// NetworkPlugin uses this method to send the data to networkplugin server
void sendData(const std::string &string) {
m_conn->write(Swift::createSafeByteArray(string));
}
// This method has to call handleDataRead with all received data from network plugin server
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
if (m_firstPing) {
m_firstPing = false;
NetworkPlugin::PluginConfig cfg;
cfg.setRawXML(true);
sendConfig(cfg);
}
std::string d(data->begin(), data->end());
handleDataRead(d);
}
void handleStreamStart(const Swift::ProtocolHeader&) {}
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
#else
void handleElement(boost::shared_ptr<Swift::Element> element) {
#endif
boost::shared_ptr<Swift::Stanza> stanza = boost::dynamic_pointer_cast<Swift::Stanza>(element);
if (!stanza) {
return;
}
std::string user = stanza->getFrom().toBare();
boost::shared_ptr<Swift::Client> client = m_users[user];
if (!client)
return;
stanza->setFrom(client->getJID());
boost::shared_ptr<Swift::Message> message = boost::dynamic_pointer_cast<Swift::Message>(stanza);
if (message) {
client->sendMessage(message);
return;
}
boost::shared_ptr<Swift::Presence> presence = boost::dynamic_pointer_cast<Swift::Presence>(stanza);
if (presence) {
client->sendPresence(presence);
return;
}
boost::shared_ptr<Swift::IQ> iq = boost::dynamic_pointer_cast<Swift::IQ>(stanza);
if (iq) {
if (m_handlers[user]->m_id2resource.find(stanza->getID()) != m_handlers[user]->m_id2resource.end()) {
std::string resource = m_handlers[user]->m_id2resource[stanza->getID()];
if (resource.empty()) {
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain()));
} else {
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), resource));
}
m_handlers[user]->m_id2resource.erase(stanza->getID());
}
client->getIQRouter()->sendIQ(iq);
return;
}
}
void handleStreamEnd() {}
void handleRawXML(const std::string &xml) {
m_xmppParser->parse(xml);
}
void handleSwiftDisconnected(const std::string &user, const boost::optional<Swift::ClientError> &error) {
std::string message = "";
bool reconnect = false;
if (error) {
switch(error->getType()) {
case Swift::ClientError::UnknownError: message = ("Unknown Error"); reconnect = true; break;
case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break;
case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break;
case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); reconnect = true; break;
case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); reconnect = true; break;
case Swift::ClientError::XMLError: message = ("Error parsing server data"); reconnect = true; break;
case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break;
case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break;
case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break;
case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break;
case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break;
case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break;
case Swift::ClientError::SessionStartError: message = ("Error starting session"); break;
case Swift::ClientError::StreamError: message = ("Stream error"); break;
case Swift::ClientError::TLSError: message = ("Encryption error"); break;
case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break;
case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break;
case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break;
case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break;
case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break;
case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break;
case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break;
case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break;
case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break;
case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break;
case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break;
case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break;
case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break;
}
}
LOG4CXX_INFO(logger, user << ": Disconnected " << message);
handleDisconnected(user, reconnect ? 0 : 3, message);
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
m_users.erase(user);
m_handlers.erase(user);
}
#ifndef WIN32
#ifndef __FreeBSD__
#ifndef __MACH__
// force returning of memory chunks allocated by libxml2 to kernel
malloc_trim(0);
#endif
#endif
#endif
}
void handleSwiftConnected(const std::string &user) {
LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
handleConnected(user);
m_users[user]->requestRoster();
Swift::Presence::ref response = Swift::Presence::create();
response->setFrom(m_users[user]->getJID());
m_users[user]->sendPresence(response);
}
void handleSwiftRosterReceived(const std::string &user) {
Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle();
BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) {
Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID());
pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE;
handleBuddyChanged(user, item.getJID().toBare().toString(),
item.getName(), item.getGroups(), status);
}
}
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
// boost::shared_ptr<Swift::Client> client = m_users[user];
// if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) {
// return;
// }
//
// if (presence->getPayload<Swift::MUCUserPayload>() != NULL || presence->getPayload<Swift::MUCPayload>() != NULL) {
// return;
// }
//
// LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
//
// std::string message = presence->getStatus();
// std::string photo = "";
//
// boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>();
// if (update) {
// photo = update->getPhotoHash();
// }
//
// boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom());
// if (item) {
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo);
// }
// else {
// std::vector<std::string> groups;
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo);
// }
presence->setTo(user);
std::string xml = safeByteArrayToString(serializer->serializeElement(presence));
sendRawXML(xml);
}
void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) {
message->setTo(user);
std::string xml = safeByteArrayToString(serializer->serializeElement(message));
sendRawXML(xml);
}
void handleSwiftenDataRead(const Swift::SafeByteArray &data) {
std::string d = safeByteArrayToString(data);
if (!boost::starts_with(d, "<auth")) {
LOG4CXX_INFO(logger_xml, "XML IN " << d);
}
}
void handleSwiftenDataWritten(const Swift::SafeByteArray &data) {
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
}
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
boost::shared_ptr<Swift::Client> client = boost::make_shared<Swift::Client>(Swift::JID(legacyName + "/Spectrum"), password, m_factories);
m_users[user] = client;
client->setAlwaysTrustCertificates();
client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
client->onDataRead.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataRead, this, _1));
client->onDataWritten.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataWritten, this, _1));
client->getSubscriptionManager()->onPresenceSubscriptionRequest.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRequest, this, user, _1, _2, _3));
client->getSubscriptionManager()->onPresenceSubscriptionRevoked.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRevoked, this, user, _1, _2));
Swift::ClientOptions opt;
opt.allowPLAINWithoutTLS = true;
client->connect(opt);
boost::shared_ptr<ForwardIQHandler> handler = boost::make_shared<ForwardIQHandler>(this, user);
client->getIQRouter()->addHandler(handler);
m_handlers[user] = handler;
}
void handleSubscriptionRequest(const std::string &user, const Swift::JID& jid, const std::string& message, Swift::Presence::ref presence) {
handleSwiftPresenceChanged(user, presence);
}
void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setTo(user);
presence->setFrom(jid);
presence->setType(Swift::Presence::Unsubscribe);
handleSwiftPresenceChanged(user, presence);
}
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
// client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
client->disconnect();
}
}
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") {
}
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
}
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
if (!client->getRoster()->containsJID(buddyName) || client->getRoster()->getSubscriptionStateForJID(buddyName) != Swift::RosterItemPayload::Both) {
Swift::RosterItemPayload item;
item.setName(alias);
item.setJID(buddyName);
item.setGroups(groups);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
client->getSubscriptionManager()->requestSubscription(buddyName);
}
else {
Swift::JID contact(buddyName);
Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact));
item.setGroups(groups);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
}
}
}
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
}
}
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
}
void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
}
private:
Config *config;
std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
std::map<std::string, boost::shared_ptr<ForwardIQHandler> > m_handlers;
};
#ifndef WIN32
static void spectrum_sigchld_handler(int sig)
{
int status;
pid_t pid;
do {
pid = waitpid(-1, &status, WNOHANG);
} while (pid != 0 && pid != (pid_t)-1);
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
char errmsg[BUFSIZ];
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
perror(errmsg);
}
}
#endif
int main (int argc, char* argv[]) {
std::string host;
int port;
#ifndef WIN32
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
std::cout << "SIGCHLD handler can't be set\n";
return -1;
}
#endif
std::string error;
Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
if (cfg == NULL) {
std::cerr << error;
return 1;
}
Logging::initBackendLogging(cfg);
Swift::SimpleEventLoop eventLoop;
loop_ = &eventLoop;
np = new SwiftenPlugin(cfg, &eventLoop, host, port);
loop_->run();
return 0;
}
// Transport includes
#include "transport/config.h"
#include "transport/networkplugin.h"
#include "transport/logging.h"
#include "boost/date_time/posix_time/posix_time.hpp"
// Swiften
#include "Swiften/Swiften.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#ifndef WIN32
// for signal handler
#include "unistd.h"
#include "signal.h"
#include "sys/wait.h"
#include "sys/signal.h"
#endif
#ifndef __FreeBSD__
#ifndef __MACH__
// malloc_trim
#include "malloc.h"
#endif
#endif
// Boost
#include <boost/algorithm/string.hpp>
using namespace boost::filesystem;
using namespace boost::program_options;
using namespace Transport;
DEFINE_LOGGER(logger, "Swiften");
DEFINE_LOGGER(logger_xml, "backend.xml");
// eventloop
Swift::SimpleEventLoop *loop_;
// Plugins
class SwiftenPlugin;
NetworkPlugin *np = NULL;
Swift::XMPPSerializer *serializer;
class ForwardIQHandler : public Swift::IQHandler {
public:
std::map <std::string, std::string> m_id2resource;
ForwardIQHandler(NetworkPlugin *np, const std::string &user) {
m_np = np;
m_user = user;
}
bool handleIQ(boost::shared_ptr<Swift::IQ> iq) {
if (iq->getPayload<Swift::RosterPayload>() != NULL) {
return false;
}
if (iq->getType() == Swift::IQ::Get) {
m_id2resource[iq->getID()] = iq->getFrom().getResource();
}
iq->setTo(m_user);
std::string xml = safeByteArrayToString(serializer->serializeElement(iq));
m_np->sendRawXML(xml);
return true;
}
private:
NetworkPlugin *m_np;
std::string m_user;
};
class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient {
public:
Swift::BoostNetworkFactories *m_factories;
Swift::BoostIOServiceThread m_boostIOServiceThread;
boost::shared_ptr<Swift::Connection> m_conn;
bool m_firstPing;
Swift::FullPayloadSerializerCollection collection;
Swift::XMPPParser *m_xmppParser;
Swift::FullPayloadParserFactoryCollection m_collection2;
SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
this->config = config;
m_firstPing = true;
m_factories = new Swift::BoostNetworkFactories(loop);
m_conn = m_factories->getConnectionFactory()->createConnection();
m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1));
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
#if HAVE_SWIFTEN_3
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType, false);
#else
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType);
#endif
m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory());
m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
LOG4CXX_INFO(logger, "Starting the plugin.");
}
// NetworkPlugin uses this method to send the data to networkplugin server
void sendData(const std::string &string) {
m_conn->write(Swift::createSafeByteArray(string));
}
// This method has to call handleDataRead with all received data from network plugin server
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
if (m_firstPing) {
m_firstPing = false;
NetworkPlugin::PluginConfig cfg;
cfg.setRawXML(true);
sendConfig(cfg);
}
std::string d(data->begin(), data->end());
handleDataRead(d);
}
void handleStreamStart(const Swift::ProtocolHeader&) {}
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
#else
void handleElement(boost::shared_ptr<Swift::Element> element) {
#endif
boost::shared_ptr<Swift::Stanza> stanza = boost::dynamic_pointer_cast<Swift::Stanza>(element);
if (!stanza) {
return;
}
std::string user = stanza->getFrom().toBare();
boost::shared_ptr<Swift::Client> client = m_users[user];
if (!client)
return;
stanza->setFrom(client->getJID());
boost::shared_ptr<Swift::Message> message = boost::dynamic_pointer_cast<Swift::Message>(stanza);
if (message) {
client->sendMessage(message);
return;
}
boost::shared_ptr<Swift::Presence> presence = boost::dynamic_pointer_cast<Swift::Presence>(stanza);
if (presence) {
client->sendPresence(presence);
return;
}
boost::shared_ptr<Swift::IQ> iq = boost::dynamic_pointer_cast<Swift::IQ>(stanza);
if (iq) {
if (m_handlers[user]->m_id2resource.find(stanza->getID()) != m_handlers[user]->m_id2resource.end()) {
std::string resource = m_handlers[user]->m_id2resource[stanza->getID()];
if (resource.empty()) {
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain()));
} else {
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), resource));
}
m_handlers[user]->m_id2resource.erase(stanza->getID());
}
client->getIQRouter()->sendIQ(iq);
return;
}
}
void handleStreamEnd() {}
void handleRawXML(const std::string &xml) {
m_xmppParser->parse(xml);
}
void handleSwiftDisconnected(const std::string &user, const boost::optional<Swift::ClientError> &error) {
std::string message = "";
bool reconnect = false;
if (error) {
switch(error->getType()) {
case Swift::ClientError::UnknownError: message = ("Unknown Error"); reconnect = true; break;
case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break;
case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break;
case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); reconnect = true; break;
case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); reconnect = true; break;
case Swift::ClientError::XMLError: message = ("Error parsing server data"); reconnect = true; break;
case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break;
case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break;
case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break;
case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break;
case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break;
case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break;
case Swift::ClientError::SessionStartError: message = ("Error starting session"); break;
case Swift::ClientError::StreamError: message = ("Stream error"); break;
case Swift::ClientError::TLSError: message = ("Encryption error"); break;
case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break;
case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break;
case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break;
case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break;
case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break;
case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break;
case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break;
case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break;
case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break;
case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break;
case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break;
case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break;
case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break;
}
}
LOG4CXX_INFO(logger, user << ": Disconnected " << message);
handleDisconnected(user, reconnect ? 0 : 3, message);
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
m_users.erase(user);
m_handlers.erase(user);
}
#ifndef WIN32
#ifndef __FreeBSD__
#ifndef __MACH__
// force returning of memory chunks allocated by libxml2 to kernel
malloc_trim(0);
#endif
#endif
#endif
}
void handleSwiftConnected(const std::string &user) {
LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
handleConnected(user);
m_users[user]->requestRoster();
Swift::Presence::ref response = Swift::Presence::create();
response->setFrom(m_users[user]->getJID());
m_users[user]->sendPresence(response);
}
void handleSwiftRosterReceived(const std::string &user) {
Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle();
BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) {
Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID());
pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE;
handleBuddyChanged(user, item.getJID().toBare().toString(),
item.getName(), item.getGroups(), status);
}
}
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
// boost::shared_ptr<Swift::Client> client = m_users[user];
// if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) {
// return;
// }
//
// if (presence->getPayload<Swift::MUCUserPayload>() != NULL || presence->getPayload<Swift::MUCPayload>() != NULL) {
// return;
// }
//
// LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
//
// std::string message = presence->getStatus();
// std::string photo = "";
//
// boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>();
// if (update) {
// photo = update->getPhotoHash();
// }
//
// boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom());
// if (item) {
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo);
// }
// else {
// std::vector<std::string> groups;
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo);
// }
presence->setTo(user);
std::string xml = safeByteArrayToString(serializer->serializeElement(presence));
sendRawXML(xml);
}
void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) {
message->setTo(user);
std::string xml = safeByteArrayToString(serializer->serializeElement(message));
sendRawXML(xml);
}
void handleSwiftenDataRead(const Swift::SafeByteArray &data) {
std::string d = safeByteArrayToString(data);
if (!boost::starts_with(d, "<auth")) {
LOG4CXX_INFO(logger_xml, "XML IN " << d);
}
}
void handleSwiftenDataWritten(const Swift::SafeByteArray &data) {
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
}
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
boost::shared_ptr<Swift::Client> client = boost::make_shared<Swift::Client>(Swift::JID(legacyName + "/Spectrum"), password, m_factories);
m_users[user] = client;
client->setAlwaysTrustCertificates();
client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
client->onDataRead.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataRead, this, _1));
client->onDataWritten.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataWritten, this, _1));
client->getSubscriptionManager()->onPresenceSubscriptionRequest.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRequest, this, user, _1, _2, _3));
client->getSubscriptionManager()->onPresenceSubscriptionRevoked.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRevoked, this, user, _1, _2));
Swift::ClientOptions opt;
opt.allowPLAINWithoutTLS = true;
client->connect(opt);
boost::shared_ptr<ForwardIQHandler> handler = boost::make_shared<ForwardIQHandler>(this, user);
client->getIQRouter()->addHandler(handler);
m_handlers[user] = handler;
}
void handleSubscriptionRequest(const std::string &user, const Swift::JID& jid, const std::string& message, Swift::Presence::ref presence) {
handleSwiftPresenceChanged(user, presence);
}
void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setTo(user);
presence->setFrom(jid);
presence->setType(Swift::Presence::Unsubscribe);
handleSwiftPresenceChanged(user, presence);
}
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
// client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
client->disconnect();
}
}
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") {
}
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
}
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
if (!client->getRoster()->containsJID(buddyName) || client->getRoster()->getSubscriptionStateForJID(buddyName) != Swift::RosterItemPayload::Both) {
Swift::RosterItemPayload item;
item.setName(alias);
item.setJID(buddyName);
item.setGroups(groups);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
client->getSubscriptionManager()->requestSubscription(buddyName);
}
else {
Swift::JID contact(buddyName);
Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact));
item.setGroups(groups);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
}
}
}
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
}
}
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
}
void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
}
private:
Config *config;
std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
std::map<std::string, boost::shared_ptr<ForwardIQHandler> > m_handlers;
};
#ifndef WIN32
static void spectrum_sigchld_handler(int sig)
{
int status;
pid_t pid;
do {
pid = waitpid(-1, &status, WNOHANG);
} while (pid != 0 && pid != (pid_t)-1);
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
char errmsg[BUFSIZ];
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
perror(errmsg);
}
}
#endif
int main (int argc, char* argv[]) {
std::string host;
int port;
#ifndef WIN32
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
std::cout << "SIGCHLD handler can't be set\n";
return -1;
}
#endif
std::string error;
Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
if (cfg == NULL) {
std::cerr << error;
return 1;
}
Logging::initBackendLogging(cfg);
Swift::SimpleEventLoop eventLoop;
loop_ = &eventLoop;
np = new SwiftenPlugin(cfg, &eventLoop, host, port);
loop_->run();
return 0;
}

View File

@ -1,18 +1,18 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.c *.cpp)
ADD_EXECUTABLE(spectrum2_template_backend ${SRC})
if (CMAKE_COMPILER_IS_GNUCXX)
if (NOT WIN32)
target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
else()
target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
endif()
else()
target_link_libraries(spectrum2_template_backend transport ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
endif()
#INSTALL(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.c *.cpp)
ADD_EXECUTABLE(spectrum2_template_backend ${SRC})
if (CMAKE_COMPILER_IS_GNUCXX)
if (NOT WIN32)
target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
else()
target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
endif()
else()
target_link_libraries(spectrum2_template_backend transport ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
endif()
#INSTALL(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin)

File diff suppressed because it is too large Load Diff

View File

@ -1,189 +1,189 @@
#ifndef TWITTER_PLUGIN
#define TWITTER_PLUGIN
#include "transport/config.h"
#include "transport/networkplugin.h"
#include "transport/logging.h"
#include "transport/sqlite3backend.h"
#include "transport/mysqlbackend.h"
#include "transport/pqxxbackend.h"
#include "transport/storagebackend.h"
#include "transport/threadpool.h"
#include "Swiften/Swiften.h"
#ifndef _WIN32
#include "unistd.h"
#include "signal.h"
#include "sys/wait.h"
#include "sys/signal.h"
#endif
#include <boost/algorithm/string.hpp>
#include <boost/signal.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include "twitcurl.h"
#include "TwitterResponseParser.h"
#include <iostream>
#include <sstream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#include <cstdio>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#if HAVE_SWIFTEN_3
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#else
#include "Swiften/StringCodecs/SHA1.h"
#endif
using namespace boost::filesystem;
using namespace boost::program_options;
using namespace Transport;
#define STR(x) (std::string("(") + x.from + ", " + x.to + ", " + x.message + ")")
class TwitterPlugin;
extern TwitterPlugin *np;
extern Swift::SimpleEventLoop *loop_; // Event Loop
class TwitterPlugin : public NetworkPlugin {
public:
Swift::BoostNetworkFactories *m_factories;
Swift::BoostIOServiceThread m_boostIOServiceThread;
boost::shared_ptr<Swift::Connection> m_conn;
#if HAVE_SWIFTEN_3
boost::shared_ptr<Swift::CryptoProvider> cryptoProvider;
#endif
Swift::Timer::ref tweet_timer;
Swift::Timer::ref message_timer;
StorageBackend *storagebackend;
TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port);
~TwitterPlugin();
// Send data to NetworkPlugin server
void sendData(const std::string &string);
// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class)
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data);
// User trying to login into his twitter account
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
// User logging out
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/);
void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/);
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "");
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups);
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups);
void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/);
void pollForTweets();
void pollForDirectMessages();
bool getUserOAuthKeyAndSecret(const std::string user, std::string &key, std::string &secret);
bool checkSpectrum1User(const std::string user);
bool storeUserOAuthKeyAndSecret(const std::string user, const std::string OAuthKey, const std::string OAuthSecret);
void initUserSession(const std::string user, const std::string legacyName, const std::string password);
void OAuthFlowComplete(const std::string user, twitCurl *obj);
void pinExchangeComplete(const std::string user, const std::string OAuthAccessTokenKey, const std::string OAuthAccessTokenSecret);
void updateLastTweetID(const std::string user, const std::string ID);
std::string getMostRecentTweetID(const std::string user);
void updateLastDMID(const std::string user, const std::string ID);
std::string getMostRecentDMID(const std::string user);
void clearRoster(const std::string user);
int getTwitterMode(const std::string user);
bool setTwitterMode(const std::string user, int m);
/****************** Twitter response handlers **************************************/
void statusUpdateResponse(std::string &user, Error &errMsg);
void helpMessageResponse(std::string &user, std::string &msg);
void populateRoster(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
void displayFriendlist(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
void displayTweets(std::string &user, std::string &userRequested, std::vector<Status> &tweets , Error &errMsg);
void directMessageResponse(std::string &user, std::string &username, std::vector<DirectMessage> &messages, Error &errMsg);
void createFriendResponse(std::string &user, User &frnd, std::string &img, Error &errMsg);
void deleteFriendResponse(std::string &user, User &frnd, Error &errMsg);
void RetweetResponse(std::string &user, Error &errMsg);
void profileImageResponse(std::string &user, std::string &buddy, std::string &img, unsigned int reqID, Error &errMsg);
/***********************************************************************************/
private:
std::string getMostRecentTweetIDUnsafe(const std::string user);
std::string getMostRecentDMIDUnsafe(const std::string user);
enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED};
enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM};
Config *config;
std::string adminLegacyName;
std::string adminChatRoom;
std::string adminNickName;
std::string adminAlias;
std::string consumerKey;
std::string consumerSecret;
std::string OAUTH_KEY;
std::string OAUTH_SECRET;
std::string MODE;
boost::mutex dblock, userlock;
ThreadPool *tp;
std::set<std::string> onlineUsers;
struct UserData
{
std::string legacyName;
bool spectrum1User; //Legacy support
User userTwitterObj;
std::string userImg;
twitCurl* sessions;
status connectionState;
std::string mostRecentTweetID;
std::string mostRecentDirectMessageID;
std::string nickName;
std::set<std::string> buddies;
std::map<std::string, User> buddiesInfo;
std::map<std::string, std::string> buddiesImgs;
mode twitterMode;
UserData() { sessions = NULL; }
};
std::map<std::string, UserData> userdb;
bool m_firstPing;
};
#endif
#ifndef TWITTER_PLUGIN
#define TWITTER_PLUGIN
#include "transport/config.h"
#include "transport/networkplugin.h"
#include "transport/logging.h"
#include "transport/sqlite3backend.h"
#include "transport/mysqlbackend.h"
#include "transport/pqxxbackend.h"
#include "transport/storagebackend.h"
#include "transport/threadpool.h"
#include "Swiften/Swiften.h"
#ifndef _WIN32
#include "unistd.h"
#include "signal.h"
#include "sys/wait.h"
#include "sys/signal.h"
#endif
#include <boost/algorithm/string.hpp>
#include <boost/signal.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include "twitcurl.h"
#include "TwitterResponseParser.h"
#include <iostream>
#include <sstream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#include <cstdio>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#if HAVE_SWIFTEN_3
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#else
#include "Swiften/StringCodecs/SHA1.h"
#endif
using namespace boost::filesystem;
using namespace boost::program_options;
using namespace Transport;
#define STR(x) (std::string("(") + x.from + ", " + x.to + ", " + x.message + ")")
class TwitterPlugin;
extern TwitterPlugin *np;
extern Swift::SimpleEventLoop *loop_; // Event Loop
class TwitterPlugin : public NetworkPlugin {
public:
Swift::BoostNetworkFactories *m_factories;
Swift::BoostIOServiceThread m_boostIOServiceThread;
boost::shared_ptr<Swift::Connection> m_conn;
#if HAVE_SWIFTEN_3
boost::shared_ptr<Swift::CryptoProvider> cryptoProvider;
#endif
Swift::Timer::ref tweet_timer;
Swift::Timer::ref message_timer;
StorageBackend *storagebackend;
TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port);
~TwitterPlugin();
// Send data to NetworkPlugin server
void sendData(const std::string &string);
// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class)
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data);
// User trying to login into his twitter account
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
// User logging out
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/);
void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/);
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "");
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups);
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups);
void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/);
void pollForTweets();
void pollForDirectMessages();
bool getUserOAuthKeyAndSecret(const std::string user, std::string &key, std::string &secret);
bool checkSpectrum1User(const std::string user);
bool storeUserOAuthKeyAndSecret(const std::string user, const std::string OAuthKey, const std::string OAuthSecret);
void initUserSession(const std::string user, const std::string legacyName, const std::string password);
void OAuthFlowComplete(const std::string user, twitCurl *obj);
void pinExchangeComplete(const std::string user, const std::string OAuthAccessTokenKey, const std::string OAuthAccessTokenSecret);
void updateLastTweetID(const std::string user, const std::string ID);
std::string getMostRecentTweetID(const std::string user);
void updateLastDMID(const std::string user, const std::string ID);
std::string getMostRecentDMID(const std::string user);
void clearRoster(const std::string user);
int getTwitterMode(const std::string user);
bool setTwitterMode(const std::string user, int m);
/****************** Twitter response handlers **************************************/
void statusUpdateResponse(std::string &user, Error &errMsg);
void helpMessageResponse(std::string &user, std::string &msg);
void populateRoster(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
void displayFriendlist(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
void displayTweets(std::string &user, std::string &userRequested, std::vector<Status> &tweets , Error &errMsg);
void directMessageResponse(std::string &user, std::string &username, std::vector<DirectMessage> &messages, Error &errMsg);
void createFriendResponse(std::string &user, User &frnd, std::string &img, Error &errMsg);
void deleteFriendResponse(std::string &user, User &frnd, Error &errMsg);
void RetweetResponse(std::string &user, Error &errMsg);
void profileImageResponse(std::string &user, std::string &buddy, std::string &img, unsigned int reqID, Error &errMsg);
/***********************************************************************************/
private:
std::string getMostRecentTweetIDUnsafe(const std::string user);
std::string getMostRecentDMIDUnsafe(const std::string user);
enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED};
enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM};
Config *config;
std::string adminLegacyName;
std::string adminChatRoom;
std::string adminNickName;
std::string adminAlias;
std::string consumerKey;
std::string consumerSecret;
std::string OAUTH_KEY;
std::string OAUTH_SECRET;
std::string MODE;
boost::mutex dblock, userlock;
ThreadPool *tp;
std::set<std::string> onlineUsers;
struct UserData
{
std::string legacyName;
bool spectrum1User; //Legacy support
User userTwitterObj;
std::string userImg;
twitCurl* sessions;
status connectionState;
std::string mostRecentTweetID;
std::string mostRecentDirectMessageID;
std::string nickName;
std::set<std::string> buddies;
std::map<std::string, User> buddiesInfo;
std::map<std::string, std::string> buddiesImgs;
mode twitterMode;
UserData() { sessions = NULL; }
};
std::map<std::string, UserData> userdb;
bool m_firstPing;
};
#endif

View File

@ -1,64 +1,64 @@
//******************************************************************************
//* HMAC_SHA1.cpp : Implementation of HMAC SHA1 algorithm
//* Comfort to RFC 2104
//*
//******************************************************************************
#include "HMAC_SHA1.h"
#include <iostream>
#include <memory>
void CHMAC_SHA1::HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest)
{
memset(SHA1_Key, 0, SHA1_BLOCK_SIZE);
/* repeated 64 times for values in ipad and opad */
memset(m_ipad, 0x36, sizeof(m_ipad));
memset(m_opad, 0x5c, sizeof(m_opad));
/* STEP 1 */
if (key_len > SHA1_BLOCK_SIZE)
{
CSHA1::Reset();
CSHA1::Update((UINT_8 *)key, key_len);
CSHA1::Final();
CSHA1::GetHash((UINT_8 *)SHA1_Key);
}
else
memcpy(SHA1_Key, key, key_len);
/* STEP 2 */
for (size_t i=0; i<sizeof(m_ipad); i++)
{
m_ipad[i] ^= SHA1_Key[i];
}
/* STEP 3 */
memcpy(AppendBuf1, m_ipad, sizeof(m_ipad));
memcpy(AppendBuf1 + sizeof(m_ipad), text, text_len);
/* STEP 4 */
CSHA1::Reset();
CSHA1::Update((UINT_8 *)AppendBuf1, sizeof(m_ipad) + text_len);
CSHA1::Final();
CSHA1::GetHash((UINT_8 *)szReport);
/* STEP 5 */
for (size_t j=0; j<sizeof(m_opad); j++)
{
m_opad[j] ^= SHA1_Key[j];
}
/* STEP 6 */
memcpy(AppendBuf2, m_opad, sizeof(m_opad));
memcpy(AppendBuf2 + sizeof(m_opad), szReport, SHA1_DIGEST_LENGTH);
/*STEP 7 */
CSHA1::Reset();
CSHA1::Update((UINT_8 *)AppendBuf2, sizeof(m_opad) + SHA1_DIGEST_LENGTH);
CSHA1::Final();
CSHA1::GetHash((UINT_8 *)digest);
}
//******************************************************************************
//* HMAC_SHA1.cpp : Implementation of HMAC SHA1 algorithm
//* Comfort to RFC 2104
//*
//******************************************************************************
#include "HMAC_SHA1.h"
#include <iostream>
#include <memory>
void CHMAC_SHA1::HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest)
{
memset(SHA1_Key, 0, SHA1_BLOCK_SIZE);
/* repeated 64 times for values in ipad and opad */
memset(m_ipad, 0x36, sizeof(m_ipad));
memset(m_opad, 0x5c, sizeof(m_opad));
/* STEP 1 */
if (key_len > SHA1_BLOCK_SIZE)
{
CSHA1::Reset();
CSHA1::Update((UINT_8 *)key, key_len);
CSHA1::Final();
CSHA1::GetHash((UINT_8 *)SHA1_Key);
}
else
memcpy(SHA1_Key, key, key_len);
/* STEP 2 */
for (size_t i=0; i<sizeof(m_ipad); i++)
{
m_ipad[i] ^= SHA1_Key[i];
}
/* STEP 3 */
memcpy(AppendBuf1, m_ipad, sizeof(m_ipad));
memcpy(AppendBuf1 + sizeof(m_ipad), text, text_len);
/* STEP 4 */
CSHA1::Reset();
CSHA1::Update((UINT_8 *)AppendBuf1, sizeof(m_ipad) + text_len);
CSHA1::Final();
CSHA1::GetHash((UINT_8 *)szReport);
/* STEP 5 */
for (size_t j=0; j<sizeof(m_opad); j++)
{
m_opad[j] ^= SHA1_Key[j];
}
/* STEP 6 */
memcpy(AppendBuf2, m_opad, sizeof(m_opad));
memcpy(AppendBuf2 + sizeof(m_opad), szReport, SHA1_DIGEST_LENGTH);
/*STEP 7 */
CSHA1::Reset();
CSHA1::Update((UINT_8 *)AppendBuf2, sizeof(m_opad) + SHA1_DIGEST_LENGTH);
CSHA1::Final();
CSHA1::GetHash((UINT_8 *)digest);
}

View File

@ -1,53 +1,53 @@
/*
100% free public domain implementation of the HMAC-SHA1 algorithm
by Chien-Chung, Chung (Jim Chung) <jimchung1221@gmail.com>
*/
#ifndef __HMAC_SHA1_H__
#define __HMAC_SHA1_H__
#include "SHA1.h"
typedef unsigned char BYTE ;
class CHMAC_SHA1 : public CSHA1
{
private:
BYTE m_ipad[64];
BYTE m_opad[64];
char * szReport ;
char * SHA1_Key ;
char * AppendBuf1 ;
char * AppendBuf2 ;
public:
enum {
SHA1_DIGEST_LENGTH = 20,
SHA1_BLOCK_SIZE = 64,
HMAC_BUF_LEN = 4096
} ;
CHMAC_SHA1()
:szReport(new char[HMAC_BUF_LEN]),
SHA1_Key(new char[HMAC_BUF_LEN]),
AppendBuf1(new char[HMAC_BUF_LEN]),
AppendBuf2(new char[HMAC_BUF_LEN])
{}
~CHMAC_SHA1()
{
delete[] szReport ;
delete[] AppendBuf1 ;
delete[] AppendBuf2 ;
delete[] SHA1_Key ;
}
void HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest);
};
#endif /* __HMAC_SHA1_H__ */
/*
100% free public domain implementation of the HMAC-SHA1 algorithm
by Chien-Chung, Chung (Jim Chung) <jimchung1221@gmail.com>
*/
#ifndef __HMAC_SHA1_H__
#define __HMAC_SHA1_H__
#include "SHA1.h"
typedef unsigned char BYTE ;
class CHMAC_SHA1 : public CSHA1
{
private:
BYTE m_ipad[64];
BYTE m_opad[64];
char * szReport ;
char * SHA1_Key ;
char * AppendBuf1 ;
char * AppendBuf2 ;
public:
enum {
SHA1_DIGEST_LENGTH = 20,
SHA1_BLOCK_SIZE = 64,
HMAC_BUF_LEN = 4096
} ;
CHMAC_SHA1()
:szReport(new char[HMAC_BUF_LEN]),
SHA1_Key(new char[HMAC_BUF_LEN]),
AppendBuf1(new char[HMAC_BUF_LEN]),
AppendBuf2(new char[HMAC_BUF_LEN])
{}
~CHMAC_SHA1()
{
delete[] szReport ;
delete[] AppendBuf1 ;
delete[] AppendBuf2 ;
delete[] SHA1_Key ;
}
void HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest);
};
#endif /* __HMAC_SHA1_H__ */

View File

@ -1,274 +1,274 @@
/*
100% free public domain implementation of the SHA-1 algorithm
by Dominik Reichl <dominik.reichl@t-online.de>
Web: http://www.dominik-reichl.de/
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
- You can set the endianness in your files, no need to modify the
header file of the CSHA1 class any more
- Aligned data support
- Made support/compilation of the utility functions (ReportHash
and HashFile) optional (useful, if bytes count, for example in
embedded environments)
Version 1.5 - 2005-01-01
- 64-bit compiler compatibility added
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
- Removed unnecessary variable initializations
- ROL32 improvement for the Microsoft compiler (using _rotl)
======== Test Vectors (from FIPS PUB 180-1) ========
SHA1("abc") =
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
SHA1(A million repetitions of "a") =
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#include "SHA1.h"
#ifdef SHA1_UTILITY_FUNCTIONS
#define SHA1_MAX_FILE_BUFFER 8000
#endif
// Rotate x bits to the left
#ifndef ROL32
#ifdef _MSC_VER
#define ROL32(_val32, _nBits) _rotl(_val32, _nBits)
#else
#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits))))
#endif
#endif
#ifdef SHA1_LITTLE_ENDIAN
#define SHABLK0(i) (m_block->l[i] = \
(ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))
#else
#define SHABLK0(i) (m_block->l[i])
#endif
#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \
^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))
// SHA-1 rounds
#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }
CSHA1::CSHA1()
{
m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace;
Reset();
}
CSHA1::~CSHA1()
{
Reset();
}
void CSHA1::Reset()
{
// SHA1 initialization constants
m_state[0] = 0x67452301;
m_state[1] = 0xEFCDAB89;
m_state[2] = 0x98BADCFE;
m_state[3] = 0x10325476;
m_state[4] = 0xC3D2E1F0;
m_count[0] = 0;
m_count[1] = 0;
}
void CSHA1::Transform(UINT_32 *state, UINT_8 *buffer)
{
// Copy state[] to working vars
UINT_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
memcpy(m_block, buffer, 64);
// 4 rounds of 20 operations each. Loop unrolled.
_R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
_R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
_R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
_R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
_R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
_R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
_R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
_R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
_R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
_R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
_R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
_R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
_R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
_R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
_R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
_R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
_R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
_R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
_R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
_R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);
// Add the working vars back into state
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
// Wipe variables
#ifdef SHA1_WIPE_VARIABLES
a = b = c = d = e = 0;
#endif
}
// Use this function to hash in binary data and strings
void CSHA1::Update(UINT_8 *data, UINT_32 len)
{
UINT_32 i, j;
j = (m_count[0] >> 3) & 63;
if((m_count[0] += len << 3) < (len << 3)) m_count[1]++;
m_count[1] += (len >> 29);
if((j + len) > 63)
{
i = 64 - j;
memcpy(&m_buffer[j], data, i);
Transform(m_state, m_buffer);
for(; i + 63 < len; i += 64) Transform(m_state, &data[i]);
j = 0;
}
else i = 0;
memcpy(&m_buffer[j], &data[i], len - i);
}
#ifdef SHA1_UTILITY_FUNCTIONS
// Hash in file contents
bool CSHA1::HashFile(char *szFileName)
{
unsigned long ulFileSize, ulRest, ulBlocks;
unsigned long i;
UINT_8 uData[SHA1_MAX_FILE_BUFFER];
FILE *fIn;
if(szFileName == NULL) return false;
fIn = fopen(szFileName, "rb");
if(fIn == NULL) return false;
fseek(fIn, 0, SEEK_END);
ulFileSize = (unsigned long)ftell(fIn);
fseek(fIn, 0, SEEK_SET);
if(ulFileSize != 0)
{
ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER;
ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER;
}
else
{
ulBlocks = 0;
ulRest = 0;
}
for(i = 0; i < ulBlocks; i++)
{
fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn);
Update((UINT_8 *)uData, SHA1_MAX_FILE_BUFFER);
}
if(ulRest != 0)
{
fread(uData, 1, ulRest, fIn);
Update((UINT_8 *)uData, ulRest);
}
fclose(fIn); fIn = NULL;
return true;
}
#endif
void CSHA1::Final()
{
UINT_32 i;
UINT_8 finalcount[8];
for(i = 0; i < 8; i++)
finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)]
>> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
Update((UINT_8 *)"\200", 1);
while ((m_count[0] & 504) != 448)
Update((UINT_8 *)"\0", 1);
Update(finalcount, 8); // Cause a SHA1Transform()
for(i = 0; i < 20; i++)
{
m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255);
}
// Wipe variables for security reasons
#ifdef SHA1_WIPE_VARIABLES
i = 0;
memset(m_buffer, 0, 64);
memset(m_state, 0, 20);
memset(m_count, 0, 8);
memset(finalcount, 0, 8);
Transform(m_state, m_buffer);
#endif
}
#ifdef SHA1_UTILITY_FUNCTIONS
// Get the final hash as a pre-formatted string
void CSHA1::ReportHash(char *szReport, unsigned char uReportType)
{
unsigned char i;
char szTemp[16];
if(szReport == NULL) return;
if(uReportType == REPORT_HEX)
{
sprintf(szTemp, "%02X", m_digest[0]);
strcat(szReport, szTemp);
for(i = 1; i < 20; i++)
{
sprintf(szTemp, " %02X", m_digest[i]);
strcat(szReport, szTemp);
}
}
else if(uReportType == REPORT_DIGIT)
{
sprintf(szTemp, "%u", m_digest[0]);
strcat(szReport, szTemp);
for(i = 1; i < 20; i++)
{
sprintf(szTemp, " %u", m_digest[i]);
strcat(szReport, szTemp);
}
}
else strcpy(szReport, "Error: Unknown report type!");
}
#endif
// Get the raw message digest
void CSHA1::GetHash(UINT_8 *puDest)
{
memcpy(puDest, m_digest, 20);
}
/*
100% free public domain implementation of the SHA-1 algorithm
by Dominik Reichl <dominik.reichl@t-online.de>
Web: http://www.dominik-reichl.de/
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
- You can set the endianness in your files, no need to modify the
header file of the CSHA1 class any more
- Aligned data support
- Made support/compilation of the utility functions (ReportHash
and HashFile) optional (useful, if bytes count, for example in
embedded environments)
Version 1.5 - 2005-01-01
- 64-bit compiler compatibility added
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
- Removed unnecessary variable initializations
- ROL32 improvement for the Microsoft compiler (using _rotl)
======== Test Vectors (from FIPS PUB 180-1) ========
SHA1("abc") =
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
SHA1(A million repetitions of "a") =
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#include "SHA1.h"
#ifdef SHA1_UTILITY_FUNCTIONS
#define SHA1_MAX_FILE_BUFFER 8000
#endif
// Rotate x bits to the left
#ifndef ROL32
#ifdef _MSC_VER
#define ROL32(_val32, _nBits) _rotl(_val32, _nBits)
#else
#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits))))
#endif
#endif
#ifdef SHA1_LITTLE_ENDIAN
#define SHABLK0(i) (m_block->l[i] = \
(ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))
#else
#define SHABLK0(i) (m_block->l[i])
#endif
#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \
^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))
// SHA-1 rounds
#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }
CSHA1::CSHA1()
{
m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace;
Reset();
}
CSHA1::~CSHA1()
{
Reset();
}
void CSHA1::Reset()
{
// SHA1 initialization constants
m_state[0] = 0x67452301;
m_state[1] = 0xEFCDAB89;
m_state[2] = 0x98BADCFE;
m_state[3] = 0x10325476;
m_state[4] = 0xC3D2E1F0;
m_count[0] = 0;
m_count[1] = 0;
}
void CSHA1::Transform(UINT_32 *state, UINT_8 *buffer)
{
// Copy state[] to working vars
UINT_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
memcpy(m_block, buffer, 64);
// 4 rounds of 20 operations each. Loop unrolled.
_R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
_R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
_R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
_R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
_R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
_R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
_R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
_R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
_R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
_R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
_R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
_R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
_R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
_R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
_R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
_R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
_R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
_R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
_R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
_R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);
// Add the working vars back into state
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
// Wipe variables
#ifdef SHA1_WIPE_VARIABLES
a = b = c = d = e = 0;
#endif
}
// Use this function to hash in binary data and strings
void CSHA1::Update(UINT_8 *data, UINT_32 len)
{
UINT_32 i, j;
j = (m_count[0] >> 3) & 63;
if((m_count[0] += len << 3) < (len << 3)) m_count[1]++;
m_count[1] += (len >> 29);
if((j + len) > 63)
{
i = 64 - j;
memcpy(&m_buffer[j], data, i);
Transform(m_state, m_buffer);
for(; i + 63 < len; i += 64) Transform(m_state, &data[i]);
j = 0;
}
else i = 0;
memcpy(&m_buffer[j], &data[i], len - i);
}
#ifdef SHA1_UTILITY_FUNCTIONS
// Hash in file contents
bool CSHA1::HashFile(char *szFileName)
{
unsigned long ulFileSize, ulRest, ulBlocks;
unsigned long i;
UINT_8 uData[SHA1_MAX_FILE_BUFFER];
FILE *fIn;
if(szFileName == NULL) return false;
fIn = fopen(szFileName, "rb");
if(fIn == NULL) return false;
fseek(fIn, 0, SEEK_END);
ulFileSize = (unsigned long)ftell(fIn);
fseek(fIn, 0, SEEK_SET);
if(ulFileSize != 0)
{
ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER;
ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER;
}
else
{
ulBlocks = 0;
ulRest = 0;
}
for(i = 0; i < ulBlocks; i++)
{
fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn);
Update((UINT_8 *)uData, SHA1_MAX_FILE_BUFFER);
}
if(ulRest != 0)
{
fread(uData, 1, ulRest, fIn);
Update((UINT_8 *)uData, ulRest);
}
fclose(fIn); fIn = NULL;
return true;
}
#endif
void CSHA1::Final()
{
UINT_32 i;
UINT_8 finalcount[8];
for(i = 0; i < 8; i++)
finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)]
>> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
Update((UINT_8 *)"\200", 1);
while ((m_count[0] & 504) != 448)
Update((UINT_8 *)"\0", 1);
Update(finalcount, 8); // Cause a SHA1Transform()
for(i = 0; i < 20; i++)
{
m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255);
}
// Wipe variables for security reasons
#ifdef SHA1_WIPE_VARIABLES
i = 0;
memset(m_buffer, 0, 64);
memset(m_state, 0, 20);
memset(m_count, 0, 8);
memset(finalcount, 0, 8);
Transform(m_state, m_buffer);
#endif
}
#ifdef SHA1_UTILITY_FUNCTIONS
// Get the final hash as a pre-formatted string
void CSHA1::ReportHash(char *szReport, unsigned char uReportType)
{
unsigned char i;
char szTemp[16];
if(szReport == NULL) return;
if(uReportType == REPORT_HEX)
{
sprintf(szTemp, "%02X", m_digest[0]);
strcat(szReport, szTemp);
for(i = 1; i < 20; i++)
{
sprintf(szTemp, " %02X", m_digest[i]);
strcat(szReport, szTemp);
}
}
else if(uReportType == REPORT_DIGIT)
{
sprintf(szTemp, "%u", m_digest[0]);
strcat(szReport, szTemp);
for(i = 1; i < 20; i++)
{
sprintf(szTemp, " %u", m_digest[i]);
strcat(szReport, szTemp);
}
}
else strcpy(szReport, "Error: Unknown report type!");
}
#endif
// Get the raw message digest
void CSHA1::GetHash(UINT_8 *puDest)
{
memcpy(puDest, m_digest, 20);
}

View File

@ -1,148 +1,148 @@
/*
100% free public domain implementation of the SHA-1 algorithm
by Dominik Reichl <dominik.reichl@t-online.de>
Web: http://www.dominik-reichl.de/
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
- You can set the endianness in your files, no need to modify the
header file of the CSHA1 class any more
- Aligned data support
- Made support/compilation of the utility functions (ReportHash
and HashFile) optional (useful, if bytes count, for example in
embedded environments)
Version 1.5 - 2005-01-01
- 64-bit compiler compatibility added
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
- Removed unnecessary variable initializations
- ROL32 improvement for the Microsoft compiler (using _rotl)
======== Test Vectors (from FIPS PUB 180-1) ========
SHA1("abc") =
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
SHA1(A million repetitions of "a") =
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#ifndef ___SHA1_HDR___
#define ___SHA1_HDR___
#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
#define SHA1_UTILITY_FUNCTIONS
#endif
#include <memory.h> // Needed for memset and memcpy
#ifdef SHA1_UTILITY_FUNCTIONS
#include <stdio.h> // Needed for file access and sprintf
#include <string.h> // Needed for strcat and strcpy
#endif
#ifdef _MSC_VER
#include <stdlib.h>
#endif
// You can define the endian mode in your files, without modifying the SHA1
// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
// in your files, before including the SHA1.h header file. If you don't
// define anything, the class defaults to little endian.
#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
#define SHA1_LITTLE_ENDIAN
#endif
// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if
// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
// defaults to wiping.
#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
#define SHA1_WIPE_VARIABLES
#endif
/////////////////////////////////////////////////////////////////////////////
// Define 8- and 32-bit variables
#ifndef UINT_32
#ifdef _MSC_VER
#define UINT_8 unsigned __int8
#define UINT_32 unsigned __int32
#else
#define UINT_8 unsigned char
#if (ULONG_MAX == 0xFFFFFFFF)
#define UINT_32 unsigned long
#else
#define UINT_32 unsigned int
#endif
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
// Declare SHA1 workspace
typedef union
{
UINT_8 c[64];
UINT_32 l[16];
} SHA1_WORKSPACE_BLOCK;
class CSHA1
{
public:
#ifdef SHA1_UTILITY_FUNCTIONS
// Two different formats for ReportHash(...)
enum
{
REPORT_HEX = 0,
REPORT_DIGIT = 1
};
#endif
// Constructor and Destructor
CSHA1();
~CSHA1();
UINT_32 m_state[5];
UINT_32 m_count[2];
UINT_32 __reserved1[1];
UINT_8 m_buffer[64];
UINT_8 m_digest[20];
UINT_32 __reserved2[3];
void Reset();
// Update the hash value
void Update(UINT_8 *data, UINT_32 len);
#ifdef SHA1_UTILITY_FUNCTIONS
bool HashFile(char *szFileName);
#endif
// Finalize hash and report
void Final();
// Report functions: as pre-formatted and raw data
#ifdef SHA1_UTILITY_FUNCTIONS
void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX);
#endif
void GetHash(UINT_8 *puDest);
private:
// Private SHA-1 transformation
void Transform(UINT_32 *state, UINT_8 *buffer);
// Member variables
UINT_8 m_workspace[64];
SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above
};
#endif
/*
100% free public domain implementation of the SHA-1 algorithm
by Dominik Reichl <dominik.reichl@t-online.de>
Web: http://www.dominik-reichl.de/
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
- You can set the endianness in your files, no need to modify the
header file of the CSHA1 class any more
- Aligned data support
- Made support/compilation of the utility functions (ReportHash
and HashFile) optional (useful, if bytes count, for example in
embedded environments)
Version 1.5 - 2005-01-01
- 64-bit compiler compatibility added
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
- Removed unnecessary variable initializations
- ROL32 improvement for the Microsoft compiler (using _rotl)
======== Test Vectors (from FIPS PUB 180-1) ========
SHA1("abc") =
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
SHA1(A million repetitions of "a") =
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#ifndef ___SHA1_HDR___
#define ___SHA1_HDR___
#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
#define SHA1_UTILITY_FUNCTIONS
#endif
#include <memory.h> // Needed for memset and memcpy
#ifdef SHA1_UTILITY_FUNCTIONS
#include <stdio.h> // Needed for file access and sprintf
#include <string.h> // Needed for strcat and strcpy
#endif
#ifdef _MSC_VER
#include <stdlib.h>
#endif
// You can define the endian mode in your files, without modifying the SHA1
// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
// in your files, before including the SHA1.h header file. If you don't
// define anything, the class defaults to little endian.
#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
#define SHA1_LITTLE_ENDIAN
#endif
// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if
// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
// defaults to wiping.
#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
#define SHA1_WIPE_VARIABLES
#endif
/////////////////////////////////////////////////////////////////////////////
// Define 8- and 32-bit variables
#ifndef UINT_32
#ifdef _MSC_VER
#define UINT_8 unsigned __int8
#define UINT_32 unsigned __int32
#else
#define UINT_8 unsigned char
#if (ULONG_MAX == 0xFFFFFFFF)
#define UINT_32 unsigned long
#else
#define UINT_32 unsigned int
#endif
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
// Declare SHA1 workspace
typedef union
{
UINT_8 c[64];
UINT_32 l[16];
} SHA1_WORKSPACE_BLOCK;
class CSHA1
{
public:
#ifdef SHA1_UTILITY_FUNCTIONS
// Two different formats for ReportHash(...)
enum
{
REPORT_HEX = 0,
REPORT_DIGIT = 1
};
#endif
// Constructor and Destructor
CSHA1();
~CSHA1();
UINT_32 m_state[5];
UINT_32 m_count[2];
UINT_32 __reserved1[1];
UINT_8 m_buffer[64];
UINT_8 m_digest[20];
UINT_32 __reserved2[3];
void Reset();
// Update the hash value
void Update(UINT_8 *data, UINT_32 len);
#ifdef SHA1_UTILITY_FUNCTIONS
bool HashFile(char *szFileName);
#endif
// Finalize hash and report
void Final();
// Report functions: as pre-formatted and raw data
#ifdef SHA1_UTILITY_FUNCTIONS
void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX);
#endif
void GetHash(UINT_8 *puDest);
private:
// Private SHA-1 transformation
void Transform(UINT_32 *state, UINT_8 *buffer);
// Member variables
UINT_8 m_workspace[64];
SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above
};
#endif

View File

@ -1,123 +1,123 @@
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#include "base64.h"
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#include "base64.h"
#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}

View File

@ -1,4 +1,4 @@
#include <string>
std::string base64_encode(unsigned char const* , unsigned int len);
#include <string>
std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);

File diff suppressed because it is too large Load Diff

View File

@ -1,93 +1,93 @@
#ifndef __OAUTHLIB_H__
#define __OAUTHLIB_H__
#include "time.h"
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <map>
typedef enum _eOAuthHttpRequestType
{
eOAuthHttpInvalid = 0,
eOAuthHttpGet,
eOAuthHttpPost,
eOAuthHttpDelete
} eOAuthHttpRequestType;
typedef std::list<std::string> oAuthKeyValueList;
typedef std::map<std::string, std::string> oAuthKeyValuePairs;
class oAuth
{
public:
oAuth();
~oAuth();
/* OAuth public methods used by twitCurl */
void getConsumerKey( std::string& consumerKey /* out */ );
void setConsumerKey( const std::string& consumerKey /* in */ );
void getConsumerSecret( std::string& consumerSecret /* out */ );
void setConsumerSecret( const std::string& consumerSecret /* in */ );
void getOAuthTokenKey( std::string& oAuthTokenKey /* out */ );
void setOAuthTokenKey( const std::string& oAuthTokenKey /* in */ );
void getOAuthTokenSecret( std::string& oAuthTokenSecret /* out */ );
void setOAuthTokenSecret( const std::string& oAuthTokenSecret /* in */ );
void getOAuthScreenName( std::string& oAuthScreenName /* out */ );
void setOAuthScreenName( const std::string& oAuthScreenName /* in */ );
void getOAuthPin( std::string& oAuthPin /* out */ );
void setOAuthPin( const std::string& oAuthPin /* in */ );
bool getOAuthHeader( const eOAuthHttpRequestType eType, /* in */
const std::string& rawUrl, /* in */
const std::string& rawData, /* in */
std::string& oAuthHttpHeader, /* out */
const bool includeOAuthVerifierPin = false /* in */ );
bool extractOAuthTokenKeySecret( const std::string& requestTokenResponse /* in */ );
oAuth clone();
private:
/* OAuth data */
std::string m_consumerKey;
std::string m_consumerSecret;
std::string m_oAuthTokenKey;
std::string m_oAuthTokenSecret;
std::string m_oAuthPin;
std::string m_nonce;
std::string m_timeStamp;
std::string m_oAuthScreenName;
/* OAuth twitter related utility methods */
void buildOAuthRawDataKeyValPairs( const std::string& rawData, /* in */
bool urlencodeData, /* in */
oAuthKeyValuePairs& rawDataKeyValuePairs /* out */ );
bool buildOAuthTokenKeyValuePairs( const bool includeOAuthVerifierPin, /* in */
const std::string& oauthSignature, /* in */
oAuthKeyValuePairs& keyValueMap /* out */,
const bool generateTimestamp /* in */ );
bool getStringFromOAuthKeyValuePairs( const oAuthKeyValuePairs& rawParamMap, /* in */
std::string& rawParams, /* out */
const std::string& paramsSeperator /* in */ );
bool getSignature( const eOAuthHttpRequestType eType, /* in */
const std::string& rawUrl, /* in */
const oAuthKeyValuePairs& rawKeyValuePairs, /* in */
std::string& oAuthSignature /* out */ );
void generateNonceTimeStamp();
};
#endif // __OAUTHLIB_H__
#ifndef __OAUTHLIB_H__
#define __OAUTHLIB_H__
#include "time.h"
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <map>
typedef enum _eOAuthHttpRequestType
{
eOAuthHttpInvalid = 0,
eOAuthHttpGet,
eOAuthHttpPost,
eOAuthHttpDelete
} eOAuthHttpRequestType;
typedef std::list<std::string> oAuthKeyValueList;
typedef std::map<std::string, std::string> oAuthKeyValuePairs;
class oAuth
{
public:
oAuth();
~oAuth();
/* OAuth public methods used by twitCurl */
void getConsumerKey( std::string& consumerKey /* out */ );
void setConsumerKey( const std::string& consumerKey /* in */ );
void getConsumerSecret( std::string& consumerSecret /* out */ );
void setConsumerSecret( const std::string& consumerSecret /* in */ );
void getOAuthTokenKey( std::string& oAuthTokenKey /* out */ );
void setOAuthTokenKey( const std::string& oAuthTokenKey /* in */ );
void getOAuthTokenSecret( std::string& oAuthTokenSecret /* out */ );
void setOAuthTokenSecret( const std::string& oAuthTokenSecret /* in */ );
void getOAuthScreenName( std::string& oAuthScreenName /* out */ );
void setOAuthScreenName( const std::string& oAuthScreenName /* in */ );
void getOAuthPin( std::string& oAuthPin /* out */ );
void setOAuthPin( const std::string& oAuthPin /* in */ );
bool getOAuthHeader( const eOAuthHttpRequestType eType, /* in */
const std::string& rawUrl, /* in */
const std::string& rawData, /* in */
std::string& oAuthHttpHeader, /* out */
const bool includeOAuthVerifierPin = false /* in */ );
bool extractOAuthTokenKeySecret( const std::string& requestTokenResponse /* in */ );
oAuth clone();
private:
/* OAuth data */
std::string m_consumerKey;
std::string m_consumerSecret;
std::string m_oAuthTokenKey;
std::string m_oAuthTokenSecret;
std::string m_oAuthPin;
std::string m_nonce;
std::string m_timeStamp;
std::string m_oAuthScreenName;
/* OAuth twitter related utility methods */
void buildOAuthRawDataKeyValPairs( const std::string& rawData, /* in */
bool urlencodeData, /* in */
oAuthKeyValuePairs& rawDataKeyValuePairs /* out */ );
bool buildOAuthTokenKeyValuePairs( const bool includeOAuthVerifierPin, /* in */
const std::string& oauthSignature, /* in */
oAuthKeyValuePairs& keyValueMap /* out */,
const bool generateTimestamp /* in */ );
bool getStringFromOAuthKeyValuePairs( const oAuthKeyValuePairs& rawParamMap, /* in */
std::string& rawParams, /* out */
const std::string& paramsSeperator /* in */ );
bool getSignature( const eOAuthHttpRequestType eType, /* in */
const std::string& rawUrl, /* in */
const oAuthKeyValuePairs& rawKeyValuePairs, /* in */
std::string& oAuthSignature /* out */ );
void generateNonceTimeStamp();
};
#endif // __OAUTHLIB_H__

File diff suppressed because it is too large Load Diff

View File

@ -1,140 +1,140 @@
# Microsoft Developer Studio Project File - Name="twitcurl" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=twitcurl - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "twitcurl.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "twitcurl.mak" CFG="twitcurl - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "twitcurl - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "twitcurl - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "twitcurl - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "twitcurl - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "./curl" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "twitcurl - Win32 Release"
# Name "twitcurl - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\base64.cpp
# End Source File
# Begin Source File
SOURCE=.\HMAC_SHA1.cpp
# End Source File
# Begin Source File
SOURCE=.\oauthlib.cpp
# End Source File
# Begin Source File
SOURCE=.\SHA1.cpp
# End Source File
# Begin Source File
SOURCE=.\twitcurl.cpp
# End Source File
# Begin Source File
SOURCE=.\urlencode.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\base64.h
# End Source File
# Begin Source File
SOURCE=.\HMAC_SHA1.h
# End Source File
# Begin Source File
SOURCE=.\oauthlib.h
# End Source File
# Begin Source File
SOURCE=.\SHA1.h
# End Source File
# Begin Source File
SOURCE=.\twitcurl.h
# End Source File
# Begin Source File
SOURCE=.\urlencode.h
# End Source File
# End Group
# End Target
# End Project
# Microsoft Developer Studio Project File - Name="twitcurl" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=twitcurl - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "twitcurl.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "twitcurl.mak" CFG="twitcurl - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "twitcurl - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "twitcurl - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "twitcurl - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "twitcurl - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "./curl" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "twitcurl - Win32 Release"
# Name "twitcurl - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\base64.cpp
# End Source File
# Begin Source File
SOURCE=.\HMAC_SHA1.cpp
# End Source File
# Begin Source File
SOURCE=.\oauthlib.cpp
# End Source File
# Begin Source File
SOURCE=.\SHA1.cpp
# End Source File
# Begin Source File
SOURCE=.\twitcurl.cpp
# End Source File
# Begin Source File
SOURCE=.\urlencode.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\base64.h
# End Source File
# Begin Source File
SOURCE=.\HMAC_SHA1.h
# End Source File
# Begin Source File
SOURCE=.\oauthlib.h
# End Source File
# Begin Source File
SOURCE=.\SHA1.h
# End Source File
# Begin Source File
SOURCE=.\twitcurl.h
# End Source File
# Begin Source File
SOURCE=.\urlencode.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -1,29 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "twitcurl"=.\twitcurl.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "twitcurl"=.\twitcurl.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -1,190 +1,190 @@
#ifndef _TWITCURL_H_
#define _TWITCURL_H_
#include <string>
#include <sstream>
#include <cstring>
#include <vector>
#include "oauthlib.h"
#include "curl/curl.h"
/* Few common types used by twitCurl */
namespace twitCurlTypes
{
typedef enum _eTwitCurlApiFormatType
{
eTwitCurlApiFormatJson = 0,
eTwitCurlApiFormatXml,
eTwitCurlApiFormatMax
} eTwitCurlApiFormatType;
typedef enum _eTwitCurlProtocolType
{
eTwitCurlProtocolHttps = 0,
eTwitCurlProtocolHttp,
eTwitCurlProtocolMax
} eTwitCurlProtocolType;
};
/* twitCurl class */
class twitCurl
{
public:
twitCurl();
~twitCurl();
/* Twitter OAuth authorization methods */
oAuth& getOAuth();
bool oAuthRequestToken( std::string& authorizeUrl /* out */ );
bool oAuthAccessToken();
bool oAuthHandlePIN( const std::string& authorizeUrl /* in */ );
/* Twitter login APIs, set once and forget */
std::string& getTwitterUsername();
std::string& getTwitterPassword();
void setTwitterUsername( std::string& userName /* in */ );
void setTwitterPassword( std::string& passWord /* in */ );
/* Twitter search APIs */
bool search( std::string& searchQuery /* in */, std::string resultCount = "" /* in */ );
/* Twitter status APIs */
bool statusUpdate( std::string& newStatus /* in */, std::string inReplyToStatusId = "" /* in */ );
bool statusShowById( std::string& statusId /* in */ );
bool statusDestroyById( std::string& statusId /* in */ );
bool retweetById( std::string& statusId /* in */ );
/* Twitter timeline APIs */
bool timelineHomeGet( std::string sinceId = "" /* in */ );
bool timelinePublicGet();
bool timelineFriendsGet();
bool timelineUserGet( bool trimUser /* in */, bool includeRetweets /* in */,
unsigned int tweetCount /* in */,
std::string userInfo = "" /* in */,
bool isUserId = false /* in */ );
bool featuredUsersGet();
bool mentionsGet( std::string sinceId = "" /* in */ );
/* Twitter user APIs */
bool userLookup( std::vector<std::string> &userInfo /* in */, bool isUserId = false /* in */ );
bool userGet( std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool friendsGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
bool followersGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
/* Twitter direct message APIs */
bool directMessageGet( std::string sinceId = "" /* in */ );
bool directMessageSend( std::string& userInfo /* in */, std::string& dMsg /* in */, bool isUserId = false /* in */ );
bool directMessageGetSent();
bool directMessageDestroyById( std::string& dMsgId /* in */ );
/* Twitter friendships APIs */
bool friendshipCreate( std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool friendshipDestroy( std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool friendshipShow( std::string& userInfo /* in */, bool isUserId = false /* in */ );
/* Twitter social graphs APIs */
bool friendsIdsGet( std::string& nextCursor /* in */,
std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool followersIdsGet( std::string& nextCursor /* in */,
std::string& userInfo /* in */, bool isUserId = false /* in */ );
/* Twitter account APIs */
bool accountRateLimitGet();
bool accountVerifyCredGet();
/* Twitter favorites APIs */
bool favoriteGet();
bool favoriteCreate( std::string& statusId /* in */ );
bool favoriteDestroy( std::string& statusId /* in */ );
/* Twitter block APIs */
bool blockCreate( std::string& userInfo /* in */ );
bool blockDestroy( std::string& userInfo /* in */ );
bool blockListGet( std::string& nextCursor /* in */,
bool includeEntities /* in */, bool skipStatus /* in */ );
bool blockIdsGet( std::string& nextCursor /* in */, bool stringifyIds /* in */ );
/* Twitter search APIs */
bool savedSearchGet();
bool savedSearchCreate( std::string& query /* in */ );
bool savedSearchShow( std::string& searchId /* in */ );
bool savedSearchDestroy( std::string& searchId /* in */ );
/* Twitter trends APIs (JSON) */
bool trendsGet();
bool trendsDailyGet();
bool trendsWeeklyGet();
bool trendsCurrentGet();
bool trendsAvailableGet();
/* cURL APIs */
bool isCurlInit();
void getLastWebResponse( std::string& outWebResp /* out */ );
void getLastCurlError( std::string& outErrResp /* out */);
/* Internal cURL related methods */
int saveLastWebResponse( char*& data, size_t size );
/* cURL proxy APIs */
std::string& getProxyServerIp();
std::string& getProxyServerPort();
std::string& getProxyUserName();
std::string& getProxyPassword();
void setProxyServerIp( std::string& proxyServerIp /* in */ );
void setProxyServerPort( std::string& proxyServerPort /* in */ );
void setProxyUserName( std::string& proxyUserName /* in */ );
void setProxyPassword( std::string& proxyPassword /* in */ );
/* Clones this object */
twitCurl* clone();
private:
/* cURL data */
CURL* m_curlHandle;
char* m_errorBuffer;
std::string m_callbackData;
/* cURL flags */
bool m_curlProxyParamsSet;
bool m_curlLoginParamsSet;
bool m_curlCallbackParamsSet;
/* cURL proxy data */
std::string m_proxyServerIp;
std::string m_proxyServerPort;
std::string m_proxyUserName;
std::string m_proxyPassword;
/* Twitter data */
std::string m_twitterUsername;
std::string m_twitterPassword;
/* Twitter API type */
twitCurlTypes::eTwitCurlApiFormatType m_eApiFormatType;
twitCurlTypes::eTwitCurlProtocolType m_eProtocolType;
/* OAuth data */
oAuth m_oAuth;
/* Private methods */
void clearCurlCallbackBuffers();
void prepareCurlProxy();
void prepareCurlCallback();
void prepareCurlUserPass();
void prepareStandardParams();
bool performGet( const std::string& getUrl );
bool performGetInternal( const std::string& getUrl,
const std::string& oAuthHttpHeader );
bool performDelete( const std::string& deleteUrl );
bool performPost( const std::string& postUrl, std::string dataStr = "" );
/* Internal cURL related methods */
static int curlCallback( char* data, size_t size, size_t nmemb, twitCurl* pTwitCurlObj );
};
/* Private functions */
void utilMakeCurlParams( std::string& outStr, std::string& inParam1, std::string& inParam2 );
void utilMakeUrlForUser( std::string& outUrl, const std::string& baseUrl, std::string& userInfo, bool isUserId );
#endif // _TWITCURL_H_
#ifndef _TWITCURL_H_
#define _TWITCURL_H_
#include <string>
#include <sstream>
#include <cstring>
#include <vector>
#include "oauthlib.h"
#include "curl/curl.h"
/* Few common types used by twitCurl */
namespace twitCurlTypes
{
typedef enum _eTwitCurlApiFormatType
{
eTwitCurlApiFormatJson = 0,
eTwitCurlApiFormatXml,
eTwitCurlApiFormatMax
} eTwitCurlApiFormatType;
typedef enum _eTwitCurlProtocolType
{
eTwitCurlProtocolHttps = 0,
eTwitCurlProtocolHttp,
eTwitCurlProtocolMax
} eTwitCurlProtocolType;
};
/* twitCurl class */
class twitCurl
{
public:
twitCurl();
~twitCurl();
/* Twitter OAuth authorization methods */
oAuth& getOAuth();
bool oAuthRequestToken( std::string& authorizeUrl /* out */ );
bool oAuthAccessToken();
bool oAuthHandlePIN( const std::string& authorizeUrl /* in */ );
/* Twitter login APIs, set once and forget */
std::string& getTwitterUsername();
std::string& getTwitterPassword();
void setTwitterUsername( std::string& userName /* in */ );
void setTwitterPassword( std::string& passWord /* in */ );
/* Twitter search APIs */
bool search( std::string& searchQuery /* in */, std::string resultCount = "" /* in */ );
/* Twitter status APIs */
bool statusUpdate( std::string& newStatus /* in */, std::string inReplyToStatusId = "" /* in */ );
bool statusShowById( std::string& statusId /* in */ );
bool statusDestroyById( std::string& statusId /* in */ );
bool retweetById( std::string& statusId /* in */ );
/* Twitter timeline APIs */
bool timelineHomeGet( std::string sinceId = "" /* in */ );
bool timelinePublicGet();
bool timelineFriendsGet();
bool timelineUserGet( bool trimUser /* in */, bool includeRetweets /* in */,
unsigned int tweetCount /* in */,
std::string userInfo = "" /* in */,
bool isUserId = false /* in */ );
bool featuredUsersGet();
bool mentionsGet( std::string sinceId = "" /* in */ );
/* Twitter user APIs */
bool userLookup( std::vector<std::string> &userInfo /* in */, bool isUserId = false /* in */ );
bool userGet( std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool friendsGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
bool followersGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
/* Twitter direct message APIs */
bool directMessageGet( std::string sinceId = "" /* in */ );
bool directMessageSend( std::string& userInfo /* in */, std::string& dMsg /* in */, bool isUserId = false /* in */ );
bool directMessageGetSent();
bool directMessageDestroyById( std::string& dMsgId /* in */ );
/* Twitter friendships APIs */
bool friendshipCreate( std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool friendshipDestroy( std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool friendshipShow( std::string& userInfo /* in */, bool isUserId = false /* in */ );
/* Twitter social graphs APIs */
bool friendsIdsGet( std::string& nextCursor /* in */,
std::string& userInfo /* in */, bool isUserId = false /* in */ );
bool followersIdsGet( std::string& nextCursor /* in */,
std::string& userInfo /* in */, bool isUserId = false /* in */ );
/* Twitter account APIs */
bool accountRateLimitGet();
bool accountVerifyCredGet();
/* Twitter favorites APIs */
bool favoriteGet();
bool favoriteCreate( std::string& statusId /* in */ );
bool favoriteDestroy( std::string& statusId /* in */ );
/* Twitter block APIs */
bool blockCreate( std::string& userInfo /* in */ );
bool blockDestroy( std::string& userInfo /* in */ );
bool blockListGet( std::string& nextCursor /* in */,
bool includeEntities /* in */, bool skipStatus /* in */ );
bool blockIdsGet( std::string& nextCursor /* in */, bool stringifyIds /* in */ );
/* Twitter search APIs */
bool savedSearchGet();
bool savedSearchCreate( std::string& query /* in */ );
bool savedSearchShow( std::string& searchId /* in */ );
bool savedSearchDestroy( std::string& searchId /* in */ );
/* Twitter trends APIs (JSON) */
bool trendsGet();
bool trendsDailyGet();
bool trendsWeeklyGet();
bool trendsCurrentGet();
bool trendsAvailableGet();
/* cURL APIs */
bool isCurlInit();
void getLastWebResponse( std::string& outWebResp /* out */ );
void getLastCurlError( std::string& outErrResp /* out */);
/* Internal cURL related methods */
int saveLastWebResponse( char*& data, size_t size );
/* cURL proxy APIs */
std::string& getProxyServerIp();
std::string& getProxyServerPort();
std::string& getProxyUserName();
std::string& getProxyPassword();
void setProxyServerIp( std::string& proxyServerIp /* in */ );
void setProxyServerPort( std::string& proxyServerPort /* in */ );
void setProxyUserName( std::string& proxyUserName /* in */ );
void setProxyPassword( std::string& proxyPassword /* in */ );
/* Clones this object */
twitCurl* clone();
private:
/* cURL data */
CURL* m_curlHandle;
char* m_errorBuffer;
std::string m_callbackData;
/* cURL flags */
bool m_curlProxyParamsSet;
bool m_curlLoginParamsSet;
bool m_curlCallbackParamsSet;
/* cURL proxy data */
std::string m_proxyServerIp;
std::string m_proxyServerPort;
std::string m_proxyUserName;
std::string m_proxyPassword;
/* Twitter data */
std::string m_twitterUsername;
std::string m_twitterPassword;
/* Twitter API type */
twitCurlTypes::eTwitCurlApiFormatType m_eApiFormatType;
twitCurlTypes::eTwitCurlProtocolType m_eProtocolType;
/* OAuth data */
oAuth m_oAuth;
/* Private methods */
void clearCurlCallbackBuffers();
void prepareCurlProxy();
void prepareCurlCallback();
void prepareCurlUserPass();
void prepareStandardParams();
bool performGet( const std::string& getUrl );
bool performGetInternal( const std::string& getUrl,
const std::string& oAuthHttpHeader );
bool performDelete( const std::string& deleteUrl );
bool performPost( const std::string& postUrl, std::string dataStr = "" );
/* Internal cURL related methods */
static int curlCallback( char* data, size_t size, size_t nmemb, twitCurl* pTwitCurlObj );
};
/* Private functions */
void utilMakeCurlParams( std::string& outStr, std::string& inParam1, std::string& inParam2 );
void utilMakeUrlForUser( std::string& outUrl, const std::string& baseUrl, std::string& userInfo, bool isUserId );
#endif // _TWITCURL_H_

View File

@ -1,37 +1,37 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: twitcurl - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp" with contents
[
/nologo /ML /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/twitcurl.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
"C:\Projects\twitcurl\base64.cpp"
"C:\Projects\twitcurl\HMAC_SHA1.cpp"
"C:\Projects\twitcurl\oauthlib.cpp"
"C:\Projects\twitcurl\SHA1.cpp"
"C:\Projects\twitcurl\twitcurl.cpp"
"C:\Projects\twitcurl\urlencode.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp"
Creating command line "link.exe -lib /nologo /out:"Release\twitcurl.lib" .\Release\base64.obj .\Release\HMAC_SHA1.obj .\Release\oauthlib.obj .\Release\SHA1.obj .\Release\twitcurl.obj .\Release\urlencode.obj "
<h3>Output Window</h3>
Compiling...
base64.cpp
HMAC_SHA1.cpp
oauthlib.cpp
SHA1.cpp
twitcurl.cpp
urlencode.cpp
Creating library...
<h3>Results</h3>
twitcurl.lib - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: twitcurl - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp" with contents
[
/nologo /ML /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/twitcurl.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
"C:\Projects\twitcurl\base64.cpp"
"C:\Projects\twitcurl\HMAC_SHA1.cpp"
"C:\Projects\twitcurl\oauthlib.cpp"
"C:\Projects\twitcurl\SHA1.cpp"
"C:\Projects\twitcurl\twitcurl.cpp"
"C:\Projects\twitcurl\urlencode.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp"
Creating command line "link.exe -lib /nologo /out:"Release\twitcurl.lib" .\Release\base64.obj .\Release\HMAC_SHA1.obj .\Release\oauthlib.obj .\Release\SHA1.obj .\Release\twitcurl.obj .\Release\urlencode.obj "
<h3>Output Window</h3>
Compiling...
base64.cpp
HMAC_SHA1.cpp
oauthlib.cpp
SHA1.cpp
twitcurl.cpp
urlencode.cpp
Creating library...
<h3>Results</h3>
twitcurl.lib - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1,20 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twitcurl", "twitcurl.vcproj", "{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.ActiveCfg = Release|Win32
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.Build.0 = Release|Win32
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.ActiveCfg = Release|Win32
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twitcurl", "twitcurl.vcproj", "{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.ActiveCfg = Release|Win32
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.Build.0 = Release|Win32
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.ActiveCfg = Release|Win32
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,347 +1,347 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="twitcurl"
ProjectGUID="{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./curl"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/twitcurl.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\Debug\twitcurl.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/twitcurl.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="./include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;CURL_STATICLIB"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/twitcurl.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
LinkLibraryDependencies="true"
AdditionalDependencies="libcurl.lib"
OutputFile=".\Release\twitcurl.lib"
AdditionalLibraryDirectories="./lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/twitcurl.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="base64.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="HMAC_SHA1.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="oauthlib.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="SHA1.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="twitcurl.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="urlencode.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="base64.h"
>
</File>
<File
RelativePath="HMAC_SHA1.h"
>
</File>
<File
RelativePath="oauthlib.h"
>
</File>
<File
RelativePath="SHA1.h"
>
</File>
<File
RelativePath="twitcurl.h"
>
</File>
<File
RelativePath=".\twitcurlurls.h"
>
</File>
<File
RelativePath="urlencode.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="twitcurl"
ProjectGUID="{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./curl"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/twitcurl.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\Debug\twitcurl.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/twitcurl.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="./include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;CURL_STATICLIB"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/twitcurl.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
LinkLibraryDependencies="true"
AdditionalDependencies="libcurl.lib"
OutputFile=".\Release\twitcurl.lib"
AdditionalLibraryDirectories="./lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/twitcurl.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="base64.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="HMAC_SHA1.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="oauthlib.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="SHA1.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="twitcurl.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="urlencode.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="base64.h"
>
</File>
<File
RelativePath="HMAC_SHA1.h"
>
</File>
<File
RelativePath="oauthlib.h"
>
</File>
<File
RelativePath="SHA1.h"
>
</File>
<File
RelativePath="twitcurl.h"
>
</File>
<File
RelativePath=".\twitcurlurls.h"
>
</File>
<File
RelativePath="urlencode.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,156 +1,156 @@
#ifndef _TWITCURLURLS_H_
#define _TWITCURLURLS_H_
#include <string>
#include <cstring>
/* Default values used in twitcurl */
namespace twitCurlDefaults
{
/* Constants */
const int TWITCURL_DEFAULT_BUFFSIZE = 1024;
const std::string TWITCURL_COLON = ":";
const char TWITCURL_EOS = '\0';
const unsigned int MAX_TIMELINE_TWEET_COUNT = 200;
/* Miscellaneous data used to build twitter URLs*/
const std::string TWITCURL_STATUSSTRING = "status=";
const std::string TWITCURL_TEXTSTRING = "text=";
const std::string TWITCURL_QUERYSTRING = "query=";
const std::string TWITCURL_SEARCHQUERYSTRING = "q=";
const std::string TWITCURL_SCREENNAME = "screen_name=";
const std::string TWITCURL_USERID = "user_id=";
const std::string TWITCURL_EXTENSIONFORMATS[2] = { ".json",
".xml"
};
const std::string TWITCURL_PROTOCOLS[2] = { "https://",
"http://"
};
const std::string TWITCURL_TARGETSCREENNAME = "target_screen_name=";
const std::string TWITCURL_TARGETUSERID = "target_id=";
const std::string TWITCURL_SINCEID = "since_id=";
const std::string TWITCURL_TRIMUSER = "trim_user=true";
const std::string TWITCURL_INCRETWEETS = "include_rts=true";
const std::string TWITCURL_COUNT = "count=";
const std::string TWITCURL_NEXT_CURSOR = "cursor=";
const std::string TWITCURL_SKIP_STATUS = "skip_status=";
const std::string TWITCURL_INCLUDE_ENTITIES = "include_entities=";
const std::string TWITCURL_STRINGIFY_IDS = "stringify_ids=";
const std::string TWITCURL_INREPLYTOSTATUSID = "in_reply_to_status_id=";
/* URL separators */
const std::string TWITCURL_URL_SEP_AMP = "&";
const std::string TWITCURL_URL_SEP_QUES = "?";
};
/* Default twitter URLs */
namespace twitterDefaults
{
/* Base URL */
const std::string TWITCURL_BASE_URL = "api.twitter.com/1.1/";
/* Search URLs */
const std::string TWITCURL_SEARCH_URL = TWITCURL_BASE_URL + "search/tweets";
/* Status URLs */
const std::string TWITCURL_STATUSUPDATE_URL = TWITCURL_BASE_URL + "statuses/update";
const std::string TWITCURL_STATUSSHOW_URL = TWITCURL_BASE_URL + "statuses/show/";
const std::string TWITCURL_STATUDESTROY_URL = TWITCURL_BASE_URL + "statuses/destroy/";
const std::string TWITCURL_RETWEET_URL = TWITCURL_BASE_URL + "statuses/retweet/";
/* Timeline URLs */
const std::string TWITCURL_HOME_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/home_timeline";
const std::string TWITCURL_PUBLIC_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/public_timeline";
const std::string TWITCURL_FEATURED_USERS_URL = TWITCURL_BASE_URL + "statuses/featured";
const std::string TWITCURL_FRIENDS_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/friends_timeline";
const std::string TWITCURL_MENTIONS_URL = TWITCURL_BASE_URL + "statuses/mentions";
const std::string TWITCURL_USERTIMELINE_URL = TWITCURL_BASE_URL + "statuses/user_timeline";
/* Users URLs */
const std::string TWITCURL_LOOKUPUSERS_URL = TWITCURL_BASE_URL + "users/lookup";
const std::string TWITCURL_SHOWUSERS_URL = TWITCURL_BASE_URL + "users/show";
const std::string TWITCURL_SHOWFRIENDS_URL = TWITCURL_BASE_URL + "statuses/friends";
const std::string TWITCURL_SHOWFOLLOWERS_URL = TWITCURL_BASE_URL + "statuses/followers";
/* Direct messages URLs */
const std::string TWITCURL_DIRECTMESSAGES_URL = TWITCURL_BASE_URL + "direct_messages";
const std::string TWITCURL_DIRECTMESSAGENEW_URL = TWITCURL_BASE_URL + "direct_messages/new";
const std::string TWITCURL_DIRECTMESSAGESSENT_URL = TWITCURL_BASE_URL + "direct_messages/sent";
const std::string TWITCURL_DIRECTMESSAGEDESTROY_URL = TWITCURL_BASE_URL + "direct_messages/destroy/";
/* Friendships URLs */
const std::string TWITCURL_FRIENDSHIPSCREATE_URL = TWITCURL_BASE_URL + "friendships/create";
const std::string TWITCURL_FRIENDSHIPSDESTROY_URL = TWITCURL_BASE_URL + "friendships/destroy";
const std::string TWITCURL_FRIENDSHIPSSHOW_URL = TWITCURL_BASE_URL + "friendships/show";
/* Social graphs URLs */
const std::string TWITCURL_FRIENDSIDS_URL = TWITCURL_BASE_URL + "friends/ids";
const std::string TWITCURL_FOLLOWERSIDS_URL = TWITCURL_BASE_URL + "followers/ids";
/* Account URLs */
const std::string TWITCURL_ACCOUNTRATELIMIT_URL = TWITCURL_BASE_URL + "account/rate_limit_status";
const std::string TWITCURL_ACCOUNTVERIFYCRED_URL = TWITCURL_BASE_URL + "account/verify_credentials";
/* Favorites URLs */
const std::string TWITCURL_FAVORITESGET_URL = TWITCURL_BASE_URL + "favorites";
const std::string TWITCURL_FAVORITECREATE_URL = TWITCURL_BASE_URL + "favorites/create/";
const std::string TWITCURL_FAVORITEDESTROY_URL = TWITCURL_BASE_URL + "favorites/destroy/";
/* Block URLs */
const std::string TWITCURL_BLOCKSCREATE_URL = TWITCURL_BASE_URL + "blocks/create/";
const std::string TWITCURL_BLOCKSDESTROY_URL = TWITCURL_BASE_URL + "blocks/destroy/";
const std::string TWITCURL_BLOCKSLIST_URL = TWITCURL_BASE_URL + "blocks/list";
const std::string TWITCURL_BLOCKSIDS_URL = TWITCURL_BASE_URL + "blocks/ids";
/* Saved Search URLs */
const std::string TWITCURL_SAVEDSEARCHGET_URL = TWITCURL_BASE_URL + "saved_searches";
const std::string TWITCURL_SAVEDSEARCHSHOW_URL = TWITCURL_BASE_URL + "saved_searches/show/";
const std::string TWITCURL_SAVEDSEARCHCREATE_URL = TWITCURL_BASE_URL + "saved_searches/create";
const std::string TWITCURL_SAVEDSEARCHDESTROY_URL = TWITCURL_BASE_URL + "saved_searches/destroy/";
/* Trends URLs */
const std::string TWITCURL_TRENDS_URL = TWITCURL_BASE_URL + "trends";
const std::string TWITCURL_TRENDSDAILY_URL = TWITCURL_BASE_URL + "trends/daily";
const std::string TWITCURL_TRENDSCURRENT_URL = TWITCURL_BASE_URL + "trends/current";
const std::string TWITCURL_TRENDSWEEKLY_URL = TWITCURL_BASE_URL + "trends/weekly";
const std::string TWITCURL_TRENDSAVAILABLE_URL = TWITCURL_BASE_URL + "trends/available";
};
namespace oAuthLibDefaults
{
/* Constants */
const int OAUTHLIB_BUFFSIZE = 1024;
const int OAUTHLIB_BUFFSIZE_LARGE = 1024;
const std::string OAUTHLIB_CONSUMERKEY_KEY = "oauth_consumer_key";
const std::string OAUTHLIB_CALLBACK_KEY = "oauth_callback";
const std::string OAUTHLIB_VERSION_KEY = "oauth_version";
const std::string OAUTHLIB_SIGNATUREMETHOD_KEY = "oauth_signature_method";
const std::string OAUTHLIB_SIGNATURE_KEY = "oauth_signature";
const std::string OAUTHLIB_TIMESTAMP_KEY = "oauth_timestamp";
const std::string OAUTHLIB_NONCE_KEY = "oauth_nonce";
const std::string OAUTHLIB_TOKEN_KEY = "oauth_token";
const std::string OAUTHLIB_TOKENSECRET_KEY = "oauth_token_secret";
const std::string OAUTHLIB_VERIFIER_KEY = "oauth_verifier";
const std::string OAUTHLIB_SCREENNAME_KEY = "screen_name";
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_KEY = "authenticity_token";
const std::string OAUTHLIB_SESSIONUSERNAME_KEY = "session[username_or_email]";
const std::string OAUTHLIB_SESSIONPASSWORD_KEY = "session[password]";
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_TWITTER_RESP_KEY = "authenticity_token\" type=\"hidden\" value=\"";
const std::string OAUTHLIB_TOKEN_TWITTER_RESP_KEY = "oauth_token\" type=\"hidden\" value=\"";
const std::string OAUTHLIB_PIN_TWITTER_RESP_KEY = "code-desc\"><code>";
const std::string OAUTHLIB_TOKEN_END_TAG_TWITTER_RESP = "\" />";
const std::string OAUTHLIB_PIN_END_TAG_TWITTER_RESP = "</code>";
const std::string OAUTHLIB_AUTHHEADER_STRING = "Authorization: OAuth ";
};
namespace oAuthTwitterApiUrls
{
/* Twitter OAuth API URLs */
const std::string OAUTHLIB_TWITTER_REQUEST_TOKEN_URL = "api.twitter.com/oauth/request_token";
const std::string OAUTHLIB_TWITTER_AUTHORIZE_URL = "api.twitter.com/oauth/authorize?oauth_token=";
const std::string OAUTHLIB_TWITTER_ACCESS_TOKEN_URL = "api.twitter.com/oauth/access_token";
};
#endif // _TWITCURLURLS_H_
#ifndef _TWITCURLURLS_H_
#define _TWITCURLURLS_H_
#include <string>
#include <cstring>
/* Default values used in twitcurl */
namespace twitCurlDefaults
{
/* Constants */
const int TWITCURL_DEFAULT_BUFFSIZE = 1024;
const std::string TWITCURL_COLON = ":";
const char TWITCURL_EOS = '\0';
const unsigned int MAX_TIMELINE_TWEET_COUNT = 200;
/* Miscellaneous data used to build twitter URLs*/
const std::string TWITCURL_STATUSSTRING = "status=";
const std::string TWITCURL_TEXTSTRING = "text=";
const std::string TWITCURL_QUERYSTRING = "query=";
const std::string TWITCURL_SEARCHQUERYSTRING = "q=";
const std::string TWITCURL_SCREENNAME = "screen_name=";
const std::string TWITCURL_USERID = "user_id=";
const std::string TWITCURL_EXTENSIONFORMATS[2] = { ".json",
".xml"
};
const std::string TWITCURL_PROTOCOLS[2] = { "https://",
"http://"
};
const std::string TWITCURL_TARGETSCREENNAME = "target_screen_name=";
const std::string TWITCURL_TARGETUSERID = "target_id=";
const std::string TWITCURL_SINCEID = "since_id=";
const std::string TWITCURL_TRIMUSER = "trim_user=true";
const std::string TWITCURL_INCRETWEETS = "include_rts=true";
const std::string TWITCURL_COUNT = "count=";
const std::string TWITCURL_NEXT_CURSOR = "cursor=";
const std::string TWITCURL_SKIP_STATUS = "skip_status=";
const std::string TWITCURL_INCLUDE_ENTITIES = "include_entities=";
const std::string TWITCURL_STRINGIFY_IDS = "stringify_ids=";
const std::string TWITCURL_INREPLYTOSTATUSID = "in_reply_to_status_id=";
/* URL separators */
const std::string TWITCURL_URL_SEP_AMP = "&";
const std::string TWITCURL_URL_SEP_QUES = "?";
};
/* Default twitter URLs */
namespace twitterDefaults
{
/* Base URL */
const std::string TWITCURL_BASE_URL = "api.twitter.com/1.1/";
/* Search URLs */
const std::string TWITCURL_SEARCH_URL = TWITCURL_BASE_URL + "search/tweets";
/* Status URLs */
const std::string TWITCURL_STATUSUPDATE_URL = TWITCURL_BASE_URL + "statuses/update";
const std::string TWITCURL_STATUSSHOW_URL = TWITCURL_BASE_URL + "statuses/show/";
const std::string TWITCURL_STATUDESTROY_URL = TWITCURL_BASE_URL + "statuses/destroy/";
const std::string TWITCURL_RETWEET_URL = TWITCURL_BASE_URL + "statuses/retweet/";
/* Timeline URLs */
const std::string TWITCURL_HOME_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/home_timeline";
const std::string TWITCURL_PUBLIC_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/public_timeline";
const std::string TWITCURL_FEATURED_USERS_URL = TWITCURL_BASE_URL + "statuses/featured";
const std::string TWITCURL_FRIENDS_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/friends_timeline";
const std::string TWITCURL_MENTIONS_URL = TWITCURL_BASE_URL + "statuses/mentions";
const std::string TWITCURL_USERTIMELINE_URL = TWITCURL_BASE_URL + "statuses/user_timeline";
/* Users URLs */
const std::string TWITCURL_LOOKUPUSERS_URL = TWITCURL_BASE_URL + "users/lookup";
const std::string TWITCURL_SHOWUSERS_URL = TWITCURL_BASE_URL + "users/show";
const std::string TWITCURL_SHOWFRIENDS_URL = TWITCURL_BASE_URL + "statuses/friends";
const std::string TWITCURL_SHOWFOLLOWERS_URL = TWITCURL_BASE_URL + "statuses/followers";
/* Direct messages URLs */
const std::string TWITCURL_DIRECTMESSAGES_URL = TWITCURL_BASE_URL + "direct_messages";
const std::string TWITCURL_DIRECTMESSAGENEW_URL = TWITCURL_BASE_URL + "direct_messages/new";
const std::string TWITCURL_DIRECTMESSAGESSENT_URL = TWITCURL_BASE_URL + "direct_messages/sent";
const std::string TWITCURL_DIRECTMESSAGEDESTROY_URL = TWITCURL_BASE_URL + "direct_messages/destroy/";
/* Friendships URLs */
const std::string TWITCURL_FRIENDSHIPSCREATE_URL = TWITCURL_BASE_URL + "friendships/create";
const std::string TWITCURL_FRIENDSHIPSDESTROY_URL = TWITCURL_BASE_URL + "friendships/destroy";
const std::string TWITCURL_FRIENDSHIPSSHOW_URL = TWITCURL_BASE_URL + "friendships/show";
/* Social graphs URLs */
const std::string TWITCURL_FRIENDSIDS_URL = TWITCURL_BASE_URL + "friends/ids";
const std::string TWITCURL_FOLLOWERSIDS_URL = TWITCURL_BASE_URL + "followers/ids";
/* Account URLs */
const std::string TWITCURL_ACCOUNTRATELIMIT_URL = TWITCURL_BASE_URL + "account/rate_limit_status";
const std::string TWITCURL_ACCOUNTVERIFYCRED_URL = TWITCURL_BASE_URL + "account/verify_credentials";
/* Favorites URLs */
const std::string TWITCURL_FAVORITESGET_URL = TWITCURL_BASE_URL + "favorites";
const std::string TWITCURL_FAVORITECREATE_URL = TWITCURL_BASE_URL + "favorites/create/";
const std::string TWITCURL_FAVORITEDESTROY_URL = TWITCURL_BASE_URL + "favorites/destroy/";
/* Block URLs */
const std::string TWITCURL_BLOCKSCREATE_URL = TWITCURL_BASE_URL + "blocks/create/";
const std::string TWITCURL_BLOCKSDESTROY_URL = TWITCURL_BASE_URL + "blocks/destroy/";
const std::string TWITCURL_BLOCKSLIST_URL = TWITCURL_BASE_URL + "blocks/list";
const std::string TWITCURL_BLOCKSIDS_URL = TWITCURL_BASE_URL + "blocks/ids";
/* Saved Search URLs */
const std::string TWITCURL_SAVEDSEARCHGET_URL = TWITCURL_BASE_URL + "saved_searches";
const std::string TWITCURL_SAVEDSEARCHSHOW_URL = TWITCURL_BASE_URL + "saved_searches/show/";
const std::string TWITCURL_SAVEDSEARCHCREATE_URL = TWITCURL_BASE_URL + "saved_searches/create";
const std::string TWITCURL_SAVEDSEARCHDESTROY_URL = TWITCURL_BASE_URL + "saved_searches/destroy/";
/* Trends URLs */
const std::string TWITCURL_TRENDS_URL = TWITCURL_BASE_URL + "trends";
const std::string TWITCURL_TRENDSDAILY_URL = TWITCURL_BASE_URL + "trends/daily";
const std::string TWITCURL_TRENDSCURRENT_URL = TWITCURL_BASE_URL + "trends/current";
const std::string TWITCURL_TRENDSWEEKLY_URL = TWITCURL_BASE_URL + "trends/weekly";
const std::string TWITCURL_TRENDSAVAILABLE_URL = TWITCURL_BASE_URL + "trends/available";
};
namespace oAuthLibDefaults
{
/* Constants */
const int OAUTHLIB_BUFFSIZE = 1024;
const int OAUTHLIB_BUFFSIZE_LARGE = 1024;
const std::string OAUTHLIB_CONSUMERKEY_KEY = "oauth_consumer_key";
const std::string OAUTHLIB_CALLBACK_KEY = "oauth_callback";
const std::string OAUTHLIB_VERSION_KEY = "oauth_version";
const std::string OAUTHLIB_SIGNATUREMETHOD_KEY = "oauth_signature_method";
const std::string OAUTHLIB_SIGNATURE_KEY = "oauth_signature";
const std::string OAUTHLIB_TIMESTAMP_KEY = "oauth_timestamp";
const std::string OAUTHLIB_NONCE_KEY = "oauth_nonce";
const std::string OAUTHLIB_TOKEN_KEY = "oauth_token";
const std::string OAUTHLIB_TOKENSECRET_KEY = "oauth_token_secret";
const std::string OAUTHLIB_VERIFIER_KEY = "oauth_verifier";
const std::string OAUTHLIB_SCREENNAME_KEY = "screen_name";
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_KEY = "authenticity_token";
const std::string OAUTHLIB_SESSIONUSERNAME_KEY = "session[username_or_email]";
const std::string OAUTHLIB_SESSIONPASSWORD_KEY = "session[password]";
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_TWITTER_RESP_KEY = "authenticity_token\" type=\"hidden\" value=\"";
const std::string OAUTHLIB_TOKEN_TWITTER_RESP_KEY = "oauth_token\" type=\"hidden\" value=\"";
const std::string OAUTHLIB_PIN_TWITTER_RESP_KEY = "code-desc\"><code>";
const std::string OAUTHLIB_TOKEN_END_TAG_TWITTER_RESP = "\" />";
const std::string OAUTHLIB_PIN_END_TAG_TWITTER_RESP = "</code>";
const std::string OAUTHLIB_AUTHHEADER_STRING = "Authorization: OAuth ";
};
namespace oAuthTwitterApiUrls
{
/* Twitter OAuth API URLs */
const std::string OAUTHLIB_TWITTER_REQUEST_TOKEN_URL = "api.twitter.com/oauth/request_token";
const std::string OAUTHLIB_TWITTER_AUTHORIZE_URL = "api.twitter.com/oauth/authorize?oauth_token=";
const std::string OAUTHLIB_TWITTER_ACCESS_TOKEN_URL = "api.twitter.com/oauth/access_token";
};
#endif // _TWITCURLURLS_H_

View File

@ -1,40 +1,40 @@
#include "urlencode.h"
std::string char2hex( char dec )
{
char dig1 = (dec&0xF0)>>4;
char dig2 = (dec&0x0F);
if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48 in ascii
if (10<= dig1 && dig1<=15) dig1+=65-10; //A,65 in ascii
if ( 0<= dig2 && dig2<= 9) dig2+=48;
if (10<= dig2 && dig2<=15) dig2+=65-10;
std::string r;
r.append( &dig1, 1);
r.append( &dig2, 1);
return r;
}
std::string urlencode( const std::string &c )
{
std::string escaped;
int max = c.length();
for(int i=0; i<max; i++)
{
if ( (48 <= c[i] && c[i] <= 57) ||//0-9
(65 <= c[i] && c[i] <= 90) ||//ABC...XYZ
(97 <= c[i] && c[i] <= 122) || //abc...xyz
(c[i]=='~' || c[i]=='-' || c[i]=='_' || c[i]=='.')
)
{
escaped.append( &c[i], 1);
}
else
{
escaped.append("%");
escaped.append( char2hex(c[i]) );//converts char 255 to string "FF"
}
}
return escaped;
#include "urlencode.h"
std::string char2hex( char dec )
{
char dig1 = (dec&0xF0)>>4;
char dig2 = (dec&0x0F);
if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48 in ascii
if (10<= dig1 && dig1<=15) dig1+=65-10; //A,65 in ascii
if ( 0<= dig2 && dig2<= 9) dig2+=48;
if (10<= dig2 && dig2<=15) dig2+=65-10;
std::string r;
r.append( &dig1, 1);
r.append( &dig2, 1);
return r;
}
std::string urlencode( const std::string &c )
{
std::string escaped;
int max = c.length();
for(int i=0; i<max; i++)
{
if ( (48 <= c[i] && c[i] <= 57) ||//0-9
(65 <= c[i] && c[i] <= 90) ||//ABC...XYZ
(97 <= c[i] && c[i] <= 122) || //abc...xyz
(c[i]=='~' || c[i]=='-' || c[i]=='_' || c[i]=='.')
)
{
escaped.append( &c[i], 1);
}
else
{
escaped.append("%");
escaped.append( char2hex(c[i]) );//converts char 255 to string "FF"
}
}
return escaped;
}

View File

@ -1,10 +1,10 @@
#ifndef __URLENCODE_H__
#define __URLENCODE_H__
#include <iostream>
#include <string>
std::string char2hex( char dec );
std::string urlencode( const std::string &c );
#ifndef __URLENCODE_H__
#define __URLENCODE_H__
#include <iostream>
#include <string>
std::string char2hex( char dec );
std::string urlencode( const std::string &c );
#endif // __URLENCODE_H__

View File

@ -1,38 +1,45 @@
FIND_LIBRARY(SWIFTEN_LIBRARY NAMES Swiften Swiften3 HINTS ../lib)
FIND_PATH(SWIFTEN_INCLUDE_DIR NAMES "Swiften/Swiften.h" PATH_SUFFIXES libSwiften Swiften HINTS ../include)
if( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
find_program(SWIFTEN_CONFIG_EXECUTABLE NAMES swiften-config DOC "swiften-config executable" HINTS ../bin)
set( SWIFTEN_CFLAGS "" )
if (SWIFTEN_CONFIG_EXECUTABLE)
execute_process(
COMMAND ${SWIFTEN_CONFIG_EXECUTABLE} --libs
OUTPUT_VARIABLE SWIFTEN_LIB)
string(REGEX REPLACE "[\r\n]" " " SWIFTEN_LIB ${SWIFTEN_LIB})
string(REGEX REPLACE " +$" "" SWIFTEN_LIB ${SWIFTEN_LIB})
string(REGEX REPLACE " " ";" SWIFTEN_LIB ${SWIFTEN_LIB})
set(SWIFTEN_LIBRARY "")
foreach(f ${SWIFTEN_LIB})
STRING(SUBSTRING ${f} 0 2 f_out)
STRING(COMPARE EQUAL ${f_out} "/L" IS_PATH)
if(${IS_PATH})
string(REGEX REPLACE "/LIBPATH:" "" f_replaced "${f}")
message("Added link directory: ${f_replaced}")
link_directories(${f_replaced})
else()
list(APPEND SWIFTEN_LIBRARY ${f})
endif()
endforeach(f)
set( SWIFTEN_FOUND 1 )
else()
message( STATUS "Could NOT find swiften-config" )
endif()
if (SWIFTEN_FOUND)
set( SWIFTEN_INCLUDE_DIR ${SWIFTEN_INCLUDE_DIR} )
message( STATUS "Found libSwiften: ${SWIFTEN_LIBRARY}, ${SWIFTEN_INCLUDE_DIR}")
endif()
else( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
message( STATUS "Could NOT find libSwiften" )
endif( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
FIND_LIBRARY(SWIFTEN_LIBRARY NAMES Swiften Swiften3 HINTS ../lib)
FIND_PATH(SWIFTEN_INCLUDE_DIR NAMES "Swiften/Swiften.h" PATH_SUFFIXES libSwiften Swiften HINTS ../include)
if( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
find_program(SWIFTEN_CONFIG_EXECUTABLE NAMES swiften-config DOC "swiften-config executable" HINTS ../bin)
set( SWIFTEN_CFLAGS "" )
if (SWIFTEN_CONFIG_EXECUTABLE)
execute_process(
COMMAND ${SWIFTEN_CONFIG_EXECUTABLE} --libs
OUTPUT_VARIABLE SWIFTEN_LIB)
string(REGEX REPLACE "[\r\n]" " " SWIFTEN_LIB ${SWIFTEN_LIB})
string(REGEX REPLACE " +$" "" SWIFTEN_LIB ${SWIFTEN_LIB})
set(SWIFTEN_LIBRARY "")
if (APPLE)
string(REGEX MATCHALL "-framework [A-Za-z]+" APPLE_FRAMEWORKS ${SWIFTEN_LIB})
foreach(framework ${APPLE_FRAMEWORKS})
list(APPEND SWIFTEN_LIBRARY ${framework} )
endforeach(framework)
string(REGEX REPLACE "-framework [A-Za-z]+" "" SWIFTEN_LIB ${SWIFTEN_LIB})
endif(APPLE)
string(REGEX REPLACE " " ";" SWIFTEN_LIB ${SWIFTEN_LIB})
foreach(f ${SWIFTEN_LIB})
STRING(SUBSTRING ${f} 0 2 f_out)
STRING(COMPARE EQUAL ${f_out} "/L" IS_PATH)
if(${IS_PATH})
string(REGEX REPLACE "/LIBPATH:" "" f_replaced "${f}")
message("Added link directory: ${f_replaced}")
link_directories(${f_replaced})
else()
list(APPEND SWIFTEN_LIBRARY ${f})
endif()
endforeach(f)
set( SWIFTEN_FOUND 1 )
else()
message( STATUS "Could NOT find swiften-config" )
endif()
if (SWIFTEN_FOUND)
set( SWIFTEN_INCLUDE_DIR ${SWIFTEN_INCLUDE_DIR} )
message( STATUS "Found libSwiften: ${SWIFTEN_LIBRARY}, ${SWIFTEN_INCLUDE_DIR}")
endif()
else( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
message( STATUS "Could NOT find libSwiften" )
endif( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )

View File

@ -1 +1 @@
ADD_SUBDIRECTORY(transport)
ADD_SUBDIRECTORY(transport)

View File

@ -1,110 +1,110 @@
/*
* Copyright (c) 2011 Tobias Markmann
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#include "CombinedOutgoingFileTransferManager.h"
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/JID/JID.h>
#include "Swiften/Disco/EntityCapsProvider.h"
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swiften/Jingle/JingleSessionImpl.h>
#include <Swiften/Jingle/JingleContentID.h>
#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/Base/foreach.h>
namespace Swift {
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
idGenerator = new IDGenerator();
}
CombinedOutgoingFileTransferManager::~CombinedOutgoingFileTransferManager() {
delete idGenerator;
}
boost::shared_ptr<OutgoingFileTransfer> CombinedOutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr<ReadBytestream> readBytestream, const StreamInitiationFileInfo& fileInfo) {
// check if receipient support Jingle FT
boost::optional<JID> fullJID = highestPriorityJIDSupportingJingle(receipient);
if (!fullJID.is_initialized()) {
fullJID = highestPriorityJIDSupportingSI(receipient);
}
else {
JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, receipient, idGenerator->generateID(), iqRouter);
//jsManager->getSession(receipient, idGenerator->generateID());
assert(jingleSession);
jsManager->registerOutgoingSession(from, jingleSession);
#if !HAVE_SWIFTEN_3
boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT = boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy));
return jingleFT;
#endif
}
if (!fullJID.is_initialized()) {
return boost::shared_ptr<OutgoingFileTransfer>();
}
// otherwise try SI
boost::shared_ptr<MyOutgoingSIFileTransfer> jingleFT = boost::shared_ptr<MyOutgoingSIFileTransfer>(new MyOutgoingSIFileTransfer(idGenerator->generateID(), from, fullJID.get(), fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription(), readBytestream, iqRouter, bytestreamServer, bytestreamRegistry));
// else fail
return jingleFT;
}
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingJingle(const JID& bareJID) {
JID fullReceipientJID;
int priority = INT_MIN;
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
//iterate over them
foreach(Presence::ref pres, presences) {
if (pres->getPriority() > priority) {
// look up caps from the jid
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
if (info && info->hasFeature(DiscoInfo::JingleFeature) && info->hasFeature(DiscoInfo::JingleFTFeature) &&
info->hasFeature(DiscoInfo::JingleTransportsIBBFeature)) {
priority = pres->getPriority();
fullReceipientJID = pres->getFrom();
}
}
}
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
}
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingSI(const JID& bareJID) {
JID fullReceipientJID;
int priority = INT_MIN;
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
//iterate over them
foreach(Presence::ref pres, presences) {
if (pres->getPriority() > priority) {
// look up caps from the jid
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
if (info && info->hasFeature("http://jabber.org/protocol/si/profile/file-transfer")) {
priority = pres->getPriority();
fullReceipientJID = pres->getFrom();
}
}
}
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
}
}
/*
* Copyright (c) 2011 Tobias Markmann
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#include "CombinedOutgoingFileTransferManager.h"
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/JID/JID.h>
#include "Swiften/Disco/EntityCapsProvider.h"
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swiften/Jingle/JingleSessionImpl.h>
#include <Swiften/Jingle/JingleContentID.h>
#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/Base/foreach.h>
namespace Swift {
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
idGenerator = new IDGenerator();
}
CombinedOutgoingFileTransferManager::~CombinedOutgoingFileTransferManager() {
delete idGenerator;
}
boost::shared_ptr<OutgoingFileTransfer> CombinedOutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr<ReadBytestream> readBytestream, const StreamInitiationFileInfo& fileInfo) {
// check if receipient support Jingle FT
boost::optional<JID> fullJID = highestPriorityJIDSupportingJingle(receipient);
if (!fullJID.is_initialized()) {
fullJID = highestPriorityJIDSupportingSI(receipient);
}
else {
JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, receipient, idGenerator->generateID(), iqRouter);
//jsManager->getSession(receipient, idGenerator->generateID());
assert(jingleSession);
jsManager->registerOutgoingSession(from, jingleSession);
#if !HAVE_SWIFTEN_3
boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT = boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy));
return jingleFT;
#endif
}
if (!fullJID.is_initialized()) {
return boost::shared_ptr<OutgoingFileTransfer>();
}
// otherwise try SI
boost::shared_ptr<MyOutgoingSIFileTransfer> jingleFT = boost::shared_ptr<MyOutgoingSIFileTransfer>(new MyOutgoingSIFileTransfer(idGenerator->generateID(), from, fullJID.get(), fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription(), readBytestream, iqRouter, bytestreamServer, bytestreamRegistry));
// else fail
return jingleFT;
}
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingJingle(const JID& bareJID) {
JID fullReceipientJID;
int priority = INT_MIN;
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
//iterate over them
foreach(Presence::ref pres, presences) {
if (pres->getPriority() > priority) {
// look up caps from the jid
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
if (info && info->hasFeature(DiscoInfo::JingleFeature) && info->hasFeature(DiscoInfo::JingleFTFeature) &&
info->hasFeature(DiscoInfo::JingleTransportsIBBFeature)) {
priority = pres->getPriority();
fullReceipientJID = pres->getFrom();
}
}
}
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
}
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingSI(const JID& bareJID) {
JID fullReceipientJID;
int priority = INT_MIN;
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
//iterate over them
foreach(Presence::ref pres, presences) {
if (pres->getPriority() > priority) {
// look up caps from the jid
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
if (info && info->hasFeature("http://jabber.org/protocol/si/profile/file-transfer")) {
priority = pres->getPriority();
fullReceipientJID = pres->getFrom();
}
}
}
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
}
}

View File

@ -1,58 +1,58 @@
/*
* Copyright (c) 2011 Tobias Markmann
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
#include <Swiften/JID/JID.h>
#include "transport/presenceoracle.h"
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class JingleSessionManager;
class IQRouter;
class EntityCapsProvider;
class RemoteJingleTransportCandidateSelectorFactory;
class LocalJingleTransportCandidateGeneratorFactory;
class OutgoingFileTransfer;
class JID;
class IDGenerator;
class ReadBytestream;
class StreamInitiationFileInfo;
class SOCKS5BytestreamRegistry;
class SOCKS5BytestreamProxy;
class SOCKS5BytestreamServer;
class PresenceOracle;
class CombinedOutgoingFileTransferManager {
public:
CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
~CombinedOutgoingFileTransferManager();
boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&);
private:
boost::optional<JID> highestPriorityJIDSupportingJingle(const JID& bareJID);
boost::optional<JID> highestPriorityJIDSupportingSI(const JID& bareJID);
JingleSessionManager* jsManager;
IQRouter* iqRouter;
EntityCapsProvider* capsProvider;
RemoteJingleTransportCandidateSelectorFactory* remoteFactory;
LocalJingleTransportCandidateGeneratorFactory* localFactory;
IDGenerator *idGenerator;
SOCKS5BytestreamRegistry* bytestreamRegistry;
SOCKS5BytestreamProxy* bytestreamProxy;
Transport::PresenceOracle* presenceOracle;
SOCKS5BytestreamServer *bytestreamServer;
};
}
/*
* Copyright (c) 2011 Tobias Markmann
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
#include <Swiften/JID/JID.h>
#include "transport/presenceoracle.h"
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class JingleSessionManager;
class IQRouter;
class EntityCapsProvider;
class RemoteJingleTransportCandidateSelectorFactory;
class LocalJingleTransportCandidateGeneratorFactory;
class OutgoingFileTransfer;
class JID;
class IDGenerator;
class ReadBytestream;
class StreamInitiationFileInfo;
class SOCKS5BytestreamRegistry;
class SOCKS5BytestreamProxy;
class SOCKS5BytestreamServer;
class PresenceOracle;
class CombinedOutgoingFileTransferManager {
public:
CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
~CombinedOutgoingFileTransferManager();
boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&);
private:
boost::optional<JID> highestPriorityJIDSupportingJingle(const JID& bareJID);
boost::optional<JID> highestPriorityJIDSupportingSI(const JID& bareJID);
JingleSessionManager* jsManager;
IQRouter* iqRouter;
EntityCapsProvider* capsProvider;
RemoteJingleTransportCandidateSelectorFactory* remoteFactory;
LocalJingleTransportCandidateGeneratorFactory* localFactory;
IDGenerator *idGenerator;
SOCKS5BytestreamRegistry* bytestreamRegistry;
SOCKS5BytestreamProxy* bytestreamProxy;
Transport::PresenceOracle* presenceOracle;
SOCKS5BytestreamServer *bytestreamServer;
};
}

View File

@ -1,118 +1,118 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
#include <boost/bind.hpp>
#include <Swiften/FileTransfer/StreamInitiationRequest.h>
#include <Swiften/FileTransfer/BytestreamsRequest.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/IBBSendSession.h>
namespace Swift {
MyOutgoingSIFileTransfer::MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer), registry(registry) {
}
void MyOutgoingSIFileTransfer::start() {
StreamInitiation::ref streamInitiation(new StreamInitiation());
streamInitiation->setID(id);
streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size));
streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams");
streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb");
StreamInitiationRequest::ref request = StreamInitiationRequest::create(from, to, streamInitiation, iqRouter);
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2));
request->send();
}
void MyOutgoingSIFileTransfer::stop() {
}
void MyOutgoingSIFileTransfer::cancel() {
// TODO
// session->sendTerminate(JinglePayload::Reason::Cancel);
if (ibbSession) {
ibbSession->stop();
}
#if !HAVE_SWIFTEN_3
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
if (serverSession) {
serverSession->stop();
}
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
#endif
}
void MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) {
if (error) {
finish(FileTransferError());
}
else {
if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") {
#if !HAVE_SWIFTEN_3
registry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(id, from, to), bytestream);
socksServer->addReadBytestream(id, from, to, bytestream);
#endif
Bytestreams::ref bytestreams(new Bytestreams());
bytestreams->setStreamID(id);
HostAddressPort addressPort = socksServer->getAddressPort();
bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort()));
BytestreamsRequest::ref request = BytestreamsRequest::create(from, to, bytestreams, iqRouter);
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2));
request->send();
}
else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") {
ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, from, to, bytestream, iqRouter));
ibbSession->onFinished.connect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
ibbSession->start();
#if !HAVE_SWIFTEN_3
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
#endif
}
}
}
void MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) {
if (error) {
finish(FileTransferError());
return;
}
#if !HAVE_SWIFTEN_3
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
// serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1));
// serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1));
serverSession->startTransfer();
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
#endif
//socksServer->onTransferFinished.connect();
}
void MyOutgoingSIFileTransfer::finish(boost::optional<FileTransferError> error) {
if (ibbSession) {
ibbSession->onFinished.disconnect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
ibbSession.reset();
}
#if !HAVE_SWIFTEN_3
socksServer->removeReadBytestream(id, from, to);
if(error) {
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
}
else {
onStateChange(FileTransfer::State(FileTransfer::State::Finished));
}
#endif
onFinished(error);
}
void MyOutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) {
finish(error);
}
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
#include <boost/bind.hpp>
#include <Swiften/FileTransfer/StreamInitiationRequest.h>
#include <Swiften/FileTransfer/BytestreamsRequest.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/IBBSendSession.h>
namespace Swift {
MyOutgoingSIFileTransfer::MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer), registry(registry) {
}
void MyOutgoingSIFileTransfer::start() {
StreamInitiation::ref streamInitiation(new StreamInitiation());
streamInitiation->setID(id);
streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size));
streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams");
streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb");
StreamInitiationRequest::ref request = StreamInitiationRequest::create(from, to, streamInitiation, iqRouter);
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2));
request->send();
}
void MyOutgoingSIFileTransfer::stop() {
}
void MyOutgoingSIFileTransfer::cancel() {
// TODO
// session->sendTerminate(JinglePayload::Reason::Cancel);
if (ibbSession) {
ibbSession->stop();
}
#if !HAVE_SWIFTEN_3
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
if (serverSession) {
serverSession->stop();
}
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
#endif
}
void MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) {
if (error) {
finish(FileTransferError());
}
else {
if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") {
#if !HAVE_SWIFTEN_3
registry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(id, from, to), bytestream);
socksServer->addReadBytestream(id, from, to, bytestream);
#endif
Bytestreams::ref bytestreams(new Bytestreams());
bytestreams->setStreamID(id);
HostAddressPort addressPort = socksServer->getAddressPort();
bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort()));
BytestreamsRequest::ref request = BytestreamsRequest::create(from, to, bytestreams, iqRouter);
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2));
request->send();
}
else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") {
ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, from, to, bytestream, iqRouter));
ibbSession->onFinished.connect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
ibbSession->start();
#if !HAVE_SWIFTEN_3
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
#endif
}
}
}
void MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) {
if (error) {
finish(FileTransferError());
return;
}
#if !HAVE_SWIFTEN_3
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
// serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1));
// serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1));
serverSession->startTransfer();
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
#endif
//socksServer->onTransferFinished.connect();
}
void MyOutgoingSIFileTransfer::finish(boost::optional<FileTransferError> error) {
if (ibbSession) {
ibbSession->onFinished.disconnect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
ibbSession.reset();
}
#if !HAVE_SWIFTEN_3
socksServer->removeReadBytestream(id, from, to);
if(error) {
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
}
else {
onStateChange(FileTransfer::State(FileTransfer::State::Finished));
}
#endif
onFinished(error);
}
void MyOutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) {
finish(error);
}
}

View File

@ -1,58 +1,58 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
#include <Swiften/FileTransfer/ReadBytestream.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/FileTransfer/FileTransferError.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Elements/StreamInitiation.h>
#include <Swiften/Elements/Bytestreams.h>
#include <Swiften/Elements/ErrorPayload.h>
#include <Swiften/FileTransfer/IBBSendSession.h>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class IQRouter;
class SOCKS5BytestreamServer;
class SOCKS5BytestreamRegistry;
class MyOutgoingSIFileTransfer : public OutgoingFileTransfer {
public:
MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry);
virtual void start();
virtual void stop();
virtual void cancel();
boost::signal<void (const boost::optional<FileTransferError>&)> onFinished;
private:
void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref);
void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref);
void finish(boost::optional<FileTransferError> error);
void handleIBBSessionFinished(boost::optional<FileTransferError> error);
private:
std::string id;
JID from;
JID to;
std::string name;
int size;
std::string description;
boost::shared_ptr<ReadBytestream> bytestream;
IQRouter* iqRouter;
SOCKS5BytestreamServer* socksServer;
boost::shared_ptr<IBBSendSession> ibbSession;
SOCKS5BytestreamRegistry *registry;
};
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
#include <Swiften/FileTransfer/ReadBytestream.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/FileTransfer/FileTransferError.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Elements/StreamInitiation.h>
#include <Swiften/Elements/Bytestreams.h>
#include <Swiften/Elements/ErrorPayload.h>
#include <Swiften/FileTransfer/IBBSendSession.h>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class IQRouter;
class SOCKS5BytestreamServer;
class SOCKS5BytestreamRegistry;
class MyOutgoingSIFileTransfer : public OutgoingFileTransfer {
public:
MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry);
virtual void start();
virtual void stop();
virtual void cancel();
boost::signal<void (const boost::optional<FileTransferError>&)> onFinished;
private:
void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref);
void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref);
void finish(boost::optional<FileTransferError> error);
void handleIBBSessionFinished(boost::optional<FileTransferError> error);
private:
std::string id;
JID from;
JID to;
std::string name;
int size;
std::string description;
boost::shared_ptr<ReadBytestream> bytestream;
IQRouter* iqRouter;
SOCKS5BytestreamServer* socksServer;
boost::shared_ptr<IBBSendSession> ibbSession;
SOCKS5BytestreamRegistry *registry;
};
}

View File

@ -25,7 +25,7 @@ void DummyConnectionServer::stop() {
}
void DummyConnectionServer::acceptConnection(boost::shared_ptr<Connection> connection) {
void DummyConnectionServer::acceptConnection(boost::shared_ptr<Swift::Connection> connection) {
eventLoop->postEvent(
boost::bind(boost::ref(onNewConnection), connection),
shared_from_this());

View File

@ -30,7 +30,11 @@ namespace Swift {
return ref(new DummyConnectionServer(eventLoop));
}
void acceptConnection(boost::shared_ptr<Connection> connection);
void acceptConnection(boost::shared_ptr<Swift::Connection> connection);
virtual boost::optional<Swift::ConnectionServer::Error> tryStart() {
return boost::optional<Swift::ConnectionServer::Error>();
}
virtual void start();
virtual void stop();

View File

@ -9,6 +9,12 @@
#include <Swiften/Network/DummyConnectionFactory.h>
#include <Swiften/Network/PlatformDomainNameResolver.h>
#include <Swiften/Network/DummyConnectionServerFactory.h>
#if HAVE_SWIFTEN_3
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#include <Swiften/Network/NetworkEnvironment.h>
#include <Swiften/Network/PlatformNetworkEnvironment.h>
#endif
namespace Swift {
@ -18,6 +24,8 @@ DummyNetworkFactories::DummyNetworkFactories(EventLoop* eventLoop) {
#if HAVE_SWIFTEN_3
idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create());
domainNameResolver = new PlatformDomainNameResolver(idnConverter.get(), eventLoop);
cryptoProvider = PlatformCryptoProvider::create();
networkEnvironment = new PlatformNetworkEnvironment();
#else
domainNameResolver = new PlatformDomainNameResolver(eventLoop);
#endif

View File

@ -1,80 +1,88 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/Parser/PlatformXMLParserFactory.h>
#if HAVE_SWIFTEN_3
#include <Swiften/IDN/IDNConverter.h>
#include <Swiften/IDN/PlatformIDNConverter.h>
#endif
namespace Swift {
class EventLoop;
class DummyNetworkFactories : public NetworkFactories {
public:
DummyNetworkFactories(EventLoop *eventLoop);
~DummyNetworkFactories();
virtual TimerFactory* getTimerFactory() const {
return timerFactory;
}
virtual ConnectionFactory* getConnectionFactory() const {
return connectionFactory;
}
#if HAVE_SWIFTEN_3
IDNConverter* getIDNConverter() const {
return idnConverter.get();
}
#endif
DomainNameResolver* getDomainNameResolver() const {
return domainNameResolver;
}
ConnectionServerFactory* getConnectionServerFactory() const {
return connectionServerFactory;
}
virtual Swift::NATTraverser* getNATTraverser() const {
return 0;
}
Swift::XMLParserFactory* getXMLParserFactory() const {
return m_platformXMLParserFactory;
}
EventLoop *getEventLoop() const {
return eventLoop;
}
Swift::TLSContextFactory* getTLSContextFactory() const {
return 0;
}
Swift::ProxyProvider* getProxyProvider() const {
return 0;
}
private:
PlatformXMLParserFactory *m_platformXMLParserFactory;
TimerFactory* timerFactory;
ConnectionFactory* connectionFactory;
#if HAVE_SWIFTEN_3
boost::shared_ptr<IDNConverter> idnConverter;
#endif
DomainNameResolver* domainNameResolver;
ConnectionServerFactory* connectionServerFactory;
EventLoop *eventLoop;
};
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/Parser/PlatformXMLParserFactory.h>
#if HAVE_SWIFTEN_3
#include <Swiften/IDN/IDNConverter.h>
#include <Swiften/IDN/PlatformIDNConverter.h>
#endif
namespace Swift {
class EventLoop;
class DummyNetworkFactories : public NetworkFactories {
public:
DummyNetworkFactories(EventLoop *eventLoop);
~DummyNetworkFactories();
virtual TimerFactory* getTimerFactory() const {
return timerFactory;
}
virtual ConnectionFactory* getConnectionFactory() const {
return connectionFactory;
}
#if HAVE_SWIFTEN_3
IDNConverter* getIDNConverter() const {
return idnConverter.get();
}
Swift::CryptoProvider* getCryptoProvider() const {
return cryptoProvider;
}
Swift::NetworkEnvironment* getNetworkEnvironment() const {
return networkEnvironment;
}
#endif
DomainNameResolver* getDomainNameResolver() const {
return domainNameResolver;
}
ConnectionServerFactory* getConnectionServerFactory() const {
return connectionServerFactory;
}
virtual Swift::NATTraverser* getNATTraverser() const {
return 0;
}
Swift::XMLParserFactory* getXMLParserFactory() const {
return m_platformXMLParserFactory;
}
EventLoop *getEventLoop() const {
return eventLoop;
}
Swift::TLSContextFactory* getTLSContextFactory() const {
return 0;
}
Swift::ProxyProvider* getProxyProvider() const {
return 0;
}
private:
PlatformXMLParserFactory *m_platformXMLParserFactory;
TimerFactory* timerFactory;
ConnectionFactory* connectionFactory;
#if HAVE_SWIFTEN_3
boost::shared_ptr<IDNConverter> idnConverter;
CryptoProvider* cryptoProvider;
NetworkEnvironment* networkEnvironment;
#endif
DomainNameResolver* domainNameResolver;
ConnectionServerFactory* connectionServerFactory;
EventLoop *eventLoop;
};
}

View File

@ -1,183 +1,183 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Server/ServerFromClientSession.h>
#include <boost/bind.hpp>
#include <Swiften/Elements/ProtocolHeader.h>
#include <Swiften/Elements/StreamError.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Server/UserRegistry.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/StreamStack/XMPPLayer.h>
#include <Swiften/Elements/StreamFeatures.h>
#include <Swiften/Elements/ResourceBind.h>
#include <Swiften/Elements/StartSession.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Elements/AuthSuccess.h>
#include <Swiften/Elements/AuthFailure.h>
#include <Swiften/Elements/AuthRequest.h>
#include <Swiften/SASL/PLAINMessage.h>
#include <Swiften/StreamStack/StreamStack.h>
#include <Swiften/StreamStack/TLSServerLayer.h>
#include <Swiften/Elements/StartTLSRequest.h>
#include <Swiften/Elements/TLSProceed.h>
#include <iostream>
#include <Swiften/TLS/CertificateWithKey.h>
namespace Swift {
ServerFromClientSession::ServerFromClientSession(
const std::string& id,
boost::shared_ptr<Connection> connection,
PayloadParserFactoryCollection* payloadParserFactories,
PayloadSerializerCollection* payloadSerializers,
UserRegistry* userRegistry,
XMLParserFactory* factory,
Swift::JID remoteJID) :
Session(connection, payloadParserFactories, payloadSerializers, factory),
id_(id),
userRegistry_(userRegistry),
authenticated_(false),
initialized(false),
allowSASLEXTERNAL(false),
tlsLayer(0),
tlsConnected(false) {
setRemoteJID(remoteJID);
}
ServerFromClientSession::~ServerFromClientSession() {
if (tlsLayer) {
delete tlsLayer;
}
}
void ServerFromClientSession::handlePasswordValid() {
if (!isInitialized()) {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
authenticated_ = true;
getXMPPLayer()->resetParser();
}
}
void ServerFromClientSession::handlePasswordInvalid(const std::string &error) {
if (!isInitialized()) {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
if (!error.empty()) {
boost::shared_ptr<StreamError> msg(new StreamError(StreamError::UndefinedCondition, error));
getXMPPLayer()->writeElement(msg);
}
finishSession(AuthenticationFailedError);
}
}
void ServerFromClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
if (isInitialized()) {
onElementReceived(element);
}
else {
if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) {
if (authRequest->getMechanism() == "EXTERNAL") {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
authenticated_ = true;
getXMPPLayer()->resetParser();
}
else {
PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
user_ = plainMessage.getAuthenticationID();
userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), this, plainMessage.getPassword());
}
}
else {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
finishSession(NoSupportedAuthMechanismsError);
}
}
else if (dynamic_cast<StartTLSRequest*>(element.get()) != NULL) {
getXMPPLayer()->writeElement(boost::shared_ptr<TLSProceed>(new TLSProceed));
getStreamStack()->addLayer(tlsLayer);
tlsLayer->connect();
getXMPPLayer()->resetParser();
}
else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
if (boost::shared_ptr<ResourceBind> resourceBind = iq->getPayload<ResourceBind>()) {
std::string bucket = "abcdefghijklmnopqrstuvwxyz";
std::string uuid;
for (int i = 0; i < 10; i++) {
uuid += bucket[rand() % bucket.size()];
}
setRemoteJID(JID(user_, getLocalJID().getDomain(), uuid));
boost::shared_ptr<ResourceBind> resultResourceBind(new ResourceBind());
resultResourceBind->setJID(getRemoteJID());
getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind));
}
else if (iq->getPayload<StartSession>()) {
getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID()));
setInitialized();
}
}
}
}
void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
setLocalJID(JID("", incomingHeader.getTo()));
ProtocolHeader header;
header.setFrom(incomingHeader.getTo());
header.setID(id_);
getXMPPLayer()->writeHeader(header);
boost::shared_ptr<StreamFeatures> features(new StreamFeatures());
if (!authenticated_) {
if (tlsLayer && !tlsConnected) {
features->setHasStartTLS();
}
features->addAuthenticationMechanism("PLAIN");
if (allowSASLEXTERNAL) {
features->addAuthenticationMechanism("EXTERNAL");
}
}
else {
features->setHasResourceBind();
features->setHasSession();
}
getXMPPLayer()->writeElement(features);
}
void ServerFromClientSession::setInitialized() {
initialized = true;
onSessionStarted();
}
void ServerFromClientSession::setAllowSASLEXTERNAL() {
allowSASLEXTERNAL = true;
}
void ServerFromClientSession::handleSessionFinished(const boost::optional<SessionError>&) {
userRegistry_->stopLogin(JID(user_, getLocalJID().getDomain()), this);
}
void ServerFromClientSession::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert) {
tlsLayer = new TLSServerLayer(tlsContextFactory);
if (!tlsLayer->setServerCertificate(cert)) {
// std::cout << "error\n";
// TODO:
// onClosed(boost::shared_ptr<Error>(new Error(Error::InvalidTLSCertificateError)));
}
else {
tlsLayer->onError.connect(boost::bind(&ServerFromClientSession::handleTLSError, this));
tlsLayer->onConnected.connect(boost::bind(&ServerFromClientSession::handleTLSConnected, this));
// getStreamStack()->addLayer(tlsLayer);
// tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this));
// tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this));
// tlsLayer->connect();
}
}
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Server/ServerFromClientSession.h>
#include <boost/bind.hpp>
#include <Swiften/Elements/ProtocolHeader.h>
#include <Swiften/Elements/StreamError.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Server/UserRegistry.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/StreamStack/XMPPLayer.h>
#include <Swiften/Elements/StreamFeatures.h>
#include <Swiften/Elements/ResourceBind.h>
#include <Swiften/Elements/StartSession.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Elements/AuthSuccess.h>
#include <Swiften/Elements/AuthFailure.h>
#include <Swiften/Elements/AuthRequest.h>
#include <Swiften/SASL/PLAINMessage.h>
#include <Swiften/StreamStack/StreamStack.h>
#include <Swiften/StreamStack/TLSServerLayer.h>
#include <Swiften/Elements/StartTLSRequest.h>
#include <Swiften/Elements/TLSProceed.h>
#include <iostream>
#include <Swiften/TLS/CertificateWithKey.h>
namespace Swift {
ServerFromClientSession::ServerFromClientSession(
const std::string& id,
boost::shared_ptr<Connection> connection,
PayloadParserFactoryCollection* payloadParserFactories,
PayloadSerializerCollection* payloadSerializers,
UserRegistry* userRegistry,
XMLParserFactory* factory,
Swift::JID remoteJID) :
Session(connection, payloadParserFactories, payloadSerializers, factory),
id_(id),
userRegistry_(userRegistry),
authenticated_(false),
initialized(false),
allowSASLEXTERNAL(false),
tlsLayer(0),
tlsConnected(false) {
setRemoteJID(remoteJID);
}
ServerFromClientSession::~ServerFromClientSession() {
if (tlsLayer) {
delete tlsLayer;
}
}
void ServerFromClientSession::handlePasswordValid() {
if (!isInitialized()) {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
authenticated_ = true;
getXMPPLayer()->resetParser();
}
}
void ServerFromClientSession::handlePasswordInvalid(const std::string &error) {
if (!isInitialized()) {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
if (!error.empty()) {
boost::shared_ptr<StreamError> msg(new StreamError(StreamError::UndefinedCondition, error));
getXMPPLayer()->writeElement(msg);
}
finishSession(AuthenticationFailedError);
}
}
void ServerFromClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
if (isInitialized()) {
onElementReceived(element);
}
else {
if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) {
if (authRequest->getMechanism() == "EXTERNAL") {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
authenticated_ = true;
getXMPPLayer()->resetParser();
}
else {
PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
user_ = plainMessage.getAuthenticationID();
userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), this, plainMessage.getPassword());
}
}
else {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
finishSession(NoSupportedAuthMechanismsError);
}
}
else if (dynamic_cast<StartTLSRequest*>(element.get()) != NULL) {
getXMPPLayer()->writeElement(boost::shared_ptr<TLSProceed>(new TLSProceed));
getStreamStack()->addLayer(tlsLayer);
tlsLayer->connect();
getXMPPLayer()->resetParser();
}
else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
if (boost::shared_ptr<ResourceBind> resourceBind = iq->getPayload<ResourceBind>()) {
std::string bucket = "abcdefghijklmnopqrstuvwxyz";
std::string uuid;
for (int i = 0; i < 10; i++) {
uuid += bucket[rand() % bucket.size()];
}
setRemoteJID(JID(user_, getLocalJID().getDomain(), uuid));
boost::shared_ptr<ResourceBind> resultResourceBind(new ResourceBind());
resultResourceBind->setJID(getRemoteJID());
getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind));
}
else if (iq->getPayload<StartSession>()) {
getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID()));
setInitialized();
}
}
}
}
void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
setLocalJID(JID("", incomingHeader.getTo()));
ProtocolHeader header;
header.setFrom(incomingHeader.getTo());
header.setID(id_);
getXMPPLayer()->writeHeader(header);
boost::shared_ptr<StreamFeatures> features(new StreamFeatures());
if (!authenticated_) {
if (tlsLayer && !tlsConnected) {
features->setHasStartTLS();
}
features->addAuthenticationMechanism("PLAIN");
if (allowSASLEXTERNAL) {
features->addAuthenticationMechanism("EXTERNAL");
}
}
else {
features->setHasResourceBind();
features->setHasSession();
}
getXMPPLayer()->writeElement(features);
}
void ServerFromClientSession::setInitialized() {
initialized = true;
onSessionStarted();
}
void ServerFromClientSession::setAllowSASLEXTERNAL() {
allowSASLEXTERNAL = true;
}
void ServerFromClientSession::handleSessionFinished(const boost::optional<SessionError>&) {
userRegistry_->stopLogin(JID(user_, getLocalJID().getDomain()), this);
}
void ServerFromClientSession::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert) {
tlsLayer = new TLSServerLayer(tlsContextFactory);
if (!tlsLayer->setServerCertificate(cert)) {
// std::cout << "error\n";
// TODO:
// onClosed(boost::shared_ptr<Error>(new Error(Error::InvalidTLSCertificateError)));
}
else {
tlsLayer->onError.connect(boost::bind(&ServerFromClientSession::handleTLSError, this));
tlsLayer->onConnected.connect(boost::bind(&ServerFromClientSession::handleTLSConnected, this));
// getStreamStack()->addLayer(tlsLayer);
// tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this));
// tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this));
// tlsLayer->connect();
}
}
}

View File

@ -1,91 +1,91 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <Swiften/Base/boost_bsignals.h>
#include <boost/enable_shared_from_this.hpp>
#include <string>
#include <Swiften/Session/Session.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Base/ByteArray.h>
#include <Swiften/TLS/CertificateWithKey.h>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class ProtocolHeader;
class Element;
class Stanza;
class PayloadParserFactoryCollection;
class PayloadSerializerCollection;
class StreamStack;
class UserRegistry;
class XMPPLayer;
class ConnectionLayer;
class Connection;
class TLSServerLayer;
class TLSServerContextFactory;
class PKCS12Certificate;
class ServerFromClientSession : public Session {
public:
ServerFromClientSession(
const std::string& id,
boost::shared_ptr<Connection> connection,
PayloadParserFactoryCollection* payloadParserFactories,
PayloadSerializerCollection* payloadSerializers,
UserRegistry* userRegistry,
XMLParserFactory* factory,
Swift::JID remoteJID = Swift::JID());
~ServerFromClientSession();
boost::signal<void ()> onSessionStarted;
void setAllowSASLEXTERNAL();
const std::string &getUser() {
return user_;
}
void addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert);
Swift::JID getBareJID() {
return Swift::JID(user_, getLocalJID().getDomain());
}
void handlePasswordValid();
void handlePasswordInvalid(const std::string &error = "");
private:
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<ToplevelElement>);
#else
void handleElement(boost::shared_ptr<Element>);
#endif
void handleStreamStart(const ProtocolHeader& header);
void handleSessionFinished(const boost::optional<SessionError>&);
void setInitialized();
bool isInitialized() const {
return initialized;
}
void handleTLSError() { }
void handleTLSConnected() { tlsConnected = true; }
private:
std::string id_;
UserRegistry* userRegistry_;
bool authenticated_;
bool initialized;
bool allowSASLEXTERNAL;
std::string user_;
TLSServerLayer* tlsLayer;
bool tlsConnected;
};
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <Swiften/Base/boost_bsignals.h>
#include <boost/enable_shared_from_this.hpp>
#include <string>
#include <Swiften/Session/Session.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Base/ByteArray.h>
#include <Swiften/TLS/CertificateWithKey.h>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class ProtocolHeader;
class Element;
class Stanza;
class PayloadParserFactoryCollection;
class PayloadSerializerCollection;
class StreamStack;
class UserRegistry;
class XMPPLayer;
class ConnectionLayer;
class Connection;
class TLSServerLayer;
class TLSServerContextFactory;
class PKCS12Certificate;
class ServerFromClientSession : public Session {
public:
ServerFromClientSession(
const std::string& id,
boost::shared_ptr<Connection> connection,
PayloadParserFactoryCollection* payloadParserFactories,
PayloadSerializerCollection* payloadSerializers,
UserRegistry* userRegistry,
XMLParserFactory* factory,
Swift::JID remoteJID = Swift::JID());
~ServerFromClientSession();
boost::signal<void ()> onSessionStarted;
void setAllowSASLEXTERNAL();
const std::string &getUser() {
return user_;
}
void addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert);
Swift::JID getBareJID() {
return Swift::JID(user_, getLocalJID().getDomain());
}
void handlePasswordValid();
void handlePasswordInvalid(const std::string &error = "");
private:
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<ToplevelElement>);
#else
void handleElement(boost::shared_ptr<Element>);
#endif
void handleStreamStart(const ProtocolHeader& header);
void handleSessionFinished(const boost::optional<SessionError>&);
void setInitialized();
bool isInitialized() const {
return initialized;
}
void handleTLSError() { }
void handleTLSConnected() { tlsConnected = true; }
private:
std::string id_;
UserRegistry* userRegistry_;
bool authenticated_;
bool initialized;
bool allowSASLEXTERNAL;
std::string user_;
TLSServerLayer* tlsLayer;
bool tlsConnected;
};
}

View File

@ -1,179 +1,179 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Base/Error.h"
#include <iostream>
#include <boost/bind.hpp>
namespace Swift {
namespace {
// struct PriorityLessThan {
// bool operator()(const ServerSession* s1, const ServerSession* s2) const {
// return s1->getPriority() < s2->getPriority();
// }
// };
struct HasJID {
HasJID(const JID& jid) : jid(jid) {}
bool operator()(const boost::shared_ptr<ServerFromClientSession> session) const {
return session->getRemoteJID().equals(jid, JID::WithResource);
}
JID jid;
};
}
void ServerStanzaChannel::addSession(boost::shared_ptr<ServerFromClientSession> session) {
sessions[session->getRemoteJID().toBare().toString()].push_back(session);
session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
}
void ServerStanzaChannel::removeSession(boost::shared_ptr<ServerFromClientSession> session) {
session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
std::list<boost::shared_ptr<ServerFromClientSession> > &lst = sessions[session->getRemoteJID().toBare().toString()];
lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end());
}
void ServerStanzaChannel::sendIQ(boost::shared_ptr<IQ> iq) {
send(iq);
}
void ServerStanzaChannel::sendMessage(boost::shared_ptr<Message> message) {
send(message);
}
void ServerStanzaChannel::sendPresence(boost::shared_ptr<Presence> presence) {
send(presence);
}
void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session) {
if (safeByteArrayToString(data).find("</stream:stream>") != std::string::npos) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom(session->getRemoteJID());
presence->setType(Swift::Presence::Unavailable);
onPresenceReceived(presence);
}
}
#if HAVE_SWIFTEN_3
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last) {
#else
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element, bool last) {
#endif
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
candidateSessions.push_back(*i);
}
for (std::vector<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
removeSession(*i);
if (element) {
(*i)->sendElement(element);
}
if (last && (*i)->getRemoteJID().isValid()) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom((*i)->getRemoteJID());
presence->setType(Swift::Presence::Unavailable);
onPresenceReceived(presence);
}
(*i)->finishSession();
// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
if (last) {
break;
}
}
}
std::string ServerStanzaChannel::getNewIQID() {
return idGenerator.generateID();
}
void ServerStanzaChannel::send(boost::shared_ptr<Stanza> stanza) {
JID to = stanza->getTo();
assert(to.isValid());
// For a full JID, first try to route to a session with the full JID
if (!to.isBare()) {
std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = std::find_if(sessions[stanza->getTo().toBare().toString()].begin(), sessions[stanza->getTo().toBare().toString()].end(), HasJID(to));
if (i != sessions[stanza->getTo().toBare().toString()].end()) {
(*i)->sendElement(stanza);
return;
}
}
// Look for candidate sessions
to = to.toBare();
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[stanza->getTo().toBare().toString()].begin(); i != sessions[stanza->getTo().toBare().toString()].end(); ++i) {
if ((*i)->getRemoteJID().equals(to, JID::WithoutResource)) {
candidateSessions.push_back(*i);
(*i)->sendElement(stanza);
}
}
if (candidateSessions.empty()) {
return;
}
// Find the session with the highest priority
// std::vector<ServerSession*>::const_iterator i = std::max_element(sessions.begin(), sessions.end(), PriorityLessThan());
// (*i)->sendStanza(stanza);
return;
}
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession>& session) {
removeSession(session);
// if (!session->initiatedFinish()) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom(session->getRemoteJID());
presence->setType(Swift::Presence::Unavailable);
onPresenceReceived(presence);
// }
}
void ServerStanzaChannel::handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession>& session) {
boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
if (!stanza) {
return;
}
stanza->setFrom(session->getRemoteJID());
if (!stanza->getFrom().isValid())
return;
boost::shared_ptr<Message> message = boost::dynamic_pointer_cast<Message>(stanza);
if (message) {
onMessageReceived(message);
return;
}
boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza);
if (presence) {
onPresenceReceived(presence);
return;
}
boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza);
if (iq) {
onIQReceived(iq);
return;
}
}
void ServerStanzaChannel::handleSessionInitialized() {
onAvailableChanged(true);
}
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Base/Error.h"
#include <iostream>
#include <boost/bind.hpp>
namespace Swift {
namespace {
// struct PriorityLessThan {
// bool operator()(const ServerSession* s1, const ServerSession* s2) const {
// return s1->getPriority() < s2->getPriority();
// }
// };
struct HasJID {
HasJID(const JID& jid) : jid(jid) {}
bool operator()(const boost::shared_ptr<ServerFromClientSession> session) const {
return session->getRemoteJID().equals(jid, JID::WithResource);
}
JID jid;
};
}
void ServerStanzaChannel::addSession(boost::shared_ptr<ServerFromClientSession> session) {
sessions[session->getRemoteJID().toBare().toString()].push_back(session);
session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
}
void ServerStanzaChannel::removeSession(boost::shared_ptr<ServerFromClientSession> session) {
session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
std::list<boost::shared_ptr<ServerFromClientSession> > &lst = sessions[session->getRemoteJID().toBare().toString()];
lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end());
}
void ServerStanzaChannel::sendIQ(boost::shared_ptr<IQ> iq) {
send(iq);
}
void ServerStanzaChannel::sendMessage(boost::shared_ptr<Message> message) {
send(message);
}
void ServerStanzaChannel::sendPresence(boost::shared_ptr<Presence> presence) {
send(presence);
}
void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session) {
if (safeByteArrayToString(data).find("</stream:stream>") != std::string::npos) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom(session->getRemoteJID());
presence->setType(Swift::Presence::Unavailable);
onPresenceReceived(presence);
}
}
#if HAVE_SWIFTEN_3
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last) {
#else
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element, bool last) {
#endif
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
candidateSessions.push_back(*i);
}
for (std::vector<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
removeSession(*i);
if (element) {
(*i)->sendElement(element);
}
if (last && (*i)->getRemoteJID().isValid()) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom((*i)->getRemoteJID());
presence->setType(Swift::Presence::Unavailable);
onPresenceReceived(presence);
}
(*i)->finishSession();
// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
if (last) {
break;
}
}
}
std::string ServerStanzaChannel::getNewIQID() {
return idGenerator.generateID();
}
void ServerStanzaChannel::send(boost::shared_ptr<Stanza> stanza) {
JID to = stanza->getTo();
assert(to.isValid());
// For a full JID, first try to route to a session with the full JID
if (!to.isBare()) {
std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = std::find_if(sessions[stanza->getTo().toBare().toString()].begin(), sessions[stanza->getTo().toBare().toString()].end(), HasJID(to));
if (i != sessions[stanza->getTo().toBare().toString()].end()) {
(*i)->sendElement(stanza);
return;
}
}
// Look for candidate sessions
to = to.toBare();
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[stanza->getTo().toBare().toString()].begin(); i != sessions[stanza->getTo().toBare().toString()].end(); ++i) {
if ((*i)->getRemoteJID().equals(to, JID::WithoutResource)) {
candidateSessions.push_back(*i);
(*i)->sendElement(stanza);
}
}
if (candidateSessions.empty()) {
return;
}
// Find the session with the highest priority
// std::vector<ServerSession*>::const_iterator i = std::max_element(sessions.begin(), sessions.end(), PriorityLessThan());
// (*i)->sendStanza(stanza);
return;
}
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession>& session) {
removeSession(session);
// if (!session->initiatedFinish()) {
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom(session->getRemoteJID());
presence->setType(Swift::Presence::Unavailable);
onPresenceReceived(presence);
// }
}
void ServerStanzaChannel::handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession>& session) {
boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
if (!stanza) {
return;
}
stanza->setFrom(session->getRemoteJID());
if (!stanza->getFrom().isValid())
return;
boost::shared_ptr<Message> message = boost::dynamic_pointer_cast<Message>(stanza);
if (message) {
onMessageReceived(message);
return;
}
boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza);
if (presence) {
onPresenceReceived(presence);
return;
}
boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza);
if (iq) {
onIQReceived(iq);
return;
}
}
void ServerStanzaChannel::handleSessionInitialized() {
onAvailableChanged(true);
}
}

View File

@ -1,62 +1,62 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include "Swiften/Base/IDGenerator.h"
#include "Swiften/Server/ServerFromClientSession.h"
#include "Swiften/Client/StanzaChannel.h"
#include "Swiften/Elements/Message.h"
#include "Swiften/Elements/IQ.h"
#include "Swiften/Elements/Presence.h"
#include "Swiften/TLS/Certificate.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class Error;
class ServerStanzaChannel : public StanzaChannel {
public:
void addSession(boost::shared_ptr<ServerFromClientSession> session);
void removeSession(boost::shared_ptr<ServerFromClientSession> session);
void sendIQ(boost::shared_ptr<IQ> iq);
void sendMessage(boost::shared_ptr<Message> message);
void sendPresence(boost::shared_ptr<Presence> presence);
#if HAVE_SWIFTEN_3
void finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last = false);
#else
void finishSession(const JID& to, boost::shared_ptr<Element> element, bool last = false);
#endif
bool getStreamManagementEnabled() const {
return false;
}
bool isAvailable() const {
return true;
}
std::vector<Certificate::ref> getPeerCertificateChain() const {
return std::vector<Certificate::ref>();
}
private:
std::string getNewIQID();
void send(boost::shared_ptr<Stanza> stanza);
void handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession> &session);
void handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession> &session);
void handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session);
void handleSessionInitialized();
private:
IDGenerator idGenerator;
// [JID][resources][ServerFromClientSession]
std::map<std::string, std::list<boost::shared_ptr<ServerFromClientSession> > > sessions;
};
}
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include "Swiften/Base/IDGenerator.h"
#include "Swiften/Server/ServerFromClientSession.h"
#include "Swiften/Client/StanzaChannel.h"
#include "Swiften/Elements/Message.h"
#include "Swiften/Elements/IQ.h"
#include "Swiften/Elements/Presence.h"
#include "Swiften/TLS/Certificate.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Swift {
class Error;
class ServerStanzaChannel : public StanzaChannel {
public:
void addSession(boost::shared_ptr<ServerFromClientSession> session);
void removeSession(boost::shared_ptr<ServerFromClientSession> session);
void sendIQ(boost::shared_ptr<IQ> iq);
void sendMessage(boost::shared_ptr<Message> message);
void sendPresence(boost::shared_ptr<Presence> presence);
#if HAVE_SWIFTEN_3
void finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last = false);
#else
void finishSession(const JID& to, boost::shared_ptr<Element> element, bool last = false);
#endif
bool getStreamManagementEnabled() const {
return false;
}
bool isAvailable() const {
return true;
}
std::vector<Certificate::ref> getPeerCertificateChain() const {
return std::vector<Certificate::ref>();
}
private:
std::string getNewIQID();
void send(boost::shared_ptr<Stanza> stanza);
void handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession> &session);
void handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession> &session);
void handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session);
void handleSessionInitialized();
private:
IDGenerator idGenerator;
// [JID][resources][ServerFromClientSession]
std::map<std::string, std::list<boost::shared_ptr<ServerFromClientSession> > > sessions;
};
}

View File

@ -1,83 +1,83 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#include <Swiften/Elements/StreamInitiationFileInfo.h>
#if !HAVE_SWIFTEN_3
#include <Swiften/FileTransfer/ConnectivityManager.h>
#endif
#include <Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h>
#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
#if !HAVE_SWIFTEN_3
#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>
#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>
#else
#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
#endif
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#if !HAVE_SWIFTEN_3
#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>
#endif
namespace Transport {
class UserManager;
class User;
class Component;
class Buddy;
class FileTransferManager {
public:
typedef struct Transfer {
boost::shared_ptr<Swift::OutgoingFileTransfer> ft;
Swift::JID from;
Swift::JID to;
boost::shared_ptr<Swift::ReadBytestream> readByteStream;
} Transfer;
FileTransferManager(Component *component, UserManager *userManager);
virtual ~FileTransferManager();
FileTransferManager::Transfer sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info);
private:
Component *m_component;
UserManager *m_userManager;
Swift::CombinedOutgoingFileTransferManager* m_outgoingFTManager;
Swift::RemoteJingleTransportCandidateSelectorFactory* m_remoteCandidateSelectorFactory;
Swift::LocalJingleTransportCandidateGeneratorFactory* m_localCandidateGeneratorFactory;
Swift::JingleSessionManager *m_jingleSessionManager;
Swift::SOCKS5BytestreamRegistry* m_bytestreamRegistry;
#if HAVE_SWIFTEN_3
Swift::SOCKS5BytestreamServerManager* m_proxyServerManager;
Swift::SOCKS5BytestreamProxiesManager *m_proxyManager;
#else
Swift::SOCKS5BytestreamServer* m_bytestreamServer;
Swift::SOCKS5BytestreamProxy* m_bytestreamProxy;
Swift::SOCKS5BytestreamServer *bytestreamServer;
Swift::ConnectivityManager* m_connectivityManager;
#endif
};
}
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#include <Swiften/Elements/StreamInitiationFileInfo.h>
#if !HAVE_SWIFTEN_3
#include <Swiften/FileTransfer/ConnectivityManager.h>
#endif
#include <Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h>
#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
#if !HAVE_SWIFTEN_3
#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>
#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>
#else
#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
#endif
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#if !HAVE_SWIFTEN_3
#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>
#endif
namespace Transport {
class UserManager;
class User;
class Component;
class Buddy;
class FileTransferManager {
public:
typedef struct Transfer {
boost::shared_ptr<Swift::OutgoingFileTransfer> ft;
Swift::JID from;
Swift::JID to;
boost::shared_ptr<Swift::ReadBytestream> readByteStream;
} Transfer;
FileTransferManager(Component *component, UserManager *userManager);
virtual ~FileTransferManager();
FileTransferManager::Transfer sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info);
private:
Component *m_component;
UserManager *m_userManager;
Swift::CombinedOutgoingFileTransferManager* m_outgoingFTManager;
Swift::RemoteJingleTransportCandidateSelectorFactory* m_remoteCandidateSelectorFactory;
Swift::LocalJingleTransportCandidateGeneratorFactory* m_localCandidateGeneratorFactory;
Swift::JingleSessionManager *m_jingleSessionManager;
Swift::SOCKS5BytestreamRegistry* m_bytestreamRegistry;
#if HAVE_SWIFTEN_3
Swift::SOCKS5BytestreamServerManager* m_proxyServerManager;
Swift::SOCKS5BytestreamProxiesManager *m_proxyManager;
#else
Swift::SOCKS5BytestreamServer* m_bytestreamServer;
Swift::SOCKS5BytestreamProxy* m_bytestreamProxy;
Swift::SOCKS5BytestreamServer *bytestreamServer;
Swift::ConnectivityManager* m_connectivityManager;
#endif
};
}

View File

@ -21,6 +21,7 @@
#pragma once
#include <time.h>
#undef TYPE_BOOL
#include "transport/protocol.pb.h"
// #include "conversation.h"
#include <iostream>

View File

@ -1,199 +1,199 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <time.h>
#include "Swiften/Presence/PresenceOracle.h"
#include "Swiften/Disco/EntityCapsManager.h"
#include "Swiften/Network/BoostConnectionServer.h"
#include "Swiften/Network/Connection.h"
#include "Swiften/Elements/ChatState.h"
#include "Swiften/Elements/RosterItemPayload.h"
#include "Swiften/Elements/VCard.h"
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
#include "Swiften/Parser/XMPPParser.h"
#include "Swiften/Parser/XMPPParserClient.h"
#include "Swiften/Serializer/XMPPSerializer.h"
#include "storagebackend.h"
#include "transport/filetransfermanager.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Transport {
class UserManager;
class User;
class Component;
class Buddy;
class LocalBuddy;
class Config;
class NetworkConversation;
class VCardResponder;
class RosterResponder;
class BlockResponder;
class DummyReadBytestream;
class AdminInterface;
class DiscoItemsResponder;
class NetworkPluginServer : Swift::XMPPParserClient {
public:
struct Backend {
int pongReceived;
std::list<User *> users;
Swift::SafeByteArray data;
boost::shared_ptr<Swift::Connection> connection;
unsigned long res;
unsigned long init_res;
unsigned long shared;
bool acceptUsers;
bool longRun;
bool willDie;
std::string id;
};
NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager, DiscoItemsResponder *discoItemsResponder);
virtual ~NetworkPluginServer();
void start();
void setAdminInterface(AdminInterface *adminInterface) {
m_adminInterface = adminInterface;
}
int getBackendCount() {
return m_clients.size();
}
const std::list<Backend *> &getBackends() {
return m_clients;
}
const std::vector<std::string> &getCrashedBackends() {
return m_crashedBackends;
}
void collectBackend();
bool moveToLongRunBackend(User *user);
void handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &message);
public:
void handleNewClientConnection(boost::shared_ptr<Swift::Connection> c);
void handleSessionFinished(Backend *c);
void handlePongReceived(Backend *c);
void handleDataRead(Backend *c, boost::shared_ptr<Swift::SafeByteArray> data);
void handleConnectedPayload(const std::string &payload);
void handleDisconnectedPayload(const std::string &payload);
void handleBuddyChangedPayload(const std::string &payload);
void handleBuddyRemovedPayload(const std::string &payload);
void handleConvMessagePayload(const std::string &payload, bool subject = false);
void handleConvMessageAckPayload(const std::string &payload);
void handleParticipantChangedPayload(const std::string &payload);
void handleRoomChangedPayload(const std::string &payload);
void handleVCardPayload(const std::string &payload);
void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type);
void handleAuthorizationPayload(const std::string &payload);
void handleAttentionPayload(const std::string &payload);
void handleStatsPayload(Backend *c, const std::string &payload);
void handleFTStartPayload(const std::string &payload);
void handleFTFinishPayload(const std::string &payload);
void handleFTDataPayload(Backend *b, const std::string &payload);
void handleQueryPayload(Backend *b, const std::string &payload);
void handleBackendConfigPayload(const std::string &payload);
void handleRoomListPayload(const std::string &payload);
void handleRawXML(const std::string &xml);
void handleUserCreated(User *user);
void handleRoomJoined(User *user, const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password);
void handleRoomLeft(User *user, const std::string &room);
void handleUserReadyToConnect(User *user);
void handleUserPresenceChanged(User *user, Swift::Presence::ref presence);
void handleUserDestroyed(User *user);
void handleBuddyUpdated(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleBuddyRemoved(Buddy *buddy);
void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleUserBuddyAdded(User *user, Buddy *buddy);
void handleUserBuddyRemoved(User *user, Buddy *buddy);
void handleBlockToggled(Buddy *buddy);
void handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> vcard);
void handleVCardRequired(User *user, const std::string &name, unsigned int id);
void handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id);
void handleFTAccepted(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID);
void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size);
void handleFTDataNeeded(Backend *b, unsigned long ftid);
void handlePIDTerminated(unsigned long pid);
private:
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
void pingTimeout();
void sendPing(Backend *c);
Backend *getFreeClient(bool acceptUsers = true, bool longRun = false, bool check = false);
void connectWaitingUsers();
void loginDelayFinished();
void handleRawIQReceived(boost::shared_ptr<Swift::IQ> iq);
void handleRawPresenceReceived(boost::shared_ptr<Swift::Presence> presence);
void handleStreamStart(const Swift::ProtocolHeader&) {}
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
#else
void handleElement(boost::shared_ptr<Swift::Element> element);
#endif
void handleStreamEnd() {}
UserManager *m_userManager;
VCardResponder *m_vcardResponder;
RosterResponder *m_rosterResponder;
BlockResponder *m_blockResponder;
Config *m_config;
boost::shared_ptr<Swift::ConnectionServer> m_server;
std::list<Backend *> m_clients;
std::vector<unsigned long> m_pids;
Swift::Timer::ref m_pingTimer;
Swift::Timer::ref m_collectTimer;
Swift::Timer::ref m_loginTimer;
Component *m_component;
std::list<User *> m_waitingUsers;
bool m_isNextLongRun;
std::map<unsigned long, FileTransferManager::Transfer> m_filetransfers;
FileTransferManager *m_ftManager;
std::vector<std::string> m_crashedBackends;
AdminInterface *m_adminInterface;
bool m_startingBackend;
DiscoItemsResponder *m_discoItemsResponder;
time_t m_lastLogin;
Swift::XMPPParser *m_xmppParser;
Swift::FullPayloadParserFactoryCollection m_collection;
Swift::XMPPSerializer *m_serializer;
Swift::FullPayloadSerializerCollection m_collection2;
std::map <std::string, std::string> m_id2resource;
};
}
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <time.h>
#include "Swiften/Presence/PresenceOracle.h"
#include "Swiften/Disco/EntityCapsManager.h"
#include "Swiften/Network/BoostConnectionServer.h"
#include "Swiften/Network/Connection.h"
#include "Swiften/Elements/ChatState.h"
#include "Swiften/Elements/RosterItemPayload.h"
#include "Swiften/Elements/VCard.h"
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
#include "Swiften/Parser/XMPPParser.h"
#include "Swiften/Parser/XMPPParserClient.h"
#include "Swiften/Serializer/XMPPSerializer.h"
#include "storagebackend.h"
#include "transport/filetransfermanager.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Transport {
class UserManager;
class User;
class Component;
class Buddy;
class LocalBuddy;
class Config;
class NetworkConversation;
class VCardResponder;
class RosterResponder;
class BlockResponder;
class DummyReadBytestream;
class AdminInterface;
class DiscoItemsResponder;
class NetworkPluginServer : Swift::XMPPParserClient {
public:
struct Backend {
int pongReceived;
std::list<User *> users;
Swift::SafeByteArray data;
boost::shared_ptr<Swift::Connection> connection;
unsigned long res;
unsigned long init_res;
unsigned long shared;
bool acceptUsers;
bool longRun;
bool willDie;
std::string id;
};
NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager, DiscoItemsResponder *discoItemsResponder);
virtual ~NetworkPluginServer();
void start();
void setAdminInterface(AdminInterface *adminInterface) {
m_adminInterface = adminInterface;
}
int getBackendCount() {
return m_clients.size();
}
const std::list<Backend *> &getBackends() {
return m_clients;
}
const std::vector<std::string> &getCrashedBackends() {
return m_crashedBackends;
}
void collectBackend();
bool moveToLongRunBackend(User *user);
void handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &message);
public:
void handleNewClientConnection(boost::shared_ptr<Swift::Connection> c);
void handleSessionFinished(Backend *c);
void handlePongReceived(Backend *c);
void handleDataRead(Backend *c, boost::shared_ptr<Swift::SafeByteArray> data);
void handleConnectedPayload(const std::string &payload);
void handleDisconnectedPayload(const std::string &payload);
void handleBuddyChangedPayload(const std::string &payload);
void handleBuddyRemovedPayload(const std::string &payload);
void handleConvMessagePayload(const std::string &payload, bool subject = false);
void handleConvMessageAckPayload(const std::string &payload);
void handleParticipantChangedPayload(const std::string &payload);
void handleRoomChangedPayload(const std::string &payload);
void handleVCardPayload(const std::string &payload);
void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type);
void handleAuthorizationPayload(const std::string &payload);
void handleAttentionPayload(const std::string &payload);
void handleStatsPayload(Backend *c, const std::string &payload);
void handleFTStartPayload(const std::string &payload);
void handleFTFinishPayload(const std::string &payload);
void handleFTDataPayload(Backend *b, const std::string &payload);
void handleQueryPayload(Backend *b, const std::string &payload);
void handleBackendConfigPayload(const std::string &payload);
void handleRoomListPayload(const std::string &payload);
void handleRawXML(const std::string &xml);
void handleUserCreated(User *user);
void handleRoomJoined(User *user, const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password);
void handleRoomLeft(User *user, const std::string &room);
void handleUserReadyToConnect(User *user);
void handleUserPresenceChanged(User *user, Swift::Presence::ref presence);
void handleUserDestroyed(User *user);
void handleBuddyUpdated(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleBuddyRemoved(Buddy *buddy);
void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleUserBuddyAdded(User *user, Buddy *buddy);
void handleUserBuddyRemoved(User *user, Buddy *buddy);
void handleBlockToggled(Buddy *buddy);
void handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> vcard);
void handleVCardRequired(User *user, const std::string &name, unsigned int id);
void handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id);
void handleFTAccepted(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID);
void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size);
void handleFTDataNeeded(Backend *b, unsigned long ftid);
void handlePIDTerminated(unsigned long pid);
private:
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
void pingTimeout();
void sendPing(Backend *c);
Backend *getFreeClient(bool acceptUsers = true, bool longRun = false, bool check = false);
void connectWaitingUsers();
void loginDelayFinished();
void handleRawIQReceived(boost::shared_ptr<Swift::IQ> iq);
void handleRawPresenceReceived(boost::shared_ptr<Swift::Presence> presence);
void handleStreamStart(const Swift::ProtocolHeader&) {}
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
#else
void handleElement(boost::shared_ptr<Swift::Element> element);
#endif
void handleStreamEnd() {}
UserManager *m_userManager;
VCardResponder *m_vcardResponder;
RosterResponder *m_rosterResponder;
BlockResponder *m_blockResponder;
Config *m_config;
boost::shared_ptr<Swift::ConnectionServer> m_server;
std::list<Backend *> m_clients;
std::vector<unsigned long> m_pids;
Swift::Timer::ref m_pingTimer;
Swift::Timer::ref m_collectTimer;
Swift::Timer::ref m_loginTimer;
Component *m_component;
std::list<User *> m_waitingUsers;
bool m_isNextLongRun;
std::map<unsigned long, FileTransferManager::Transfer> m_filetransfers;
FileTransferManager *m_ftManager;
std::vector<std::string> m_crashedBackends;
AdminInterface *m_adminInterface;
bool m_startingBackend;
DiscoItemsResponder *m_discoItemsResponder;
time_t m_lastLogin;
Swift::XMPPParser *m_xmppParser;
Swift::FullPayloadParserFactoryCollection m_collection;
Swift::XMPPSerializer *m_serializer;
Swift::FullPayloadSerializerCollection m_collection2;
std::map <std::string, std::string> m_id2resource;
};
}

View File

@ -1,77 +1,77 @@
/**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <string>
#include <algorithm>
#include <map>
#include "transport/adhoccommand.h"
#include "transport/adhoccommandfactory.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Transport {
class Component;
class UserManager;
class StorageBackend;
class SettingsAdHocCommand : public AdHocCommand {
public:
typedef enum { Init, WaitingForResponse } State;
SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to);
/// Destructor.
virtual ~SettingsAdHocCommand();
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload);
private:
boost::shared_ptr<Swift::Command> getForm();
boost::shared_ptr<Swift::Command> handleResponse(boost::shared_ptr<Swift::Command> payload);
State m_state;
};
class SettingsAdHocCommandFactory : public AdHocCommandFactory {
public:
SettingsAdHocCommandFactory() {
m_userSettings["send_headlines"] = "0";
m_userSettings["stay_connected"] = "0";
}
virtual ~SettingsAdHocCommandFactory() {}
AdHocCommand *createAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) {
return new SettingsAdHocCommand(component, userManager, storageBackend, initiator, to);
}
std::string getNode() {
return "settings";
}
std::string getName() {
return "Transport settings";
}
};
}
/**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <string>
#include <algorithm>
#include <map>
#include "transport/adhoccommand.h"
#include "transport/adhoccommandfactory.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Transport {
class Component;
class UserManager;
class StorageBackend;
class SettingsAdHocCommand : public AdHocCommand {
public:
typedef enum { Init, WaitingForResponse } State;
SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to);
/// Destructor.
virtual ~SettingsAdHocCommand();
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload);
private:
boost::shared_ptr<Swift::Command> getForm();
boost::shared_ptr<Swift::Command> handleResponse(boost::shared_ptr<Swift::Command> payload);
State m_state;
};
class SettingsAdHocCommandFactory : public AdHocCommandFactory {
public:
SettingsAdHocCommandFactory() {
m_userSettings["send_headlines"] = "0";
m_userSettings["stay_connected"] = "0";
}
virtual ~SettingsAdHocCommandFactory() {}
AdHocCommand *createAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) {
return new SettingsAdHocCommand(component, userManager, storageBackend, initiator, to);
}
std::string getNode() {
return "settings";
}
std::string getName() {
return "Transport settings";
}
};
}

View File

@ -1,87 +1,87 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/InBandRegistrationPayload.h"
#include "Swiften/Elements/RosterPayload.h"
#include <boost/signal.hpp>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Transport {
struct UserInfo;
class Component;
class StorageBackend;
class UserManager;
class Config;
/// Allows users to register the transport using service discovery.
class UserRegistration : public Swift::Responder<Swift::InBandRegistrationPayload> {
public:
/// Creates new UserRegistration handler.
/// \param component Component associated with this class
/// \param userManager UserManager associated with this class
/// \param storageBackend StorageBackend where the registered users will be stored
UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend);
/// Destroys UserRegistration.
~UserRegistration();
/// Registers new user. This function stores user into database and subscribe user to transport.
/// \param userInfo UserInfo struct with informations about registered user
/// \return false if user is already registered
bool registerUser(const UserInfo &userInfo);
/// Unregisters user. This function removes all data about user from databa, unsubscribe all buddies
/// managed by this transport and disconnects user if he's connected.
/// \param barejid bare JID of user to unregister
/// \return false if there is no such user registered
bool unregisterUser(const std::string &barejid);
/// Called when new user has been registered.
/// \param userInfo UserInfo struct with informations about user
boost::signal<void (const UserInfo &userInfo)> onUserRegistered;
/// Called when user has been unregistered.
/// \param userInfo UserInfo struct with informations about user
boost::signal<void (const UserInfo &userInfo)> onUserUnregistered;
/// Called when user's registration has been updated.
/// \param userInfo UserInfo struct with informations about user
boost::signal<void (const UserInfo &userInfo)> onUserUpdated;
private:
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
void handleRegisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const UserInfo &row);
void handleUnregisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const std::string &barejid);
Component *m_component;
StorageBackend *m_storageBackend;
UserManager *m_userManager;
Config *m_config;
};
}
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/InBandRegistrationPayload.h"
#include "Swiften/Elements/RosterPayload.h"
#include <boost/signal.hpp>
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
namespace Transport {
struct UserInfo;
class Component;
class StorageBackend;
class UserManager;
class Config;
/// Allows users to register the transport using service discovery.
class UserRegistration : public Swift::Responder<Swift::InBandRegistrationPayload> {
public:
/// Creates new UserRegistration handler.
/// \param component Component associated with this class
/// \param userManager UserManager associated with this class
/// \param storageBackend StorageBackend where the registered users will be stored
UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend);
/// Destroys UserRegistration.
~UserRegistration();
/// Registers new user. This function stores user into database and subscribe user to transport.
/// \param userInfo UserInfo struct with informations about registered user
/// \return false if user is already registered
bool registerUser(const UserInfo &userInfo);
/// Unregisters user. This function removes all data about user from databa, unsubscribe all buddies
/// managed by this transport and disconnects user if he's connected.
/// \param barejid bare JID of user to unregister
/// \return false if there is no such user registered
bool unregisterUser(const std::string &barejid);
/// Called when new user has been registered.
/// \param userInfo UserInfo struct with informations about user
boost::signal<void (const UserInfo &userInfo)> onUserRegistered;
/// Called when user has been unregistered.
/// \param userInfo UserInfo struct with informations about user
boost::signal<void (const UserInfo &userInfo)> onUserUnregistered;
/// Called when user's registration has been updated.
/// \param userInfo UserInfo struct with informations about user
boost::signal<void (const UserInfo &userInfo)> onUserUpdated;
private:
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
void handleRegisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const UserInfo &row);
void handleUnregisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const std::string &barejid);
Component *m_component;
StorageBackend *m_storageBackend;
UserManager *m_userManager;
Config *m_config;
};
}

View File

@ -1 +1 @@
ADD_SUBDIRECTORY(sqlite3)
ADD_SUBDIRECTORY(sqlite3)

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SQLITE_SRC *.c *.h)
ADD_LIBRARY(sqlite3 STATIC ${HEADERS} ${SQLITE_SRC})
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SQLITE_SRC *.c *.h)
ADD_LIBRARY(sqlite3 STATIC ${HEADERS} ${SQLITE_SRC})
INSTALL(TARGETS sqlite3 LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries)

View File

@ -1,38 +1,38 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp *.h)
FILE(GLOB HEADERS ../include/transport/*.h)
set(EXTRA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../src/memoryusage.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/logging.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/config.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/util.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
if (NOT WIN32)
ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ${EXTRA_SOURCES})
else()
ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${EXTRA_SOURCES} )
endif()
ADD_DEPENDENCIES(transport-plugin pb)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
if (CMAKE_COMPILER_IS_GNUCXX)
if (NOT WIN32)
ADD_DEFINITIONS(-fPIC)
endif()
endif()
if (NOT WIN32)
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES})
else()
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib)
endif()
SET_TARGET_PROPERTIES(transport-plugin PROPERTIES
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
)
INSTALL(TARGETS transport-plugin LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc")
#INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc" DESTINATION lib/pkgconfig)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp *.h)
FILE(GLOB HEADERS ../include/transport/*.h)
set(EXTRA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../src/memoryusage.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/logging.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/config.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/util.cpp)
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
if (NOT WIN32)
ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ${EXTRA_SOURCES})
else()
ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${EXTRA_SOURCES} )
endif()
ADD_DEPENDENCIES(transport-plugin pb)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
if (CMAKE_COMPILER_IS_GNUCXX)
if (NOT WIN32)
ADD_DEFINITIONS(-fPIC)
endif()
endif()
if (NOT WIN32)
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES})
else()
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib)
endif()
SET_TARGET_PROPERTIES(transport-plugin PROPERTIES
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
)
INSTALL(TARGETS transport-plugin LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc")
#INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc" DESTINATION lib/pkgconfig)

View File

@ -1,15 +1,15 @@
cmake_minimum_required(VERSION 2.6)
if (PROTOBUF_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
COMMENT "Running Python protocol buffer compiler on protocol.proto"
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
)
ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
endif()
cmake_minimum_required(VERSION 2.6)
if (PROTOBUF_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
COMMENT "Running Python protocol buffer compiler on protocol.proto"
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
)
ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
endif()

View File

@ -1,48 +1,48 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
if (WIN32)
FILE(GLOB WIN_SRC win32/*.cpp)
include_directories(win32)
include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/sqlite3")
ADD_EXECUTABLE(spectrum2 ${SRC} ${WIN_SRC})
else()
ADD_EXECUTABLE(spectrum2 ${SRC})
endif()
ADD_DEPENDENCIES(spectrum2 spectrum2_libpurple_backend)
ADD_DEPENDENCIES(spectrum2 spectrum2_libircclient-qt_backend)
if (WIN32)
target_link_libraries(spectrum2 transport sqlite3 ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
else ()
target_link_libraries(spectrum2 transport ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
endif()
INSTALL(TARGETS spectrum2 RUNTIME DESTINATION bin)
INSTALL(FILES
sample2_gateway.cfg
RENAME spectrum.cfg.example
DESTINATION /etc/spectrum2/transports
)
INSTALL(FILES
sample2.cfg
RENAME spectrum_server_mode.cfg.example
DESTINATION /etc/spectrum2/transports
)
INSTALL(FILES
backend-logging.cfg
DESTINATION /etc/spectrum2
)
INSTALL(FILES
logging.cfg
DESTINATION /etc/spectrum2
)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp)
if (WIN32)
FILE(GLOB WIN_SRC win32/*.cpp)
include_directories(win32)
include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/sqlite3")
ADD_EXECUTABLE(spectrum2 ${SRC} ${WIN_SRC})
else()
ADD_EXECUTABLE(spectrum2 ${SRC})
endif()
ADD_DEPENDENCIES(spectrum2 spectrum2_libpurple_backend)
ADD_DEPENDENCIES(spectrum2 spectrum2_libircclient-qt_backend)
if (WIN32)
target_link_libraries(spectrum2 transport sqlite3 ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
else ()
target_link_libraries(spectrum2 transport ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
endif()
INSTALL(TARGETS spectrum2 RUNTIME DESTINATION bin)
INSTALL(FILES
sample2_gateway.cfg
RENAME spectrum.cfg.example
DESTINATION /etc/spectrum2/transports
)
INSTALL(FILES
sample2.cfg
RENAME spectrum_server_mode.cfg.example
DESTINATION /etc/spectrum2/transports
)
INSTALL(FILES
backend-logging.cfg
DESTINATION /etc/spectrum2
)
INSTALL(FILES
logging.cfg
DESTINATION /etc/spectrum2
)

View File

@ -1,19 +1,19 @@
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp *.c)
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../src/config.cpp ../../src/util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
cmake_minimum_required(VERSION 2.6)
FILE(GLOB SRC *.cpp *.c)
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../src/config.cpp ../../src/util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
ADD_DEPENDENCIES(spectrum2_manager pb)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
if(APPLE)
target_link_libraries(spectrum2_manager ${APPLE_FRAMEWORKS})
endif()
INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin)
INSTALL(FILES
spectrum_manager.cfg
DESTINATION /etc/spectrum2
)
INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin)
INSTALL(FILES
spectrum_manager.cfg
DESTINATION /etc/spectrum2
)

View File

@ -1,200 +1,200 @@
#include "managerconfig.h"
#include "methods.h"
#include "server.h"
#include "transport/config.h"
#include "transport/protocol.pb.h"
#include "Swiften/Swiften.h"
#include "Swiften/EventLoop/SimpleEventLoop.h"
#include <boost/foreach.hpp>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <cstdlib>
#include "signal.h"
#include "sys/wait.h"
using namespace Transport;
using namespace boost::filesystem;
using namespace boost;
// static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactories &networkFactories, const std::string &message) {
// path p(CONFIG_STRING(config, "service.config_directory"));
//
// try {
// if (!exists(p)) {
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
// exit(6);
// }
//
// if (!is_directory(p)) {
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
// exit(7);
// }
//
// directory_iterator end_itr;
// for (directory_iterator itr(p); itr != end_itr; ++itr) {
// if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
// Config cfg;
// if (cfg.load(itr->path().string()) == false) {
// std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
// continue;
// }
//
// if (CONFIG_VECTOR(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
// std::cerr << itr->path().string() << ": service.admin_jid or service.admin_password empty. This server can't be queried over XMPP.\n";
// continue;
// }
//
// finished++;
// Swift::Client *client = new Swift::Client(CONFIG_VECTOR(&cfg, "service.admin_jid")[0], CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
// client->setAlwaysTrustCertificates();
// client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid")));
// client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid")));
// client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, CONFIG_STRING(&cfg, "service.jid")));
// Swift::ClientOptions opt;
// opt.allowPLAINWithoutTLS = true;
// client->connect(opt);
// }
// }
// }
// catch (const filesystem_error& ex) {
// std::cerr << "boost filesystem error\n";
// exit(5);
// }
// }
int main(int argc, char **argv)
{
ManagerConfig config;
std::string config_file;
std::vector<std::string> command;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <COMMAND>\n"
" spectrum [OPTIONS] <instance_JID> <other>\nCommands:\n"
" start - start all local Spectrum2 instances\n"
" stop - stop all local Spectrum2 instances\n"
" restart - restart all local Spectrum2 instances\n"
" status - status of local Spectrum2 instances\n"
" <other> - send command to local Spectrum2 instance and print output\n"
"Allowed options");
desc.add_options()
("help,h", "Show help output")
("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum_manager.cfg"), "Spectrum manager config file")
("command", boost::program_options::value<std::vector<std::string> >(&command), "Command")
;
try
{
boost::program_options::positional_options_description p;
p.add("command", -1);
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
options(desc).positional(p).run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
return 2;
}
catch (...)
{
std::cout << desc << "\n";
return 3;
}
if (!config.load(config_file)) {
std::cerr << "Can't load configuration file.\n";
return 4;
}
if (command.empty()) {
std::cout << desc << "\n";
return 1;
}
if (command[0] == "start") {
return start_instances(&config);
}
else if (command[0] == "stop") {
stop_instances(&config);
}
else if (command[0] == "status") {
return show_status(&config);
}
else if (command[0] == "list") {
std::vector<std::string> list = show_list(&config);
}
else if (command[0] == "restart") {
return restart_instances(&config);
}
else if (command[0] == "server") {
Server server(&config);
if (server.start() == false) {
std::cerr << "Can't set up server handler.\n";
return 1;
}
while (1) { sleep(10); }
}
else {
if (command.size() < 2) {
std::cout << desc << "\n";
return 11;
}
Swift::SimpleEventLoop eventLoop;
Swift::BoostNetworkFactories networkFactories(&eventLoop);
std::string jid = command[0];
command.erase(command.begin());
std::string cmd = boost::algorithm::join(command, " ");
if (cmd == "start") {
return start_instances(&config, jid);
}
else if (cmd == "stop") {
stop_instances(&config, jid);
return 0;
}
else if (cmd == "restart") {
return restart_instances(&config, jid);
}
ask_local_server(&config, networkFactories, jid, cmd);
// std::string message = command;
// m = &message;
// ask_local_server(&config, networkFactories, message);
eventLoop.runUntilEvents();
struct timeval td_start,td_end;
float elapsed = 0;
gettimeofday(&td_start, NULL);
time_t started = time(NULL);
while(get_response().empty()) {
eventLoop.runUntilEvents();
}
if (!get_response().empty()) {
gettimeofday(&td_end, NULL);
elapsed = 1000000.0 * (td_end.tv_sec -td_start.tv_sec); \
elapsed += (td_end.tv_usec - td_start.tv_usec); \
elapsed = elapsed / 1000 / 1000; \
// std::cout << "Response received after " << (elapsed) << " seconds\n";
}
}
}
#include "managerconfig.h"
#include "methods.h"
#include "server.h"
#include "transport/config.h"
#include "transport/protocol.pb.h"
#include "Swiften/Swiften.h"
#include "Swiften/EventLoop/SimpleEventLoop.h"
#include <boost/foreach.hpp>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <cstdlib>
#include "signal.h"
#include "sys/wait.h"
using namespace Transport;
using namespace boost::filesystem;
using namespace boost;
// static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactories &networkFactories, const std::string &message) {
// path p(CONFIG_STRING(config, "service.config_directory"));
//
// try {
// if (!exists(p)) {
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
// exit(6);
// }
//
// if (!is_directory(p)) {
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
// exit(7);
// }
//
// directory_iterator end_itr;
// for (directory_iterator itr(p); itr != end_itr; ++itr) {
// if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
// Config cfg;
// if (cfg.load(itr->path().string()) == false) {
// std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
// continue;
// }
//
// if (CONFIG_VECTOR(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
// std::cerr << itr->path().string() << ": service.admin_jid or service.admin_password empty. This server can't be queried over XMPP.\n";
// continue;
// }
//
// finished++;
// Swift::Client *client = new Swift::Client(CONFIG_VECTOR(&cfg, "service.admin_jid")[0], CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
// client->setAlwaysTrustCertificates();
// client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid")));
// client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid")));
// client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, CONFIG_STRING(&cfg, "service.jid")));
// Swift::ClientOptions opt;
// opt.allowPLAINWithoutTLS = true;
// client->connect(opt);
// }
// }
// }
// catch (const filesystem_error& ex) {
// std::cerr << "boost filesystem error\n";
// exit(5);
// }
// }
int main(int argc, char **argv)
{
ManagerConfig config;
std::string config_file;
std::vector<std::string> command;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <COMMAND>\n"
" spectrum [OPTIONS] <instance_JID> <other>\nCommands:\n"
" start - start all local Spectrum2 instances\n"
" stop - stop all local Spectrum2 instances\n"
" restart - restart all local Spectrum2 instances\n"
" status - status of local Spectrum2 instances\n"
" <other> - send command to local Spectrum2 instance and print output\n"
"Allowed options");
desc.add_options()
("help,h", "Show help output")
("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum_manager.cfg"), "Spectrum manager config file")
("command", boost::program_options::value<std::vector<std::string> >(&command), "Command")
;
try
{
boost::program_options::positional_options_description p;
p.add("command", -1);
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
options(desc).positional(p).run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
return 2;
}
catch (...)
{
std::cout << desc << "\n";
return 3;
}
if (!config.load(config_file)) {
std::cerr << "Can't load configuration file.\n";
return 4;
}
if (command.empty()) {
std::cout << desc << "\n";
return 1;
}
if (command[0] == "start") {
return start_instances(&config);
}
else if (command[0] == "stop") {
stop_instances(&config);
}
else if (command[0] == "status") {
return show_status(&config);
}
else if (command[0] == "list") {
std::vector<std::string> list = show_list(&config);
}
else if (command[0] == "restart") {
return restart_instances(&config);
}
else if (command[0] == "server") {
Server server(&config);
if (server.start() == false) {
std::cerr << "Can't set up server handler.\n";
return 1;
}
while (1) { sleep(10); }
}
else {
if (command.size() < 2) {
std::cout << desc << "\n";
return 11;
}
Swift::SimpleEventLoop eventLoop;
Swift::BoostNetworkFactories networkFactories(&eventLoop);
std::string jid = command[0];
command.erase(command.begin());
std::string cmd = boost::algorithm::join(command, " ");
if (cmd == "start") {
return start_instances(&config, jid);
}
else if (cmd == "stop") {
stop_instances(&config, jid);
return 0;
}
else if (cmd == "restart") {
return restart_instances(&config, jid);
}
ask_local_server(&config, networkFactories, jid, cmd);
// std::string message = command;
// m = &message;
// ask_local_server(&config, networkFactories, message);
eventLoop.runUntilEvents();
struct timeval td_start,td_end;
float elapsed = 0;
gettimeofday(&td_start, NULL);
time_t started = time(NULL);
while(get_response().empty()) {
eventLoop.runUntilEvents();
}
if (!get_response().empty()) {
gettimeofday(&td_end, NULL);
elapsed = 1000000.0 * (td_end.tv_sec -td_start.tv_sec); \
elapsed += (td_end.tv_usec - td_start.tv_usec); \
elapsed = elapsed / 1000 / 1000; \
// std::cout << "Response received after " << (elapsed) << " seconds\n";
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,301 +1,301 @@
// Copyright (c) 2004-2012 Sergey Lyubka
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef MONGOOSE_HEADER_INCLUDED
#define MONGOOSE_HEADER_INCLUDED
#include <stdio.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
struct mg_context; // Handle for the HTTP service itself
struct mg_connection; // Handle for the individual connection
// This structure contains information about the HTTP request.
struct mg_request_info {
void *user_data; // User-defined pointer passed to mg_start()
char *request_method; // "GET", "POST", etc
char *uri; // URL-decoded URI
char *http_version; // E.g. "1.0", "1.1"
char *query_string; // URL part after '?' (not including '?') or NULL
char *remote_user; // Authenticated user, or NULL if no auth used
char *log_message; // Mongoose error log message, MG_EVENT_LOG only
long remote_ip; // Client's IP address
int remote_port; // Client's port
int status_code; // HTTP reply status code, e.g. 200
int is_ssl; // 1 if SSL-ed, 0 if not
int num_headers; // Number of headers
struct mg_header {
char *name; // HTTP header name
char *value; // HTTP header value
} http_headers[64]; // Maximum 64 headers
};
// Various events on which user-defined function is called by Mongoose.
enum mg_event {
MG_NEW_REQUEST, // New HTTP request has arrived from the client
MG_REQUEST_COMPLETE, // Mongoose has finished handling the request
MG_HTTP_ERROR, // HTTP error must be returned to the client
MG_EVENT_LOG, // Mongoose logs an event, request_info.log_message
MG_INIT_SSL // Mongoose initializes SSL. Instead of mg_connection *,
// SSL context is passed to the callback function.
};
// Prototype for the user-defined function. Mongoose calls this function
// on every MG_* event.
//
// Parameters:
// event: which event has been triggered.
// conn: opaque connection handler. Could be used to read, write data to the
// client, etc. See functions below that have "mg_connection *" arg.
//
// Return:
// If handler returns non-NULL, that means that handler has processed the
// request by sending appropriate HTTP reply to the client. Mongoose treats
// the request as served.
// If handler returns NULL, that means that handler has not processed
// the request. Handler must not send any data to the client in this case.
// Mongoose proceeds with request handling as if nothing happened.
typedef void * (*mg_callback_t)(enum mg_event event,
struct mg_connection *conn);
// Start web server.
//
// Parameters:
// callback: user defined event handling function or NULL.
// options: NULL terminated list of option_name, option_value pairs that
// specify Mongoose configuration parameters.
//
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
// processing is required for these, signal handlers must be set up
// after calling mg_start().
//
//
// Example:
// const char *options[] = {
// "document_root", "/var/www",
// "listening_ports", "80,443s",
// NULL
// };
// struct mg_context *ctx = mg_start(&my_func, NULL, options);
//
// Please refer to http://code.google.com/p/mongoose/wiki/MongooseManual
// for the list of valid option and their possible values.
//
// Return:
// web server context, or NULL on error.
struct mg_context *mg_start(mg_callback_t callback, void *user_data,
const char **options);
// Stop the web server.
//
// Must be called last, when an application wants to stop the web server and
// release all associated resources. This function blocks until all Mongoose
// threads are stopped. Context pointer becomes invalid.
void mg_stop(struct mg_context *);
// Get the value of particular configuration parameter.
// The value returned is read-only. Mongoose does not allow changing
// configuration at run time.
// If given parameter name is not valid, NULL is returned. For valid
// names, return value is guaranteed to be non-NULL. If parameter is not
// set, zero-length string is returned.
const char *mg_get_option(const struct mg_context *ctx, const char *name);
// Return array of strings that represent valid configuration options.
// For each option, a short name, long name, and default value is returned.
// Array is NULL terminated.
const char **mg_get_valid_option_names(void);
// Add, edit or delete the entry in the passwords file.
//
// This function allows an application to manipulate .htpasswd files on the
// fly by adding, deleting and changing user records. This is one of the
// several ways of implementing authentication on the server side. For another,
// cookie-based way please refer to the examples/chat.c in the source tree.
//
// If password is not NULL, entry is added (or modified if already exists).
// If password is NULL, entry is deleted.
//
// Return:
// 1 on success, 0 on error.
int mg_modify_passwords_file(const char *passwords_file_name,
const char *domain,
const char *user,
const char *password);
// Return mg_request_info structure associated with the request.
// Always succeeds.
const struct mg_request_info *mg_get_request_info(const struct mg_connection *);
// Send data to the client.
// Return:
// 0 when the connection has been closed
// -1 on error
// number of bytes written on success
int mg_write(struct mg_connection *, const void *buf, size_t len);
// Send data to the browser using printf() semantics.
//
// Works exactly like mg_write(), but allows to do message formatting.
// Below are the macros for enabling compiler-specific checks for
// printf-like arguments.
#undef PRINTF_FORMAT_STRING
#if _MSC_VER >= 1400
#include <sal.h>
#if _MSC_VER > 1400
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
#else
#define PRINTF_FORMAT_STRING(s) __format_string s
#endif
#else
#define PRINTF_FORMAT_STRING(s) s
#endif
#ifdef __GNUC__
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
#else
#define PRINTF_ARGS(x, y)
#endif
int mg_printf(struct mg_connection *,
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
// Send contents of the entire file together with HTTP headers.
void mg_send_file(struct mg_connection *conn, const char *path);
// Read data from the remote end, return number of bytes read.
int mg_read(struct mg_connection *, void *buf, size_t len);
// Get the value of particular HTTP header.
//
// This is a helper function. It traverses request_info->http_headers array,
// and if the header is present in the array, returns its value. If it is
// not present, NULL is returned.
const char *mg_get_header(const struct mg_connection *, const char *name);
// Get a value of particular form variable.
//
// Parameters:
// data: pointer to form-uri-encoded buffer. This could be either POST data,
// or request_info.query_string.
// data_len: length of the encoded data.
// var_name: variable name to decode from the buffer
// buf: destination buffer for the decoded variable
// buf_len: length of the destination buffer
//
// Return:
// On success, length of the decoded variable.
// On error:
// -1 (variable not found, or destination buffer is too small).
// -2 (destination buffer is NULL or zero length).
//
// Destination buffer is guaranteed to be '\0' - terminated if it is not
// NULL or zero length. In case of failure, dst[0] == '\0'.
int mg_get_var(const char *data, size_t data_len,
const char *var_name, char *buf, size_t buf_len);
// Fetch value of certain cookie variable into the destination buffer.
//
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
// parameter. This function returns only first occurrence.
//
// Return:
// On success, value length.
// On error, -1 (either "Cookie:" header is not present at all, or the
// requested parameter is not found, or destination buffer is too small
// to hold the value).
int mg_get_cookie(const struct mg_connection *,
const char *cookie_name, char *buf, size_t buf_len);
// Connect to the remote web server.
// Return:
// On success, valid pointer to the new connection
// On error, NULL
struct mg_connection *mg_connect(struct mg_context *ctx,
const char *host, int port, int use_ssl);
// Close the connection opened by mg_connect().
void mg_close_connection(struct mg_connection *conn);
// Download given URL to a given file.
// url: URL to download
// path: file name where to save the data
// request_info: pointer to a structure that will hold parsed reply headers
// buf, bul_len: a buffer for the reply headers
// Return:
// On error, NULL
// On success, opened file stream to the downloaded contents. The stream
// is positioned to the end of the file. It is the user's responsibility
// to fclose() the opened file stream.
FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
char *buf, size_t buf_len, struct mg_request_info *request_info);
// Convenience function -- create detached thread.
// Return: 0 on success, non-0 on error.
typedef void * (*mg_thread_func_t)(void *);
int mg_start_thread(mg_thread_func_t f, void *p);
// Return builtin mime type for the given file name.
// For unrecognized extensions, "text/plain" is returned.
const char *mg_get_builtin_mime_type(const char *file_name);
// Return Mongoose version.
const char *mg_version(void);
// MD5 hash given strings.
// Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
// ASCIIz strings. When function returns, buf will contain human-readable
// MD5 hash. Example:
// char buf[33];
// mg_md5(buf, "aa", "bb", NULL);
void mg_md5(char buf[33], ...);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // MONGOOSE_HEADER_INCLUDED
// Copyright (c) 2004-2012 Sergey Lyubka
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef MONGOOSE_HEADER_INCLUDED
#define MONGOOSE_HEADER_INCLUDED
#include <stdio.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
struct mg_context; // Handle for the HTTP service itself
struct mg_connection; // Handle for the individual connection
// This structure contains information about the HTTP request.
struct mg_request_info {
void *user_data; // User-defined pointer passed to mg_start()
char *request_method; // "GET", "POST", etc
char *uri; // URL-decoded URI
char *http_version; // E.g. "1.0", "1.1"
char *query_string; // URL part after '?' (not including '?') or NULL
char *remote_user; // Authenticated user, or NULL if no auth used
char *log_message; // Mongoose error log message, MG_EVENT_LOG only
long remote_ip; // Client's IP address
int remote_port; // Client's port
int status_code; // HTTP reply status code, e.g. 200
int is_ssl; // 1 if SSL-ed, 0 if not
int num_headers; // Number of headers
struct mg_header {
char *name; // HTTP header name
char *value; // HTTP header value
} http_headers[64]; // Maximum 64 headers
};
// Various events on which user-defined function is called by Mongoose.
enum mg_event {
MG_NEW_REQUEST, // New HTTP request has arrived from the client
MG_REQUEST_COMPLETE, // Mongoose has finished handling the request
MG_HTTP_ERROR, // HTTP error must be returned to the client
MG_EVENT_LOG, // Mongoose logs an event, request_info.log_message
MG_INIT_SSL // Mongoose initializes SSL. Instead of mg_connection *,
// SSL context is passed to the callback function.
};
// Prototype for the user-defined function. Mongoose calls this function
// on every MG_* event.
//
// Parameters:
// event: which event has been triggered.
// conn: opaque connection handler. Could be used to read, write data to the
// client, etc. See functions below that have "mg_connection *" arg.
//
// Return:
// If handler returns non-NULL, that means that handler has processed the
// request by sending appropriate HTTP reply to the client. Mongoose treats
// the request as served.
// If handler returns NULL, that means that handler has not processed
// the request. Handler must not send any data to the client in this case.
// Mongoose proceeds with request handling as if nothing happened.
typedef void * (*mg_callback_t)(enum mg_event event,
struct mg_connection *conn);
// Start web server.
//
// Parameters:
// callback: user defined event handling function or NULL.
// options: NULL terminated list of option_name, option_value pairs that
// specify Mongoose configuration parameters.
//
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
// processing is required for these, signal handlers must be set up
// after calling mg_start().
//
//
// Example:
// const char *options[] = {
// "document_root", "/var/www",
// "listening_ports", "80,443s",
// NULL
// };
// struct mg_context *ctx = mg_start(&my_func, NULL, options);
//
// Please refer to http://code.google.com/p/mongoose/wiki/MongooseManual
// for the list of valid option and their possible values.
//
// Return:
// web server context, or NULL on error.
struct mg_context *mg_start(mg_callback_t callback, void *user_data,
const char **options);
// Stop the web server.
//
// Must be called last, when an application wants to stop the web server and
// release all associated resources. This function blocks until all Mongoose
// threads are stopped. Context pointer becomes invalid.
void mg_stop(struct mg_context *);
// Get the value of particular configuration parameter.
// The value returned is read-only. Mongoose does not allow changing
// configuration at run time.
// If given parameter name is not valid, NULL is returned. For valid
// names, return value is guaranteed to be non-NULL. If parameter is not
// set, zero-length string is returned.
const char *mg_get_option(const struct mg_context *ctx, const char *name);
// Return array of strings that represent valid configuration options.
// For each option, a short name, long name, and default value is returned.
// Array is NULL terminated.
const char **mg_get_valid_option_names(void);
// Add, edit or delete the entry in the passwords file.
//
// This function allows an application to manipulate .htpasswd files on the
// fly by adding, deleting and changing user records. This is one of the
// several ways of implementing authentication on the server side. For another,
// cookie-based way please refer to the examples/chat.c in the source tree.
//
// If password is not NULL, entry is added (or modified if already exists).
// If password is NULL, entry is deleted.
//
// Return:
// 1 on success, 0 on error.
int mg_modify_passwords_file(const char *passwords_file_name,
const char *domain,
const char *user,
const char *password);
// Return mg_request_info structure associated with the request.
// Always succeeds.
const struct mg_request_info *mg_get_request_info(const struct mg_connection *);
// Send data to the client.
// Return:
// 0 when the connection has been closed
// -1 on error
// number of bytes written on success
int mg_write(struct mg_connection *, const void *buf, size_t len);
// Send data to the browser using printf() semantics.
//
// Works exactly like mg_write(), but allows to do message formatting.
// Below are the macros for enabling compiler-specific checks for
// printf-like arguments.
#undef PRINTF_FORMAT_STRING
#if _MSC_VER >= 1400
#include <sal.h>
#if _MSC_VER > 1400
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
#else
#define PRINTF_FORMAT_STRING(s) __format_string s
#endif
#else
#define PRINTF_FORMAT_STRING(s) s
#endif
#ifdef __GNUC__
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
#else
#define PRINTF_ARGS(x, y)
#endif
int mg_printf(struct mg_connection *,
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
// Send contents of the entire file together with HTTP headers.
void mg_send_file(struct mg_connection *conn, const char *path);
// Read data from the remote end, return number of bytes read.
int mg_read(struct mg_connection *, void *buf, size_t len);
// Get the value of particular HTTP header.
//
// This is a helper function. It traverses request_info->http_headers array,
// and if the header is present in the array, returns its value. If it is
// not present, NULL is returned.
const char *mg_get_header(const struct mg_connection *, const char *name);
// Get a value of particular form variable.
//
// Parameters:
// data: pointer to form-uri-encoded buffer. This could be either POST data,
// or request_info.query_string.
// data_len: length of the encoded data.
// var_name: variable name to decode from the buffer
// buf: destination buffer for the decoded variable
// buf_len: length of the destination buffer
//
// Return:
// On success, length of the decoded variable.
// On error:
// -1 (variable not found, or destination buffer is too small).
// -2 (destination buffer is NULL or zero length).
//
// Destination buffer is guaranteed to be '\0' - terminated if it is not
// NULL or zero length. In case of failure, dst[0] == '\0'.
int mg_get_var(const char *data, size_t data_len,
const char *var_name, char *buf, size_t buf_len);
// Fetch value of certain cookie variable into the destination buffer.
//
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
// parameter. This function returns only first occurrence.
//
// Return:
// On success, value length.
// On error, -1 (either "Cookie:" header is not present at all, or the
// requested parameter is not found, or destination buffer is too small
// to hold the value).
int mg_get_cookie(const struct mg_connection *,
const char *cookie_name, char *buf, size_t buf_len);
// Connect to the remote web server.
// Return:
// On success, valid pointer to the new connection
// On error, NULL
struct mg_connection *mg_connect(struct mg_context *ctx,
const char *host, int port, int use_ssl);
// Close the connection opened by mg_connect().
void mg_close_connection(struct mg_connection *conn);
// Download given URL to a given file.
// url: URL to download
// path: file name where to save the data
// request_info: pointer to a structure that will hold parsed reply headers
// buf, bul_len: a buffer for the reply headers
// Return:
// On error, NULL
// On success, opened file stream to the downloaded contents. The stream
// is positioned to the end of the file. It is the user's responsibility
// to fclose() the opened file stream.
FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
char *buf, size_t buf_len, struct mg_request_info *request_info);
// Convenience function -- create detached thread.
// Return: 0 on success, non-0 on error.
typedef void * (*mg_thread_func_t)(void *);
int mg_start_thread(mg_thread_func_t f, void *p);
// Return builtin mime type for the given file name.
// For unrecognized extensions, "text/plain" is returned.
const char *mg_get_builtin_mime_type(const char *file_name);
// Return Mongoose version.
const char *mg_version(void);
// MD5 hash given strings.
// Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
// ASCIIz strings. When function returns, buf will contain human-readable
// MD5 hash. Example:
// char buf[33];
// mg_md5(buf, "aa", "bb", NULL);
void mg_md5(char buf[33], ...);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // MONGOOSE_HEADER_INCLUDED

View File

@ -1,167 +1,167 @@
/**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "discoinforesponder.h"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/algorithm/string.hpp>
#include "Swiften/Disco/DiscoInfoResponder.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "transport/config.h"
#include "transport/logging.h"
#include "Swiften/Disco/CapsInfoGenerator.h"
using namespace Swift;
using namespace boost;
DEFINE_LOGGER(logger, "DiscoInfoResponder");
namespace Transport {
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router, Config *config) : Swift::GetResponder<DiscoInfo>(router) {
m_config = config;
m_config->onBackendConfigUpdated.connect(boost::bind(&DiscoInfoResponder::updateFeatures, this));
m_buddyInfo = NULL;
m_transportInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"),
CONFIG_STRING(m_config, "identity.category"),
CONFIG_STRING(m_config, "identity.type")));
#if HAVE_SWIFTEN_3
crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
#endif
updateFeatures();
}
DiscoInfoResponder::~DiscoInfoResponder() {
delete m_buddyInfo;
}
void DiscoInfoResponder::updateFeatures() {
std::list<std::string> features2;
features2.push_back("jabber:iq:register");
features2.push_back("jabber:iq:gateway");
features2.push_back("jabber:iq:private");
features2.push_back("http://jabber.org/protocol/disco#info");
features2.push_back("http://jabber.org/protocol/commands");
if (CONFIG_BOOL_DEFAULTED(m_config, "features.muc", false)) {
features2.push_back("http://jabber.org/protocol/muc");
}
setTransportFeatures(features2);
std::list<std::string> features;
features.push_back("http://jabber.org/protocol/disco#items");
features.push_back("http://jabber.org/protocol/disco#info");
features.push_back("http://jabber.org/protocol/chatstates");
features.push_back("http://jabber.org/protocol/xhtml-im");
if (CONFIG_BOOL_DEFAULTED(m_config, "features.receipts", false)) {
features.push_back("urn:xmpp:receipts");
}
setBuddyFeatures(features);
}
void DiscoInfoResponder::setTransportFeatures(std::list<std::string> &features) {
for (std::list<std::string>::iterator it = features.begin(); it != features.end(); it++) {
if (!m_transportInfo.hasFeature(*it)) {
m_transportInfo.addFeature(*it);
}
}
}
void DiscoInfoResponder::setBuddyFeatures(std::list<std::string> &f) {
delete m_buddyInfo;
m_buddyInfo = new Swift::DiscoInfo;
m_buddyInfo->addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"), "client", "pc"));
for (std::list<std::string>::iterator it = f.begin(); it != f.end(); it++) {
if (!m_buddyInfo->hasFeature(*it)) {
m_buddyInfo->addFeature(*it);
}
}
#if HAVE_SWIFTEN_3
CapsInfoGenerator caps("spectrum", crypto.get());
#else
CapsInfoGenerator caps("spectrum");
#endif
m_capsInfo = caps.generateCapsInfo(*m_buddyInfo);
onBuddyCapsInfoChanged(m_capsInfo);
}
void DiscoInfoResponder::addRoom(const std::string &jid, const std::string &name) {
std::string j = jid;
boost::algorithm::to_lower(j);
m_rooms[j] = name;
}
void DiscoInfoResponder::clearRooms() {
m_rooms.clear();
}
void DiscoInfoResponder::addAdHocCommand(const std::string &node, const std::string &name) {
m_commands[node] = node;
}
bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> info) {
// disco#info for transport
if (to.getNode().empty()) {
// Adhoc command
if (m_commands.find(info->getNode()) != m_commands.end()) {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
res->addFeature("http://jabber.org/protocol/commands");
res->addFeature("jabber:x:data");
res->addIdentity(DiscoInfo::Identity(m_commands[info->getNode()], "automation", "command-node"));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
else if (info->getNode() == "http://jabber.org/protocol/commands") {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
res->addIdentity(DiscoInfo::Identity("Commands", "automation", "command-list"));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
else {
if (!info->getNode().empty()) {
sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel);
return true;
}
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo));
res->setNode(info->getNode());
sendResponse(from, id, res);
}
}
// disco#info for room
else if (m_rooms.find(to.toBare().toString()) != m_rooms.end()) {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
res->addIdentity(DiscoInfo::Identity(m_rooms[to.toBare().toString()], "conference", "text"));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
// disco#info for buddy
else {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(*m_buddyInfo));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
return true;
}
}
/**
* XMPP - libpurple transport
*
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "discoinforesponder.h"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/algorithm/string.hpp>
#include "Swiften/Disco/DiscoInfoResponder.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "transport/config.h"
#include "transport/logging.h"
#include "Swiften/Disco/CapsInfoGenerator.h"
using namespace Swift;
using namespace boost;
DEFINE_LOGGER(logger, "DiscoInfoResponder");
namespace Transport {
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router, Config *config) : Swift::GetResponder<DiscoInfo>(router) {
m_config = config;
m_config->onBackendConfigUpdated.connect(boost::bind(&DiscoInfoResponder::updateFeatures, this));
m_buddyInfo = NULL;
m_transportInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"),
CONFIG_STRING(m_config, "identity.category"),
CONFIG_STRING(m_config, "identity.type")));
#if HAVE_SWIFTEN_3
crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
#endif
updateFeatures();
}
DiscoInfoResponder::~DiscoInfoResponder() {
delete m_buddyInfo;
}
void DiscoInfoResponder::updateFeatures() {
std::list<std::string> features2;
features2.push_back("jabber:iq:register");
features2.push_back("jabber:iq:gateway");
features2.push_back("jabber:iq:private");
features2.push_back("http://jabber.org/protocol/disco#info");
features2.push_back("http://jabber.org/protocol/commands");
if (CONFIG_BOOL_DEFAULTED(m_config, "features.muc", false)) {
features2.push_back("http://jabber.org/protocol/muc");
}
setTransportFeatures(features2);
std::list<std::string> features;
features.push_back("http://jabber.org/protocol/disco#items");
features.push_back("http://jabber.org/protocol/disco#info");
features.push_back("http://jabber.org/protocol/chatstates");
features.push_back("http://jabber.org/protocol/xhtml-im");
if (CONFIG_BOOL_DEFAULTED(m_config, "features.receipts", false)) {
features.push_back("urn:xmpp:receipts");
}
setBuddyFeatures(features);
}
void DiscoInfoResponder::setTransportFeatures(std::list<std::string> &features) {
for (std::list<std::string>::iterator it = features.begin(); it != features.end(); it++) {
if (!m_transportInfo.hasFeature(*it)) {
m_transportInfo.addFeature(*it);
}
}
}
void DiscoInfoResponder::setBuddyFeatures(std::list<std::string> &f) {
delete m_buddyInfo;
m_buddyInfo = new Swift::DiscoInfo;
m_buddyInfo->addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"), "client", "pc"));
for (std::list<std::string>::iterator it = f.begin(); it != f.end(); it++) {
if (!m_buddyInfo->hasFeature(*it)) {
m_buddyInfo->addFeature(*it);
}
}
#if HAVE_SWIFTEN_3
CapsInfoGenerator caps("spectrum", crypto.get());
#else
CapsInfoGenerator caps("spectrum");
#endif
m_capsInfo = caps.generateCapsInfo(*m_buddyInfo);
onBuddyCapsInfoChanged(m_capsInfo);
}
void DiscoInfoResponder::addRoom(const std::string &jid, const std::string &name) {
std::string j = jid;
boost::algorithm::to_lower(j);
m_rooms[j] = name;
}
void DiscoInfoResponder::clearRooms() {
m_rooms.clear();
}
void DiscoInfoResponder::addAdHocCommand(const std::string &node, const std::string &name) {
m_commands[node] = node;
}
bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> info) {
// disco#info for transport
if (to.getNode().empty()) {
// Adhoc command
if (m_commands.find(info->getNode()) != m_commands.end()) {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
res->addFeature("http://jabber.org/protocol/commands");
res->addFeature("jabber:x:data");
res->addIdentity(DiscoInfo::Identity(m_commands[info->getNode()], "automation", "command-node"));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
else if (info->getNode() == "http://jabber.org/protocol/commands") {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
res->addIdentity(DiscoInfo::Identity("Commands", "automation", "command-list"));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
else {
if (!info->getNode().empty()) {
sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel);
return true;
}
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo));
res->setNode(info->getNode());
sendResponse(from, id, res);
}
}
// disco#info for room
else if (m_rooms.find(to.toBare().toString()) != m_rooms.end()) {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
res->addIdentity(DiscoInfo::Identity(m_rooms[to.toBare().toString()], "conference", "text"));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
// disco#info for buddy
else {
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(*m_buddyInfo));
res->setNode(info->getNode());
sendResponse(from, to, id, res);
}
return true;
}
}

View File

@ -1,75 +1,75 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <vector>
#include <list>
#include <boost/signal.hpp>
#include "Swiften/Queries/GetResponder.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Elements/CapsInfo.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#if HAVE_SWIFTEN_3
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#endif
namespace Transport {
class Config;
class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
public:
DiscoInfoResponder(Swift::IQRouter *router, Config *config);
~DiscoInfoResponder();
void setTransportFeatures(std::list<std::string> &features);
void setBuddyFeatures(std::list<std::string> &features);
void addRoom(const std::string &jid, const std::string &name);
void clearRooms();
void addAdHocCommand(const std::string &node, const std::string &name);
boost::signal<void (const Swift::CapsInfo &capsInfo)> onBuddyCapsInfoChanged;
Swift::CapsInfo &getBuddyCapsInfo() {
return m_capsInfo;
}
private:
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> payload);
void updateFeatures();
Swift::DiscoInfo m_transportInfo;
Swift::DiscoInfo *m_buddyInfo;
Config *m_config;
Swift::CapsInfo m_capsInfo;
std::map<std::string, std::string> m_rooms;
std::map<std::string, std::string> m_commands;
#if HAVE_SWIFTEN_3
boost::shared_ptr<Swift::CryptoProvider> crypto;
#endif
};
}
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#pragma once
#include <vector>
#include <list>
#include <boost/signal.hpp>
#include "Swiften/Queries/GetResponder.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Elements/CapsInfo.h"
#include <Swiften/Version.h>
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
#if HAVE_SWIFTEN_3
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#endif
namespace Transport {
class Config;
class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
public:
DiscoInfoResponder(Swift::IQRouter *router, Config *config);
~DiscoInfoResponder();
void setTransportFeatures(std::list<std::string> &features);
void setBuddyFeatures(std::list<std::string> &features);
void addRoom(const std::string &jid, const std::string &name);
void clearRooms();
void addAdHocCommand(const std::string &node, const std::string &name);
boost::signal<void (const Swift::CapsInfo &capsInfo)> onBuddyCapsInfoChanged;
Swift::CapsInfo &getBuddyCapsInfo() {
return m_capsInfo;
}
private:
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> payload);
void updateFeatures();
Swift::DiscoInfo m_transportInfo;
Swift::DiscoInfo *m_buddyInfo;
Config *m_config;
Swift::CapsInfo m_capsInfo;
std::map<std::string, std::string> m_rooms;
std::map<std::string, std::string> m_commands;
#if HAVE_SWIFTEN_3
boost::shared_ptr<Swift::CryptoProvider> crypto;
#endif
};
}

View File

@ -1,102 +1,102 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "transport/filetransfermanager.h"
#include "transport/transport.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/buddy.h"
#include "transport/logging.h"
#include "Swiften/Network/ConnectionServerFactory.h"
namespace Transport {
DEFINE_LOGGER(logger, "FileTransferManager");
FileTransferManager::FileTransferManager(Component *component, UserManager *userManager) {
m_component = component;
m_userManager = userManager;
m_jingleSessionManager = new Swift::JingleSessionManager(m_component->getIQRouter());
#if !HAVE_SWIFTEN_3
m_connectivityManager = new Swift::ConnectivityManager(m_component->getNetworkFactories()->getNATTraverser());
#endif
m_bytestreamRegistry = new Swift::SOCKS5BytestreamRegistry();
#if !HAVE_SWIFTEN_3
m_bytestreamProxy = new Swift::SOCKS5BytestreamProxy(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
m_localCandidateGeneratorFactory = new Swift::DefaultLocalJingleTransportCandidateGeneratorFactory(m_connectivityManager, m_bytestreamRegistry, m_bytestreamProxy, "thishouldnotbeused");
m_remoteCandidateSelectorFactory = new Swift::DefaultRemoteJingleTransportCandidateSelectorFactory(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
#else
m_proxyManager = new Swift::SOCKS5BytestreamProxiesManager(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory(), m_component->getNetworkFactories()->getDomainNameResolver(), m_component->getIQRouter(), "bar.com");
#endif
boost::shared_ptr<Swift::ConnectionServer> server = m_component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(19645);
server->start();
#if HAVE_SWIFTEN_3
m_proxyServerManager = new Swift::SOCKS5BytestreamServerManager(m_bytestreamRegistry, m_component->getNetworkFactories()->getConnectionServerFactory(), m_component->getNetworkFactories()->getNetworkEnvironment(), m_component->getNetworkFactories()->getNATTraverser());
#else
m_bytestreamServer = new Swift::SOCKS5BytestreamServer(server, m_bytestreamRegistry);
m_bytestreamServer->start();
m_outgoingFTManager = new Swift::CombinedOutgoingFileTransferManager(m_jingleSessionManager, m_component->getIQRouter(),
m_userManager, m_remoteCandidateSelectorFactory,
m_localCandidateGeneratorFactory, m_bytestreamRegistry,
m_bytestreamProxy, m_component->getPresenceOracle(),
m_bytestreamServer);
#endif
// WARNING: Swiften crashes when this is uncommented... But we probably need it for working Jingle FT
// m_connectivityManager->addListeningPort(19645);
}
FileTransferManager::~FileTransferManager() {
#if !HAVE_SWIFTEN_3
m_bytestreamServer->stop();
delete m_remoteCandidateSelectorFactory;
delete m_localCandidateGeneratorFactory;
#endif
delete m_outgoingFTManager;
delete m_jingleSessionManager;
delete m_bytestreamRegistry;
#if !HAVE_SWIFTEN_3
delete m_bytestreamServer;
delete m_bytestreamProxy;
delete m_connectivityManager;
#endif
}
FileTransferManager::Transfer FileTransferManager::sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info) {
FileTransferManager::Transfer transfer;
transfer.from = buddy->getJID();
transfer.to = user->getJID();
transfer.readByteStream = byteStream;
LOG4CXX_INFO(logger, "Starting FT from '" << transfer.from << "' to '" << transfer.to << "'")
transfer.ft = m_outgoingFTManager->createOutgoingFileTransfer(transfer.from, transfer.to, transfer.readByteStream, info);
// if (transfer.ft) {
// m_filetransfers.push_back(ft);
// ft->onStateChange.connect(boost::bind(&User::handleFTStateChanged, this, _1, Buddy::JIDToLegacyName(from), info.getName(), info.getSize(), id));
// transfer.ft->start();
// }
return transfer;
}
}
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "transport/filetransfermanager.h"
#include "transport/transport.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/buddy.h"
#include "transport/logging.h"
#include "Swiften/Network/ConnectionServerFactory.h"
namespace Transport {
DEFINE_LOGGER(logger, "FileTransferManager");
FileTransferManager::FileTransferManager(Component *component, UserManager *userManager) {
m_component = component;
m_userManager = userManager;
m_jingleSessionManager = new Swift::JingleSessionManager(m_component->getIQRouter());
#if !HAVE_SWIFTEN_3
m_connectivityManager = new Swift::ConnectivityManager(m_component->getNetworkFactories()->getNATTraverser());
#endif
m_bytestreamRegistry = new Swift::SOCKS5BytestreamRegistry();
#if !HAVE_SWIFTEN_3
m_bytestreamProxy = new Swift::SOCKS5BytestreamProxy(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
m_localCandidateGeneratorFactory = new Swift::DefaultLocalJingleTransportCandidateGeneratorFactory(m_connectivityManager, m_bytestreamRegistry, m_bytestreamProxy, "thishouldnotbeused");
m_remoteCandidateSelectorFactory = new Swift::DefaultRemoteJingleTransportCandidateSelectorFactory(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
#else
m_proxyManager = new Swift::SOCKS5BytestreamProxiesManager(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory(), m_component->getNetworkFactories()->getDomainNameResolver(), m_component->getIQRouter(), "bar.com");
#endif
boost::shared_ptr<Swift::ConnectionServer> server = m_component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(19645);
server->start();
#if HAVE_SWIFTEN_3
m_proxyServerManager = new Swift::SOCKS5BytestreamServerManager(m_bytestreamRegistry, m_component->getNetworkFactories()->getConnectionServerFactory(), m_component->getNetworkFactories()->getNetworkEnvironment(), m_component->getNetworkFactories()->getNATTraverser());
#else
m_bytestreamServer = new Swift::SOCKS5BytestreamServer(server, m_bytestreamRegistry);
m_bytestreamServer->start();
m_outgoingFTManager = new Swift::CombinedOutgoingFileTransferManager(m_jingleSessionManager, m_component->getIQRouter(),
m_userManager, m_remoteCandidateSelectorFactory,
m_localCandidateGeneratorFactory, m_bytestreamRegistry,
m_bytestreamProxy, m_component->getPresenceOracle(),
m_bytestreamServer);
#endif
// WARNING: Swiften crashes when this is uncommented... But we probably need it for working Jingle FT
// m_connectivityManager->addListeningPort(19645);
}
FileTransferManager::~FileTransferManager() {
#if !HAVE_SWIFTEN_3
m_bytestreamServer->stop();
delete m_remoteCandidateSelectorFactory;
delete m_localCandidateGeneratorFactory;
#endif
delete m_outgoingFTManager;
delete m_jingleSessionManager;
delete m_bytestreamRegistry;
#if !HAVE_SWIFTEN_3
delete m_bytestreamServer;
delete m_bytestreamProxy;
delete m_connectivityManager;
#endif
}
FileTransferManager::Transfer FileTransferManager::sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info) {
FileTransferManager::Transfer transfer;
transfer.from = buddy->getJID();
transfer.to = user->getJID();
transfer.readByteStream = byteStream;
LOG4CXX_INFO(logger, "Starting FT from '" << transfer.from << "' to '" << transfer.to << "'")
transfer.ft = m_outgoingFTManager->createOutgoingFileTransfer(transfer.from, transfer.to, transfer.readByteStream, info);
// if (transfer.ft) {
// m_filetransfers.push_back(ft);
// ft->onStateChange.connect(boost::bind(&User::handleFTStateChanged, this, _1, Buddy::JIDToLegacyName(from), info.getName(), info.getSize(), id));
// transfer.ft->start();
// }
return transfer;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +1,181 @@
/**
* XMPP - libpurple transport
*
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "transport/settingsadhoccommand.h"
#include "transport/conversation.h"
#include "transport/usermanager.h"
#include "transport/buddy.h"
#include "transport/factory.h"
#include "transport/user.h"
#include "transport/logging.h"
#include "transport/storagebackend.h"
namespace Transport {
DEFINE_LOGGER(logger, "SettingsAdHocCommand");
SettingsAdHocCommand::SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, userManager, storageBackend, initiator, to) {
m_state = Init;
#if HAVE_SWIFTEN_3
Swift::FormField::ref field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, "1");
#else
Swift::BooleanFormField::ref field;
field = Swift::BooleanFormField::create(true);
#endif
field->setName("enable_transport");
field->setLabel("Enable transport");
addFormField(field);
#if HAVE_SWIFTEN_3
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0"));
#else
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0") == "1");
#endif
field->setName("send_headlines");
field->setLabel("Allow sending messages as headlines");
addFormField(field);
#if HAVE_SWIFTEN_3
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0"));
#else
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0") == "1");
#endif
field->setName("stay_connected");
field->setLabel("Stay connected to legacy network when offline on XMPP");
addFormField(field);
}
SettingsAdHocCommand::~SettingsAdHocCommand() {
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::getForm() {
if (!m_storageBackend) {
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
#if HAVE_SWIFTEN_3
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "This server does not support transport settings. There is no storage backend configured"));
#else
form->addField(Swift::FixedFormField::create("This server does not support transport settings. There is no storage backend configured"));
#endif
response->setForm(form);
return response;
}
UserInfo user;
if (m_storageBackend->getUser(m_initiator.toBare().toString(), user) == false) {
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
#if HAVE_SWIFTEN_3
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "You are not registered."));
#else
form->addField(Swift::FixedFormField::create("You are not registered."));
#endif
response->setForm(form);
return response;
}
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Executing));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
// FIXME: Support for more types than boolean
#if HAVE_SWIFTEN_3
if (field->getType() == Swift::FormField::BooleanType) {
std::string value = field->getBoolValue() ? "1" : "0";
int type = (int) TYPE_BOOLEAN;
m_storageBackend->getUserSetting(user.id, field->getName(), type, value);
field->setBoolValue(value == "1");
}
#else
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(field)) {
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(field));
std::string value = f->getValue() ? "1" : "0";
int type = (int)TYPE_BOOLEAN;
m_storageBackend->getUserSetting(user.id, f->getName(), type, value);
f->setValue(value == "1");
}
#endif
form->addField(field);
}
response->setForm(form);
return response;
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleResponse(boost::shared_ptr<Swift::Command> payload) {
UserInfo user;
bool registered = m_storageBackend->getUser(m_initiator.toBare().toString(), user);
if (registered && payload->getForm()) {
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
Swift::FormField::ref received = payload->getForm()->getField(field->getName());
if (!received) {
continue;
}
#if HAVE_SWIFTEN_3
if (received->getType() == Swift::FormField::BooleanType) {
std::string value = received->getBoolValue() ? "1" : "0";
m_storageBackend->updateUserSetting(user.id, received->getName(), value);
} else if (received->getType() == Swift::FormField::TextSingleType) {
m_storageBackend->updateUserSetting(user.id, received->getName(), received->getTextSingleValue());
}
#else
// FIXME: Support for more types than boolean
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(received)) {
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(received));
std::string value = f->getValue() ? "1" : "0";
m_storageBackend->updateUserSetting(user.id, f->getName(), value);
}
else if (boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received)) {
Swift::TextSingleFormField::ref f(boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received));
m_storageBackend->updateUserSetting(user.id, f->getName(), f->getValue());
}
#endif
}
}
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
return response;
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleRequest(boost::shared_ptr<Swift::Command> payload) {
boost::shared_ptr<Swift::Command> response;
if (payload->getAction() == Swift::Command::Cancel) {
response = boost::shared_ptr<Swift::Command>(new Swift::Command("settings", m_id, Swift::Command::Canceled));
return response;
}
switch (m_state) {
case Init:
response = getForm();
m_state = WaitingForResponse;
break;
case WaitingForResponse:
response = handleResponse(payload);
break;
default:
break;
}
return response;
}
}
/**
* XMPP - libpurple transport
*
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "transport/settingsadhoccommand.h"
#include "transport/conversation.h"
#include "transport/usermanager.h"
#include "transport/buddy.h"
#include "transport/factory.h"
#include "transport/user.h"
#include "transport/logging.h"
#include "transport/storagebackend.h"
namespace Transport {
DEFINE_LOGGER(logger, "SettingsAdHocCommand");
SettingsAdHocCommand::SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, userManager, storageBackend, initiator, to) {
m_state = Init;
#if HAVE_SWIFTEN_3
Swift::FormField::ref field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, "1");
#else
Swift::BooleanFormField::ref field;
field = Swift::BooleanFormField::create(true);
#endif
field->setName("enable_transport");
field->setLabel("Enable transport");
addFormField(field);
#if HAVE_SWIFTEN_3
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0"));
#else
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0") == "1");
#endif
field->setName("send_headlines");
field->setLabel("Allow sending messages as headlines");
addFormField(field);
#if HAVE_SWIFTEN_3
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0"));
#else
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0") == "1");
#endif
field->setName("stay_connected");
field->setLabel("Stay connected to legacy network when offline on XMPP");
addFormField(field);
}
SettingsAdHocCommand::~SettingsAdHocCommand() {
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::getForm() {
if (!m_storageBackend) {
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
#if HAVE_SWIFTEN_3
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "This server does not support transport settings. There is no storage backend configured"));
#else
form->addField(Swift::FixedFormField::create("This server does not support transport settings. There is no storage backend configured"));
#endif
response->setForm(form);
return response;
}
UserInfo user;
if (m_storageBackend->getUser(m_initiator.toBare().toString(), user) == false) {
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
#if HAVE_SWIFTEN_3
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "You are not registered."));
#else
form->addField(Swift::FixedFormField::create("You are not registered."));
#endif
response->setForm(form);
return response;
}
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Executing));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
// FIXME: Support for more types than boolean
#if HAVE_SWIFTEN_3
if (field->getType() == Swift::FormField::BooleanType) {
std::string value = field->getBoolValue() ? "1" : "0";
int type = (int) TYPE_BOOLEAN;
m_storageBackend->getUserSetting(user.id, field->getName(), type, value);
field->setBoolValue(value == "1");
}
#else
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(field)) {
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(field));
std::string value = f->getValue() ? "1" : "0";
int type = (int)TYPE_BOOLEAN;
m_storageBackend->getUserSetting(user.id, f->getName(), type, value);
f->setValue(value == "1");
}
#endif
form->addField(field);
}
response->setForm(form);
return response;
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleResponse(boost::shared_ptr<Swift::Command> payload) {
UserInfo user;
bool registered = m_storageBackend->getUser(m_initiator.toBare().toString(), user);
if (registered && payload->getForm()) {
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
Swift::FormField::ref received = payload->getForm()->getField(field->getName());
if (!received) {
continue;
}
#if HAVE_SWIFTEN_3
if (received->getType() == Swift::FormField::BooleanType) {
std::string value = received->getBoolValue() ? "1" : "0";
m_storageBackend->updateUserSetting(user.id, received->getName(), value);
} else if (received->getType() == Swift::FormField::TextSingleType) {
m_storageBackend->updateUserSetting(user.id, received->getName(), received->getTextSingleValue());
}
#else
// FIXME: Support for more types than boolean
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(received)) {
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(received));
std::string value = f->getValue() ? "1" : "0";
m_storageBackend->updateUserSetting(user.id, f->getName(), value);
}
else if (boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received)) {
Swift::TextSingleFormField::ref f(boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received));
m_storageBackend->updateUserSetting(user.id, f->getName(), f->getValue());
}
#endif
}
}
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
return response;
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleRequest(boost::shared_ptr<Swift::Command> payload) {
boost::shared_ptr<Swift::Command> response;
if (payload->getAction() == Swift::Command::Cancel) {
response = boost::shared_ptr<Swift::Command>(new Swift::Command("settings", m_id, Swift::Command::Canceled));
return response;
}
switch (m_state) {
case Init:
response = getForm();
m_state = WaitingForResponse;
break;
case WaitingForResponse:
response = handleResponse(payload);
break;
default:
break;
}
return response;
}
}

View File

@ -150,8 +150,11 @@ void BasicTest::dumpReceived() {
std::cout << "Stream2:\n";
std::cout << receivedData2 << "\n";
}
#if HAVE_SWIFTEN_3
void BasicTest::handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
#else
void BasicTest::handleElement(boost::shared_ptr<Swift::Element> element) {
#endif
if (stream1_active) {
received.push_back(element);
}

View File

@ -45,6 +45,7 @@
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Server/ServerFromClientSession.h"
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
using namespace Transport;
@ -217,9 +218,11 @@ class BasicTest : public Swift::XMPPParserClient {
void handleDataReceived2(const Swift::SafeByteArray &data);
void handleStreamStart(const Swift::ProtocolHeader&);
#if HAVE_SWIFTEN_3
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
#else
void handleElement(boost::shared_ptr<Swift::Element> element);
#endif
void handleStreamEnd();
void injectPresence(boost::shared_ptr<Swift::Presence> &response);

View File

@ -1,151 +0,0 @@
#include "transport/userregistry.h"
#include "transport/userregistration.h"
#include "transport/config.h"
#include "transport/storagebackend.h"
#include "transport/user.h"
#include "transport/transport.h"
#include "transport/conversation.h"
#include "transport/usermanager.h"
#include "transport/localbuddy.h"
#include "transport/settingsadhoccommand.h"
#include "transport/filetransfermanager.h"
#include "transport/adhocmanager.h"
#include "transport/memoryreadbytestream.h"
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <Swiften/Swiften.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
#include <Swiften/Server/Server.h>
#include <Swiften/Network/DummyNetworkFactories.h>
#include <Swiften/Network/DummyConnectionServer.h>
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Server/ServerFromClientSession.h"
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
#include "basictest.h"
using namespace Transport;
class FileTransferManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_TEST_SUITE(FileTransferManagerTest);
CPPUNIT_TEST(sendFileNoMethod);
CPPUNIT_TEST(sendFileSIIBB);
CPPUNIT_TEST_SUITE_END();
public:
FileTransferManager *manager;
std::string data;
FileTransferManager::Transfer transfer;
bool dataNeeded;
Swift::FileTransfer::State::FTState ftState;
boost::shared_ptr<MemoryReadBytestream> bytestream;
void setUp (void) {
setMeUp();
dataNeeded = false;
data = "This is our testing file\n";
manager = new FileTransferManager(component, userManager);
connectUser();
add2Buddies();
received.clear();
}
void tearDown (void) {
received.clear();
delete manager;
disconnectUser();
tearMeDown();
}
void handleFTDataNeeded() {
dataNeeded = true;
// std::cout << "data needed\n";
}
void handleFTStateChanged(Swift::FileTransfer::State state) {
// std::cout << "state changed " << state.state << "\n";
ftState = state.state;
}
void _sendFile() {
User *user = userManager->getUser("user@localhost");
Swift::StreamInitiationFileInfo fileInfo;
fileInfo.setSize(data.size());
fileInfo.setName("test.pdf");
bytestream = boost::shared_ptr<MemoryReadBytestream>(new MemoryReadBytestream(data.size()));
bytestream->onDataNeeded.connect(boost::bind(&FileTransferManagerTest::handleFTDataNeeded, this));
transfer = manager->sendFile(user, user->getRosterManager()->getBuddy("buddy1"), bytestream, fileInfo);
}
void sendFileNoMethod() {
_sendFile();
CPPUNIT_ASSERT(!transfer.ft);
}
void sendFileSIIBB() {
User *user = userManager->getUser("user@localhost");
boost::shared_ptr<Swift::DiscoInfo> info(new Swift::DiscoInfo());
info->addFeature("http://jabber.org/protocol/si/profile/file-transfer");
user->handleDiscoInfo("user@localhost/resource", info);
// Send file request
_sendFile();
CPPUNIT_ASSERT(transfer.ft);
transfer.ft->onStateChange.connect(boost::bind(&FileTransferManagerTest::handleFTStateChanged, this, _1));
transfer.ft->start();
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::IQ *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Set, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::StreamInitiation>());
CPPUNIT_ASSERT_EQUAL(std::string("test.pdf"), dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getPayload<Swift::StreamInitiation>()->getFileInfo()->getName());
CPPUNIT_ASSERT_EQUAL((int) data.size(), (int) dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getPayload<Swift::StreamInitiation>()->getFileInfo()->getSize());
// request acceptation
Swift::IQ::ref accept = Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID());
Swift::StreamInitiation::ref payload(new Swift::StreamInitiation());
payload->setRequestedMethod("http://jabber.org/protocol/ibb");
accept->addPayload(payload);
injectIQ(accept);
loop->processEvents();
received.erase(received.begin());
// handle open packet and accept the FT
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::IQ *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Set, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::IBB>());
CPPUNIT_ASSERT_EQUAL(Swift::IBB::Open, getStanza(received[0])->getPayload<Swift::IBB>()->getAction());
injectIQ(Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID()));
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(true, dataNeeded);
CPPUNIT_ASSERT_EQUAL(Swift::FileTransfer::State::Transferring, ftState);
bytestream->appendData(data); // this will be send in one packet...
loop->processEvents();
received.erase(received.begin());
// we received data now
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::IQ *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Set, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::IBB>());
CPPUNIT_ASSERT_EQUAL(Swift::IBB::Data, getStanza(received[0])->getPayload<Swift::IBB>()->getAction());
injectIQ(Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID()));
loop->processEvents();
received.erase(received.begin());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION (FileTransferManagerTest);

View File

@ -147,7 +147,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
// set enabled_transport = 0
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("enable_transport");
boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->setValue(false);
f->setBoolValue(false);
std::string sessionId = getStanza(received[0])->getPayload<Swift::Command>()->getSessionID();
@ -207,7 +207,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
// set enabled_transport = 0
f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("enable_transport");
CPPUNIT_ASSERT_EQUAL(false, boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->getValue());
CPPUNIT_ASSERT_EQUAL(false, f->getBoolValue());
}
void executeTwoCommands() {
@ -355,7 +355,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
// set enabled_transport = 0
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("send_headlines");
boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->setValue(true);
f->setBoolValue(true);
std::string sessionId = getStanza(received[0])->getPayload<Swift::Command>()->getSessionID();
@ -397,7 +397,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>()->getForm());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>()->getForm()->getField("send_headlines"));
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("send_headlines");
CPPUNIT_ASSERT_EQUAL(true, boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->getValue());
CPPUNIT_ASSERT_EQUAL(true, f->getBoolValue());
}
};

View File

@ -1,363 +1,363 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "transport/transport.h"
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "transport/storagebackend.h"
#include "transport/factory.h"
#include "transport/userregistry.h"
#include "transport/logging.h"
#include "storageparser.h"
#ifdef _WIN32
#include <Swiften/TLS/CAPICertificate.h>
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
#else
#include "Swiften/TLS/PKCS12Certificate.h"
#include "Swiften/TLS/CertificateWithKey.h"
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
#endif
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
#include "transport/BlockParser.h"
#include "transport/BlockSerializer.h"
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
#include "Swiften/Parser/GenericPayloadParserFactory.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Elements/InBandRegistrationPayload.h"
using namespace Swift;
using namespace boost;
namespace Transport {
DEFINE_LOGGER(logger, "Component");
DEFINE_LOGGER(logger_xml, "Component.XML");
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
m_component = NULL;
m_userRegistry = NULL;
m_server = NULL;
m_reconnectCount = 0;
m_config = config;
m_config->onBackendConfigUpdated.connect(boost::bind(&Component::handleBackendConfigChanged, this));
m_factory = factory;
m_loop = loop;
m_userRegistry = userRegistry;
m_rawXML = false;
m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
m_factories = factories;
m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
m_reconnectTimer->onTick.connect(bind(&Component::start, this));
if (CONFIG_BOOL(m_config, "service.server_mode")) {
LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
if (!CONFIG_STRING(m_config, "service.cert").empty()) {
#ifndef _WIN32
//TODO: fix
LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
LOG4CXX_INFO(logger, "SSLv23_server_method used.");
TLSServerContextFactory *f = new OpenSSLServerContextFactory();
CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
m_server->addTLSEncryption(f, certificate);
#endif
}
else {
LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
}
// m_server->start();
m_stanzaChannel = m_server->getStanzaChannel();
m_iqRouter = m_server->getIQRouter();
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_server->addPayloadSerializer(new Transport::BlockSerializer());
m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
m_server->addPayloadSerializer(new Swift::StatsSerializer());
m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
}
else {
LOG4CXX_INFO(logger, "Creating component in gateway mode");
#if HAVE_SWIFTEN_3
m_component = new Swift::Component(m_jid, CONFIG_STRING(m_config, "service.password"), m_factories);
#else
m_component = new Swift::Component(loop, m_factories, m_jid, CONFIG_STRING(m_config, "service.password"));
#endif
m_component->setSoftwareVersion("Spectrum", SPECTRUM_VERSION);
m_component->onConnected.connect(bind(&Component::handleConnected, this));
m_component->onError.connect(boost::bind(&Component::handleConnectionError, this, _1));
m_component->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
m_component->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
m_component->addPayloadSerializer(new Swift::AttentionSerializer());
m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_component->addPayloadSerializer(new Transport::BlockSerializer());
m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
m_component->addPayloadSerializer(new Swift::StatsSerializer());
m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
m_stanzaChannel = m_component->getStanzaChannel();
m_iqRouter = m_component->getIQRouter();
}
m_capsMemoryStorage = new CapsMemoryStorage();
#if HAVE_SWIFTEN_3
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter, m_factories->getCryptoProvider());
#else
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
#endif
m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
//
// m_registerHandler = new SpectrumRegisterHandler(m_component);
// m_registerHandler->start();
}
Component::~Component() {
delete m_presenceOracle;
delete m_entityCapsManager;
delete m_capsManager;
delete m_capsMemoryStorage;
if (m_component)
delete m_component;
if (m_server) {
m_server->stop();
delete m_server;
}
}
bool Component::handleIQ(boost::shared_ptr<Swift::IQ> iq) {
if (!m_rawXML) {
return false;
}
if (iq->getPayload<Swift::RosterPayload>() != NULL) { return false; }
if (iq->getPayload<Swift::InBandRegistrationPayload>() != NULL) { return false; }
if (iq->getPayload<Swift::StatsPayload>() != NULL) { return false; }
if (iq->getTo().getNode().empty()) {
return false;
}
onRawIQReceived(iq);
return true;
}
void Component::handleBackendConfigChanged() {
if (!m_rawXML && CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
m_rawXML = true;
m_iqRouter->addHandler(this);
}
}
Swift::StanzaChannel *Component::getStanzaChannel() {
return m_stanzaChannel;
}
Transport::PresenceOracle *Component::getPresenceOracle() {
return m_presenceOracle;
}
void Component::start() {
if (m_component && !m_component->isAvailable()) {
LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
if (CONFIG_INT(m_config, "service.port") == 5222) {
LOG4CXX_WARN(logger, "Port 5222 is usually used for client connections, not for component connections! Are you sure you are using right port?");
}
m_reconnectCount++;
m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
m_reconnectTimer->stop();
}
else if (m_server) {
LOG4CXX_INFO(logger, "Starting component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server->start();
//Type casting to BoostConnectionServer since onStopped signal is not defined in ConnectionServer
//Ideally, onStopped must be defined in ConnectionServer
if (boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())) {
boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())->onStopped.connect(boost::bind(&Component::handleServerStopped, this, _1));
}
// We're connected right here, because we're in server mode...
handleConnected();
}
}
void Component::stop() {
if (m_component) {
m_reconnectCount = 0;
// TODO: Call this once swiften will fix assert(!session_);
// m_component->disconnect();
m_reconnectTimer->stop();
}
else if (m_server) {
LOG4CXX_INFO(logger, "Stopping component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server->stop();
}
}
void Component::handleConnected() {
onConnected();
m_reconnectCount = 0;
m_reconnectTimer->stop();
}
void Component::handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e) {
if(e != NULL ) {
if(*e == Swift::BoostConnectionServer::Conflict) {
LOG4CXX_INFO(logger, "Port "<< CONFIG_INT(m_config, "service.port") << " already in use! Stopping server..");
if (CONFIG_INT(m_config, "service.port") == 5347) {
LOG4CXX_INFO(logger, "Port 5347 is usually used for components. You are using server_mode=1. Are you sure you don't want to use server_mode=0 and run spectrum as component?");
}
}
if(*e == Swift::BoostConnectionServer::UnknownError)
LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
exit(1);
}
}
void Component::handleConnectionError(const ComponentError &error) {
onConnectionError(error);
// if (m_reconnectCount == 2)
// Component::instance()->userManager()->removeAllUsers();
std::string str = "Unknown error";
switch (error.getType()) {
case ComponentError::UnknownError: str = "Unknown error"; break;
case ComponentError::ConnectionError: str = "Connection error"; break;
case ComponentError::ConnectionReadError: str = "Connection read error"; break;
case ComponentError::ConnectionWriteError: str = "Connection write error"; break;
case ComponentError::XMLError: str = "XML Error"; break;
case ComponentError::AuthenticationFailedError: str = "Authentication failed error"; break;
case ComponentError::UnexpectedElementError: str = "Unexpected element error"; break;
}
LOG4CXX_INFO(logger, "Disconnected from XMPP server. Error: " << str);
m_reconnectTimer->start();
}
void Component::handleDataRead(const Swift::SafeByteArray &data) {
std::string d = safeByteArrayToString(data);
if (!boost::starts_with(d, "<auth")) {
LOG4CXX_INFO(logger_xml, "XML IN " << d);
}
}
void Component::handleDataWritten(const Swift::SafeByteArray &data) {
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
}
void Component::handlePresence(Swift::Presence::ref presence) {
// filter out login/logout presence spam
if (!presence->getTo().getNode().empty())
return;
// filter out bad presences
if (!presence->getFrom().isValid()) {
return;
}
switch (presence->getType()) {
case Presence::Error:
case Presence::Subscribe:
case Presence::Subscribed:
case Presence::Unsubscribe:
case Presence::Unsubscribed:
return;
default:
break;
};
// check if we have this client's capabilities and ask for them
if (presence->getType() != Swift::Presence::Unavailable) {
boost::shared_ptr<CapsInfo> capsInfo = presence->getPayload<CapsInfo>();
if (capsInfo && capsInfo->getHash() == "sha-1") {
/*haveFeatures = */m_entityCapsManager->getCaps(presence->getFrom()) != DiscoInfo::ref();
}
#ifdef SUPPORT_LEGACY_CAPS
else {
GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter);
discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom()));
discoInfoRequest->send();
}
#endif
}
onUserPresenceReceived(presence);
}
void Component::handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid) {
#ifdef SUPPORT_LEGACY_CAPS
onUserDiscoInfoReceived(jid, info);
#endif
}
void Component::handleCapsChanged(const Swift::JID& jid) {
onUserDiscoInfoReceived(jid, m_entityCapsManager->getCaps(jid));
}
}
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "transport/transport.h"
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "transport/storagebackend.h"
#include "transport/factory.h"
#include "transport/userregistry.h"
#include "transport/logging.h"
#include "storageparser.h"
#ifdef _WIN32
#include <Swiften/TLS/CAPICertificate.h>
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
#else
#include "Swiften/TLS/PKCS12Certificate.h"
#include "Swiften/TLS/CertificateWithKey.h"
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
#endif
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
#include "transport/BlockParser.h"
#include "transport/BlockSerializer.h"
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
#include "Swiften/Parser/GenericPayloadParserFactory.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Elements/InBandRegistrationPayload.h"
using namespace Swift;
using namespace boost;
namespace Transport {
DEFINE_LOGGER(logger, "Component");
DEFINE_LOGGER(logger_xml, "Component.XML");
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
m_component = NULL;
m_userRegistry = NULL;
m_server = NULL;
m_reconnectCount = 0;
m_config = config;
m_config->onBackendConfigUpdated.connect(boost::bind(&Component::handleBackendConfigChanged, this));
m_factory = factory;
m_loop = loop;
m_userRegistry = userRegistry;
m_rawXML = false;
m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
m_factories = factories;
m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
m_reconnectTimer->onTick.connect(bind(&Component::start, this));
if (CONFIG_BOOL(m_config, "service.server_mode")) {
LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
if (!CONFIG_STRING(m_config, "service.cert").empty()) {
#ifndef _WIN32
//TODO: fix
LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
LOG4CXX_INFO(logger, "SSLv23_server_method used.");
TLSServerContextFactory *f = new OpenSSLServerContextFactory();
CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
m_server->addTLSEncryption(f, certificate);
#endif
}
else {
LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
}
// m_server->start();
m_stanzaChannel = m_server->getStanzaChannel();
m_iqRouter = m_server->getIQRouter();
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_server->addPayloadSerializer(new Transport::BlockSerializer());
m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
m_server->addPayloadSerializer(new Swift::StatsSerializer());
m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
}
else {
LOG4CXX_INFO(logger, "Creating component in gateway mode");
#if HAVE_SWIFTEN_3
m_component = new Swift::Component(m_jid, CONFIG_STRING(m_config, "service.password"), m_factories);
#else
m_component = new Swift::Component(loop, m_factories, m_jid, CONFIG_STRING(m_config, "service.password"));
#endif
m_component->setSoftwareVersion("Spectrum", SPECTRUM_VERSION);
m_component->onConnected.connect(bind(&Component::handleConnected, this));
m_component->onError.connect(boost::bind(&Component::handleConnectionError, this, _1));
m_component->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
m_component->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
m_component->addPayloadSerializer(new Swift::AttentionSerializer());
m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_component->addPayloadSerializer(new Transport::BlockSerializer());
m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
m_component->addPayloadSerializer(new Swift::StatsSerializer());
m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
m_stanzaChannel = m_component->getStanzaChannel();
m_iqRouter = m_component->getIQRouter();
}
m_capsMemoryStorage = new CapsMemoryStorage();
#if HAVE_SWIFTEN_3
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter, m_factories->getCryptoProvider());
#else
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
#endif
m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
//
// m_registerHandler = new SpectrumRegisterHandler(m_component);
// m_registerHandler->start();
}
Component::~Component() {
delete m_presenceOracle;
delete m_entityCapsManager;
delete m_capsManager;
delete m_capsMemoryStorage;
if (m_component)
delete m_component;
if (m_server) {
m_server->stop();
delete m_server;
}
}
bool Component::handleIQ(boost::shared_ptr<Swift::IQ> iq) {
if (!m_rawXML) {
return false;
}
if (iq->getPayload<Swift::RosterPayload>() != NULL) { return false; }
if (iq->getPayload<Swift::InBandRegistrationPayload>() != NULL) { return false; }
if (iq->getPayload<Swift::StatsPayload>() != NULL) { return false; }
if (iq->getTo().getNode().empty()) {
return false;
}
onRawIQReceived(iq);
return true;
}
void Component::handleBackendConfigChanged() {
if (!m_rawXML && CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
m_rawXML = true;
m_iqRouter->addHandler(this);
}
}
Swift::StanzaChannel *Component::getStanzaChannel() {
return m_stanzaChannel;
}
Transport::PresenceOracle *Component::getPresenceOracle() {
return m_presenceOracle;
}
void Component::start() {
if (m_component && !m_component->isAvailable()) {
LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
if (CONFIG_INT(m_config, "service.port") == 5222) {
LOG4CXX_WARN(logger, "Port 5222 is usually used for client connections, not for component connections! Are you sure you are using right port?");
}
m_reconnectCount++;
m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
m_reconnectTimer->stop();
}
else if (m_server) {
LOG4CXX_INFO(logger, "Starting component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server->start();
//Type casting to BoostConnectionServer since onStopped signal is not defined in ConnectionServer
//Ideally, onStopped must be defined in ConnectionServer
if (boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())) {
boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())->onStopped.connect(boost::bind(&Component::handleServerStopped, this, _1));
}
// We're connected right here, because we're in server mode...
handleConnected();
}
}
void Component::stop() {
if (m_component) {
m_reconnectCount = 0;
// TODO: Call this once swiften will fix assert(!session_);
// m_component->disconnect();
m_reconnectTimer->stop();
}
else if (m_server) {
LOG4CXX_INFO(logger, "Stopping component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server->stop();
}
}
void Component::handleConnected() {
onConnected();
m_reconnectCount = 0;
m_reconnectTimer->stop();
}
void Component::handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e) {
if(e != NULL ) {
if(*e == Swift::BoostConnectionServer::Conflict) {
LOG4CXX_INFO(logger, "Port "<< CONFIG_INT(m_config, "service.port") << " already in use! Stopping server..");
if (CONFIG_INT(m_config, "service.port") == 5347) {
LOG4CXX_INFO(logger, "Port 5347 is usually used for components. You are using server_mode=1. Are you sure you don't want to use server_mode=0 and run spectrum as component?");
}
}
if(*e == Swift::BoostConnectionServer::UnknownError)
LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
exit(1);
}
}
void Component::handleConnectionError(const ComponentError &error) {
onConnectionError(error);
// if (m_reconnectCount == 2)
// Component::instance()->userManager()->removeAllUsers();
std::string str = "Unknown error";
switch (error.getType()) {
case ComponentError::UnknownError: str = "Unknown error"; break;
case ComponentError::ConnectionError: str = "Connection error"; break;
case ComponentError::ConnectionReadError: str = "Connection read error"; break;
case ComponentError::ConnectionWriteError: str = "Connection write error"; break;
case ComponentError::XMLError: str = "XML Error"; break;
case ComponentError::AuthenticationFailedError: str = "Authentication failed error"; break;
case ComponentError::UnexpectedElementError: str = "Unexpected element error"; break;
}
LOG4CXX_INFO(logger, "Disconnected from XMPP server. Error: " << str);
m_reconnectTimer->start();
}
void Component::handleDataRead(const Swift::SafeByteArray &data) {
std::string d = safeByteArrayToString(data);
if (!boost::starts_with(d, "<auth")) {
LOG4CXX_INFO(logger_xml, "XML IN " << d);
}
}
void Component::handleDataWritten(const Swift::SafeByteArray &data) {
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
}
void Component::handlePresence(Swift::Presence::ref presence) {
// filter out login/logout presence spam
if (!presence->getTo().getNode().empty())
return;
// filter out bad presences
if (!presence->getFrom().isValid()) {
return;
}
switch (presence->getType()) {
case Presence::Error:
case Presence::Subscribe:
case Presence::Subscribed:
case Presence::Unsubscribe:
case Presence::Unsubscribed:
return;
default:
break;
};
// check if we have this client's capabilities and ask for them
if (presence->getType() != Swift::Presence::Unavailable) {
boost::shared_ptr<CapsInfo> capsInfo = presence->getPayload<CapsInfo>();
if (capsInfo && capsInfo->getHash() == "sha-1") {
/*haveFeatures = */m_entityCapsManager->getCaps(presence->getFrom()) != DiscoInfo::ref();
}
#ifdef SUPPORT_LEGACY_CAPS
else {
GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter);
discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom()));
discoInfoRequest->send();
}
#endif
}
onUserPresenceReceived(presence);
}
void Component::handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid) {
#ifdef SUPPORT_LEGACY_CAPS
onUserDiscoInfoReceived(jid, info);
#endif
}
void Component::handleCapsChanged(const Swift::JID& jid) {
onUserDiscoInfoReceived(jid, m_entityCapsManager->getCaps(jid));
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff