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); }
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; } return true; }
bool SmtpClient::connectToHost() { if (useSsl) ((QSslSocket*) socket)->connectToHostEncrypted(host, port); else socket->connectToHost(host, port); // 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; } } catch (ResponseTimeoutException) { return false; } // If no errors occured the function returns true. return true; }
void SmtpClient::sendMessage(const QString &text) throw (SendMessageTimeoutException) { socket->write(text.toUtf8() + "\r\n"); if (! socket->waitForBytesWritten(sendMessageTimeout)) { emit smtpError(SendDataTimeoutError); throw SendMessageTimeoutException(); } }
void SmtpClient::waitForResponse() throw (ResponseTimeoutException) { if (!socket->waitForReadyRead(responseTimeout)) { emit smtpError(ResponseTimeoutError); throw ResponseTimeoutException(); } // Save the server's response responseText = socket->readAll(); // 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); }
void Smtp::dnsLookupHelper() { QValueList<QDns::MailServer> s = mxLookup->mailServers(); if ( s.isEmpty() ) { if ( !mxLookup->isWorking() ){ emit smtpError( tr( "Error in MX record lookup" ) ); } return; } emit status( tr( "Connecting to %1" ).arg( s.first().name ) ); socket->connectToHost( s.first().name, 25 ); t = new QTextStream( socket ); }
void Smtp::readyRead() { // SMTP is line-oriented if ( !socket->canReadLine() ){ return; } QString responseLine; do { responseLine = socket->readLine(); response += responseLine; } while( socket->canReadLine() && responseLine[3] != ' ' ); responseLine.truncate( 3 ); if ( state == Init && responseLine[0] == '2' ) { // banner was okay, let's go on *t << "HELO there\r\n"; state = Mail; } else if ( state == Mail && responseLine[0] == '2' ) { // HELO response was okay (well, it has to be) *t << "MAIL FROM: <" << from << ">\r\n"; state = Rcpt; } else if ( state == Rcpt && responseLine[0] == '2' ) { *t << "RCPT TO: <" << rcpt << ">\r\n"; state = Data; } else if ( state == Data && responseLine[0] == '2' ) { *t << "DATA\r\n"; state = Body; } else if ( state == Body && responseLine[0] == '3' ) { *t << message << ".\r\n"; state = Quit; } else if ( state == Quit && responseLine[0] == '2' ) { *t << "QUIT\r\n"; // here, we just close. state = Close; emit messageSent(); } else if ( state == Close ) { deleteLater(); return; } else { emit smtpError(response); state = Close; } response = ""; }
bool SmtpClient::connectToHost() { switch (connectionType) { case TlsConnection: break; 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; }