Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 30/05/2014, à 00:46

moi4567

[C++] Envoi de mails!

Bonjour à tous smile

Je "travail" en ce moment sur un projet où j'ai besoin d'envoyer un mail à une adresse précise. Je suis donc aller demandé à mon amis Google si il n'avait pas ça sous la main et je suis tombé là dessus. Je ne souhaite pas réinventer la roue, j'ai donc simplement repris le code source cool.

Je me suis donc mis a faire quelques tests, régler ce qui n'allait pas ect... Seulement voilà, il y a une erreur que je n'arrive pas à résoudre seul. Je pense que cela viens de l'instruction "DATA:" mais je n'en suis pas sur. Voici le résultat:

Connecté au serveur smtp.bbox.fr
En attente de la reponse ...

220 mail-3y.bbox.fr ESMTP Postfix

250-mail-3y.bbox.fr
250-PIPELINING
250-SIZE 28735780
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
250 2.1.0 Ok
250 2.1.5 Ok
221 2.7.0 Error: I can break rules, too. Goodbye.

Socket fermé.

J'ai déjà fait mes recherches et je suis tombé sur d'autres personnes avec le même problème mais pas de solutions réelles. Je suppose que cette erreur (221 2.7.0 Error: I can break rules, too. Goodbye.) viens de l'instruction "DATA:" mais ce ne sont que des suppositions yikes.

Savez-vous comment régler ce problème? smile

Merci d'avance wink

EDIT: Voici mon code source, ça peux servir ^^'
Dites le moi si il vous le faut en entier smile

char lemail[] = "EHLO bbox.fr\r\n"
		"MAIL FROM: <exemple@test.com>\n"
		"RCPT TO: <exemple@gmail.com>\n"

		"DATA:\r\n"
		"Essayons ça comme message."
		"Avec plusieurs lignes."
		".\r\n"

		"QUIT\r\n\r\n";

Dernière modification par moi4567 (Le 30/05/2014, à 00:50)

Hors ligne

#2 Le 30/05/2014, à 08:38

Brunod

Re : [C++] Envoi de mails!

Tu n'as pas besoin d'authentification pour l'envoi par smtp ?


Windows est un système d'exploitation de l'homme par l'ordinateur. Linux, c'est le contraire...
39 pc linux convertis

Hors ligne

#3 Le 30/05/2014, à 08:46

omc

Re : [C++] Envoi de mails!

Bonjour,
Beaucoup de serveurs smtp sont ultra-parano.
Si ils détectent la moindre anomalie ils refusent le mail.

As-tu essayer d'envoyer un mail avec telnet ?

Dernière modification par omc (Le 30/05/2014, à 08:47)

Hors ligne

#4 Le 30/05/2014, à 09:17

bruno

Re : [C++] Envoi de mails!

Bonjour,

Je vois au moins une erreur :

DATA:

n'est pas une commande SMTP valide, c'est juste DATA sans les :


Edit: le serveur qui reçoit le courriel va probablement le refuser en disant que le message n'est pas conforme à la RFC 2822. Il faut rajouter les en-têtes From et To après la commande DATA :

DATA
From : <envoyeur@example.com>
To: <destinataire@example.com>
Subject: ceci n'est pas un essai

montexte 
.

Dernière modification par bruno (Le 30/05/2014, à 09:33)

Hors ligne

#5 Le 30/05/2014, à 10:38

claudius01

Re : [C++] Envoi de mails!

Bonjour,

moi4567 a écrit :

Je ne souhaite pas réinventer la roue, j'ai donc simplement repris le code source...

Il y a aussi sendmail qui permettra au moins de lever le doute sur les éventuelles authentifications et autres données invalides dans le courrier...


Cordialement, A+
--
Claudius

Hors ligne

#6 Le 30/05/2014, à 18:01

moi4567

Re : [C++] Envoi de mails!

Bonjour à tous smile
Merci de vos réponses je n'en attendais pas tant ^^

Brunod a écrit :

Tu n'as pas besoin d'authentification pour l'envoi par smtp ?

@Brunod : J'espère pas, j'ai essayé avec la commande sendmail mais elle n'envoie rien non plus... Il me semble bien qu'il est possible d'envoyer des mails même à partir d'une adresse n'existant même pas. Donc a priori, je ne pense pas avoir besoin d'authentification et je préférerais ne pas avoir à l'utiliser. Après si j'ai pas le choix je ferrais avec  smile.


omc a écrit :

Bonjour,
Beaucoup de serveurs smtp sont ultra-parano.
Si ils détectent la moindre anomalie ils refusent le mail.

As-tu essayer d'envoyer un mail avec telnet ?

@omc : Non, pourquoi? Ca changerais quelque chose (sachant que mon problème semble venir des commandes serveur)? yikes


Bruno a écrit :

Bonjour,

Je vois au moins une erreur :

DATA:

n'est pas une commande SMTP valide, c'est juste DATA sans les :

Edit: le serveur qui reçoit le courriel va probablement le refuser en disant que le message n'est pas conforme à la RFC 2822. Il faut rajouter les en-têtes From et To après la commande DATA :

DATA
From : <envoyeur@example.com>
To: <destinataire@example.com>
Subject: ceci n'est pas un essai

montexte 
.

@bruno : J'ai modifié l'erreur dans la commande "DATA". Cependant le serveur ne l'accepte pas mad
PS: Les modifications que j'ai apportées sont plus bas.


claudius01 a écrit :

Bonjour,

   

moi4567 a écrit :

Je ne souhaite pas réinventer la roue, j'ai donc simplement repris le code source...

Il y a aussi sendmail qui permettra au moins de lever le doute sur les éventuelles authentifications et autres données invalides dans le courrier...

Cordialement, A+
--
Claudius

@Claudius : J'ai essayé la commande sendmail et elle n'envoie rien. Soit j'ai ce fameux problème d'authentification, soit j'ai mal utilisé la commande. Voici comment je m'y prend:

sendmail exemple@gmail.com < /mail.txt

(Le tout en root)


Les modifications:

Désormais mes commandes pour le serveur sont les suivantes smile :

char lemail[] = "EHLO bbox.fr\r\n"
		"MAIL FROM: <exemple@test.com>\n"
		"RCPT TO: <exemple@gmail.com>\n"
		"DATA\r\n"
		"Subject: Petit test\r\n"
 		"FROM: <exemple@test.com>\r\n"
		"TO: <exemple@gmail.com>\r\n"
		"Essayons ça comme message\r\n"
		"Avec plusieurs lignes!r\n"
		".\r\n"
		"QUIT\r\n\r\n";

Le retour:

Connecté au serveur smtp.bbox.fr
En attente de la reponse ...

220 mail-2y.bbox.fr ESMTP Postfix

250-mail-2y.bbox.fr
250-PIPELINING
250-SIZE 28735780
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
250 2.1.0 Ok
250 2.1.5 Ok
503 5.5.0 <DATA>: Data command rejected: Improper use of SMTP command pipelining
221 2.7.0 Error: I can break rules, too. Goodbye.

Socket fermé.

Hors ligne

#7 Le 30/05/2014, à 20:42

pires57

Re : [C++] Envoi de mails!

<?php
     $to      = 'adresse@mail.com';
     $subject = 'Mail PHP';
     $message = 'Bonjour, comme je me fais chier je me suis un peu amusé ce soir';
     $headers = 'From: me@mail.com' . "\r\n" .
     'Reply-To: me@mail.com' . "\r\n" .
     'X-Mailer: PHP/' . phpversion();

     mail($to, $subject, $message, $headers);
 ?>

Utilisateur d'Archlinux, Ubuntu et Kali Linux
Administrateur système et réseau spécialisé Linux.
LinkedIn

Hors ligne

#8 Le 01/06/2014, à 17:57

tiramiseb

Re : [C++] Envoi de mails!

Salut,

Pourquoi "\r\n" en fin de ligne ? C'est sous Windows qu'on utilise "\r\n". Le protocole SMTP utilise, comme tous les trucs "normaux", un simple "\n" pour le retour à la ligne...

Hors ligne

#9 Le 01/06/2014, à 18:06

pires57

Re : [C++] Envoi de mails!

Et bien voila tiramiseb tu t'es répondu tout seul, lorsque j'ai codé ce bout de script j'étais dans un environnement windows


Utilisateur d'Archlinux, Ubuntu et Kali Linux
Administrateur système et réseau spécialisé Linux.
LinkedIn

Hors ligne

#10 Le 01/06/2014, à 18:18

tiramiseb

Re : [C++] Envoi de mails!

pires57 : hu ? Je parle à mol4567...

mol4567: autre idée, essaye de remplacer "EHLO" par "HELO".

Hors ligne

#11 Le 01/06/2014, à 18:44

pires57

Re : [C++] Envoi de mails!

je l'avais pris pour moi, j'ai fait la même chose dans mon php^^


Utilisateur d'Archlinux, Ubuntu et Kali Linux
Administrateur système et réseau spécialisé Linux.
LinkedIn

Hors ligne

#12 Le 01/06/2014, à 19:47

bruno

Re : [C++] Envoi de mails!

Il faut utiliser \r\n (CRLF) dans un dialogue SMTP. cf. http://www.ietf.org/rfc/rfc2822.txt section 2

Hors ligne

#13 Le 01/06/2014, à 20:17

tiramiseb

Re : [C++] Envoi de mails!

Ah oui. Au temps pour moi. Toutes mes excuses smile

Hors ligne

#14 Le 01/06/2014, à 21:37

moi4567

Re : [C++] Envoi de mails!

tiramiseb a écrit :

pires57 : hu ? Je parle à mol4567...

mol4567: autre idée, essaye de remplacer "EHLO" par "HELO".

Déjà essayé, ça ne change rien hmm

Hors ligne

#15 Le 01/06/2014, à 21:42

tiramiseb

Re : [C++] Envoi de mails!

Et éventuellement le nom que tu présentes après le "HELO" ou le "EHLO" : il refuse peut-être que tu te présentes comme "bbox.fr"...

Tu as essayé à la main ?

Hors ligne

#16 Le 01/06/2014, à 21:45

moi4567

Re : [C++] Envoi de mails!

Toujours le même problème, même à la main hmm
(improper use of smtp command pipelining)

Hors ligne

#17 Le 01/06/2014, à 22:05

tiramiseb

Re : [C++] Envoi de mails!

Peux-tu nous montrer un copier-coller complet de ta tentative à la main, tout compris (du prompt de la commande au prompt suivant) ?

Hors ligne

#18 Le 02/06/2014, à 10:58

eiger

Re : [C++] Envoi de mails!

Essaie de couper ton buffer en 2 parties, comme ceci:

char lemail[] = "EHLO bbox.fr\r\n"
		"MAIL FROM: <exemple@test.com>\n"
		"RCPT TO: <exemple@gmail.com>\n"
		"DATA\r\n";
char lemail2[] = "Subject: Petit test\r\n"
 		"FROM: <exemple@test.com>\r\n"
		"TO: <exemple@gmail.com>\r\n"
		"Essayons ça comme message\r\n"
		"Avec plusieurs lignes!r\n"
		".\r\n"
		"QUIT\r\n\r\n";

et envoie le 2e paquet uniquement après avoir reçu une réponse intermédiaire positive du serveur.

Hors ligne

#19 Le 02/06/2014, à 11:01

tiramiseb

Re : [C++] Envoi de mails!

eiger: c'est une bonne idée, très bonne piste je dirais même. Cela dit, c'est dans cet esprit que j'ai demandé si le test à la main fonctionne. Mais j'ai oublié de préciser qu'avec le test à la main il faut attendre les réponses du serveur smile

Hors ligne

#20 Le 02/06/2014, à 13:35

eiger

Re : [C++] Envoi de mails!

tiramiseb a écrit :

eiger: c'est une bonne idée, très bonne piste je dirais même. Cela dit, c'est dans cet esprit que j'ai demandé si le test à la main fonctionne. Mais j'ai oublié de préciser qu'avec le test à la main il faut attendre les réponses du serveur smile

En effet, en testant à la main, cela devrait fonctionner.

D'ailleurs pour préciser mon premier message, je pense qu'il faudrait même découper le message en 3. Il faudrait attendre la réponse au premier EHLO. En effet, ici on envoie toutes les commandes en vrac, sans s'être assuré que le serveur supporte le pipelining. Le serveur répond PIPELINING en réponse au EHLO. S'il vérifie la séquence, il est parfaitement en droit de refuser le paquet de commandes, s'il détecte qu'on a envoyé 4 commandes sans avoir attendu la réponse au EHLO.

Mais en effet, en testant à la main, on devrait pouvoir vérifier tout ça.

Hors ligne

#21 Le 02/06/2014, à 14:25

bruno

Re : [C++] Envoi de mails!

Je ne pense pas que cela pose un problème quelconque au serveur SMTP de recevoir les commandes en « bloc », à partir du moment où elle sont acheminées correctement, c'est à dire séparées par des CRLF ce qui n'est pas le cas dans le code copié ici.

Il faut un \r\n après les commandes MAIL FROM et RCPT TO

Mai il faudrait déjà être sur que tu arrives à envoyer un courriel avec telnet :

telnet smtp.bbox.fr 25

Hors ligne

#22 Le 02/06/2014, à 14:47

eiger

Re : [C++] Envoi de mails!

bruno a écrit :

Je ne pense pas que cela pose un problème quelconque au serveur SMTP de recevoir les commandes en « bloc », à partir du moment où elle sont acheminées correctement, c'est à dire séparées par des CRLF ce qui n'est pas le cas dans le code copié ici.

Je pense que cela peut poser problème si le protocole n'est pas respecté. Le fait d'envoyer les commandes en bloc s'appelle "pipelining". C'est une extension au protocole SMTP de base. SMTP fonctionne à la base selon un modèle séquentiel "une commande - une réponse". Voir la RFC 1854 à ce sujet. Le serveur SMTP signale le support du pipelining dans sa réponse au EHLO. Avant cette réponse, un client SMTP ne devrait pas supposer que le pipelining est supporté. Un serveur pointilleux peut très bien se plaindre du non-respect du pipelining si un client lui envoie 4 commandes sans attendre la réponse au EHLO.

A priori, si l'on en croit la doc de Postfix, ce comportement du serveur peut être contrôlé par "reject_unauth_pipelining". Si cette option est activée et que l'on n'a pas la main sur le serveur, il ne doit pas rester beaucoup d'autres solutions à part respecter la RFC et "pipeliner" uniquement les commandes qui peuvent l'être.

En testant à la main par un telnet sur le port 25 et en envoyant les commandes une à une, le serveur ne devrait plus se plaindre d'un "Improper use of SMTP command pipelining".

Hors ligne

#23 Le 02/06/2014, à 15:02

bruno

Re : [C++] Envoi de mails!

Entièrement d'accord wink Mais moi4567 nous a indiqué le retour de ses commandes. On y voit bien que le « pipelining » est activé et que les premières commandes sont acceptées (MAIL FROM: et RCPT TO:), l'échec se produit au moment d'envoyer la commande DATA…

Hors ligne

#24 Le 02/06/2014, à 15:19

tiramiseb

Re : [C++] Envoi de mails!

Du coup, pour compiler le tout, je propose de tenter une connexion à la main, avec la commande :

telnet smtp.bbox.fr 25

(en changeant "smtp.bbox.fr" selon le nom du serveur à utiliser)
... puis de taper les lignes suivantes une à une, en attendant à chaque fois la réponse du serveur (sauf pour le contenu de DATA bien sûr) :

HELO example.com
MAIL FROM: <exemple@test.com>
RCPT TO: <exemple@gmail.com>
DATA
Petit test d'envoi d'e-mail
.
QUIT

Et si ça marche, se rapprocher progressivement du résultat voulu (pipelining, adresses à utiliser, etc) jusqu'à trouver où est le problème...
(ou alors implémenter le protocole SMTP correctement...)



Cela étant dit, moi4567, je me demande pourquoi tu n'utilises pas une bibliothèque faite pour ça, si tu ne veux pas réinventer la roue.
En cherchant quelques secondes sur Google, j'ai trouvé mention de VMime, libCURL, libquickmail...

Dernière modification par tiramiseb (Le 02/06/2014, à 15:19)

Hors ligne

#25 Le 02/06/2014, à 19:02

moi4567

Re : [C++] Envoi de mails!

tiramiseb a écrit :

Du coup, pour compiler le tout, je propose de tenter une connexion à la main, avec la commande :

telnet smtp.bbox.fr 25

(en changeant "smtp.bbox.fr" selon le nom du serveur à utiliser)
... puis de taper les lignes suivantes une à une, en attendant à chaque fois la réponse du serveur (sauf pour le contenu de DATA bien sûr) :

HELO example.com
MAIL FROM: <exemple@test.com>
RCPT TO: <exemple@gmail.com>
DATA
Petit test d'envoi d'e-mail
.
QUIT

Et si ça marche, se rapprocher progressivement du résultat voulu (pipelining, adresses à utiliser, etc) jusqu'à trouver où est le problème...
(ou alors implémenter le protocole SMTP correctement...)



Merci à vous et à toi tiramiseb pour ce "best of" ^^

J'ai testé à la main, les commandes les une après les autres et aucuns problèmes et lorsque j'essaie tous d'un coup ça ne passe pas. En revanche, je peux l'envoyer en 2 parties:


1er partie:

$ telnet smtp.bbox.fr 25
Trying 194.158.122.55...
Connected to smtp.bbox.fr.
Escape character is '^]'.
220 mail-2y.bbox.fr ESMTP Postfix
HELO bbox.fr
MAIL FROM: <exemple@test.com>
RCPT TO: <zaegffhgjhgfghjtertfgd@yopmail.com>250 mail-2y.bbox.fr
250 2.1.0 Ok

250 2.1.5 Ok

2ème partie:

DATA
Petit test d'envoi d'e-mail
.
QUIT354 End data with <CR><LF>.<CR><LF>
250 2.0.0 Ok: queued as 5711788

221 2.0.0 Bye
Connection closed by foreign host.


J'ai changé l'adresse qui reçois le message par une adresse "jetable" car Gmail classe ça en spam et les bloques (pour des raisons de non-conformité, je suppose).
Donc en 2 fois, ça fonctionne! Si quelqu'un vois une erreur ou un oubli qui peux me permettre d'envoyer mes mails en une fois je prend ^^

tiramiseb a écrit :

Cela étant dit, moi4567, je me demande pourquoi tu n'utilises pas une bibliothèque faite pour ça, si tu ne veux pas réinventer la roue.

Je pensais avoir trouvé ce qu'il me fallait avec ce code et on commence à s'approcher du but big_smile. Cependant c'est vrai que si j'aurais su j'serrais pas v'nu et j'aurais pris une autre fonction. Mais je vais pas abandonner si près du but lol

Hors ligne