I am writing a IRC client in C++ (with the help of the SFML library), but it is behaving strangely. I send the NICK and USER commands and I can connect to the server, but the JOIN command has many strange thing happening that I have to write "Random code that magically works" to solve. I am pretty sure that the commands adhere to the IRC RFC as well.
I know that the sockets are sending what they are supposed to send and I have verified it with Wireshark, so what I post here is what the message of the packet is. In the following examples the socket is already connected to the IRC server (which in this case is irc.freenode.net)
This works:
char mess[] ="NICK lmno \n\rUSER lmno 0 * :lmno\n\rJOIN #mytest\n\r";
Socket.Send(mess, sizeof(mess));
This does not:
char msg[] = "NICK lmno \r\nUSER lmno 0 * :lmno \r\n";
char msga[] = "JOIN #mytest \r\n";
Socket.Send(msg, sizeof(msg));
Socket.Send(msga, sizeof(msga));
But curiously this works:
char msg[] = "NICK lmno \r\nUSER lmno 0 * :lmno \r\n";
char msga[] = "JOIN #mytest \r\n";
Socket.Send(msg, sizeof(msg));
Socket.Send(msga, sizeof(msga));
Socket.Send(msga, sizeof(msga));
I did do some research on this topic and no one seems to have the same problem. Stranger is that when I tried this in telnet, I only have to send JOIN once.
Is anyone able to give me some advice?
Thanks,
SFI
It might have to do with the terminating '\0' character at the end of a c-string. Try
Socket.Send(msg, sizeof(msg) - 1);
Socket.Send(msga, sizeof(msga) - 1);
Related
I want to build an stmp client using c++ for learning purposes.
After I managed to implement the initial connection + auth login I am stuck on sending the message after using the data command.
Here is my code
void sendmail()
{
write_command("MAIL FROM: <foo#bar.de>");
write_command("RCPT TO: <bar.foo#baz.de>");
write_command("DATA");
write_command("Subject: testmail"); // HANGS here after data command
write_command("BlaBlub");
write_command(" ");
write_command(".");
write_command("QUIT");
}
void write_command(std::string command)
{
ssize_t n;
empty_buffer();
command += '\r';
command += '\n';
char command_buffer[255];
strcpy(command_buffer, command.c_str());
n = write(sockfd,command_buffer,strlen(command_buffer));
if (n < 0){
error("ERROR writing to socket");
}
n = read_to_buffer();
if (n < 0) {
error("ERROR reading from socket");
}
printf("%s\n",this->buffer);
}
I'm using smtp.mailtrap.io on port 25.
Here is a gist with the full class https://gist.github.com/xhallix/7f2d87a8b2eab4953d161059c2482b37
Here is the server output
Starting smpt client
220 mailtrap.io ESMTP ready
250-mailtrap.io
250-SIZE 5242880
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-AUTH PLAIN LOGIN CRAM-MD5
250 STARTTLS
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 2.0.0 OK
250 2.1.0 Ok
250 2.1.0 Ok
354 Go ahead
(HANGS HERE)
Thanks for helping me out
DATA command expects the whole mail message, as shown here. The write_command() sends a message by lines and expects response after each line. Since the server returns the response once the mail message is finished (after empty line and dot), it stays in the hanging mode after the first message line. This code snippet can be helpful for your case.
BTW, you should put an empty line between the mail header and body, which I guess is after the subject line. Also, it might happen that the server rejects the message without the From and To headers.
I'm using Qt and I recently made a similar application using gmail. Now, I want to send the email from outlook to gmail. EDIT: I just tried sending from outlook to outlook using an app password but still empty email in my outlook inbox... END EDIT Here is my code:
if(file.open(QIODevice::ReadWrite)){ //Writes in the msg.txt
QTextStream stream(&file);
stream << "From: \"Me\" <xxxxxxxxxx#outlook.com>" << endl;
stream << "To: \"Me\" <xxxxxxxxxxxx#gmail.com>" << endl;
stream << "Subject: Subject" << endl;
stream << msg << endl; //msg is just a QString variable
}
QString cmd = "ccurl smtp://smtp-mail.outlook.com:587 -v --mail-from \"xxxxxxxxxxxx#outlook.com\" --mail-rcpt \"xxxxxxxxxxxx#gmail.com\" --ssl -u xxxxxxxxxxxxxx#outlook.com:xxxxxxxxxxxxxx -T \"msg.txt\" -k --anyauth --insecure & pause";
const std::string s = cmd.toStdString();
const char* ccmd = s.c_str();
system(ccmd);
Pause is just used for testing purposes. Also, my .exe is named 'ccurl' and the console that appears doesn't throw any error. I do receive an email but it just says something like (Empty)
---
Email checked by avast....
Thanks for your help!
Ps. Don't tell me to use libcurl instead
You are missing an empty line between the end of the headers and the start of the message body. Without it, the rest of the message is interpreted as if it was still part of the headers.
Also, endl forces a flush in the stream for no good reason, which kills performance when done on files. Just use \n.
I recently began to use the scapy library for Python 2.x I found there to be minimal documentation on the sniff() function. I began to play around with it and found that I can veiw TCP packets at a very low level. So far I have only found informational data. For example:
Here is what I put in the scapy terminal:
A = sniff(filter="tcp and host 216.58.193.78", count=2)
This is a request to google.com asking for the homepage:
<Ether dst=e8:de:27:55:17:f3 src=00:24:1d:20:a6:1b type=0x800 |<IP version=4L ihl=5L tos=0x0 len=60 id=46627 flags=DF frag=0L ttl=64 proto=tcp chksum=0x2a65 src=192.168.0.2 dst=216.58.193.78 options=[] |<TCP sport=54036 dport=www seq=2948286264 ack=0 dataofs=10L reserved=0L flags=S window=29200 chksum=0x5a62 urgptr=0 options=[('MSS', 1460), ('SAckOK', ''), ('Timestamp', (389403, 0)), ('NOP', None), ('WScale', 7)] |>>>
Here is the response:
<Ether dst=00:24:1d:20:a6:1b src=e8:de:27:55:17:f3 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=60 id=42380 flags= frag=0L ttl=55 proto=tcp chksum=0x83fc src=216.58.193.78 dst=192.168.0.2 options=[] |<TCP sport=www dport=54036 seq=3087468609 ack=2948286265 dataofs=10L reserved=0L flags=SA window=42540 chksum=0xecaf urgptr=0 options=[('MSS', 1430), ('SAckOK', ''), ('Timestamp', (2823173876, 389403)), ('NOP', None), ('WScale', 7)] |>>>
Using this function, is there a way that I can extract HTML code from the response?
Also, what do those packets look like?
And finaly, Why are both of these packets nearly identical?
The segments in your example are "nearly identical" because they are the TCP SYN and SYN-ACK segments which are part of the TCP handshake, HTTP request and response comes after that during the connection (usually when in ESTABLISHED state except when TCP Fast Open option is used) so you need to look at segments after the handshake to get the data you are interested in.
SYN
C ---------------> S
SYN-ACK
C <--------------- S
ACK
C ---------------> S
HTTP request
C ---------------> S
ACK
C <--------------- S
HTTP response
C <--------------- S <= Here is the server's answer
ACK
C ---------------> S
...
You can use Scapy's Raw layer to extract data above TCP in your case (e.g. pkt[Raw])
Have you tried using scapy-http? It's a great scapy extension that helps with this exact issue
I'm developing a RESTful API using Mongoose Web Server. I'm sending a file using
mg_send_file(conn, path, NULL);
but if the file is plain text, or a PDF, it just displays in the browser, instead of forcing the download, which is what I need.
How can I achieve that?
Thanks
--- Update:
I also tried to use
const char* extraHeaders = "Content-Disposition: attachment;
filename=somefilename.txt";
mg_send_file(conn, "somefilename.txt", extraHeaders);
return MG_MORE;
but the connection keeps running, nothing happens.
Final solution was:
const char* extraHeaders = "Content-Disposition: attachment;
filename=\"somefilename.txt\"\r\n";
mg_send_file(conn, "somefilename.txt", extraHeaders);
return MG_MORE;
Note the filename between "", and the \r\n at the end of any extra header.
What means a result of 0x000000be in send command:
iResult = send( ConnectSocket, dataToSend, (int) strlen(dataToSend), 0 );
I didn't found this return code here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
Any ideas?
Thx
The value returned by send is the number of bytes it sent. If it fails it returns SOCKET_ERROR and you use WSAGetLastError to get the error code, which is the codes listed in your link. Read the manual page for send instead.