| 578 | } |
| 579 | |
| 580 | int FtpSSLWrapper::OnSSLCertificate(const SSL * ssl, const X509* certificate, int verifyResult) { |
| 581 | if (certificate == NULL) { |
| 582 | OutErr("[FTPS] No certificate presented by server, aborting connection."); |
| 583 | return UTE_ERROR; |
| 584 | } |
| 585 | |
| 586 | //since the CTX is setup before connections are made, it is possible a previously untrusted certificate becomes trusted but verify_cert |
| 587 | //has no idea of that. This loop allows those certificates to 'pass' as well, as they would have anyway later on |
| 588 | bool previouslyAccepted = false; |
| 589 | int size = (int)m_certificates->size(); |
| 590 | for(int i = 0; i < size; i++) { |
| 591 | if (!X509_cmp(certificate, (X509*)m_certificates->at(i))) { |
| 592 | previouslyAccepted = true; |
| 593 | break; |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | if (verifyResult == X509_V_OK || previouslyAccepted) { |
| 598 | OutMsg("[FTPS] Certificate valid."); |
| 599 | } else { |
| 600 | //X509_error_string(verifyResult); |
| 601 | OutErr("[FTPS] Certificate invalid (%d): %s.", verifyResult, X509_verify_cert_error_string(verifyResult)); |
| 602 | |
| 603 | //MessageDialog md; |
| 604 | //int ret = md.Create(_MainOutputWindow, TEXT("FTP(E)S certificate verification"), TEXT("The certificate is unknown. Do you trust it?")); |
| 605 | static const TCHAR * msgString = |
| 606 | TEXT("The certificate is invalid because of the following reason:\r\n") |
| 607 | TEXT("%s (code %d)\r\n") |
| 608 | TEXT("Do you accept it anyway? ") |
| 609 | TEXT("Please note that it may have other errors as well."); |
| 610 | |
| 611 | TCHAR * msgBuf = SU::TSprintfNB(msgString, X509_verify_cert_error_string(verifyResult), verifyResult); |
| 612 | int ret = MessageBox(_MainOutputWindow, msgBuf, TEXT("FTP(E)S certificate verification"), MB_YESNO | MB_ICONWARNING); |
| 613 | SU::FreeTChar(msgBuf); |
| 614 | if (ret == IDYES) { |
| 615 | OutMsg("[FTPS] Certificate accepted"); |
| 616 | |
| 617 | if (m_certificates) { |
| 618 | SSL_get_peer_certificate(ssl); //increase reference counter |
| 619 | m_certificates->push_back(certificate); |
| 620 | } |
| 621 | } else { |
| 622 | OutMsg("[FTPS] Certificate rejected"); |
| 623 | return UTE_ERROR; |
| 624 | } |
| 625 | } |
| 626 | return UTE_SUCCESS; |
| 627 | } |
| 628 | |
| 629 | BOOL FtpSSLWrapper::IsConnected() { |
| 630 | if (IsDataWaiting()) |