Commit d23c8bdc authored by fred's avatar fred
Browse files

extract ftp server from ncs to an external process

parent 2c597e5a
......@@ -883,8 +883,9 @@ void Http_admin::admin_user_post(QxtWebRequestEvent* event)
mongodb_->Insert("users", t_user);
if (ftp) {
emit create_ftp_user(form_field["email"]);
qDebug() << "EMIT CREATE FTP USER";
QString command = "{\"email\": \"" + form_field["email"] + "\", \"password\": \"" + str_ftp_token + "\", \"path\": \"" + str_ftp_directory + "\"}";
emit create_ftp_user("ftp", command);
qDebug() << "EMIT CREATE FTP USER : " << command;
}
......
......@@ -89,10 +89,10 @@ private:
QBool http_auth(QString auth, QHash <QString, QString> &hauth, QString &str_session_uuid);
signals:
void create_api_user(QString email);
void create_ftp_user(QString email);
void create_xmpp_user(QString email);
void create_bittorrent_user(QString email);
void create_api_user(QString);
void create_ftp_user(QString, QString);
void create_xmpp_user(QString);
void create_bittorrent_user(QString);
};
#endif // HTTP_ADMIN_H
......@@ -82,7 +82,7 @@ Dispatcher::Dispatcher(params ncs_params)
service->Http_admin_init();
if (ncs_params.api_port != 0) service->Http_api_init();
if (ncs_params.tracker_port != 0) service->Nodetrack_init();
if (ncs_params.ftp_server_port != 0) service->Nodeftp_init();
//if (ncs_params.ftp_server_port != 0) service->Nodeftp_init();
if (ncs_params.xmpp_client_port != 0 && ncs_params.xmpp_server_port != 0 ) service->Xmpp_init();
service->Worker_init();
service->link();
......
......@@ -30,7 +30,8 @@ SOURCES += main.cpp \
service.cpp \
mongodb.cpp \
http_admin.cpp \
zerogw.cpp
zerogw.cpp \
statemachine.cpp
LIBS += ./externals/mongo-cxx-driver/libmongoclient.a \
-lz \
-lboost_system \
......@@ -70,4 +71,5 @@ HEADERS += main.h \
service.h \
mongodb.h \
http_admin.h \
zerogw.h
zerogw.h \
statemachine.h
......@@ -446,13 +446,10 @@ void Service::Worker_init()
worker_api->moveToThread(worker_thread_api);
worker_thread_api->start();
//connect(this, SIGNAL(shutdown()), worker_api, SLOT(destructor()), Qt::BlockingQueuedConnection);
}
void Service::link()
{
if (m_nodeftp) connect(m_http_admin, SIGNAL(create_ftp_user(QString)), m_nodeftp, SLOT(add_ftp_user(QString)), Qt::DirectConnection);
if (m_nodeftp) connect(api_user, SIGNAL(create_ftp_user(QString)), m_nodeftp, SLOT(add_ftp_user(QString)), Qt::DirectConnection);
connect(m_http_admin, SIGNAL(create_ftp_user(QString,QString)), worker_api, SLOT(publish_command(QString,QString)), Qt::QueuedConnection);
connect(api_user, SIGNAL(create_ftp_user(QString,QString)), worker_api, SLOT(publish_command(QString,QString)), Qt::QueuedConnection);
}
......@@ -50,7 +50,7 @@
#include <stdarg.h>
#include <sys/stat.h>
//#include <QTest>
#include <QTest>
#include "CFtpServerConfig.h"
......
......@@ -38,7 +38,7 @@
* @def CFTPSERVER_ENABLE_EVENTS
* Enable or disable events.
*/
#define CFTPSERVER_ENABLE_EVENTS
//#define CFTPSERVER_ENABLE_EVENTS
/**
* @def CFTPSERVER_ENABLE_ZLIB
......
......@@ -19,19 +19,102 @@
****************************************************************************/
#include "main.h"
#include <QCoreApplication>
int Service::sighupFd[2]={};
int Service::sigtermFd[2]={};
QSettings settings("nodecast", "nodeftp");
// http://doc.qt.nokia.com/4.7/unix-signals.html
static void setup_unix_signal_handlers()
{
struct sigaction hup, term;
hup.sa_handler = Service::hupSignalHandler;
sigemptyset(&hup.sa_mask);
hup.sa_flags = 0;
hup.sa_flags |= SA_RESTART;
/*if (sigaction(SIGHUP, &hup, 0) > 0)
return 1;*/
term.sa_handler = Service::termSignalHandler;
sigemptyset(&term.sa_mask);
term.sa_flags |= SA_RESTART;
/*if (sigaction(SIGTERM, &term, 0) > 0)
return 2;
return 0;*/
sigaction (SIGINT, &hup, NULL);
sigaction (SIGTERM, &term, NULL);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
params ftp_params;
params nodeftp_params;
bool debug;
bool verbose;
QxtCommandOptions options;
options.add("debug", "show debug informations");
options.alias("debug", "d");
options.add("base-directory", "set the ftp base directory", QxtCommandOptions::Required);
options.alias("base-directory", "bd");
options.add("ftp-server-port", "set the ftp server port", QxtCommandOptions::Optional);
options.alias("ftp-server-port", "fsp");
options.add("help", "show this help text");
options.alias("help", "h");
options.parse(QCoreApplication::arguments());
if(options.count("help") || options.showUnrecognizedWarning()) {
options.showUsage();
return -1;
}
if(options.count("base-directory")) {
nodeftp_params.base_directory = options.value("base-directory").toString();
settings.setValue("base-directory", nodeftp_params.base_directory);
}
else if(settings.contains("base-directory"))
{
nodeftp_params.base_directory = settings.value("base-directory").toString();
}
else {
std::cout << "ncs: --ncs-base-directory requires a parameter" << std::endl;
options.showUsage();
return -1;
}
if(options.count("ftp-server-port")) {
nodeftp_params.ftp_server_port = options.value("ftp-server-port").toInt();
settings.setValue("ftp-server-port", nodeftp_params.ftp_server_port);
}
else if(settings.contains("ftp-server-port"))
{
nodeftp_params.ftp_server_port = settings.value("ftp-server-port").toInt();
}
else nodeftp_params.ftp_server_port = 0;
settings.sync();
setup_unix_signal_handlers();
ftp_params.base_directory="/tmp";
ftp_params.server_port=2121;
Service *service;
service = new Service(ftp_params);
service = new Service(nodeftp_params);
return a.exec();
}
......@@ -7,7 +7,6 @@
#include <qstring.h>
#include <qtextstream.h>
#include <qsocketnotifier.h>
#include <QxtJSON>
//#include <QxtNetwork>
#include <QDateTime>
#include <iostream>
......@@ -16,51 +15,7 @@
#include <QThread>
#include <QTextStream>
#include "service.h"
class Io : public QObject
{
Q_OBJECT
public:
Io();
~Io();
private slots:
void readStdin();
private:
QFile *io_log;
QSocketNotifier* notifier;
QTextStream* input;
signals:
void parseData(QString s);
};
class NCWhandler : public QObject
{
Q_OBJECT
public:
NCWhandler();
~NCWhandler();
public slots:
void push_payload(QString s);
void writeStdout(QString s);
signals:
void emit_payload(QVariant payload);
private:
QFile *handler_log;
QTextStream* output;
};
#include <signal.h>
......
......@@ -26,11 +26,11 @@ void OnServerEvent( int Event )
switch( Event )
{
case CFtpServer::START_LISTENING:
printf("* Server is listening !\r\n");
//printf("* Server is listening !\r\n");
break;
case CFtpServer::START_ACCEPTING:
printf("* Server is accepting incoming connexions !\r\n");
//printf("* Server is accepting incoming connexions !\r\n");
break;
case CFtpServer::STOP_LISTENING:
......@@ -60,9 +60,9 @@ void OnUserEvent( int Event, CFtpServer::CUserEntry *pUser, void *pArg )
switch( Event )
{
case CFtpServer::NEW_USER:
printf("* A new user has been created:\r\n"
/* printf("* A new user has been created:\r\n"
"\tLogin: %s\r\n" "\tPassword: %s\r\n" "\tStart directory: %s\r\n",
pUser->GetLogin(), pUser->GetPassword(), pUser->GetStartDirectory() );
pUser->GetLogin(), pUser->GetPassword(), pUser->GetStartDirectory() );*/
break;
case CFtpServer::DELETE_USER:
......@@ -76,9 +76,9 @@ void OnClientEvent( int Event, CFtpServer::CClientEntry *pClient, void *pArg )
switch( Event )
{
case CFtpServer::NEW_CLIENT:
printf( "* A new client has been created:\r\n"
/* printf( "* A new client has been created:\r\n"
"\tClient IP: [%s]\r\n\tServer IP: [%s]\r\n",
inet_ntoa( *pClient->GetIP() ), inet_ntoa( *pClient->GetServerIP() ) );
inet_ntoa( *pClient->GetIP() ), inet_ntoa( *pClient->GetServerIP() ) );*/
break;
case CFtpServer::DELETE_CLIENT:
......@@ -86,7 +86,7 @@ void OnClientEvent( int Event, CFtpServer::CClientEntry *pClient, void *pArg )
break;
case CFtpServer::CLIENT_AUTH:
printf( "* A client has logged-in as \"%s\".\r\n", pClient->GetUser()->GetLogin() );
//printf( "* A client has logged-in as \"%s\".\r\n", pClient->GetUser()->GetLogin() );
break;
case CFtpServer::CLIENT_SOFTWARE:
......@@ -140,33 +140,8 @@ void OnClientEvent( int Event, CFtpServer::CClientEntry *pClient, void *pArg )
}
bool Nodeftp::ncs_auth(QString email, QString &token, QString &directory)
{
/* QCryptographicHash cipher( QCryptographicHash::Sha1 );
cipher.addData(password.simplified().toAscii());
QByteArray password_hash = cipher.result();
qDebug() << "password_hash : " << password_hash.toHex();
password_hashed = QString::fromLatin1(password_hash.toHex());
*/
BSONObj bauth = BSON("email" << email.toStdString());
//BSONObj l_user = mongodb_->Find("users", bauth);
BSONObj l_user;
if (l_user.nFields() == 0)
{
qDebug() << "Nodeftp::ncs_auth auth failed !";
return false;
}
token = QString::fromStdString(l_user.getFieldDotted("ftp.token").str());
directory = QString::fromStdString(l_user.getFieldDotted("ftp.directory").str());
return true;
}
Nodeftp::Nodeftp(QString a_directory, int port) : m_directory(a_directory), m_port(port)
{
//mongodb_ = Mongodb::getInstance ();
FtpServer = new CFtpServer();
#ifdef CFTPSERVER_ENABLE_EVENTS
......@@ -190,22 +165,23 @@ Nodeftp::Nodeftp(QString a_directory, int port) : m_directory(a_directory), m_po
}
void Nodeftp::add_ftp_user(QString email)
bool Nodeftp::add_ftp_user(QString email, QString password, QString path)
{
qDebug() << "Nodeftp::add_user : " << email;
// check auth
QString token, directory;
if (ncs_auth(email, token, directory))
{
//if (ncs_auth(email, token, directory))
//{
// create user's directory
QString userdirectory = m_directory + "/ftp/" + directory;
QString userdirectory = m_directory + "/" + path;
if (!QDir(userdirectory).exists()) QDir().mkdir(userdirectory);
CFtpServer::CUserEntry *pUser = FtpServer->AddUser( email.toAscii(), token.toAscii(), userdirectory.toAscii() );
CFtpServer::CUserEntry *pUser = FtpServer->AddUser( email.toAscii(), password.toAscii(), userdirectory.toAscii() );
if( pUser )
{
printf( "-User successfully created ! :)\r\n" );
//printf( "-User successfully created ! :)\r\n" );
pUser->SetMaxNumberOfClient( 5 ); // 0 Unlimited
/* pUser->SetPrivileges( CFtpServer::READFILE | CFtpServer::WRITEFILE |
......@@ -222,30 +198,35 @@ void Nodeftp::add_ftp_user(QString email)
#endif
}
else qErrnoWarning( "-Unable to create pUser" );
}
else qErrnoWarning( "-Failed to create user" );
else return false;
//}
//else return false;
return true;
}
void Nodeftp::ftp_init()
{
output = new QTextStream( stdout, QIODevice::WriteOnly );
log = new QFile("/tmp/ftp");
if (!log->open(QIODevice::Append | QIODevice::Text))
return;
// If you only want to listen on the TCP Loopback interface,
// replace 'INNADDR_ANY' by 'inet_addr("127.0.0.1")'.
if( FtpServer->StartListening( INADDR_ANY, m_port ) ) {
qDebug( "FTP : Server is listening !" );
// qDebug( "FTP : Server is listening !" );
if( FtpServer->StartAccepting() ) {
qDebug( "FTP : Server successfuly started !" );
populate();
for( ;; )
sleep(1);
// qDebug( "FTP : Server successfuly started !" );
writeStdout("{\"action\": \"get_ftp_users\", \"from\": \"ftp\", \"dest\": \"self\"}");
} else
qDebug( "FTP : Unable to accept incoming connections" );
FtpServer->StopListening();
} else
qErrnoWarning( "FTP : Unable to listen" );
......@@ -253,21 +234,85 @@ void Nodeftp::ftp_init()
}
void Nodeftp::populate()
{
BSONObj filter = BSON("ftp.activated" << true);
//QList <BSONObj> users_list = mongodb_->FindAll("users", filter);
QList <BSONObj> users_list;
foreach (BSONObj l_user, users_list)
{
add_ftp_user(QString::fromStdString(l_user.getField("email").str()));
}
}
Nodeftp::~Nodeftp()
{
qErrnoWarning( "FTP Exiting" );
FtpServer->StopListening();
delete FtpServer;
log->close();
}
void Nodeftp::writeStdout(QString s)
{
(*output) << s;
//while (!(*output).atEnd()) {};
(*output).flush();
}
void Nodeftp::receive_payload(QString s)
{
// writeStdout("PARSE : " + s);
//return;
//std::cout << s.toStdString() << std::endl;
// Do something with your received data here
//writeStdout(s);
QVariant json = QxtJSON::parse(s);
if (json.toMap().contains("email") &&
json.toMap().contains("password") &&
json.toMap().contains("path"))
{
user_email = json.toMap()["email"].toString();
user_password = json.toMap()["password"].toString();
user_path = json.toMap()["path"].toString();
/* writeStdout("event : " + event);
qDebug() << "usageid : " << usageid;
qDebug() << "value : " << value;
qDebug() << "contentid : " << contentid;
*/
//$datetime=date('Y-m-d H:i:s',$dt);
//QDateTime l_timestamp = QDateTime::currentDateTimeUtc();
//QString timestamp = l_timestamp.toString("yyyy-MM-dd HH:mm:ss");
bool res = add_ftp_user(user_email, user_password, user_path);
//writeStdout("REQ SQL : " + req);
/*query->exec("SELECT VERSION()");
while (query->next())
{
QString name = query->value(0).toString();
//qDebug() << name;
writeStdout(name);
}*/
QString t_bool = res ? "ok" : "ko";
writeStdout("{\"action\": \"terminate\", \"status\": \"" + t_bool + "\"}");
}
else
writeStdout("{\"error\": \"parsing json\", \"status\": \"false\"}");
}
......@@ -25,6 +25,10 @@
#include <QObject>
#include <QDir>
#include <QCryptographicHash>
#include <QSocketNotifier>
#include <QxtJSON>
#include <QTextStream>
#include <QDebug>
class Nodeftp : public QObject
{
......@@ -34,17 +38,24 @@ public:
~Nodeftp();
private:
bool ncs_auth(QString login, QString &token, QString &directory);
void populate();
void writeStdout(QString s);
QString m_directory;
int m_port;
CFtpServer *FtpServer;
//Mongodb *mongodb_;
QString user_email;
QString user_password;
QString user_path;
QTextStream* output;
QFile *log;
public slots:
void ftp_init();
void add_ftp_user(QString email);
bool add_ftp_user(QString email, QString password, QString path);
void receive_payload(QString s);
//void remove_user(QString username);
};
......
......@@ -8,7 +8,9 @@ QMAKE_CXXFLAGS += -D_FILE_OFFSET_BITS=64
QT += core \
network \
xml
xml \
testlib
QT -= gui
TARGET = nodeftp
......@@ -31,3 +33,13 @@ HEADERS += \
CFtpServer.h \
service.h \
main.h
LIBS += -lz \
-lboost_system \
-lboost_filesystem-mt \
-lboost_thread-mt \
-lQxtCore
INCLUDEPATH += ../../externals/libqxt/
INCLUDEPATH += ../../externals/libqxt/src/core
......@@ -20,29 +20,159 @@
#include "service.h"
Service::Service(params ftp_params, QObject *parent) : m_ftp_params(ftp_params), QObject(parent)
Io::~Io()
{
notifier->setEnabled(false);
delete(input);
io_log->close();
qDebug() << "END IO";
}
Io::Io() : QObject()
{
m_nodeftp = NULL;
}
input = new QTextStream( stdin, QIODevice::ReadOnly );
// Demand notification when there is data to be read from stdin
notifier = new QSocketNotifier( STDIN_FILENO, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin()), Qt::DirectConnection);
io_log = new QFile("/tmp/ncw_nodeftp");
if (!io_log->open(QIODevice::Append | QIODevice::Text))
return;
//*cout << prompt;
}
void Io::readStdin()
{
notifier->setEnabled(false);
// qDebug() << "READ STDIN";
// Read the data
QString line = input->readLine();
io_log->write(line.toAscii());
io_log->write("\n");
io_log->flush();