mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-12-25 19:00:12 +01:00
src: fix the smtp protocol handling
Signed-off-by: Janos SUTO <sj@acts.hu>
This commit is contained in:
parent
6522d64bd7
commit
f476d49e64
@ -103,7 +103,7 @@ int searchStringInBuffer(char *s, int len1, char *what, int len2){
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
29
src/smtp.c
29
src/smtp.c
@ -72,18 +72,19 @@ void process_smtp_command(struct smtp_session *session, char *buf){
|
|||||||
|
|
||||||
void process_data(struct smtp_session *session, char *readbuf, int readlen){
|
void process_data(struct smtp_session *session, char *readbuf, int readlen){
|
||||||
char puf[SMALLBUFSIZE+BIGBUFSIZE];
|
char puf[SMALLBUFSIZE+BIGBUFSIZE];
|
||||||
int n, pos, len;
|
int n, pos, len, writelen;
|
||||||
|
|
||||||
memset(puf, 0, sizeof(puf));
|
memset(puf, 0, sizeof(puf));
|
||||||
|
len = readlen;
|
||||||
|
|
||||||
if(session->buflen > 0){
|
if(session->buflen > 0){
|
||||||
memcpy(&puf[0], session->buf, session->buflen);
|
memcpy(&puf[0], session->buf, session->buflen);
|
||||||
memcpy(&puf[session->buflen], readbuf, readlen);
|
memcpy(&puf[session->buflen], readbuf, readlen);
|
||||||
len = session->buflen + readlen;
|
|
||||||
|
len += session->buflen;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(&puf[0], readbuf, readlen);
|
memcpy(&puf[0], readbuf, readlen);
|
||||||
len = readlen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = searchStringInBuffer(&puf[0], len, SMTP_CMD_PERIOD, 5);
|
pos = searchStringInBuffer(&puf[0], len, SMTP_CMD_PERIOD, 5);
|
||||||
@ -93,27 +94,37 @@ void process_data(struct smtp_session *session, char *readbuf, int readlen){
|
|||||||
session->tot_len += pos;
|
session->tot_len += pos;
|
||||||
process_command_period(session);
|
process_command_period(session);
|
||||||
}
|
}
|
||||||
else syslog(LOG_PRIORITY, "ERROR: process_data(): failed to write %d bytes", pos);
|
else syslog(LOG_PRIORITY, "ERROR (line: %d): process_data(): failed to write %d bytes", __LINE__, pos);
|
||||||
}
|
}
|
||||||
else {
|
else if(pos < 0){
|
||||||
n = search_char_backward(&puf[0], len, '\r');
|
n = search_char_backward(&puf[0], len, '\r');
|
||||||
|
|
||||||
if(n == -1 || len - n > 4){
|
if(n == -1 || len - n > 4){
|
||||||
if(write(session->fd, puf, len) != -1){
|
|
||||||
session->tot_len += len;
|
if(n == -1) writelen = len;
|
||||||
|
else writelen = n-1;
|
||||||
|
|
||||||
|
if(writelen > 0){
|
||||||
|
if(write(session->fd, puf, writelen) != -1){
|
||||||
|
session->tot_len += writelen;
|
||||||
|
}
|
||||||
|
else syslog(LOG_PRIORITY, "ERROR (line: %d): process_data(): failed to write %d bytes", __LINE__, writelen);
|
||||||
}
|
}
|
||||||
else syslog(LOG_PRIORITY, "ERROR: process_data(): failed to write %d bytes", len);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(write(session->fd, puf, n) != -1){
|
if(write(session->fd, puf, n) != -1){
|
||||||
session->tot_len += n;
|
session->tot_len += n;
|
||||||
}
|
}
|
||||||
else syslog(LOG_PRIORITY, "process_data(): failed to write %d bytes", n);
|
else syslog(LOG_PRIORITY, "ERROR (line: %d) process_data(): failed to write %d bytes", __LINE__, n);
|
||||||
|
|
||||||
snprintf(session->buf, SMALLBUFSIZE-1, "%s", &puf[n]);
|
snprintf(session->buf, SMALLBUFSIZE-1, "%s", &puf[n]);
|
||||||
session->buflen = len - n;
|
session->buflen = len - n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// The buffer contains only the CR-LF-DOT-CR-LF sequence
|
||||||
|
process_command_period(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -309,6 +309,56 @@ static void test_smtp_commands_starttls(char *server, int port, struct data *dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_smtp_commands_period_command_in_2_parts(char *server, int port, char *part1, char *part2, struct data *data){
|
||||||
|
char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE];
|
||||||
|
|
||||||
|
connect_to_smtp_server(server, port, data);
|
||||||
|
|
||||||
|
send_helo_command(data->net);
|
||||||
|
|
||||||
|
send_smtp_command(data->net, "MAIL FROM: <sender@aaa.fu>\r\nRCPT TO: <archive@aaa.fu>\r\nDATA\r\n", recvbuf, sizeof(recvbuf)-1);
|
||||||
|
assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL");
|
||||||
|
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf)-1, "%s%s", testmessage, part1);
|
||||||
|
write1(data->net, sendbuf, strlen(sendbuf));
|
||||||
|
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf), "%s", part2);
|
||||||
|
send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1);
|
||||||
|
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf)-1, "QUIT\r\n");
|
||||||
|
send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1);
|
||||||
|
|
||||||
|
assert(strncmp(recvbuf, "250 ", 4) == 0 && "QUIT");
|
||||||
|
|
||||||
|
close(data->net->socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_smtp_commands_period_command_in_its_own_packet(char *server, int port, struct data *data){
|
||||||
|
char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE];
|
||||||
|
|
||||||
|
connect_to_smtp_server(server, port, data);
|
||||||
|
|
||||||
|
send_helo_command(data->net);
|
||||||
|
|
||||||
|
send_smtp_command(data->net, "MAIL FROM: <sender@aaa.fu>\r\nRCPT TO: <archive@aaa.fu>\r\nDATA\r\n", recvbuf, sizeof(recvbuf)-1);
|
||||||
|
assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL");
|
||||||
|
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf)-1, "%s", testmessage);
|
||||||
|
write1(data->net, sendbuf, strlen(sendbuf));
|
||||||
|
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf), "\r\n.\r\n");
|
||||||
|
send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1);
|
||||||
|
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf)-1, "QUIT\r\n");
|
||||||
|
send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1);
|
||||||
|
|
||||||
|
assert(strncmp(recvbuf, "250 ", 4) == 0 && "QUIT");
|
||||||
|
|
||||||
|
close(data->net->socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
int c, port=25;
|
int c, port=25;
|
||||||
char *server=NULL;
|
char *server=NULL;
|
||||||
@ -380,6 +430,11 @@ int main(int argc, char **argv){
|
|||||||
test_smtp_commands_with_reset_command(server, port, &data);
|
test_smtp_commands_with_reset_command(server, port, &data);
|
||||||
test_smtp_commands_partial_command(server, port, &data);
|
test_smtp_commands_partial_command(server, port, &data);
|
||||||
test_smtp_commands_partial_command_pipelining(server, port, &data);
|
test_smtp_commands_partial_command_pipelining(server, port, &data);
|
||||||
|
test_smtp_commands_period_command_in_2_parts(server, port, "\r", "\n.\r\n", &data);
|
||||||
|
test_smtp_commands_period_command_in_2_parts(server, port, "\r\n", ".\r\n", &data);
|
||||||
|
test_smtp_commands_period_command_in_2_parts(server, port, "\r\n.", "\r\n", &data);
|
||||||
|
test_smtp_commands_period_command_in_2_parts(server, port, "\r\n.\r", "\n", &data);
|
||||||
|
test_smtp_commands_period_command_in_its_own_packet(server, port, &data);
|
||||||
|
|
||||||
helo = 1; // we must use EHLO to get the STARTTLS in the response
|
helo = 1; // we must use EHLO to get the STARTTLS in the response
|
||||||
test_smtp_commands_starttls(server, port, &data);
|
test_smtp_commands_starttls(server, port, &data);
|
||||||
|
Loading…
Reference in New Issue
Block a user