fixed json file and added encryption

This commit is contained in:
Simon Stürz 2014-10-21 20:48:17 +02:00 committed by Michael Zanetti
parent 324a8be20f
commit a056371a4d
6 changed files with 266 additions and 100 deletions

View File

@ -2,7 +2,7 @@
GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"') GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\"
QMAKE_CXXFLAGS += -Werror #QMAKE_CXXFLAGS += -Werror
CONFIG += c++11 CONFIG += c++11
# Enable coverage option # Enable coverage option

View File

@ -237,26 +237,70 @@ ActionTypeId sendMailActionTypeId = ActionTypeId("054613b0-3666-4dad-9252-e0ebca
DevicePluginMailNotification::DevicePluginMailNotification() DevicePluginMailNotification::DevicePluginMailNotification()
{ {
m_smtpClient = new SmtpClient();
} }
DevicePluginMailNotification::~DevicePluginMailNotification() DevicePluginMailNotification::~DevicePluginMailNotification()
{ {
m_smtpClient->deleteLater();
} }
DeviceManager::DeviceSetupStatus DevicePluginMailNotification::setupDevice(Device *device) DeviceManager::DeviceSetupStatus DevicePluginMailNotification::setupDevice(Device *device)
{ {
Q_UNUSED(device)
// Google mail // Google mail
// if(device->deviceClassId() == googleMailDeviceClassId){ if(device->deviceClassId() == googleMailDeviceClassId){
// m_smtpClient->setConnectionType(SmtpClient::SslConnection); device->setName("Google Mail (" + device->paramValue("user").toString() + ")");
// m_smtpClient->setAuthMethod(SmtpClient::AuthLogin); SmtpClient *smtpClient = new SmtpClient("smtp.gmail.com",
// m_smtpClient->setPort(465); 465,
// m_smtpClient->setHost("smtp.gmail.com"); device->paramValue("user").toString(),
// m_smtpClient->login(device->paramValue("user").toString(), device->paramValue("password").toString()); device->paramValue("password").toString(),
// } SmtpClient::AuthLogin,
return DeviceManager::DeviceSetupStatusSuccess; SmtpClient::EncryptionSSL,
this);
smtpClient->setSender(device->paramValue("user").toString());
smtpClient->setRecipiant(device->paramValue("recipient").toString());
connect(smtpClient, &SmtpClient::sendMailFinished, this, &DevicePluginMailNotification::sendMailFinished);
// TODO: test connection;
m_clients.insert(smtpClient,device);
return DeviceManager::DeviceSetupStatusSuccess;
//return DeviceManager::DeviceSetupStatusAsync;
}
// Custom mail
if(device->deviceClassId() == customMailDeviceClassId){
device->setName("Custom Mail (" + device->paramValue("sender mail").toString() + ")");
SmtpClient *smtpClient = new SmtpClient(this);
smtpClient->setHost(device->paramValue("SMTP server").toString());
smtpClient->setPort(device->paramValue("port").toInt());
smtpClient->setUser(device->paramValue("user").toString());
smtpClient->setPassword(device->paramValue("password").toString());
if(device->paramValue("authentification").toString() == "PLAIN"){
smtpClient->setAuthMethod(SmtpClient::AuthPlain);
}
if(device->paramValue("authentification").toString() == "LOGIN"){
smtpClient->setAuthMethod(SmtpClient::AuthLogin);
}
if(device->paramValue("encryption").toString() == "NONE"){
smtpClient->setEncryptionType(SmtpClient::EncryptionNone);
}
if(device->paramValue("encryption").toString() == "SSL"){
smtpClient->setEncryptionType(SmtpClient::EncryptionSSL);
}
if(device->paramValue("encryption").toString() == "TLS"){
smtpClient->setEncryptionType(SmtpClient::EncryptionTLS);
}
smtpClient->setRecipiant(device->paramValue("recipient").toString());
smtpClient->setSender(device->paramValue("sender mail").toString());
connect(smtpClient, &SmtpClient::sendMailFinished, this, &DevicePluginMailNotification::sendMailFinished);
// TODO: test connection;
m_clients.insert(smtpClient,device);
return DeviceManager::DeviceSetupStatusSuccess;
//return DeviceManager::DeviceSetupStatusAsync;
}
return DeviceManager::DeviceSetupStatusFailure;
} }
DeviceManager::HardwareResources DevicePluginMailNotification::requiredHardware() const DeviceManager::HardwareResources DevicePluginMailNotification::requiredHardware() const
@ -266,34 +310,20 @@ DeviceManager::HardwareResources DevicePluginMailNotification::requiredHardware(
DeviceManager::DeviceError DevicePluginMailNotification::executeAction(Device *device, const Action &action) DeviceManager::DeviceError DevicePluginMailNotification::executeAction(Device *device, const Action &action)
{ {
qDebug() << "execute action " << sendMailActionTypeId.toString();
if(action.actionTypeId() == sendMailActionTypeId){ if(action.actionTypeId() == sendMailActionTypeId){
// Google mail SmtpClient *smtpClient= m_clients.key(device);
if(device->deviceClassId() == googleMailDeviceClassId){ smtpClient->sendMail(action.param("subject").value().toString(), action.param("body").value().toString(), action.id());
m_smtpClient->setConnectionType(SmtpClient::SslConnection);
m_smtpClient->setAuthMethod(SmtpClient::AuthLogin);
m_smtpClient->setPort(465);
m_smtpClient->setHost("smtp.gmail.com");
m_smtpClient->setUser(device->paramValue("user").toString());
m_smtpClient->setPassword(device->paramValue("password").toString());
m_smtpClient->setRecipiant(device->paramValue("recipiant").toString());
}
if(device->deviceClassId() == customMailDeviceClassId){ return DeviceManager::DeviceErrorAsync;
m_smtpClient->setConnectionType(SmtpClient::SslConnection); }
if(device->paramValue("auth").toString() == "PLAIN"){ return DeviceManager::DeviceErrorActionTypeNotFound;
m_smtpClient->setAuthMethod(SmtpClient::AuthPlain); }
}else if(device->paramValue("auth").toString() == "LOGIN"){
m_smtpClient->setAuthMethod(SmtpClient::AuthLogin); void DevicePluginMailNotification::sendMailFinished(const bool &success, const ActionId &actionId)
} {
m_smtpClient->setPort(device->paramValue("port").toInt()); if(success){
m_smtpClient->setHost(device->paramValue("host").toString()); emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError);
m_smtpClient->setUser(device->paramValue("user").toString()); }else{
m_smtpClient->setPassword(device->paramValue("password").toString()); emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorDeviceNotFound);
}
m_smtpClient->sendMail(device->paramValue("user").toString(), device->paramValue("recipient").toString(), action.param("subject").value().toString(), action.param("body").value().toString());
} }
return DeviceManager::DeviceErrorNoError;
} }

View File

@ -38,11 +38,12 @@ public:
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private: private:
SmtpClient *m_smtpClient; QHash <SmtpClient*, Device*> m_clients;
private slots: private slots:
public slots: public slots:
void sendMailFinished(const bool &success, const ActionId &actionId);
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "Mail notification", "name": "Mail notification",
"id": "72aef158-07a3-4714-93b5-fec2f9d912d1", "id": "1ae35df1-1b51-4c93-94fa-3febc77e0318",
"vendors": [ "vendors": [
{ {
"name": "guh", "name": "guh",
@ -8,10 +8,97 @@
"deviceClasses": [ "deviceClasses": [
{ {
"deviceClassId": "3869884a-1592-4b8f-84a7-994be18ff555", "deviceClassId": "3869884a-1592-4b8f-84a7-994be18ff555",
"name": "GMail", "name": "Google Mail",
"createMethods": ["user"], "createMethods": ["user"],
"paramTypes": [ "paramTypes": [
{
"name": "user",
"type": "QString"
},
{
"name": "password",
"type": "QString"
},
{
"name": "recipient",
"type": "QString"
}
],
"actionTypes": [
{
"id": "054613b0-3666-4dad-9252-e0ebca187edc",
"name": "Send mail",
"paramTypes": [
{
"name": "subject",
"type": "QString"
},
{
"name": "body",
"type": "QString"
}
]
}
]
},
{
"deviceClassId": "f4844c97-7ca6-4349-904e-ff9749a9fe74",
"name": "Custom Mail",
"createMethods": ["user"],
"paramTypes": [
{
"name": "sender mail",
"type": "QString"
},
{
"name": "user",
"type": "QString"
},
{
"name": "password",
"type": "QString"
},
{
"name": "recipient",
"type": "QString"
},
{
"name": "SMTP server",
"type": "QString"
},
{
"name": "port",
"type": "int",
"defaultValue": 25
},
{
"name": "authentification",
"type": "QString",
"defaultValue": "LOGIN",
"allowedValues": ["PLAIN", "LOGIN"]
},
{
"name": "encryption",
"type": "QString",
"defaultValue": "SSL",
"allowedValues": ["NONE","SSL","TLS"]
}
],
"actionTypes": [
{
"id": "054613b0-3666-4dad-9252-e0ebca187edc",
"name": "Send mail",
"paramTypes": [
{
"name": "subject",
"type": "QString"
},
{
"name": "body",
"type": "QString"
}
]
}
] ]
} }
] ]

View File

@ -18,15 +18,11 @@
#include "smtpclient.h" #include "smtpclient.h"
SmtpClient::SmtpClient() SmtpClient::SmtpClient(QObject *parent):
QObject(parent)
{ {
m_socket = new QSslSocket(this);
m_host = "smtp.gmail.com";
m_port = 465;
m_connectionType = SslConnection;
m_authMethod = AuthLogin;
m_state = InitState; m_state = InitState;
m_socket = new QSslSocket(this);
connect(m_socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError))); connect(m_socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError)));
connect(m_socket,SIGNAL(connected()),this,SLOT(connected())); connect(m_socket,SIGNAL(connected()),this,SLOT(connected()));
@ -35,16 +31,35 @@ SmtpClient::SmtpClient()
} }
SmtpClient::SmtpClient(QString host, int port, QString user, QString password, SmtpClient::AuthMethod authMethod, SmtpClient::EncryptionType encryptionType, QObject *parent):
m_host(host),
m_port(port),
m_user(user),
m_password(password),
m_authMethod(authMethod),
m_encryptionType(encryptionType),
QObject(parent)
{
m_state = InitState;
m_socket = new QSslSocket(this);
connect(m_socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError)));
connect(m_socket,SIGNAL(connected()),this,SLOT(connected()));
connect(m_socket,SIGNAL(readyRead()),this,SLOT(readData()));
connect(m_socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
}
void SmtpClient::connectToHost() void SmtpClient::connectToHost()
{ {
switch (m_connectionType) { switch (m_encryptionType) {
case TlsConnection: case EncryptionNone:
m_socket->connectToHost(m_host, m_port);
break;
case EncryptionSSL:
m_socket->connectToHostEncrypted(m_host, m_port); m_socket->connectToHostEncrypted(m_host, m_port);
break; break;
case SslConnection: case EncryptionTLS:
m_socket->connectToHostEncrypted(m_host, m_port);
break;
case TcpConnection:
m_socket->connectToHost(m_host,m_port); m_socket->connectToHost(m_host,m_port);
break; break;
default: default:
@ -54,9 +69,8 @@ void SmtpClient::connectToHost()
void SmtpClient::connected() void SmtpClient::connected()
{ {
qDebug() << "connected to" << m_host; // qDebug() << "connected to" << m_host;
qDebug() << "-----------------------"; // qDebug() << "-----------------------";
} }
void SmtpClient::readData() void SmtpClient::readData()
@ -70,21 +84,28 @@ void SmtpClient::readData()
} }
responseLine.truncate( 3 ); responseLine.truncate( 3 );
qDebug() << "---------------------------------------------"; // qDebug() << "---------------------------------------------";
qDebug() << "Server code:" << responseLine; // qDebug() << "Server code:" << responseLine;
qDebug() << "---------------------------------------------"; // qDebug() << "---------------------------------------------";
qDebug() << "Server data: " << response; // qDebug() << "Server data: " << response;
qDebug() << "---------------------------------------------"; // qDebug() << "---------------------------------------------";
switch (m_state) { switch (m_state) {
case InitState: case InitState:
if(responseLine == "220"){ if(responseLine == "220"){
qDebug() << "Init"; qDebug() << "Init";
send("EHLO localhost"); send("EHLO localhost");
if(m_connectionType == TlsConnection || m_connectionType == SslConnection){ if(m_encryptionType == EncryptionNone){
m_state = HandShakeState;
}else{
m_state = AuthentificationState; m_state = AuthentificationState;
break;
}
if(m_encryptionType == EncryptionSSL){
m_state = HandShakeState;
break;
}
if(m_encryptionType == EncryptionTLS){
m_state = StartTlsState;
break;
} }
} }
break; break;
@ -92,12 +113,21 @@ void SmtpClient::readData()
if(responseLine == "250"){ if(responseLine == "250"){
qDebug() << "Handshake"; qDebug() << "Handshake";
m_socket->startClientEncryption(); m_socket->startClientEncryption();
if(!m_socket->waitForEncrypted(1000)){
qDebug() << m_socket->errorString();
}
send("EHLO localhost"); send("EHLO localhost");
m_state = AuthentificationState; m_state = AuthentificationState;
} }
if(responseLine == "220"){
qDebug() << "TLS Handshake";
m_socket->startClientEncryption();
send("EHLO localhost");
m_state = AuthentificationState;
}
break;
case StartTlsState:
if(responseLine == "250"){
send("STARTTLS");
m_state = HandShakeState;
}
break; break;
case AuthentificationState: case AuthentificationState:
if(responseLine == "250"){ if(responseLine == "250"){
@ -128,7 +158,7 @@ void SmtpClient::readData()
break; break;
case MailState: case MailState:
if(responseLine == "235"){ if(responseLine == "235"){
send("MAIL FROM:<" + m_from + ">"); send("MAIL FROM:<" + m_sender + ">");
m_state = RcptState; m_state = RcptState;
} }
break; break;
@ -152,26 +182,31 @@ void SmtpClient::readData()
break; break;
case QuitState: case QuitState:
if(responseLine == "250"){ if(responseLine == "250"){
qDebug() << "--------------------------------------------"; emit sendMailFinished(true, m_actionId);
qDebug() << " MAIL SENT!!!!"; // qDebug() << "--------------------------------------------";
qDebug() << "--------------------------------------------"; // qDebug() << " MAIL SENT!!!!";
send("QUIT"); // qDebug() << "--------------------------------------------";
logout();
m_state = CloseState; m_state = CloseState;
} }
break; break;
case CloseState: case CloseState:
if(responseLine == "221"){
m_socket->close();
}
m_socket->close(); m_socket->close();
break; break;
default: default:
qDebug() << "ERROR: unexpected response from server: " << response; //qDebug() << "ERROR: unexpected response from server: " << response;
emit sendMailFinished(false, m_actionId);
break; break;
} }
} }
void SmtpClient::disconnected() void SmtpClient::disconnected()
{ {
qDebug() << "disconnected from" << m_host; // qDebug() << "disconnected from" << m_host;
qDebug() << "-----------------------"; // qDebug() << "-----------------------";
} }
void SmtpClient::login(const QString &user, const QString &password) void SmtpClient::login(const QString &user, const QString &password)
@ -179,7 +214,7 @@ void SmtpClient::login(const QString &user, const QString &password)
if(!m_socket->isOpen()){ if(!m_socket->isOpen()){
connectToHost(); connectToHost();
} }
qDebug() << "Try to login with: " << user << password; // qDebug() << "Try to login with: " << user << password;
} }
void SmtpClient::logout() void SmtpClient::logout()
@ -187,21 +222,21 @@ void SmtpClient::logout()
send("QUIT"); send("QUIT");
} }
bool SmtpClient::sendMail(const QString &from, const QString &to, const QString &subject, const QString &body) bool SmtpClient::sendMail(const QString &subject, const QString &body, const ActionId &actionId)
{ {
// mail m_actionId = actionId;
m_rcpt = to;
// create mail content
m_state = InitState; m_state = InitState;
m_from = from;
m_message.clear(); m_message.clear();
m_message = "To: " + to + "\n"; m_message = "To: " + m_rcpt + "\n";
m_message.append("From: " + from + "\n"); m_message.append("From: " + m_sender + "\n");
m_message.append("Subject: " + subject + "\n"); m_message.append("Subject: " + subject + "\n");
m_message.append(body); m_message.append(body);
m_message.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "\r\n" ) ); m_message.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "\r\n" ) );
m_message.replace( QString::fromLatin1( "\r\n.\r\n" ), QString::fromLatin1( "\r\n..\r\n" ) ); m_message.replace( QString::fromLatin1( "\r\n.\r\n" ), QString::fromLatin1( "\r\n..\r\n" ) );
m_message.append("\r\n.\r\n");
m_socket->close(); m_socket->close();
connectToHost(); connectToHost();
@ -218,9 +253,9 @@ void SmtpClient::setPort(const int &port)
m_port = port; m_port = port;
} }
void SmtpClient::setConnectionType(const SmtpClient::ConnectionType &connectionType) void SmtpClient::setEncryptionType(const SmtpClient::EncryptionType &encryptionType)
{ {
m_connectionType = connectionType; m_encryptionType = encryptionType;
} }
void SmtpClient::setAuthMethod(const SmtpClient::AuthMethod &authMethod) void SmtpClient::setAuthMethod(const SmtpClient::AuthMethod &authMethod)
@ -238,7 +273,12 @@ void SmtpClient::setPassword(const QString &password)
m_password = password; m_password = password;
} }
void SmtpClient::setRecipiant(const QString &rcpt) void SmtpClient::setSender(const QString &sender)
{
m_sender = sender;
}
void SmtpClient::setRecipiant(const QString &rcpt)
{ {
m_rcpt = rcpt; m_rcpt = rcpt;
} }
@ -250,7 +290,7 @@ void SmtpClient::socketError(QAbstractSocket::SocketError error)
void SmtpClient::send(const QString &data) void SmtpClient::send(const QString &data)
{ {
qDebug() << "sending to host:" << data; //qDebug() << "sending to host:" << data;
m_socket->write(data.toUtf8() + "\r\n"); m_socket->write(data.toUtf8() + "\r\n");
m_socket->flush(); m_socket->flush();
} }

View File

@ -24,6 +24,8 @@
#include <QTcpSocket> #include <QTcpSocket>
#include <QSslSocket> #include <QSslSocket>
#include "plugin/deviceplugin.h"
class SmtpClient : public QObject class SmtpClient : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -38,6 +40,7 @@ public:
InitState, InitState,
HandShakeState, HandShakeState,
AuthentificationState, AuthentificationState,
StartTlsState,
UserState, UserState,
PasswordState, PasswordState,
MailState, MailState,
@ -48,24 +51,27 @@ public:
CloseState CloseState
}; };
enum ConnectionType{ enum EncryptionType{
TcpConnection, // no encryption EncryptionNone, // no encryption
SslConnection, // SSL EncryptionSSL, // SSL
TlsConnection // STARTTLS EncryptionTLS // STARTTLS
}; };
explicit SmtpClient(); explicit SmtpClient(QObject *parent = 0);
explicit SmtpClient(QString host = QString(), int port = 465, QString user = QString(), QString password = QString(), AuthMethod authMethod = AuthPlain, EncryptionType encryptionType = EncryptionNone, QObject *parent = 0);
void connectToHost(); void connectToHost();
void login(const QString &user, const QString &password); void login(const QString &user, const QString &password);
void logout(); void logout();
bool sendMail(const QString &from, const QString &to, const QString &subject, const QString &body); bool sendMail(const QString &subject, const QString &body, const ActionId &actionId);
void setHost(const QString &host); void setHost(const QString &host);
void setPort(const int &port); void setPort(const int &port);
void setConnectionType(const ConnectionType &connectionType); void setEncryptionType(const EncryptionType &encryptionType);
void setAuthMethod(const AuthMethod &authMethod); void setAuthMethod(const AuthMethod &authMethod);
void setUser(const QString &user); void setUser(const QString &user);
void setPassword(const QString &password); void setPassword(const QString &password);
void setSender(const QString &sender);
void setRecipiant(const QString &rcpt); void setRecipiant(const QString &rcpt);
@ -74,17 +80,19 @@ private:
QSslSocket *m_socket; QSslSocket *m_socket;
QString m_host; QString m_host;
int m_port; int m_port;
ConnectionType m_connectionType;
AuthMethod m_authMethod;
QString m_user; QString m_user;
QString m_password; QString m_password;
QString m_from; QString m_sender;
AuthMethod m_authMethod;
EncryptionType m_encryptionType;
QString m_rcpt; QString m_rcpt;
QString m_subject; QString m_subject;
QString m_boy; QString m_boy;
QString m_message; QString m_message;
ActionId m_actionId;
signals: signals:
void sendMailFinished(const bool &success, const ActionId &actionId);
private slots: private slots:
void socketError(QAbstractSocket::SocketError error); void socketError(QAbstractSocket::SocketError error);