steps towards ssl for smtp
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10469 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,6 +3,11 @@ SubDir OBOS_TOP src add-ons mail_daemon outbound_protocols smtp ;
|
|||||||
UsePrivateHeaders mail ;
|
UsePrivateHeaders mail ;
|
||||||
SubDirHdrs [ FDirName $(OBOS_TOP) headers os add-ons mail_daemon ] ;
|
SubDirHdrs [ FDirName $(OBOS_TOP) headers os add-ons mail_daemon ] ;
|
||||||
|
|
||||||
|
if $(USESSL) {
|
||||||
|
SubDirC++Flags -DUSESSL ;
|
||||||
|
SubDirHdrs [ FDirName / boot home config include ] ;
|
||||||
|
}
|
||||||
|
|
||||||
if $(BONE_COMPATIBLE) {
|
if $(BONE_COMPATIBLE) {
|
||||||
SubDirC++Flags -DBONE ;
|
SubDirC++Flags -DBONE ;
|
||||||
} else {
|
} else {
|
||||||
@@ -15,6 +20,10 @@ Addon SMTP : mail_daemon outbound_protocols :
|
|||||||
|
|
||||||
LinkSharedOSLibs SMTP : be libmail.so $(NETWORK_LIBS) ;
|
LinkSharedOSLibs SMTP : be libmail.so $(NETWORK_LIBS) ;
|
||||||
|
|
||||||
|
if $(USESSL) {
|
||||||
|
LinkSharedOSLibs SMTP : ssl crypto ;
|
||||||
|
}
|
||||||
|
|
||||||
Package haiku-maildaemon-cvs :
|
Package haiku-maildaemon-cvs :
|
||||||
SMTP :
|
SMTP :
|
||||||
boot home config add-ons mail_daemon outbound_protocols ;
|
boot home config add-ons mail_daemon outbound_protocols ;
|
||||||
|
|||||||
@@ -39,16 +39,10 @@ typedef struct {
|
|||||||
unsigned char buffer[64]; /* input buffer */
|
unsigned char buffer[64]; /* input buffer */
|
||||||
} MD5_CTX;
|
} MD5_CTX;
|
||||||
|
|
||||||
void MD5Init PROTO_LIST ((MD5_CTX *));
|
void MD5_Init PROTO_LIST ((MD5_CTX *));
|
||||||
void MD5Update PROTO_LIST
|
void MD5_Update PROTO_LIST
|
||||||
((MD5_CTX *, unsigned char *, unsigned int));
|
((MD5_CTX *, unsigned char *, unsigned int));
|
||||||
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
|
void MD5_Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
|
||||||
void MD5Hmac(unsigned char *digest,
|
|
||||||
const unsigned char* text, int text_len,
|
|
||||||
const unsigned char* key, int key_len);
|
|
||||||
void MD5HexHmac(char *hexdigest,
|
|
||||||
const unsigned char* text, int text_len,
|
|
||||||
const unsigned char* key, int key_len);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ documentation and/or software.
|
|||||||
#define S43 15
|
#define S43 15
|
||||||
#define S44 21
|
#define S44 21
|
||||||
|
|
||||||
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
|
static void MD5_Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
|
||||||
static void Encode PROTO_LIST
|
static void Encode PROTO_LIST
|
||||||
((unsigned char *, UINT4 *, unsigned int));
|
((unsigned char *, UINT4 *, unsigned int));
|
||||||
static void Decode PROTO_LIST
|
static void Decode PROTO_LIST
|
||||||
@@ -100,7 +100,7 @@ Rotation is separate from addition to prevent recomputation.
|
|||||||
|
|
||||||
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||||
*/
|
*/
|
||||||
void MD5Init (MD5_CTX *context)
|
void MD5_Init (MD5_CTX *context)
|
||||||
/* context */
|
/* context */
|
||||||
{
|
{
|
||||||
context->count[0] = context->count[1] = 0;
|
context->count[0] = context->count[1] = 0;
|
||||||
@@ -116,7 +116,7 @@ void MD5Init (MD5_CTX *context)
|
|||||||
operation, processing another message block, and updating the
|
operation, processing another message block, and updating the
|
||||||
context.
|
context.
|
||||||
*/
|
*/
|
||||||
void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
|
void MD5_Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
|
||||||
/* context */
|
/* context */
|
||||||
/* input block */
|
/* input block */
|
||||||
/* length of input block */
|
/* length of input block */
|
||||||
@@ -139,10 +139,10 @@ void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
|
|||||||
if (inputLen >= partLen) {
|
if (inputLen >= partLen) {
|
||||||
MD5_memcpy
|
MD5_memcpy
|
||||||
((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
||||||
MD5Transform (context->state, context->buffer);
|
MD5_Transform (context->state, context->buffer);
|
||||||
|
|
||||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||||
MD5Transform (context->state, &input[i]);
|
MD5_Transform (context->state, &input[i]);
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
|
|||||||
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||||
the message digest and zeroizing the context.
|
the message digest and zeroizing the context.
|
||||||
*/
|
*/
|
||||||
void MD5Final (unsigned char digest[16], MD5_CTX *context)
|
void MD5_Final (unsigned char digest[16], MD5_CTX *context)
|
||||||
/* message digest */
|
/* message digest */
|
||||||
/* context */
|
/* context */
|
||||||
{
|
{
|
||||||
@@ -172,10 +172,10 @@ void MD5Final (unsigned char digest[16], MD5_CTX *context)
|
|||||||
*/
|
*/
|
||||||
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
MD5Update (context, PADDING, padLen);
|
MD5_Update (context, PADDING, padLen);
|
||||||
|
|
||||||
/* Append length (before padding) */
|
/* Append length (before padding) */
|
||||||
MD5Update (context, bits, 8);
|
MD5_Update (context, bits, 8);
|
||||||
/* Store state in digest */
|
/* Store state in digest */
|
||||||
Encode (digest, context->state, 16);
|
Encode (digest, context->state, 16);
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ void MD5Final (unsigned char digest[16], MD5_CTX *context)
|
|||||||
|
|
||||||
/* MD5 basic transformation. Transforms state based on block.
|
/* MD5 basic transformation. Transforms state based on block.
|
||||||
*/
|
*/
|
||||||
static void MD5Transform (UINT4 state[4], unsigned char block[64])
|
static void MD5_Transform (UINT4 state[4], unsigned char block[64])
|
||||||
{
|
{
|
||||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||||
|
|
||||||
@@ -321,90 +321,3 @@ static void MD5_memset (POINTER output, int value, unsigned int len)
|
|||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
((char *)output)[i] = (char)value;
|
((char *)output)[i] = (char)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Function: md5_hmac
|
|
||||||
** taken from the file rfc2104.txt
|
|
||||||
** written by Martin Schaaf <[email protected]>
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
MD5Hmac(unsigned char *digest,
|
|
||||||
const unsigned char* text, int text_len,
|
|
||||||
const unsigned char* key, int key_len)
|
|
||||||
{
|
|
||||||
MD5_CTX context;
|
|
||||||
unsigned char k_ipad[64]; /* inner padding -
|
|
||||||
* key XORd with ipad
|
|
||||||
*/
|
|
||||||
unsigned char k_opad[64]; /* outer padding -
|
|
||||||
* key XORd with opad
|
|
||||||
*/
|
|
||||||
/* unsigned char tk[16]; */
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* start out by storing key in pads */
|
|
||||||
memset(k_ipad, 0, sizeof k_ipad);
|
|
||||||
memset(k_opad, 0, sizeof k_opad);
|
|
||||||
if (key_len > 64) {
|
|
||||||
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
|
||||||
MD5_CTX tctx;
|
|
||||||
|
|
||||||
MD5Init(&tctx);
|
|
||||||
MD5Update(&tctx, (unsigned char*)key, key_len);
|
|
||||||
MD5Final(k_ipad, &tctx);
|
|
||||||
MD5Final(k_opad, &tctx);
|
|
||||||
} else {
|
|
||||||
memcpy(k_ipad, key, key_len);
|
|
||||||
memcpy(k_opad, key, key_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the HMAC_MD5 transform looks like:
|
|
||||||
*
|
|
||||||
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
|
||||||
*
|
|
||||||
* where K is an n byte key
|
|
||||||
* ipad is the byte 0x36 repeated 64 times
|
|
||||||
* opad is the byte 0x5c repeated 64 times
|
|
||||||
* and text is the data being protected
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* XOR key with ipad and opad values */
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
k_ipad[i] ^= 0x36;
|
|
||||||
k_opad[i] ^= 0x5c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* perform inner MD5
|
|
||||||
*/
|
|
||||||
MD5Init(&context); /* init context for 1st
|
|
||||||
* pass */
|
|
||||||
MD5Update(&context, k_ipad, 64); /* start with inner pad */
|
|
||||||
MD5Update(&context, (unsigned char*)text, text_len); /* then text of datagram */
|
|
||||||
MD5Final(digest, &context); /* finish up 1st pass */
|
|
||||||
/*
|
|
||||||
* perform outer MD5
|
|
||||||
*/
|
|
||||||
MD5Init(&context); /* init context for 2nd
|
|
||||||
* pass */
|
|
||||||
MD5Update(&context, k_opad, 64); /* start with outer pad */
|
|
||||||
MD5Update(&context, digest, 16); /* then results of 1st
|
|
||||||
* hash */
|
|
||||||
MD5Final(digest, &context); /* finish up 2nd pass */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MD5HexHmac(char *hexdigest,
|
|
||||||
const unsigned char* text, int text_len,
|
|
||||||
const unsigned char* key, int key_len)
|
|
||||||
{
|
|
||||||
unsigned char digest[16];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
MD5Hmac(digest, text, text_len, key, key_len);
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
sprintf(hexdigest + 2 * i, "%02x", digest[i]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "smtp.h"
|
#include "smtp.h"
|
||||||
|
#ifndef USESSL
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <MDRLanguage.h>
|
#include <MDRLanguage.h>
|
||||||
|
|
||||||
@@ -44,6 +46,93 @@
|
|||||||
# define D(x) ;
|
# define D(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Function: md5_hmac
|
||||||
|
** taken from the file rfc2104.txt
|
||||||
|
** written by Martin Schaaf <[email protected]>
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
MD5Hmac(unsigned char *digest,
|
||||||
|
const unsigned char* text, int text_len,
|
||||||
|
const unsigned char* key, int key_len)
|
||||||
|
{
|
||||||
|
MD5_CTX context;
|
||||||
|
unsigned char k_ipad[64]; /* inner padding -
|
||||||
|
* key XORd with ipad
|
||||||
|
*/
|
||||||
|
unsigned char k_opad[64]; /* outer padding -
|
||||||
|
* key XORd with opad
|
||||||
|
*/
|
||||||
|
/* unsigned char tk[16]; */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* start out by storing key in pads */
|
||||||
|
memset(k_ipad, 0, sizeof k_ipad);
|
||||||
|
memset(k_opad, 0, sizeof k_opad);
|
||||||
|
if (key_len > 64) {
|
||||||
|
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
||||||
|
MD5_CTX tctx;
|
||||||
|
|
||||||
|
MD5_Init(&tctx);
|
||||||
|
MD5_Update(&tctx, (unsigned char*)key, key_len);
|
||||||
|
MD5_Final(k_ipad, &tctx);
|
||||||
|
MD5_Final(k_opad, &tctx);
|
||||||
|
} else {
|
||||||
|
memcpy(k_ipad, key, key_len);
|
||||||
|
memcpy(k_opad, key, key_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the HMAC_MD5 transform looks like:
|
||||||
|
*
|
||||||
|
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||||
|
*
|
||||||
|
* where K is an n byte key
|
||||||
|
* ipad is the byte 0x36 repeated 64 times
|
||||||
|
* opad is the byte 0x5c repeated 64 times
|
||||||
|
* and text is the data being protected
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* XOR key with ipad and opad values */
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
k_ipad[i] ^= 0x36;
|
||||||
|
k_opad[i] ^= 0x5c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* perform inner MD5
|
||||||
|
*/
|
||||||
|
MD5_Init(&context); /* init context for 1st
|
||||||
|
* pass */
|
||||||
|
MD5_Update(&context, k_ipad, 64); /* start with inner pad */
|
||||||
|
MD5_Update(&context, (unsigned char*)text, text_len); /* then text of datagram */
|
||||||
|
MD5_Final(digest, &context); /* finish up 1st pass */
|
||||||
|
/*
|
||||||
|
* perform outer MD5
|
||||||
|
*/
|
||||||
|
MD5_Init(&context); /* init context for 2nd
|
||||||
|
* pass */
|
||||||
|
MD5_Update(&context, k_opad, 64); /* start with outer pad */
|
||||||
|
MD5_Update(&context, digest, 16); /* then results of 1st
|
||||||
|
* hash */
|
||||||
|
MD5_Final(digest, &context); /* finish up 2nd pass */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MD5HexHmac(char *hexdigest,
|
||||||
|
const unsigned char* text, int text_len,
|
||||||
|
const unsigned char* key, int key_len)
|
||||||
|
{
|
||||||
|
unsigned char digest[16];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
MD5Hmac(digest, text, text_len, key, key_len);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
sprintf(hexdigest + 2 * i, "%02x", digest[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Authentication types recognized. Not all methods are implemented.
|
// Authentication types recognized. Not all methods are implemented.
|
||||||
enum AuthType {
|
enum AuthType {
|
||||||
@@ -71,6 +160,7 @@ SMTPProtocol::SMTPProtocol(BMessage *message, BMailChainRunner *run)
|
|||||||
if (fStatus < B_OK) {
|
if (fStatus < B_OK) {
|
||||||
error_msg << MDR_DIALECT_CHOICE ("POP3 authentification failed. The server said:\n","POP3認証に失敗しました\n") << fLog;
|
error_msg << MDR_DIALECT_CHOICE ("POP3 authentification failed. The server said:\n","POP3認証に失敗しました\n") << fLog;
|
||||||
runner->ShowError(error_msg.String());
|
runner->ShowError(error_msg.String());
|
||||||
|
runner->Stop(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,6 +179,7 @@ SMTPProtocol::SMTPProtocol(BMessage *message, BMailChainRunner *run)
|
|||||||
error_msg << MDR_DIALECT_CHOICE (": Connection refused or host not found.",";接続が拒否されたかサーバーが見つかりません");
|
error_msg << MDR_DIALECT_CHOICE (": Connection refused or host not found.",";接続が拒否されたかサーバーが見つかりません");
|
||||||
|
|
||||||
runner->ShowError(error_msg.String());
|
runner->ShowError(error_msg.String());
|
||||||
|
runner->Stop(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +196,7 @@ SMTPProtocol::SMTPProtocol(BMessage *message, BMailChainRunner *run)
|
|||||||
error_msg << MDR_DIALECT_CHOICE ("Error while logging in to ","ログイン中にエラーが発生しました\n") << fSettings->FindString("server")
|
error_msg << MDR_DIALECT_CHOICE ("Error while logging in to ","ログイン中にエラーが発生しました\n") << fSettings->FindString("server")
|
||||||
<< MDR_DIALECT_CHOICE (". The server said:\n","サーバーエラー\n") << fLog;
|
<< MDR_DIALECT_CHOICE (". The server said:\n","サーバーエラー\n") << fLog;
|
||||||
runner->ShowError(error_msg.String());
|
runner->ShowError(error_msg.String());
|
||||||
|
runner->Stop(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +257,18 @@ SMTPProtocol::Open(const char *address, int port, bool esmtp)
|
|||||||
{
|
{
|
||||||
runner->ReportProgress(0, 0, MDR_DIALECT_CHOICE ("Connecting to server...","接続中..."));
|
runner->ReportProgress(0, 0, MDR_DIALECT_CHOICE ("Connecting to server...","接続中..."));
|
||||||
|
|
||||||
|
#ifdef USESSL
|
||||||
|
use_ssl = (fSettings->FindInt32("flavor") == 1);
|
||||||
|
ssl = NULL;
|
||||||
|
ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (port <= 0)
|
if (port <= 0)
|
||||||
|
#ifdef USESSL
|
||||||
|
port = use_ssl ? 25 : 465;
|
||||||
|
#else
|
||||||
port = 25;
|
port = 25;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32 hostIP = inet_addr(address); // first see if we can parse it as a numeric address
|
uint32 hostIP = inet_addr(address); // first see if we can parse it as a numeric address
|
||||||
if ((hostIP == 0)||(hostIP == (uint32)-1)) {
|
if ((hostIP == 0)||(hostIP == (uint32)-1)) {
|
||||||
@@ -202,6 +304,41 @@ SMTPProtocol::Open(const char *address, int port, bool esmtp)
|
|||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USESSL
|
||||||
|
if (use_ssl) {
|
||||||
|
SSL_library_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
RAND_seed(this,sizeof(SMTPProtocol));
|
||||||
|
/*--- Because we're an add-on loaded at an unpredictable time, all
|
||||||
|
the memory addresses and things contained in ourself are
|
||||||
|
esssentially random. */
|
||||||
|
|
||||||
|
ctx = SSL_CTX_new(SSLv23_method());
|
||||||
|
ssl = SSL_new(ctx);
|
||||||
|
sbio=BIO_new_socket(_fd,BIO_NOCLOSE);
|
||||||
|
SSL_set_bio(ssl,sbio,sbio);
|
||||||
|
|
||||||
|
if (SSL_connect(ssl) <= 0) {
|
||||||
|
BString error;
|
||||||
|
error << "Could not connect to SMTP server " << fSettings->FindString("server");
|
||||||
|
if (port != 465)
|
||||||
|
error << ":" << port;
|
||||||
|
error << ". (SSL Connection Error)";
|
||||||
|
runner->ShowError(error.String());
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
#ifdef BONE
|
||||||
|
close(_fd);
|
||||||
|
#else
|
||||||
|
closesocket(_fd);
|
||||||
|
#endif
|
||||||
|
_fd = -1;
|
||||||
|
runner->Stop(true);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
BString line;
|
BString line;
|
||||||
ReceiveResponse(line);
|
ReceiveResponse(line);
|
||||||
|
|
||||||
@@ -432,6 +569,16 @@ SMTPProtocol::Close()
|
|||||||
if (SendCommand(cmd.String()) != B_OK) {
|
if (SendCommand(cmd.String()) != B_OK) {
|
||||||
// Error
|
// Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USESSL
|
||||||
|
if (use_ssl) {
|
||||||
|
if (ssl)
|
||||||
|
SSL_shutdown(ssl);
|
||||||
|
if (ctx)
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BONE
|
#ifdef BONE
|
||||||
close(_fd);
|
close(_fd);
|
||||||
#else
|
#else
|
||||||
@@ -518,6 +665,15 @@ SMTPProtocol::Send(const char *to, const char *from, BPositionIO *message)
|
|||||||
if (data[i] == '\r' && data[i+1] == '\n' && data[i+2] == '.') {
|
if (data[i] == '\r' && data[i+1] == '\n' && data[i+2] == '.') {
|
||||||
foundCRLFPeriod = true;
|
foundCRLFPeriod = true;
|
||||||
// Send data up to the CRLF, and include the period too.
|
// Send data up to the CRLF, and include the period too.
|
||||||
|
#ifdef USESSL
|
||||||
|
if (use_ssl) {
|
||||||
|
if (SSL_write(ssl,data,i + 3) < 0) {
|
||||||
|
amountUnread = 0; // Stop when an error happens.
|
||||||
|
bufferLen = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (send (_fd,data, i + 3,0) < 0) {
|
if (send (_fd,data, i + 3,0) < 0) {
|
||||||
amountUnread = 0; // Stop when an error happens.
|
amountUnread = 0; // Stop when an error happens.
|
||||||
bufferLen = 0;
|
bufferLen = 0;
|
||||||
@@ -535,6 +691,11 @@ SMTPProtocol::Send(const char *to, const char *from, BPositionIO *message)
|
|||||||
if (!foundCRLFPeriod) {
|
if (!foundCRLFPeriod) {
|
||||||
if (amountUnread <= 0) { // No more data, all we have is in the buffer.
|
if (amountUnread <= 0) { // No more data, all we have is in the buffer.
|
||||||
if (bufferLen > 0) {
|
if (bufferLen > 0) {
|
||||||
|
#ifdef USESSL
|
||||||
|
if (use_ssl)
|
||||||
|
SSL_write(ssl,data,bufferLen);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
send (_fd,data, bufferLen,0);
|
send (_fd,data, bufferLen,0);
|
||||||
runner->ReportProgress (bufferLen,0);
|
runner->ReportProgress (bufferLen,0);
|
||||||
if (bufferLen >= 2)
|
if (bufferLen >= 2)
|
||||||
@@ -547,6 +708,12 @@ SMTPProtocol::Send(const char *to, const char *from, BPositionIO *message)
|
|||||||
// Send most of the buffer, except a few characters to overlap with
|
// Send most of the buffer, except a few characters to overlap with
|
||||||
// the next read, in case the CRLFPeriod is split between reads.
|
// the next read, in case the CRLFPeriod is split between reads.
|
||||||
if (bufferLen > 3) {
|
if (bufferLen > 3) {
|
||||||
|
#ifdef USESSL
|
||||||
|
if (use_ssl) {
|
||||||
|
if (SSL_write(ssl,data,bufferLen - 3) < 0)
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (send (_fd,data, bufferLen - 3,0) < 0)
|
if (send (_fd,data, bufferLen - 3,0) < 0)
|
||||||
break; // Stop when an error happens.
|
break; // Stop when an error happens.
|
||||||
runner->ReportProgress (bufferLen - 3,0);
|
runner->ReportProgress (bufferLen - 3,0);
|
||||||
@@ -590,12 +757,23 @@ SMTPProtocol::ReceiveResponse(BString &out)
|
|||||||
|
|
||||||
/* Set the socket in the mask. */
|
/* Set the socket in the mask. */
|
||||||
FD_SET(_fd, &fds);
|
FD_SET(_fd, &fds);
|
||||||
int result = select(32, &fds, NULL, NULL, &tv);
|
int result = -1;
|
||||||
|
#ifdef USESSL
|
||||||
|
if ((use_ssl) && (SSL_pending(ssl)))
|
||||||
|
result = 1;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
result = select(32, &fds, NULL, NULL, &tv);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
while (1) {
|
while (1) {
|
||||||
|
#ifdef USESSL
|
||||||
|
if (use_ssl)
|
||||||
|
r = SSL_read(ssl,buf,SMTP_RESPONSE_SIZE - 1);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
r = recv(_fd,buf, SMTP_RESPONSE_SIZE - 1,0);
|
r = recv(_fd,buf, SMTP_RESPONSE_SIZE - 1,0);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
break;
|
break;
|
||||||
@@ -620,7 +798,13 @@ SMTPProtocol::SendCommand(const char *cmd)
|
|||||||
{
|
{
|
||||||
D(bug("C:%s\n", cmd));
|
D(bug("C:%s\n", cmd));
|
||||||
|
|
||||||
if (send(_fd,cmd, ::strlen(cmd),0) == B_ERROR)
|
#ifdef USESSL
|
||||||
|
if (use_ssl) {
|
||||||
|
if (SSL_write(ssl,cmd,::strlen(cmd)) < 0)
|
||||||
|
return B_ERROR;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (send(_fd,cmd, ::strlen(cmd),0) < 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
fLog = "";
|
fLog = "";
|
||||||
@@ -662,7 +846,15 @@ instantiate_mailfilter(BMessage *settings, BMailChainRunner *status)
|
|||||||
BView *
|
BView *
|
||||||
instantiate_config_panel(BMessage *settings, BMessage *)
|
instantiate_config_panel(BMessage *settings, BMessage *)
|
||||||
{
|
{
|
||||||
BMailProtocolConfigView *view = new BMailProtocolConfigView(B_MAIL_PROTOCOL_HAS_AUTH_METHODS | B_MAIL_PROTOCOL_HAS_USERNAME | B_MAIL_PROTOCOL_HAS_PASSWORD | B_MAIL_PROTOCOL_HAS_HOSTNAME);
|
BMailProtocolConfigView *view = new BMailProtocolConfigView(B_MAIL_PROTOCOL_HAS_AUTH_METHODS | B_MAIL_PROTOCOL_HAS_USERNAME | B_MAIL_PROTOCOL_HAS_PASSWORD | B_MAIL_PROTOCOL_HAS_HOSTNAME
|
||||||
|
|
||||||
|
#ifdef USESSL
|
||||||
|
| B_MAIL_PROTOCOL_HAS_FLAVORS);
|
||||||
|
view->AddFlavor("Unencrypted");
|
||||||
|
view->AddFlavor("SSL");
|
||||||
|
#else
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
view->AddAuthMethod(MDR_DIALECT_CHOICE ("None","無し"), false);
|
view->AddAuthMethod(MDR_DIALECT_CHOICE ("None","無し"), false);
|
||||||
view->AddAuthMethod(MDR_DIALECT_CHOICE ("ESMTP","ESMTP"));
|
view->AddAuthMethod(MDR_DIALECT_CHOICE ("ESMTP","ESMTP"));
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
#include <MailAddon.h>
|
#include <MailAddon.h>
|
||||||
|
|
||||||
|
#ifdef USESSL
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
class SMTPProtocol : public BMailFilter {
|
class SMTPProtocol : public BMailFilter {
|
||||||
public:
|
public:
|
||||||
@@ -38,6 +42,14 @@ class SMTPProtocol : public BMailFilter {
|
|||||||
BMailChainRunner *runner;
|
BMailChainRunner *runner;
|
||||||
int32 fAuthType;
|
int32 fAuthType;
|
||||||
|
|
||||||
|
#ifdef USESSL
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
SSL *ssl;
|
||||||
|
BIO *sbio;
|
||||||
|
|
||||||
|
bool use_ssl;
|
||||||
|
#endif
|
||||||
|
|
||||||
status_t fStatus;
|
status_t fStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user