More work
* Refactored code out of common/ into servatrice/ * added smtp client library * disable registration when connected * validate email address * send activation token via email
This commit is contained in:
parent
8cf4461616
commit
471f6371b5
38 changed files with 2699 additions and 146 deletions
|
@ -104,11 +104,13 @@ void MainWindow::statusChanged(ClientStatus _status)
|
||||||
tabSupervisor->stop();
|
tabSupervisor->stop();
|
||||||
aSinglePlayer->setEnabled(true);
|
aSinglePlayer->setEnabled(true);
|
||||||
aConnect->setEnabled(true);
|
aConnect->setEnabled(true);
|
||||||
|
aRegister->setEnabled(true);
|
||||||
aDisconnect->setEnabled(false);
|
aDisconnect->setEnabled(false);
|
||||||
break;
|
break;
|
||||||
case StatusLoggingIn:
|
case StatusLoggingIn:
|
||||||
aSinglePlayer->setEnabled(false);
|
aSinglePlayer->setEnabled(false);
|
||||||
aConnect->setEnabled(false);
|
aConnect->setEnabled(false);
|
||||||
|
aRegister->setEnabled(false);
|
||||||
aDisconnect->setEnabled(true);
|
aDisconnect->setEnabled(true);
|
||||||
break;
|
break;
|
||||||
case StatusConnecting:
|
case StatusConnecting:
|
||||||
|
@ -179,6 +181,7 @@ void MainWindow::actSinglePlayer()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aConnect->setEnabled(false);
|
aConnect->setEnabled(false);
|
||||||
|
aRegister->setEnabled(false);
|
||||||
aSinglePlayer->setEnabled(false);
|
aSinglePlayer->setEnabled(false);
|
||||||
|
|
||||||
localServer = new LocalServer(this);
|
localServer = new LocalServer(this);
|
||||||
|
@ -226,6 +229,7 @@ void MainWindow::localGameEnded()
|
||||||
localServer = 0;
|
localServer = 0;
|
||||||
|
|
||||||
aConnect->setEnabled(true);
|
aConnect->setEnabled(true);
|
||||||
|
aRegister->setEnabled(true);
|
||||||
aSinglePlayer->setEnabled(true);
|
aSinglePlayer->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +340,7 @@ void MainWindow::registerError(Response::ResponseCode r, QString reasonStr, quin
|
||||||
QMessageBox::critical(this, tr("Registration denied"), tr("There is already an existing account with the same user name."));
|
QMessageBox::critical(this, tr("Registration denied"), tr("There is already an existing account with the same user name."));
|
||||||
break;
|
break;
|
||||||
case Response::RespEmailRequiredToRegister:
|
case Response::RespEmailRequiredToRegister:
|
||||||
QMessageBox::critical(this, tr("Registration denied"), tr("It's mandatory to specify an email when registering."));
|
QMessageBox::critical(this, tr("Registration denied"), tr("It's mandatory to specify a valid email address when registering."));
|
||||||
break;
|
break;
|
||||||
case Response::RespTooManyRequests:
|
case Response::RespTooManyRequests:
|
||||||
QMessageBox::critical(this, tr("Registration denied"), tr("Too many registration attempts from your IP address."));
|
QMessageBox::critical(this, tr("Registration denied"), tr("Too many registration attempts from your IP address."));
|
||||||
|
|
|
@ -175,64 +175,6 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
|
||||||
return authState;
|
return authState;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegistrationResult Server::registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining)
|
|
||||||
{
|
|
||||||
if (!registrationEnabled)
|
|
||||||
return RegistrationDisabled;
|
|
||||||
|
|
||||||
QString emailAddress = QString::fromStdString(cmd.email());
|
|
||||||
if (requireEmailForRegistration && emailAddress.isEmpty())
|
|
||||||
return EmailRequired;
|
|
||||||
|
|
||||||
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
|
|
||||||
|
|
||||||
// TODO: Move this method outside of the db interface
|
|
||||||
QString userName = QString::fromStdString(cmd.user_name());
|
|
||||||
if (!databaseInterface->usernameIsValid(userName))
|
|
||||||
return InvalidUsername;
|
|
||||||
|
|
||||||
if(databaseInterface->userExists(userName))
|
|
||||||
return UserAlreadyExists;
|
|
||||||
|
|
||||||
if (databaseInterface->checkUserIsBanned(ipAddress, userName, banReason, banSecondsRemaining))
|
|
||||||
return ClientIsBanned;
|
|
||||||
|
|
||||||
if (tooManyRegistrationAttempts(ipAddress))
|
|
||||||
return TooManyRequests;
|
|
||||||
|
|
||||||
QString realName = QString::fromStdString(cmd.real_name());
|
|
||||||
ServerInfo_User_Gender gender = cmd.gender();
|
|
||||||
QString country = QString::fromStdString(cmd.country());
|
|
||||||
QString password = QString::fromStdString(cmd.password());
|
|
||||||
|
|
||||||
if(password.length() < 6)
|
|
||||||
return PasswordTooShort;
|
|
||||||
|
|
||||||
bool regSucceeded = databaseInterface->registerUser(userName, realName, gender, password, emailAddress, country, !requireEmailForRegistration);
|
|
||||||
|
|
||||||
if(regSucceeded)
|
|
||||||
return requireEmailForRegistration ? AcceptedNeedsActivation : Accepted;
|
|
||||||
else
|
|
||||||
return Failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::activateUserAccount(const Command_Activate &cmd)
|
|
||||||
{
|
|
||||||
QString userName = QString::fromStdString(cmd.user_name());
|
|
||||||
QString token = QString::fromStdString(cmd.token());
|
|
||||||
|
|
||||||
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
|
|
||||||
|
|
||||||
return databaseInterface->activateUser(userName, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::tooManyRegistrationAttempts(const QString &ipAddress)
|
|
||||||
{
|
|
||||||
// TODO: implement
|
|
||||||
Q_UNUSED(ipAddress);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
|
void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&persistentPlayersLock);
|
QWriteLocker locker(&persistentPlayersLock);
|
||||||
|
|
|
@ -29,7 +29,6 @@ class CommandContainer;
|
||||||
class Command_JoinGame;
|
class Command_JoinGame;
|
||||||
|
|
||||||
enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive };
|
enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive };
|
||||||
enum RegistrationResult { Accepted, UserAlreadyExists, EmailRequired, TooManyRequests, InvalidUsername, ClientIsBanned, RegistrationDisabled, Failed, PasswordTooShort, AcceptedNeedsActivation };
|
|
||||||
|
|
||||||
class Server : public QObject
|
class Server : public QObject
|
||||||
{
|
{
|
||||||
|
@ -47,19 +46,6 @@ public:
|
||||||
void setThreaded(bool _threaded) { threaded = _threaded; }
|
void setThreaded(bool _threaded) { threaded = _threaded; }
|
||||||
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft);
|
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft);
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a user account.
|
|
||||||
* @param ipAddress The address of the connection from the user
|
|
||||||
* @param userName The username to attempt to register
|
|
||||||
* @param emailAddress The email address to associate with the new account (and to use for activation)
|
|
||||||
* @param banReason If the client is banned, the reason for the ban will be included in this string.
|
|
||||||
* @param banSecondsRemaining If the client is banned, the time left will be included in this. 0 if the ban is permanent.
|
|
||||||
* @return RegistrationResult member indicating whether it succeeded or failed.
|
|
||||||
*/
|
|
||||||
RegistrationResult registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining);
|
|
||||||
bool activateUserAccount(const Command_Activate &cmd);
|
|
||||||
|
|
||||||
bool tooManyRegistrationAttempts(const QString &ipAddress);
|
|
||||||
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
||||||
|
|
||||||
Server_AbstractUserInterface *findUser(const QString &userName) const;
|
Server_AbstractUserInterface *findUser(const QString &userName) const;
|
||||||
|
@ -131,9 +117,6 @@ protected:
|
||||||
int getUsersCount() const;
|
int getUsersCount() const;
|
||||||
int getGamesCount() const;
|
int getGamesCount() const;
|
||||||
void addRoom(Server_Room *newRoom);
|
void addRoom(Server_Room *newRoom);
|
||||||
|
|
||||||
bool registrationEnabled;
|
|
||||||
bool requireEmailForRegistration;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "pb/commands.pb.h"
|
#include "pb/commands.pb.h"
|
||||||
#include "pb/response.pb.h"
|
#include "pb/response.pb.h"
|
||||||
#include "pb/response_login.pb.h"
|
#include "pb/response_login.pb.h"
|
||||||
#include "pb/response_register.pb.h"
|
|
||||||
#include "pb/response_list_users.pb.h"
|
#include "pb/response_list_users.pb.h"
|
||||||
#include "pb/response_get_games_of_user.pb.h"
|
#include "pb/response_get_games_of_user.pb.h"
|
||||||
#include "pb/response_get_user_info.pb.h"
|
#include "pb/response_get_user_info.pb.h"
|
||||||
|
@ -145,8 +144,6 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co
|
||||||
switch ((SessionCommand::SessionCommandType) num) {
|
switch ((SessionCommand::SessionCommandType) num) {
|
||||||
case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
|
case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
|
||||||
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
|
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
|
||||||
case SessionCommand::REGISTER: resp = cmdRegisterAccount(sc.GetExtension(Command_Register::ext), rc); break;
|
|
||||||
case SessionCommand::ACTIVATE: resp = cmdActivateAccount(sc.GetExtension(Command_Activate::ext), rc); break;
|
|
||||||
case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
|
case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
|
||||||
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
|
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
|
||||||
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
||||||
|
@ -421,64 +418,6 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc)
|
|
||||||
{
|
|
||||||
qDebug() << "Got register command: " << QString::fromStdString(cmd.user_name());
|
|
||||||
|
|
||||||
QString banReason;
|
|
||||||
int banSecondsRemaining;
|
|
||||||
RegistrationResult result =
|
|
||||||
server->registerUserAccount(
|
|
||||||
this->getAddress(),
|
|
||||||
cmd,
|
|
||||||
banReason,
|
|
||||||
banSecondsRemaining);
|
|
||||||
qDebug() << "Register command result:" << result;
|
|
||||||
|
|
||||||
switch (result) {
|
|
||||||
case RegistrationDisabled:
|
|
||||||
return Response::RespRegistrationDisabled;
|
|
||||||
case Accepted:
|
|
||||||
return Response::RespRegistrationAccepted;
|
|
||||||
case AcceptedNeedsActivation:
|
|
||||||
// TODO SEND EMAIL WITH TOKEN TO THE USER
|
|
||||||
return Response::RespRegistrationAcceptedNeedsActivation;
|
|
||||||
case UserAlreadyExists:
|
|
||||||
return Response::RespUserAlreadyExists;
|
|
||||||
case EmailRequired:
|
|
||||||
return Response::RespEmailRequiredToRegister;
|
|
||||||
case TooManyRequests:
|
|
||||||
return Response::RespTooManyRequests;
|
|
||||||
case PasswordTooShort:
|
|
||||||
return Response::RespPasswordTooShort;
|
|
||||||
case InvalidUsername:
|
|
||||||
return Response::RespUsernameInvalid;
|
|
||||||
case Failed:
|
|
||||||
return Response::RespRegistrationFailed;
|
|
||||||
case ClientIsBanned:
|
|
||||||
Response_Register *re = new Response_Register;
|
|
||||||
re->set_denied_reason_str(banReason.toStdString());
|
|
||||||
if (banSecondsRemaining != 0)
|
|
||||||
re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsRemaining).toTime_t());
|
|
||||||
rc.setResponseExtension(re);
|
|
||||||
return Response::RespUserIsBanned;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response::RespInvalidCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /*rc*/)
|
|
||||||
{
|
|
||||||
if(server->activateUserAccount(cmd))
|
|
||||||
{
|
|
||||||
qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name());
|
|
||||||
return Response::RespActivationAccepted;
|
|
||||||
} else {
|
|
||||||
qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name());
|
|
||||||
return Response::RespActivationFailed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
|
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (authState == NotLoggedIn)
|
if (authState == NotLoggedIn)
|
||||||
|
|
|
@ -60,8 +60,6 @@ private:
|
||||||
|
|
||||||
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
|
||||||
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
|
|
||||||
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
||||||
|
@ -101,6 +99,7 @@ public:
|
||||||
void sendProtocolItem(const SessionEvent &item);
|
void sendProtocolItem(const SessionEvent &item);
|
||||||
void sendProtocolItem(const GameEventContainer &item);
|
void sendProtocolItem(const GameEventContainer &item);
|
||||||
void sendProtocolItem(const RoomEvent &item);
|
void sendProtocolItem(const RoomEvent &item);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,18 @@ SET(servatrice_SOURCES
|
||||||
src/settingscache.cpp
|
src/settingscache.cpp
|
||||||
src/isl_interface.cpp
|
src/isl_interface.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
|
src/smtp/emailaddress.cpp
|
||||||
|
src/smtp/mimeattachment.cpp
|
||||||
|
src/smtp/mimecontentformatter.cpp
|
||||||
|
src/smtp/mimefile.cpp
|
||||||
|
src/smtp/mimehtml.cpp
|
||||||
|
src/smtp/mimeinlinefile.cpp
|
||||||
|
src/smtp/mimemessage.cpp
|
||||||
|
src/smtp/mimemultipart.cpp
|
||||||
|
src/smtp/mimepart.cpp
|
||||||
|
src/smtp/mimetext.cpp
|
||||||
|
src/smtp/quotedprintable.cpp
|
||||||
|
src/smtp/smtpclient.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(servatrice_RESOURCES servatrice.qrc)
|
set(servatrice_RESOURCES servatrice.qrc)
|
||||||
|
|
|
@ -65,6 +65,39 @@ regonly=0
|
||||||
; to get their account activated. Default true.
|
; to get their account activated. Default true.
|
||||||
;requireemail=true
|
;requireemail=true
|
||||||
|
|
||||||
|
[smtp]
|
||||||
|
|
||||||
|
; Connectin type: currently supported method are "tcp", "ssl" and "tls"
|
||||||
|
connection=tcp
|
||||||
|
|
||||||
|
; Auth type: currently supported method are "plain" and "login"
|
||||||
|
auth=plain
|
||||||
|
|
||||||
|
; Hostname or IP addres of the smtp server
|
||||||
|
host=localhost
|
||||||
|
|
||||||
|
; Smtp port number of the smtp server. Usual values are 25 or 587 for tcp, 465 for ssl
|
||||||
|
port=25
|
||||||
|
|
||||||
|
; Username: this typically matches the "from" email address
|
||||||
|
username=root@localhost
|
||||||
|
|
||||||
|
; Password for the username
|
||||||
|
password=foobar
|
||||||
|
|
||||||
|
; Sender email address: the "from" email address
|
||||||
|
email=root@localhost
|
||||||
|
|
||||||
|
; Sender email name
|
||||||
|
name="Cockatrice server"
|
||||||
|
|
||||||
|
; Email subject
|
||||||
|
subject="Cockatrice server account activation token"
|
||||||
|
|
||||||
|
; Email body. You can use these tags here: %username %token
|
||||||
|
; They will be substituted with the actual values in the email
|
||||||
|
;
|
||||||
|
body="Hi %username, thank our for registering on our Cockatrice server\r\nHere's the activation token you need to supply for activatin your account:\r\n\r\n%token\r\n\r\nHappy gaming!"
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
|
|
||||||
|
|
|
@ -160,8 +160,8 @@ bool Servatrice::initServer()
|
||||||
authenticationMethod = AuthenticationNone;
|
authenticationMethod = AuthenticationNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
|
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
|
||||||
requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
|
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
|
||||||
|
|
||||||
qDebug() << "Registration enabled: " << registrationEnabled;
|
qDebug() << "Registration enabled: " << registrationEnabled;
|
||||||
if (registrationEnabled)
|
if (registrationEnabled)
|
||||||
|
|
|
@ -111,13 +111,13 @@ bool Servatrice_DatabaseInterface::getRequireRegistration()
|
||||||
return settingsCache->value("authentication/regonly", 0).toBool();
|
return settingsCache->value("authentication/regonly", 0).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, bool active)
|
bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active)
|
||||||
{
|
{
|
||||||
if (!checkSql())
|
if (!checkSql())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
|
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
|
||||||
QString token = PasswordHasher::generateActivationToken();
|
token = active ? QString() : PasswordHasher::generateActivationToken();
|
||||||
|
|
||||||
QSqlQuery *query = prepareQuery("insert into {prefix}_users "
|
QSqlQuery *query = prepareQuery("insert into {prefix}_users "
|
||||||
"(name, realname, gender, password_sha512, email, country, registrationDate, active, token) "
|
"(name, realname, gender, password_sha512, email, country, registrationDate, active, token) "
|
||||||
|
|
|
@ -25,9 +25,7 @@ private:
|
||||||
bool checkUserIsNameBanned(QString const &userName, QString &banReason, int &banSecondsRemaining);
|
bool checkUserIsNameBanned(QString const &userName, QString &banReason, int &banSecondsRemaining);
|
||||||
QChar getGenderChar(ServerInfo_User_Gender const &gender);
|
QChar getGenderChar(ServerInfo_User_Gender const &gender);
|
||||||
protected:
|
protected:
|
||||||
bool usernameIsValid(const QString &user);
|
|
||||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft);
|
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft);
|
||||||
bool checkUserIsBanned(const QString &ipAddress, const QString &userName, QString &banReason, int &banSecondsRemaining);
|
|
||||||
public slots:
|
public slots:
|
||||||
void initDatabase(const QSqlDatabase &_sqlDatabase);
|
void initDatabase(const QSqlDatabase &_sqlDatabase);
|
||||||
public:
|
public:
|
||||||
|
@ -62,9 +60,11 @@ public:
|
||||||
void lockSessionTables();
|
void lockSessionTables();
|
||||||
void unlockSessionTables();
|
void unlockSessionTables();
|
||||||
bool userSessionExists(const QString &userName);
|
bool userSessionExists(const QString &userName);
|
||||||
|
bool usernameIsValid(const QString &user);
|
||||||
|
bool checkUserIsBanned(const QString &ipAddress, const QString &userName, QString &banReason, int &banSecondsRemaining);
|
||||||
|
|
||||||
bool getRequireRegistration();
|
bool getRequireRegistration();
|
||||||
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, bool active = false);
|
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active = false);
|
||||||
bool activateUser(const QString &userName, const QString &token);
|
bool activateUser(const QString &userName, const QString &token);
|
||||||
|
|
||||||
void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName);
|
void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName);
|
||||||
|
|
|
@ -51,12 +51,15 @@
|
||||||
#include "pb/response_deck_list.pb.h"
|
#include "pb/response_deck_list.pb.h"
|
||||||
#include "pb/response_deck_download.pb.h"
|
#include "pb/response_deck_download.pb.h"
|
||||||
#include "pb/response_deck_upload.pb.h"
|
#include "pb/response_deck_upload.pb.h"
|
||||||
|
#include "pb/response_register.pb.h"
|
||||||
#include "pb/response_replay_list.pb.h"
|
#include "pb/response_replay_list.pb.h"
|
||||||
#include "pb/response_replay_download.pb.h"
|
#include "pb/response_replay_download.pb.h"
|
||||||
#include "pb/serverinfo_replay.pb.h"
|
#include "pb/serverinfo_replay.pb.h"
|
||||||
#include "pb/serverinfo_user.pb.h"
|
#include "pb/serverinfo_user.pb.h"
|
||||||
#include "pb/serverinfo_deckstorage.pb.h"
|
#include "pb/serverinfo_deckstorage.pb.h"
|
||||||
|
|
||||||
|
#include "smtp/SmtpMime"
|
||||||
|
|
||||||
#include "version_string.h"
|
#include "version_string.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -267,6 +270,8 @@ Response::ResponseCode ServerSocketInterface::processExtendedSessionCommand(int
|
||||||
case SessionCommand::REPLAY_DOWNLOAD: return cmdReplayDownload(cmd.GetExtension(Command_ReplayDownload::ext), rc);
|
case SessionCommand::REPLAY_DOWNLOAD: return cmdReplayDownload(cmd.GetExtension(Command_ReplayDownload::ext), rc);
|
||||||
case SessionCommand::REPLAY_MODIFY_MATCH: return cmdReplayModifyMatch(cmd.GetExtension(Command_ReplayModifyMatch::ext), rc);
|
case SessionCommand::REPLAY_MODIFY_MATCH: return cmdReplayModifyMatch(cmd.GetExtension(Command_ReplayModifyMatch::ext), rc);
|
||||||
case SessionCommand::REPLAY_DELETE_MATCH: return cmdReplayDeleteMatch(cmd.GetExtension(Command_ReplayDeleteMatch::ext), rc);
|
case SessionCommand::REPLAY_DELETE_MATCH: return cmdReplayDeleteMatch(cmd.GetExtension(Command_ReplayDeleteMatch::ext), rc);
|
||||||
|
case SessionCommand::REGISTER: return cmdRegisterAccount(cmd.GetExtension(Command_Register::ext), rc); break;
|
||||||
|
case SessionCommand::ACTIVATE: return cmdActivateAccount(cmd.GetExtension(Command_Activate::ext), rc); break;
|
||||||
default: return Response::RespFunctionNotAllowed;
|
default: return Response::RespFunctionNotAllowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -764,6 +769,179 @@ Response::ResponseCode ServerSocketInterface::cmdBanFromServer(const Command_Ban
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Response::ResponseCode ServerSocketInterface::cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc)
|
||||||
|
{
|
||||||
|
QString userName = QString::fromStdString(cmd.user_name());
|
||||||
|
qDebug() << "Got register command: " << userName;
|
||||||
|
|
||||||
|
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
|
||||||
|
if (!registrationEnabled)
|
||||||
|
return Response::RespRegistrationDisabled;
|
||||||
|
|
||||||
|
QString emailAddress = QString::fromStdString(cmd.email());
|
||||||
|
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
|
||||||
|
if (requireEmailForRegistration)
|
||||||
|
{
|
||||||
|
QRegExp rx("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}\\b");
|
||||||
|
if(emailAddress.isEmpty() || !rx.exactMatch(emailAddress))
|
||||||
|
return Response::RespEmailRequiredToRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move this method outside of the db interface
|
||||||
|
if (!sqlInterface->usernameIsValid(userName))
|
||||||
|
return Response::RespUsernameInvalid;
|
||||||
|
|
||||||
|
if(sqlInterface->userExists(userName))
|
||||||
|
return Response::RespUserAlreadyExists;
|
||||||
|
|
||||||
|
QString banReason;
|
||||||
|
int banSecondsRemaining;
|
||||||
|
if (sqlInterface->checkUserIsBanned(this->getAddress(), userName, banReason, banSecondsRemaining))
|
||||||
|
{
|
||||||
|
Response_Register *re = new Response_Register;
|
||||||
|
re->set_denied_reason_str(banReason.toStdString());
|
||||||
|
if (banSecondsRemaining != 0)
|
||||||
|
re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsRemaining).toTime_t());
|
||||||
|
rc.setResponseExtension(re);
|
||||||
|
return Response::RespUserIsBanned;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooManyRegistrationAttempts(this->getAddress()))
|
||||||
|
return Response::RespTooManyRequests;
|
||||||
|
|
||||||
|
QString realName = QString::fromStdString(cmd.real_name());
|
||||||
|
ServerInfo_User_Gender gender = cmd.gender();
|
||||||
|
QString country = QString::fromStdString(cmd.country());
|
||||||
|
QString password = QString::fromStdString(cmd.password());
|
||||||
|
|
||||||
|
// TODO make this configurable?
|
||||||
|
if(password.length() < 6)
|
||||||
|
return Response::RespPasswordTooShort;
|
||||||
|
|
||||||
|
QString token;
|
||||||
|
bool regSucceeded = sqlInterface->registerUser(userName, realName, gender, password, emailAddress, country, token, !requireEmailForRegistration);
|
||||||
|
|
||||||
|
if(regSucceeded)
|
||||||
|
{
|
||||||
|
qDebug() << "Accepted register command for user: " << userName;
|
||||||
|
if(requireEmailForRegistration)
|
||||||
|
{
|
||||||
|
// TODO call a slot on another thread to send email
|
||||||
|
sendActivationTokenMail(userName, emailAddress, token);
|
||||||
|
return Response::RespRegistrationAcceptedNeedsActivation;
|
||||||
|
} else {
|
||||||
|
return Response::RespRegistrationAccepted;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Response::RespRegistrationFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerSocketInterface::sendActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token)
|
||||||
|
{
|
||||||
|
QString tmp = settingsCache->value("smtp/connection", "tcp").toString();
|
||||||
|
SmtpClient::ConnectionType connection = SmtpClient::TcpConnection;
|
||||||
|
if(tmp == "ssl")
|
||||||
|
connection = SmtpClient::SslConnection;
|
||||||
|
else if(tmp == "tls")
|
||||||
|
connection = SmtpClient::TlsConnection;
|
||||||
|
|
||||||
|
tmp = settingsCache->value("smtp/auth", "plain").toString();
|
||||||
|
SmtpClient::AuthMethod auth = SmtpClient::AuthPlain;
|
||||||
|
if(tmp == "login")
|
||||||
|
auth = SmtpClient::AuthLogin;
|
||||||
|
|
||||||
|
QString host = settingsCache->value("smtp/host", "localhost").toString();
|
||||||
|
int port = settingsCache->value("smtp/port", 25).toInt();
|
||||||
|
QString username = settingsCache->value("smtp/username", "").toString();
|
||||||
|
QString password = settingsCache->value("smtp/password", "").toString();
|
||||||
|
QString email = settingsCache->value("smtp/email", "").toString();
|
||||||
|
QString name = settingsCache->value("smtp/name", "").toString();
|
||||||
|
QString subject = settingsCache->value("smtp/subject", "").toString();
|
||||||
|
QString body = settingsCache->value("smtp/body", "").toString();
|
||||||
|
|
||||||
|
if(email.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "[MAIL] Missing email field" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(body.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "[MAIL] Missing body field" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(recipient.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "[MAIL] Missing recipient field" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(token.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "[MAIL] Missing token field" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmtpClient smtp(host, port, connection);
|
||||||
|
smtp.setUser(username);
|
||||||
|
smtp.setPassword(password);
|
||||||
|
smtp.setAuthMethod(auth);
|
||||||
|
|
||||||
|
MimeMessage message;
|
||||||
|
EmailAddress sender(email, name);
|
||||||
|
message.setSender(&sender);
|
||||||
|
EmailAddress to(recipient, nickname);
|
||||||
|
message.addRecipient(&to);
|
||||||
|
message.setSubject(subject);
|
||||||
|
|
||||||
|
MimeText text;
|
||||||
|
text.setText(body.replace("%username", nickname).replace("%token", token));
|
||||||
|
message.addPart(&text);
|
||||||
|
|
||||||
|
// Now we can send the mail
|
||||||
|
|
||||||
|
if (!smtp.connectToHost()) {
|
||||||
|
qDebug() << "[MAIL] Failed to connect to host" << host << "on port" << port;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smtp.login()) {
|
||||||
|
qDebug() << "[MAIL] Failed to login as " << username;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smtp.sendMail(message)) {
|
||||||
|
qDebug() << "[MAIL] Failed to send mail to " << recipient;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
smtp.quit();
|
||||||
|
qDebug() << "[MAIL] Sent activation email to " << recipient << " for nickname " << nickname;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerSocketInterface::tooManyRegistrationAttempts(const QString &ipAddress)
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
Q_UNUSED(ipAddress);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Response::ResponseCode ServerSocketInterface::cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /*rc*/)
|
||||||
|
{
|
||||||
|
QString userName = QString::fromStdString(cmd.user_name());
|
||||||
|
QString token = QString::fromStdString(cmd.token());
|
||||||
|
|
||||||
|
if(sqlInterface->activateUser(userName, token))
|
||||||
|
{
|
||||||
|
qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name());
|
||||||
|
return Response::RespActivationAccepted;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name());
|
||||||
|
return Response::RespActivationFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ADMIN FUNCTIONS.
|
// ADMIN FUNCTIONS.
|
||||||
// Permission is checked by the calling function.
|
// Permission is checked by the calling function.
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ signals:
|
||||||
void outputQueueChanged();
|
void outputQueueChanged();
|
||||||
protected:
|
protected:
|
||||||
void logDebugMessage(const QString &message);
|
void logDebugMessage(const QString &message);
|
||||||
|
bool tooManyRegistrationAttempts(const QString &ipAddress);
|
||||||
private:
|
private:
|
||||||
QMutex outputQueueMutex;
|
QMutex outputQueueMutex;
|
||||||
Servatrice *servatrice;
|
Servatrice *servatrice;
|
||||||
|
@ -91,10 +92,14 @@ private:
|
||||||
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
||||||
|
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
||||||
|
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
|
||||||
|
|
||||||
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
|
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc);
|
Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc);
|
||||||
|
|
||||||
|
bool sendActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token);
|
||||||
public:
|
public:
|
||||||
ServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
ServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent = 0);
|
||||||
~ServerSocketInterface();
|
~ServerSocketInterface();
|
||||||
|
|
31
servatrice/src/smtp/SmtpMime
Normal file
31
servatrice/src/smtp/SmtpMime
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SMTPMIME_H
|
||||||
|
#define SMTPMIME_H
|
||||||
|
|
||||||
|
#include "smtpclient.h"
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include "mimehtml.h"
|
||||||
|
#include "mimeattachment.h"
|
||||||
|
#include "mimemessage.h"
|
||||||
|
#include "mimetext.h"
|
||||||
|
#include "mimeinlinefile.h"
|
||||||
|
#include "mimefile.h"
|
||||||
|
|
||||||
|
#endif // SMTPMIME_H
|
60
servatrice/src/smtp/emailaddress.cpp
Normal file
60
servatrice/src/smtp/emailaddress.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "emailaddress.h"
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
EmailAddress::EmailAddress(const QString & address, const QString & name)
|
||||||
|
{
|
||||||
|
this->address = address;
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmailAddress::~EmailAddress()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void EmailAddress::setName(const QString & name)
|
||||||
|
{
|
||||||
|
this->name = name;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmailAddress::setAddress(const QString & address)
|
||||||
|
{
|
||||||
|
this->address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & EmailAddress::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & EmailAddress::getAddress() const
|
||||||
|
{
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
61
servatrice/src/smtp/emailaddress.h
Normal file
61
servatrice/src/smtp/emailaddress.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMAILADDRESS_H
|
||||||
|
#define EMAILADDRESS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT EmailAddress : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
EmailAddress();
|
||||||
|
EmailAddress(const QString & address, const QString & name="");
|
||||||
|
|
||||||
|
~EmailAddress();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
void setName(const QString & name);
|
||||||
|
void setAddress(const QString & address);
|
||||||
|
|
||||||
|
const QString & getName() const;
|
||||||
|
const QString & getAddress() const;
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* [3] Private members */
|
||||||
|
|
||||||
|
QString name;
|
||||||
|
QString address;
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EMAILADDRESS_H
|
50
servatrice/src/smtp/mimeattachment.cpp
Normal file
50
servatrice/src/smtp/mimeattachment.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimeattachment.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeAttachment::MimeAttachment(QFile *file)
|
||||||
|
: MimeFile(file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
MimeAttachment::MimeAttachment(const QByteArray& stream, const QString& fileName): MimeFile(stream, fileName)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeAttachment::~MimeAttachment()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Protected methods */
|
||||||
|
|
||||||
|
void MimeAttachment::prepare()
|
||||||
|
{
|
||||||
|
this->header += "Content-disposition: attachment\r\n";
|
||||||
|
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimeFile::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
51
servatrice/src/smtp/mimeattachment.h
Normal file
51
servatrice/src/smtp/mimeattachment.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEATTACHMENT_H
|
||||||
|
#define MIMEATTACHMENT_H
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include "mimefile.h"
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeAttachment : public MimeFile
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeAttachment(QFile* file);
|
||||||
|
MimeAttachment(const QByteArray& stream, const QString& fileName);
|
||||||
|
|
||||||
|
~MimeAttachment();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [2] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEATTACHMENT_H
|
66
servatrice/src/smtp/mimecontentformatter.cpp
Normal file
66
servatrice/src/smtp/mimecontentformatter.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimecontentformatter.h"
|
||||||
|
|
||||||
|
MimeContentFormatter::MimeContentFormatter(int max_length) :
|
||||||
|
max_length(max_length)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QString MimeContentFormatter::format(const QString &content, bool quotedPrintable) const {
|
||||||
|
|
||||||
|
QString out;
|
||||||
|
|
||||||
|
int chars = 0;
|
||||||
|
for (int i = 0; i < content.length() ; ++i) {
|
||||||
|
chars++;
|
||||||
|
if (!quotedPrintable) {
|
||||||
|
if (chars > max_length) {
|
||||||
|
out.append("\r\n");
|
||||||
|
chars = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (content[i] == '\n') { // new line
|
||||||
|
out.append(content[i]);
|
||||||
|
chars = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((chars > max_length - 1)
|
||||||
|
|| ((content[i] == '=') && (chars > max_length - 3) )) {
|
||||||
|
out.append('=');
|
||||||
|
out.append("\r\n");
|
||||||
|
chars = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
out.append(content[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeContentFormatter::setMaxLength(int l) {
|
||||||
|
max_length = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MimeContentFormatter::getMaxLength() const {
|
||||||
|
return max_length;
|
||||||
|
}
|
43
servatrice/src/smtp/mimecontentformatter.h
Normal file
43
servatrice/src/smtp/mimecontentformatter.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMECONTENTFORMATTER_H
|
||||||
|
#define MIMECONTENTFORMATTER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeContentFormatter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MimeContentFormatter (int max_length = 76);
|
||||||
|
|
||||||
|
void setMaxLength(int l);
|
||||||
|
int getMaxLength() const;
|
||||||
|
|
||||||
|
QString format(const QString &content, bool quotedPrintable = false) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int max_length;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMECONTENTFORMATTER_H
|
70
servatrice/src/smtp/mimefile.cpp
Normal file
70
servatrice/src/smtp/mimefile.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimefile.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeFile::MimeFile(QFile *file)
|
||||||
|
{
|
||||||
|
this->file = file;
|
||||||
|
this->cType = "application/octet-stream";
|
||||||
|
this->cName = QFileInfo(*file).fileName();
|
||||||
|
this->cEncoding = Base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeFile::MimeFile(const QByteArray& stream, const QString& fileName)
|
||||||
|
{
|
||||||
|
this->cEncoding = Base64;
|
||||||
|
this->cType = "application/octet-stream";
|
||||||
|
this->file = 0;
|
||||||
|
this->cName = fileName;
|
||||||
|
this->content = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeFile::~MimeFile()
|
||||||
|
{
|
||||||
|
if (file)
|
||||||
|
delete file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and setters */
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Protected methods */
|
||||||
|
|
||||||
|
void MimeFile::prepare()
|
||||||
|
{
|
||||||
|
if (this->file)
|
||||||
|
{
|
||||||
|
file->open(QIODevice::ReadOnly);
|
||||||
|
this->content = file->readAll();
|
||||||
|
file->close();
|
||||||
|
}
|
||||||
|
/* !!! IMPORTANT !!!! */
|
||||||
|
MimePart::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
62
servatrice/src/smtp/mimefile.h
Normal file
62
servatrice/src/smtp/mimefile.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEFILE_H
|
||||||
|
#define MIMEFILE_H
|
||||||
|
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeFile : public MimePart
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeFile(const QByteArray& stream, const QString& fileName);
|
||||||
|
MimeFile(QFile *f);
|
||||||
|
~MimeFile();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [3] Protected members */
|
||||||
|
|
||||||
|
QFile* file;
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEFILE_H
|
57
servatrice/src/smtp/mimehtml.cpp
Normal file
57
servatrice/src/smtp/mimehtml.cpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimehtml.h"
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeHtml::MimeHtml(const QString &html) : MimeText(html)
|
||||||
|
{
|
||||||
|
this->cType = "text/html";
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeHtml::~MimeHtml() {}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void MimeHtml::setHtml(const QString & html)
|
||||||
|
{
|
||||||
|
this->text = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimeHtml::getHtml() const
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Protected methods */
|
||||||
|
|
||||||
|
void MimeHtml::prepare()
|
||||||
|
{
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimeText::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
61
servatrice/src/smtp/mimehtml.h
Normal file
61
servatrice/src/smtp/mimehtml.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEHTML_H
|
||||||
|
#define MIMEHTML_H
|
||||||
|
|
||||||
|
#include "mimetext.h"
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeHtml : public MimeText
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeHtml(const QString &html = "");
|
||||||
|
~MimeHtml();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void setHtml(const QString & html);
|
||||||
|
|
||||||
|
const QString& getHtml() const;
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [3] Protected members */
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEHTML_H
|
52
servatrice/src/smtp/mimeinlinefile.cpp
Normal file
52
servatrice/src/smtp/mimeinlinefile.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimeinlinefile.h"
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeInlineFile::MimeInlineFile(QFile *f)
|
||||||
|
: MimeFile(f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeInlineFile::~MimeInlineFile()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Protected methods */
|
||||||
|
|
||||||
|
void MimeInlineFile::prepare()
|
||||||
|
{
|
||||||
|
this->header += "Content-Disposition: inline\r\n";
|
||||||
|
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimeFile::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
56
servatrice/src/smtp/mimeinlinefile.h
Normal file
56
servatrice/src/smtp/mimeinlinefile.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEINLINEFILE_H
|
||||||
|
#define MIMEINLINEFILE_H
|
||||||
|
|
||||||
|
#include "mimefile.h"
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeInlineFile : public MimeFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeInlineFile(QFile *f);
|
||||||
|
~MimeInlineFile();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [3] Protected members */
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEINLINEFILE_H
|
257
servatrice/src/smtp/mimemessage.cpp
Normal file
257
servatrice/src/smtp/mimemessage.cpp
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimemessage.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include "quotedprintable.h"
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
MimeMessage::MimeMessage(bool createAutoMimeContent) :
|
||||||
|
hEncoding(MimePart::_8Bit)
|
||||||
|
{
|
||||||
|
if (createAutoMimeContent)
|
||||||
|
this->content = new MimeMultiPart();
|
||||||
|
|
||||||
|
autoMimeContentCreated = createAutoMimeContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeMessage::~MimeMessage()
|
||||||
|
{
|
||||||
|
if (this->autoMimeContentCreated)
|
||||||
|
{
|
||||||
|
this->autoMimeContentCreated = false;
|
||||||
|
delete (this->content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
MimePart& MimeMessage::getContent() {
|
||||||
|
return *content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::setContent(MimePart *content) {
|
||||||
|
if (this->autoMimeContentCreated)
|
||||||
|
{
|
||||||
|
this->autoMimeContentCreated = false;
|
||||||
|
delete (this->content);
|
||||||
|
}
|
||||||
|
this->content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::setSender(EmailAddress* e)
|
||||||
|
{
|
||||||
|
this->sender = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::addRecipient(EmailAddress* rcpt, RecipientType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case To:
|
||||||
|
recipientsTo << rcpt;
|
||||||
|
break;
|
||||||
|
case Cc:
|
||||||
|
recipientsCc << rcpt;
|
||||||
|
break;
|
||||||
|
case Bcc:
|
||||||
|
recipientsBcc << rcpt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::addTo(EmailAddress* rcpt) {
|
||||||
|
this->recipientsTo << rcpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::addCc(EmailAddress* rcpt) {
|
||||||
|
this->recipientsCc << rcpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::addBcc(EmailAddress* rcpt) {
|
||||||
|
this->recipientsBcc << rcpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::setSubject(const QString & subject)
|
||||||
|
{
|
||||||
|
this->subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::addPart(MimePart *part)
|
||||||
|
{
|
||||||
|
if (typeid(*content) == typeid(MimeMultiPart)) {
|
||||||
|
((MimeMultiPart*) content)->addPart(part);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc)
|
||||||
|
{
|
||||||
|
this->hEncoding = hEnc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EmailAddress & MimeMessage::getSender() const
|
||||||
|
{
|
||||||
|
return *sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<EmailAddress*> & MimeMessage::getRecipients(RecipientType type) const
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case To:
|
||||||
|
return recipientsTo;
|
||||||
|
case Cc:
|
||||||
|
return recipientsCc;
|
||||||
|
case Bcc:
|
||||||
|
return recipientsBcc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimeMessage::getSubject() const
|
||||||
|
{
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<MimePart*> & MimeMessage::getParts() const
|
||||||
|
{
|
||||||
|
if (typeid(*content) == typeid(MimeMultiPart)) {
|
||||||
|
return ((MimeMultiPart*) content)->getParts();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QList<MimePart*> *res = new QList<MimePart*>();
|
||||||
|
res->append(content);
|
||||||
|
return *res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public Methods */
|
||||||
|
|
||||||
|
QString MimeMessage::toString()
|
||||||
|
{
|
||||||
|
QString mime;
|
||||||
|
|
||||||
|
/* =========== MIME HEADER ============ */
|
||||||
|
|
||||||
|
/* ---------- Sender / From ----------- */
|
||||||
|
mime = "From:";
|
||||||
|
if (sender->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append(sender->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(sender->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + sender->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + sender->getAddress() + ">\r\n";
|
||||||
|
/* ---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Recipients / To ---------- */
|
||||||
|
mime += "To:";
|
||||||
|
QList<EmailAddress*>::iterator it; int i;
|
||||||
|
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i)
|
||||||
|
{
|
||||||
|
if (i != 0) { mime += ","; }
|
||||||
|
|
||||||
|
if ((*it)->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append((*it)->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append((*it)->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + (*it)->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + (*it)->getAddress() + ">";
|
||||||
|
}
|
||||||
|
mime += "\r\n";
|
||||||
|
/* ---------------------------------- */
|
||||||
|
|
||||||
|
/* ------- Recipients / Cc ---------- */
|
||||||
|
if (recipientsCc.size() != 0) {
|
||||||
|
mime += "Cc:";
|
||||||
|
}
|
||||||
|
for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i)
|
||||||
|
{
|
||||||
|
if (i != 0) { mime += ","; }
|
||||||
|
|
||||||
|
if ((*it)->getName() != "")
|
||||||
|
{
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += " =?utf-8?B?" + QByteArray().append((*it)->getName()).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append((*it)->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += " " + (*it)->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mime += " <" + (*it)->getAddress() + ">";
|
||||||
|
}
|
||||||
|
if (recipientsCc.size() != 0) {
|
||||||
|
mime += "\r\n";
|
||||||
|
}
|
||||||
|
/* ---------------------------------- */
|
||||||
|
|
||||||
|
/* ------------ Subject ------------- */
|
||||||
|
mime += "Subject: ";
|
||||||
|
|
||||||
|
|
||||||
|
switch (hEncoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
mime += "=?utf-8?B?" + QByteArray().append(subject).toBase64() + "?=";
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
mime += "=?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(subject)).replace(' ', "_").replace(':',"=3A") + "?=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mime += subject;
|
||||||
|
}
|
||||||
|
/* ---------------------------------- */
|
||||||
|
|
||||||
|
mime += "\r\n";
|
||||||
|
mime += "MIME-Version: 1.0\r\n";
|
||||||
|
|
||||||
|
mime += content->toString();
|
||||||
|
return mime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
92
servatrice/src/smtp/mimemessage.h
Normal file
92
servatrice/src/smtp/mimemessage.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEMESSAGE_H
|
||||||
|
#define MIMEMESSAGE_H
|
||||||
|
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include "mimemultipart.h"
|
||||||
|
#include "emailaddress.h"
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeMessage : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum RecipientType {
|
||||||
|
To, // primary
|
||||||
|
Cc, // carbon copy
|
||||||
|
Bcc // blind carbon copy
|
||||||
|
};
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeMessage(bool createAutoMimeConent = true);
|
||||||
|
~MimeMessage();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void setSender(EmailAddress* e);
|
||||||
|
void addRecipient(EmailAddress* rcpt, RecipientType type = To);
|
||||||
|
void addTo(EmailAddress* rcpt);
|
||||||
|
void addCc(EmailAddress* rcpt);
|
||||||
|
void addBcc(EmailAddress* rcpt);
|
||||||
|
void setSubject(const QString & subject);
|
||||||
|
void addPart(MimePart* part);
|
||||||
|
|
||||||
|
void setHeaderEncoding(MimePart::Encoding);
|
||||||
|
|
||||||
|
const EmailAddress & getSender() const;
|
||||||
|
const QList<EmailAddress*> & getRecipients(RecipientType type = To) const;
|
||||||
|
const QString & getSubject() const;
|
||||||
|
const QList<MimePart*> & getParts() const;
|
||||||
|
|
||||||
|
MimePart& getContent();
|
||||||
|
void setContent(MimePart *content);
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
virtual QString toString();
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [4] Protected members */
|
||||||
|
|
||||||
|
EmailAddress* sender;
|
||||||
|
QList<EmailAddress*> recipientsTo, recipientsCc, recipientsBcc;
|
||||||
|
QString subject;
|
||||||
|
MimePart *content;
|
||||||
|
bool autoMimeContentCreated;
|
||||||
|
|
||||||
|
MimePart::Encoding hEncoding;
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEMESSAGE_H
|
78
servatrice/src/smtp/mimemultipart.cpp
Normal file
78
servatrice/src/smtp/mimemultipart.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimemultipart.h"
|
||||||
|
#include <QTime>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
|
const QString MULTI_PART_NAMES[] = {
|
||||||
|
"multipart/mixed", // Mixed
|
||||||
|
"multipart/digest", // Digest
|
||||||
|
"multipart/alternative", // Alternative
|
||||||
|
"multipart/related", // Related
|
||||||
|
"multipart/report", // Report
|
||||||
|
"multipart/signed", // Signed
|
||||||
|
"multipart/encrypted" // Encrypted
|
||||||
|
};
|
||||||
|
|
||||||
|
MimeMultiPart::MimeMultiPart(MultiPartType type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
this->cType = MULTI_PART_NAMES[this->type];
|
||||||
|
this->cEncoding = _8Bit;
|
||||||
|
|
||||||
|
QCryptographicHash md5(QCryptographicHash::Md5);
|
||||||
|
md5.addData(QByteArray().append(qrand()));
|
||||||
|
cBoundary = md5.result().toHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeMultiPart::~MimeMultiPart() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMultiPart::addPart(MimePart *part) {
|
||||||
|
parts.append(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<MimePart*> & MimeMultiPart::getParts() const {
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMultiPart::prepare() {
|
||||||
|
QList<MimePart*>::iterator it;
|
||||||
|
|
||||||
|
content = "";
|
||||||
|
for (it = parts.begin(); it != parts.end(); it++) {
|
||||||
|
content += "--" + cBoundary + "\r\n";
|
||||||
|
(*it)->prepare();
|
||||||
|
content += (*it)->toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
content += "--" + cBoundary + "--\r\n";
|
||||||
|
|
||||||
|
MimePart::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMultiPart::setMimeType(const MultiPartType type) {
|
||||||
|
this->type = type;
|
||||||
|
this->cType = MULTI_PART_NAMES[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const {
|
||||||
|
return type;
|
||||||
|
}
|
75
servatrice/src/smtp/mimemultipart.h
Normal file
75
servatrice/src/smtp/mimemultipart.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEMULTIPART_H
|
||||||
|
#define MIMEMULTIPART_H
|
||||||
|
|
||||||
|
#include "mimepart.h"
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeMultiPart : public MimePart
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [0] Enums */
|
||||||
|
enum MultiPartType {
|
||||||
|
Mixed = 0, // RFC 2046, section 5.1.3
|
||||||
|
Digest = 1, // RFC 2046, section 5.1.5
|
||||||
|
Alternative = 2, // RFC 2046, section 5.1.4
|
||||||
|
Related = 3, // RFC 2387
|
||||||
|
Report = 4, // RFC 6522
|
||||||
|
Signed = 5, // RFC 1847, section 2.1
|
||||||
|
Encrypted = 6 // RFC 1847, section 2.2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* [0] --- */
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
MimeMultiPart(const MultiPartType type = Related);
|
||||||
|
|
||||||
|
~MimeMultiPart();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void setMimeType(const MultiPartType type);
|
||||||
|
MultiPartType getMimeType() const;
|
||||||
|
|
||||||
|
const QList<MimePart*> & getParts() const;
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
void addPart(MimePart *part);
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QList< MimePart* > parts;
|
||||||
|
|
||||||
|
MultiPartType type;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEMULTIPART_H
|
214
servatrice/src/smtp/mimepart.cpp
Normal file
214
servatrice/src/smtp/mimepart.cpp
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include "quotedprintable.h"
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimePart::MimePart()
|
||||||
|
{
|
||||||
|
cEncoding = _7Bit;
|
||||||
|
prepared = false;
|
||||||
|
cBoundary = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
MimePart::~MimePart()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void MimePart::setContent(const QByteArray & content)
|
||||||
|
{
|
||||||
|
this->content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::setHeader(const QString & header)
|
||||||
|
{
|
||||||
|
this->header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::addHeaderLine(const QString & line)
|
||||||
|
{
|
||||||
|
this->header += line + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& MimePart::getHeader() const
|
||||||
|
{
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray& MimePart::getContent() const
|
||||||
|
{
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::setContentId(const QString & cId)
|
||||||
|
{
|
||||||
|
this->cId = cId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimePart::getContentId() const
|
||||||
|
{
|
||||||
|
return this->cId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::setContentName(const QString & cName)
|
||||||
|
{
|
||||||
|
this->cName = cName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimePart::getContentName() const
|
||||||
|
{
|
||||||
|
return this->cName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::setContentType(const QString & cType)
|
||||||
|
{
|
||||||
|
this->cType = cType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimePart::getContentType() const
|
||||||
|
{
|
||||||
|
return this->cType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::setCharset(const QString & charset)
|
||||||
|
{
|
||||||
|
this->cCharset = charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimePart::getCharset() const
|
||||||
|
{
|
||||||
|
return this->cCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimePart::setEncoding(Encoding enc)
|
||||||
|
{
|
||||||
|
this->cEncoding = enc;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimePart::Encoding MimePart::getEncoding() const
|
||||||
|
{
|
||||||
|
return this->cEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeContentFormatter& MimePart::getContentFormatter()
|
||||||
|
{
|
||||||
|
return this->formatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
QString MimePart::toString()
|
||||||
|
{
|
||||||
|
if (!prepared)
|
||||||
|
prepare();
|
||||||
|
|
||||||
|
return mimeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
void MimePart::prepare()
|
||||||
|
{
|
||||||
|
mimeString = QString();
|
||||||
|
|
||||||
|
/* === Header Prepare === */
|
||||||
|
|
||||||
|
/* Content-Type */
|
||||||
|
mimeString.append("Content-Type: ").append(cType);
|
||||||
|
|
||||||
|
if (cName != "")
|
||||||
|
mimeString.append("; name=\"").append(cName).append("\"");
|
||||||
|
|
||||||
|
if (cCharset != "")
|
||||||
|
mimeString.append("; charset=").append(cCharset);
|
||||||
|
|
||||||
|
if (cBoundary != "")
|
||||||
|
mimeString.append("; boundary=").append(cBoundary);
|
||||||
|
|
||||||
|
mimeString.append("\r\n");
|
||||||
|
/* ------------ */
|
||||||
|
|
||||||
|
/* Content-Transfer-Encoding */
|
||||||
|
mimeString.append("Content-Transfer-Encoding: ");
|
||||||
|
switch (cEncoding)
|
||||||
|
{
|
||||||
|
case _7Bit:
|
||||||
|
mimeString.append("7bit\r\n");
|
||||||
|
break;
|
||||||
|
case _8Bit:
|
||||||
|
mimeString.append("8bit\r\n");
|
||||||
|
break;
|
||||||
|
case Base64:
|
||||||
|
mimeString.append("base64\r\n");
|
||||||
|
break;
|
||||||
|
case QuotedPrintable:
|
||||||
|
mimeString.append("quoted-printable\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* ------------------------ */
|
||||||
|
|
||||||
|
/* Content-Id */
|
||||||
|
if (cId != NULL)
|
||||||
|
mimeString.append("Content-ID: <").append(cId).append(">\r\n");
|
||||||
|
/* ---------- */
|
||||||
|
|
||||||
|
/* Addition header lines */
|
||||||
|
|
||||||
|
mimeString.append(header).append("\r\n");
|
||||||
|
|
||||||
|
/* ------------------------- */
|
||||||
|
|
||||||
|
/* === End of Header Prepare === */
|
||||||
|
|
||||||
|
/* === Content === */
|
||||||
|
switch (cEncoding)
|
||||||
|
{
|
||||||
|
case _7Bit:
|
||||||
|
mimeString.append(QString(content).toLatin1());
|
||||||
|
break;
|
||||||
|
case _8Bit:
|
||||||
|
mimeString.append(content);
|
||||||
|
break;
|
||||||
|
case Base64:
|
||||||
|
mimeString.append(formatter.format(content.toBase64()));
|
||||||
|
break;
|
||||||
|
case QuotedPrintable:
|
||||||
|
mimeString.append(formatter.format(QuotedPrintable::encode(content), true));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mimeString.append("\r\n");
|
||||||
|
/* === End of Content === */
|
||||||
|
|
||||||
|
prepared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4] --- */
|
114
servatrice/src/smtp/mimepart.h
Normal file
114
servatrice/src/smtp/mimepart.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMEPART_H
|
||||||
|
#define MIMEPART_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "mimecontentformatter.h"
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimePart : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [0] Enumerations */
|
||||||
|
enum Encoding {
|
||||||
|
_7Bit,
|
||||||
|
_8Bit,
|
||||||
|
Base64,
|
||||||
|
QuotedPrintable
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* [0] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimePart();
|
||||||
|
~MimePart();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
const QString& getHeader() const;
|
||||||
|
const QByteArray& getContent() const;
|
||||||
|
|
||||||
|
void setContent(const QByteArray & content);
|
||||||
|
void setHeader(const QString & header);
|
||||||
|
|
||||||
|
void addHeaderLine(const QString & line);
|
||||||
|
|
||||||
|
void setContentId(const QString & cId);
|
||||||
|
const QString & getContentId() const;
|
||||||
|
|
||||||
|
void setContentName(const QString & cName);
|
||||||
|
const QString & getContentName() const;
|
||||||
|
|
||||||
|
void setContentType(const QString & cType);
|
||||||
|
const QString & getContentType() const;
|
||||||
|
|
||||||
|
void setCharset(const QString & charset);
|
||||||
|
const QString & getCharset() const;
|
||||||
|
|
||||||
|
void setEncoding(Encoding enc);
|
||||||
|
Encoding getEncoding() const;
|
||||||
|
|
||||||
|
MimeContentFormatter& getContentFormatter();
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
virtual QString toString();
|
||||||
|
|
||||||
|
virtual void prepare();
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [4] Protected members */
|
||||||
|
|
||||||
|
QString header;
|
||||||
|
QByteArray content;
|
||||||
|
|
||||||
|
QString cId;
|
||||||
|
QString cName;
|
||||||
|
QString cType;
|
||||||
|
QString cCharset;
|
||||||
|
QString cBoundary;
|
||||||
|
Encoding cEncoding;
|
||||||
|
|
||||||
|
QString mimeString;
|
||||||
|
bool prepared;
|
||||||
|
|
||||||
|
MimeContentFormatter formatter;
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEPART_H
|
62
servatrice/src/smtp/mimetext.cpp
Normal file
62
servatrice/src/smtp/mimetext.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mimetext.h"
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeText::MimeText(const QString &txt)
|
||||||
|
{
|
||||||
|
this->text = txt;
|
||||||
|
this->cType = "text/plain";
|
||||||
|
this->cCharset = "utf-8";
|
||||||
|
this->cEncoding = _8Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeText::~MimeText() { }
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void MimeText::setText(const QString & text)
|
||||||
|
{
|
||||||
|
this->text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & MimeText::getText() const
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Protected Methods */
|
||||||
|
|
||||||
|
void MimeText::prepare()
|
||||||
|
{
|
||||||
|
this->content.clear();
|
||||||
|
this->content.append(text);
|
||||||
|
|
||||||
|
/* !!! IMPORTANT !!! */
|
||||||
|
MimePart::prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
62
servatrice/src/smtp/mimetext.h
Normal file
62
servatrice/src/smtp/mimetext.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIMETEXT_H
|
||||||
|
#define MIMETEXT_H
|
||||||
|
|
||||||
|
#include "mimepart.h"
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT MimeText : public MimePart
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
MimeText(const QString &text = "");
|
||||||
|
~MimeText();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters*/
|
||||||
|
|
||||||
|
void setText(const QString & text);
|
||||||
|
|
||||||
|
const QString & getText() const;
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [3] Protected members */
|
||||||
|
|
||||||
|
QString text;
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
void prepare();
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMETEXT_H
|
69
servatrice/src/smtp/quotedprintable.cpp
Normal file
69
servatrice/src/smtp/quotedprintable.cpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quotedprintable.h"
|
||||||
|
|
||||||
|
QString QuotedPrintable::encode(const QByteArray &input)
|
||||||
|
{
|
||||||
|
QString output;
|
||||||
|
|
||||||
|
char byte;
|
||||||
|
const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
|
for (int i = 0; i < input.length() ; ++i)
|
||||||
|
{
|
||||||
|
byte = input[i];
|
||||||
|
|
||||||
|
if ((byte == 0x20) || ((byte >= 33) && (byte <= 126) && (byte != 61)))
|
||||||
|
{
|
||||||
|
output.append(byte);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output.append('=');
|
||||||
|
output.append(hex[((byte >> 4) & 0x0F)]);
|
||||||
|
output.append(hex[(byte & 0x0F)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray QuotedPrintable::decode(const QString &input)
|
||||||
|
{
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F
|
||||||
|
const int hexVal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
|
||||||
|
|
||||||
|
QByteArray output;
|
||||||
|
|
||||||
|
for (int i = 0; i < input.length(); ++i)
|
||||||
|
{
|
||||||
|
if (input.at(i).toLatin1() == '=')
|
||||||
|
{
|
||||||
|
output.append((hexVal[input.at(i + 1).toLatin1() - '0'] << 4) + hexVal[input.at(i + 2).toLatin1() - '0']);
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output.append(input.at(i).toLatin1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
39
servatrice/src/smtp/quotedprintable.h
Normal file
39
servatrice/src/smtp/quotedprintable.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUOTEDPRINTABLE_H
|
||||||
|
#define QUOTEDPRINTABLE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT QuotedPrintable : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
static QString encode(const QByteArray &input);
|
||||||
|
static QByteArray decode(const QString &input);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QuotedPrintable();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QUOTEDPRINTABLE_H
|
482
servatrice/src/smtp/smtpclient.cpp
Normal file
482
servatrice/src/smtp/smtpclient.cpp
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "smtpclient.h"
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
|
||||||
|
/* [1] Constructors and destructors */
|
||||||
|
|
||||||
|
SmtpClient::SmtpClient(const QString & host, int port, ConnectionType connectionType) :
|
||||||
|
name("localhost"),
|
||||||
|
authMethod(AuthPlain),
|
||||||
|
connectionTimeout(5000),
|
||||||
|
responseTimeout(5000),
|
||||||
|
sendMessageTimeout(60000)
|
||||||
|
{
|
||||||
|
setConnectionType(connectionType);
|
||||||
|
|
||||||
|
this->host = host;
|
||||||
|
this->port = port;
|
||||||
|
|
||||||
|
connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||||
|
this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
||||||
|
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
this, SLOT(socketError(QAbstractSocket::SocketError)));
|
||||||
|
connect(socket, SIGNAL(readyRead()),
|
||||||
|
this, SLOT(socketReadyRead()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SmtpClient::~SmtpClient() {}
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
void SmtpClient::setUser(const QString &user)
|
||||||
|
{
|
||||||
|
this->user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setPassword(const QString &password)
|
||||||
|
{
|
||||||
|
this->password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setAuthMethod(AuthMethod method)
|
||||||
|
{
|
||||||
|
this->authMethod = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setHost(const QString &host)
|
||||||
|
{
|
||||||
|
this->host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setPort(int port)
|
||||||
|
{
|
||||||
|
this->port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setConnectionType(ConnectionType ct)
|
||||||
|
{
|
||||||
|
this->connectionType = ct;
|
||||||
|
|
||||||
|
switch (connectionType)
|
||||||
|
{
|
||||||
|
case TcpConnection:
|
||||||
|
socket = new QTcpSocket(this);
|
||||||
|
break;
|
||||||
|
case SslConnection:
|
||||||
|
case TlsConnection:
|
||||||
|
socket = new QSslSocket(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& SmtpClient::getHost() const
|
||||||
|
{
|
||||||
|
return this->host;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& SmtpClient::getUser() const
|
||||||
|
{
|
||||||
|
return this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& SmtpClient::getPassword() const
|
||||||
|
{
|
||||||
|
return this->password;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmtpClient::AuthMethod SmtpClient::getAuthMethod() const
|
||||||
|
{
|
||||||
|
return this->authMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getPort() const
|
||||||
|
{
|
||||||
|
return this->port;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmtpClient::ConnectionType SmtpClient::getConnectionType() const
|
||||||
|
{
|
||||||
|
return connectionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& SmtpClient::getName() const
|
||||||
|
{
|
||||||
|
return this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setName(const QString &name)
|
||||||
|
{
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString & SmtpClient::getResponseText() const
|
||||||
|
{
|
||||||
|
return responseText;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getResponseCode() const
|
||||||
|
{
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTcpSocket* SmtpClient::getSocket() {
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getConnectionTimeout() const
|
||||||
|
{
|
||||||
|
return connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setConnectionTimeout(int msec)
|
||||||
|
{
|
||||||
|
connectionTimeout = msec;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SmtpClient::getResponseTimeout() const
|
||||||
|
{
|
||||||
|
return responseTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::setResponseTimeout(int msec)
|
||||||
|
{
|
||||||
|
responseTimeout = msec;
|
||||||
|
}
|
||||||
|
int SmtpClient::getSendMessageTimeout() const
|
||||||
|
{
|
||||||
|
return sendMessageTimeout;
|
||||||
|
}
|
||||||
|
void SmtpClient::setSendMessageTimeout(int msec)
|
||||||
|
{
|
||||||
|
sendMessageTimeout = msec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
bool SmtpClient::connectToHost()
|
||||||
|
{
|
||||||
|
switch (connectionType)
|
||||||
|
{
|
||||||
|
case TlsConnection:
|
||||||
|
case TcpConnection:
|
||||||
|
socket->connectToHost(host, port);
|
||||||
|
break;
|
||||||
|
case SslConnection:
|
||||||
|
((QSslSocket*) socket)->connectToHostEncrypted(host, port);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tries to connect to server
|
||||||
|
if (!socket->waitForConnected(connectionTimeout))
|
||||||
|
{
|
||||||
|
emit smtpError(ConnectionTimeoutError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// If the response code is not 220 (Service ready)
|
||||||
|
// means that is something wrong with the server
|
||||||
|
if (responseCode != 220)
|
||||||
|
{
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a EHLO/HELO message to the server
|
||||||
|
// The client's first command must be EHLO/HELO
|
||||||
|
sendMessage("EHLO " + name);
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// The response code needs to be 250.
|
||||||
|
if (responseCode != 250) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionType == TlsConnection) {
|
||||||
|
// send a request to start TLS handshake
|
||||||
|
sendMessage("STARTTLS");
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// The response code needs to be 220.
|
||||||
|
if (responseCode != 220) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
((QSslSocket*) socket)->startClientEncryption();
|
||||||
|
|
||||||
|
if (!((QSslSocket*) socket)->waitForEncrypted(connectionTimeout)) {
|
||||||
|
qDebug() << ((QSslSocket*) socket)->errorString();
|
||||||
|
emit smtpError(ConnectionTimeoutError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send ELHO one more time
|
||||||
|
sendMessage("EHLO " + name);
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// The response code needs to be 250.
|
||||||
|
if (responseCode != 250) {
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ResponseTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no errors occured the function returns true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmtpClient::login()
|
||||||
|
{
|
||||||
|
return login(user, password, authMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmtpClient::login(const QString &user, const QString &password, AuthMethod method)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (method == AuthPlain)
|
||||||
|
{
|
||||||
|
// Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
|
||||||
|
sendMessage("AUTH PLAIN " + QByteArray().append((char) 0).append(user).append((char) 0).append(password).toBase64());
|
||||||
|
|
||||||
|
// Wait for the server's response
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// If the response is not 235 then the authentication was faild
|
||||||
|
if (responseCode != 235)
|
||||||
|
{
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (method == AuthLogin)
|
||||||
|
{
|
||||||
|
// Sending command: AUTH LOGIN
|
||||||
|
sendMessage("AUTH LOGIN");
|
||||||
|
|
||||||
|
// Wait for 334 response code
|
||||||
|
waitForResponse();
|
||||||
|
if (responseCode != 334) { emit smtpError(AuthenticationFailedError); return false; }
|
||||||
|
|
||||||
|
// Send the username in base64
|
||||||
|
sendMessage(QByteArray().append(user).toBase64());
|
||||||
|
|
||||||
|
// Wait for 334
|
||||||
|
waitForResponse();
|
||||||
|
if (responseCode != 334) { emit smtpError(AuthenticationFailedError); return false; }
|
||||||
|
|
||||||
|
// Send the password in base64
|
||||||
|
sendMessage(QByteArray().append(password).toBase64());
|
||||||
|
|
||||||
|
// Wait for the server's responce
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
// If the response is not 235 then the authentication was faild
|
||||||
|
if (responseCode != 235)
|
||||||
|
{
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ResponseTimeoutException e)
|
||||||
|
{
|
||||||
|
// Responce Timeout exceeded
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
// Send Timeout exceeded
|
||||||
|
emit smtpError(AuthenticationFailedError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmtpClient::sendMail(MimeMessage& email)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Send the MAIL command with the sender
|
||||||
|
sendMessage("MAIL FROM: <" + email.getSender().getAddress() + ">");
|
||||||
|
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
|
||||||
|
// Send RCPT command for each recipient
|
||||||
|
QList<EmailAddress*>::const_iterator it, itEnd;
|
||||||
|
// To (primary recipients)
|
||||||
|
for (it = email.getRecipients().begin(), itEnd = email.getRecipients().end();
|
||||||
|
it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
sendMessage("RCPT TO: <" + (*it)->getAddress() + ">");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cc (carbon copy)
|
||||||
|
for (it = email.getRecipients(MimeMessage::Cc).begin(), itEnd = email.getRecipients(MimeMessage::Cc).end();
|
||||||
|
it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
sendMessage("RCPT TO: <" + (*it)->getAddress() + ">");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bcc (blind carbon copy)
|
||||||
|
for (it = email.getRecipients(MimeMessage::Bcc).begin(), itEnd = email.getRecipients(MimeMessage::Bcc).end();
|
||||||
|
it != itEnd; ++it)
|
||||||
|
{
|
||||||
|
sendMessage("RCPT TO: <" + (*it)->getAddress() + ">");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send DATA command
|
||||||
|
sendMessage("DATA");
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 354) return false;
|
||||||
|
|
||||||
|
sendMessage(email.toString());
|
||||||
|
|
||||||
|
// Send \r\n.\r\n to end the mail data
|
||||||
|
sendMessage(".");
|
||||||
|
|
||||||
|
waitForResponse();
|
||||||
|
|
||||||
|
if (responseCode != 250) return false;
|
||||||
|
}
|
||||||
|
catch (ResponseTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::quit()
|
||||||
|
{
|
||||||
|
sendMessage("QUIT");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
void SmtpClient::waitForResponse() throw (ResponseTimeoutException)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (!socket->waitForReadyRead(responseTimeout))
|
||||||
|
{
|
||||||
|
emit smtpError(ResponseTimeoutError);
|
||||||
|
throw ResponseTimeoutException();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (socket->canReadLine()) {
|
||||||
|
// Save the server's response
|
||||||
|
responseText = socket->readLine();
|
||||||
|
|
||||||
|
// Extract the respose code from the server's responce (first 3 digits)
|
||||||
|
responseCode = responseText.left(3).toInt();
|
||||||
|
|
||||||
|
if (responseCode / 100 == 4)
|
||||||
|
emit smtpError(ServerError);
|
||||||
|
|
||||||
|
if (responseCode / 100 == 5)
|
||||||
|
emit smtpError(ClientError);
|
||||||
|
|
||||||
|
if (responseText[3] == ' ') { return; }
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::sendMessage(const QString &text) throw (SendMessageTimeoutException)
|
||||||
|
{
|
||||||
|
socket->write(text.toUtf8() + "\r\n");
|
||||||
|
if (! socket->waitForBytesWritten(sendMessageTimeout))
|
||||||
|
{
|
||||||
|
emit smtpError(SendDataTimeoutError);
|
||||||
|
throw SendMessageTimeoutException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [5] Slots for the socket's signals */
|
||||||
|
|
||||||
|
void SmtpClient::socketStateChanged(QAbstractSocket::SocketState state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::socketError(QAbstractSocket::SocketError socketError)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SmtpClient::socketReadyRead()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [5] --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
184
servatrice/src/smtp/smtpclient.h
Normal file
184
servatrice/src/smtp/smtpclient.h
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011-2012 - Tőkés Attila
|
||||||
|
|
||||||
|
This file is part of SmtpClient for Qt.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
See the LICENSE file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SMTPCLIENT_H
|
||||||
|
#define SMTPCLIENT_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtNetwork/QSslSocket>
|
||||||
|
|
||||||
|
#include "mimemessage.h"
|
||||||
|
#include "smtpexports.h"
|
||||||
|
|
||||||
|
class SMTP_EXPORT SmtpClient : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* [0] Enumerations */
|
||||||
|
|
||||||
|
enum AuthMethod
|
||||||
|
{
|
||||||
|
AuthPlain,
|
||||||
|
AuthLogin
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SmtpError
|
||||||
|
{
|
||||||
|
ConnectionTimeoutError,
|
||||||
|
ResponseTimeoutError,
|
||||||
|
SendDataTimeoutError,
|
||||||
|
AuthenticationFailedError,
|
||||||
|
ServerError, // 4xx smtp error
|
||||||
|
ClientError // 5xx smtp error
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ConnectionType
|
||||||
|
{
|
||||||
|
TcpConnection,
|
||||||
|
SslConnection,
|
||||||
|
TlsConnection // STARTTLS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* [0] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
|
SmtpClient(const QString & host = "localhost", int port = 25, ConnectionType ct = TcpConnection);
|
||||||
|
|
||||||
|
~SmtpClient();
|
||||||
|
|
||||||
|
/* [1] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] Getters and Setters */
|
||||||
|
|
||||||
|
const QString& getHost() const;
|
||||||
|
void setHost(const QString &host);
|
||||||
|
|
||||||
|
int getPort() const;
|
||||||
|
void setPort(int port);
|
||||||
|
|
||||||
|
const QString& getName() const;
|
||||||
|
void setName(const QString &name);
|
||||||
|
|
||||||
|
ConnectionType getConnectionType() const;
|
||||||
|
void setConnectionType(ConnectionType ct);
|
||||||
|
|
||||||
|
const QString & getUser() const;
|
||||||
|
void setUser(const QString &user);
|
||||||
|
|
||||||
|
const QString & getPassword() const;
|
||||||
|
void setPassword(const QString &password);
|
||||||
|
|
||||||
|
SmtpClient::AuthMethod getAuthMethod() const;
|
||||||
|
void setAuthMethod(AuthMethod method);
|
||||||
|
|
||||||
|
const QString & getResponseText() const;
|
||||||
|
int getResponseCode() const;
|
||||||
|
|
||||||
|
int getConnectionTimeout() const;
|
||||||
|
void setConnectionTimeout(int msec);
|
||||||
|
|
||||||
|
int getResponseTimeout() const;
|
||||||
|
void setResponseTimeout(int msec);
|
||||||
|
|
||||||
|
int getSendMessageTimeout() const;
|
||||||
|
void setSendMessageTimeout(int msec);
|
||||||
|
|
||||||
|
QTcpSocket* getSocket();
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] Public methods */
|
||||||
|
|
||||||
|
bool connectToHost();
|
||||||
|
|
||||||
|
bool login();
|
||||||
|
bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
|
||||||
|
|
||||||
|
bool sendMail(MimeMessage& email);
|
||||||
|
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* [4] Protected members */
|
||||||
|
|
||||||
|
QTcpSocket *socket;
|
||||||
|
|
||||||
|
QString host;
|
||||||
|
int port;
|
||||||
|
ConnectionType connectionType;
|
||||||
|
QString name;
|
||||||
|
|
||||||
|
QString user;
|
||||||
|
QString password;
|
||||||
|
AuthMethod authMethod;
|
||||||
|
|
||||||
|
int connectionTimeout;
|
||||||
|
int responseTimeout;
|
||||||
|
int sendMessageTimeout;
|
||||||
|
|
||||||
|
|
||||||
|
QString responseText;
|
||||||
|
int responseCode;
|
||||||
|
|
||||||
|
|
||||||
|
class ResponseTimeoutException {};
|
||||||
|
class SendMessageTimeoutException {};
|
||||||
|
|
||||||
|
/* [4] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [5] Protected methods */
|
||||||
|
|
||||||
|
void waitForResponse() throw (ResponseTimeoutException);
|
||||||
|
|
||||||
|
void sendMessage(const QString &text) throw (SendMessageTimeoutException);
|
||||||
|
|
||||||
|
/* [5] --- */
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
|
||||||
|
/* [6] Protected slots */
|
||||||
|
|
||||||
|
void socketStateChanged(QAbstractSocket::SocketState state);
|
||||||
|
void socketError(QAbstractSocket::SocketError error);
|
||||||
|
void socketReadyRead();
|
||||||
|
|
||||||
|
/* [6] --- */
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/* [7] Signals */
|
||||||
|
|
||||||
|
void smtpError(SmtpClient::SmtpError e);
|
||||||
|
|
||||||
|
/* [7] --- */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SMTPCLIENT_H
|
10
servatrice/src/smtp/smtpexports.h
Normal file
10
servatrice/src/smtp/smtpexports.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef SMTPEXPORTS_H
|
||||||
|
#define SMTPEXPORTS_H
|
||||||
|
|
||||||
|
#ifdef SMTP_BUILD
|
||||||
|
#define SMTP_EXPORT Q_DECL_EXPORT
|
||||||
|
#else
|
||||||
|
#define SMTP_EXPORT Q_DECL_IMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SMTPEXPORTS_H
|
Loading…
Reference in a new issue