karastojko / mailio

mailio is a cross platform C++ library for MIME format and SMTP, POP3 and IMAP protocols. It is based on standard C++ 17 and Boost library.
Other
372 stars 98 forks source link

parsing imap resp-text #138

Open yjm6560 opened 1 year ago

yjm6560 commented 1 year ago

https://www.rfc-editor.org/rfc/rfc3501#section-9

response        = *(continue-req / response-data) response-done
response-done   = response-tagged / response-fatal
response-tagged = tag SP resp-cond-state CRLF
resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
                    ; Status condition
resp-text       = ["[" resp-text-code "]" SP] text

text            = 1*TEXT-CHAR
TEXT-CHAR       = <any CHAR except CR and LF>

resp-text comes after tag and status in tagged response(response-done) and it can be all characters except CR and LF. https://github.com/karastojko/mailio/blob/75db981761cdc1fbf47a48f2f8f45fa283ed3781/src/imap.cpp#L247-L249 however mailio::imap::parse_response tries to parse it and can raise exception in following example.

e.g. mailbox name is mailbox) and gmail imap server sends it in resp-text.

$ openssl s_client -connect imap.gmail.com:993 -quiet -crlf
... # login
2 SELECT "mailbox)" # send SELECT command
# receive response
... # receive untagged response
2 OK [READ-WRITE] mailbox) selected. (Success) # tagged response. resp-text is "mailbox) selected. (Success)"

mailio::imap::parse_response tries to parse [READ-WRITE] mailbox) selected. (Success) and raise exception since parenthesis_counter is 0. https://github.com/karastojko/mailio/blob/75db981761cdc1fbf47a48f2f8f45fa283ed3781/src/imap.cpp#L1171-L1178

this problem can occurs in untagged status response like * BYE test))) data is invalid.

in additionally, it looks there is no part checking if status is PREAUTH and BYE in untagged status response.