Sprachlose SMTP Server wollen mit meinem nicht Kommunizieren!
-
Hallo,
Programmiersprache: C
Betriebsystem: Linux UbuntuMein Problem:
Ich habe einen kleinen SMTP Server geschrieben. Sehr Simpel gehalten
da er nur für einen bestimmten zweck gemacht ist: Mails empfangen.
Er funktioniert auch: Sende ich von z.b Arcor aus eine Email
an meinen SMTP Server verbindet sich Arcor, bekommt von mir den
SMTP Banner, ich bekomme ein HELO und eben die Mail übergeben.Sende ich jedoch von z.b GMX aus eine Mail. Verbindet sich GMX
zwar mit meinem Server, doch dann herrscht Funkstille.
Es tut sich Minutenlang nichts mehr. Nach einiger Zeit sendet GMX
an meinen SMTP lauter \n Chars und ich muss ihn leider Kicken.Genauso wie, wenn ich von meiner Hochschule aus ne Email an meinen SMTP
versuche zu senden. Doch krieg ich nach der Wartezeit keine \n sondern
einfach nur den QUIT befehl.Was ist da los? Starte ich auf meinem PC den Postfix SMTP Server, kann ich Emails von jedem Provider empfangen. Also muss es an meinem Code liegen oder
an etwas, was ich nicht bedacht habe bezgl. des SMTP Protokolls...Soll ich GMX nen Begrüßungsblumenstrauß überreichen oder wie
?
Hier der Code falls nötig:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <malloc.h> #include <time.h> int smpt_sck, new_sck; int laenge, anzahl; struct sockaddr_in serverinfo, clientinfo; char smtp_rec[10000]; char smtp[10000]; unsigned short int port = 587; char ip_adresse[] = "INADDR_ANY"; int i,x,mail_empfang, fails; int op_pos; char *msg_get; char *ptr; char *p_len; char mailfrom[1000]; char rcpto[1000]; int mailf; int rcpt; char message[10000]; int mail_split(); char* replace(const char* s, const char* find, const char* replace); main() { FILE *datei; mail_empfang = 0; fails = 0; smpt_sck = socket(AF_INET, SOCK_STREAM, 0); serverinfo.sin_family = AF_INET; serverinfo.sin_addr.s_addr = htonl(INADDR_ANY); serverinfo.sin_port = htons(port); laenge = sizeof(serverinfo); bind(smpt_sck, (struct sockaddr *)&serverinfo, laenge); printf("\n SYSTEM > Server listen on Port %d\n", port); listen(smpt_sck, 3); wait_again:; while(1) { new_sck = accept(smpt_sck, (struct sockaddr *)&clientinfo, &laenge); printf("\n SERVER > Connection with: %s\n",inet_ntoa(clientinfo.sin_addr)); struct tm *zeit; time_t sekunde; char time_str[80]; time(&sekunde); zeit = localtime(&sekunde); strftime(time_str, 80, "%a, %d %b %Y %H:%M:%S",zeit); sprintf(smtp, "220 mindcode.ath.cx MindCode SMTP MAIL service ready at %s +0100\n", time_str); write(new_sck,smtp,strlen(smtp)); printf("SEND > 220 mindcode.ath.cx MindCode SMTP MAIL service ready at %s +0100\n", time_str); if(new_sck > 0) break; } while(1) { new_line:; anzahl = read(new_sck,smtp_rec,sizeof(smtp_rec)); smtp_rec[anzahl-1]=0; printf("\n\nRECIEVE > %s\n", smtp_rec); if(mail_empfang == 1) { if(strncmp(smtp_rec, "QUIT",4) == 0 || strncmp(smtp_rec, "quit",4) == 0) { goto skip; } // Wahrscheinlich: Wenn kein \n mehr vorhanden, stürzt er ab... //=> Bessere Lösung finden datei = fopen ("fakemail.txt", "a"); fprintf (datei, msg_get); fprintf (datei, ""); fclose(datei); skip:; mail_empfang=0; } if(strstr( smtp_rec, "HELO" )) { sprintf(smtp,"250 OK\n"); write(new_sck,smtp,strlen(smtp)); printf("SEND > 250 OK\n"); goto new_line; } if( strstr( smtp_rec, "EHLO" )) { sprintf(smtp,"502 5.5.2 Error: command not recognized\n"); write(new_sck,smtp,strlen(smtp)); printf("END > 502 5.5.2 Error: command not recognized\n"); goto new_line; } if( strstr( smtp_rec, "MAIL" ) || strstr( smtp_rec, "mail" )) { mailf = 1; mail_split(); sprintf(smtp,"250 OK\n"); write(new_sck,smtp,strlen(smtp)); printf("SEND > 250 OK\n"); goto new_line; } if( strstr( smtp_rec, "RCPT" ) || strstr( smtp_rec, "rcpt" )) { rcpt=1; mail_split(); sprintf(smtp,"250 OK\n"); write(new_sck,smtp,strlen(smtp)); printf("SEND > 250 OK\n"); goto new_line; } if( strstr( smtp_rec, "DATA" ) || strstr( smtp_rec, "data" )) { sprintf(smtp,"354 Start mail input; end with <CRLF>.<CRLF>.\n"); write(new_sck,smtp,strlen(smtp)); printf("\n SEND > 354 Start mail input; end with <CRLF>.<CRLF>.\n"); datei = fopen ("fakemail.txt", "a"); struct tm *zeit; time_t sekunde; char time_str[80]; time(&sekunde); zeit = localtime(&sekunde); strftime(time_str, 80, "%a, %d %b %Y %H:%M:%S",zeit); fprintf (datei, "###############################################\n"); fprintf (datei, "Recieved @ %s)\n",time_str); fprintf (datei, "Mail from: "); fprintf(datei, mailfrom); fprintf(datei, "\n"); fprintf (datei, "Mail to: "); fprintf(datei, rcpto); fprintf(datei, "\n"); fprintf (datei, "###############################################\n"); fclose(datei); mail_empfang = 1; goto new_line; } if( strstr( smtp_rec, "QUIT" ) || strstr( smtp_rec, "quit" )) { if(mail_empfang == 1) { sprintf(smtp,"500 You had nothing to say? Idiot!\n"); write(new_sck,smtp,strlen(smtp)); } sprintf(smtp,"221 Have a nice day :-)\n"); write(new_sck,smtp,strlen(smtp)); printf("SEND > 221 Have a nice day :-)\n"); printf("\n SERVER > Closed conection with: %s\n\n",inet_ntoa(clientinfo.sin_addr)); close(new_sck); new_sck = 0; datei = fopen ("fakemail.txt", "a"); fprintf (datei, "\n------------------------------------------------------------------------------------------------------------\n\n\n"); close(datei); mail_empfang = 0; goto wait_again; } fails +=1; if(fails == 7) { sprintf(smtp,"421 4.7.0 You are stupid, get lost!\n"); write(new_sck,smtp,strlen(smtp)); printf("\n SEND > 421 4.7.0 You are stupid, get lost!\n"); printf("\n SERVER > Closed conection with: %s\n\n",inet_ntoa(clientinfo.sin_addr)); close(new_sck); new_sck = 0; fails = 0; goto wait_again; } if(mail_empfang == 0) { printf(smtp,"500 5.5.2 Error: What the fuck?\n"); write(new_sck,smtp,strlen(smtp)); printf("\n SEND > 500 5.5.2 Error: What the fuck?\n"); } } } int mail_split() { p_len = strstr(smtp_rec, ":"); ptr = strtok(smtp_rec, ":"); op_pos = p_len - smtp_rec; while(ptr != NULL){ if(mailf == 1) { for (i = 0; i <= 100; i++) { mailfrom[i] = *(ptr+i); } } if(rcpt == 1) { for (i = 0; i <= 100; i++) { rcpto[i] = *(ptr+i); } } ptr = strtok(NULL, ":"); } mailf=0; rcpt=0; } char* replace(const char* s, const char* find, const char* replace) { const char* p; char* ret; p = strstr(s, find); if (p == NULL) return NULL; ret = malloc(strlen(s) + strlen(replace) + 1 - strlen(find)); if (ret == NULL) return NULL; if (p != s) strncpy(ret, s, p-s); strcpy(ret + (p-s), replace); strcat(ret, p + strlen(find)); return ret; }
-
Immer wieder das Gleiche:
- keine globalen Variablen
- kein strtok
- read/write immer in einer Schleife benutzen (aber nicht so wie du)
- immer Rückgabewerte auswerten (auch bei write)
- perror benutzen (das spart das Rumrätseln wie bei dir gerade)statt smtp_rec[anzahl-1]=0; /* falls anzahl==0 ist (bedeutet EOF) ist das hier auch noch UB */ muss es heißen: smtp_rec[anzahl]=0; aber natürlich nur bei anzahl != -1
- ... u.v.m.
-
Ja, danke,
Ich bin nunmal noch Anfänger und Programmiere in C erst seit
einem Monat. Werde die Fehler beheben so gut ich es kann und mich
erneut melden