|
34 | 34 |
|
35 | 35 | #include "EMailSender.h"
|
36 | 36 | #include <stdio.h>
|
| 37 | +#if defined(ESP32) |
| 38 | +#include <mbedtls/base64.h> |
| 39 | +#endif |
| 40 | + |
37 | 41 | //#include <SPIFFS.h>
|
38 | 42 | //#include <LittleFS.h>
|
39 | 43 |
|
@@ -624,7 +628,70 @@ EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte s
|
624 | 628 | // String auth = "AUTH PLAIN "+String(encode64(logPass));
|
625 | 629 | DEBUG_PRINTLN(auth);
|
626 | 630 | client.println(auth);
|
627 |
| - }else{ |
| 631 | + } |
| 632 | +#if defined(ESP32) |
| 633 | + else if (this->isCramMD5Login == true) { |
| 634 | + DEBUG_PRINTLN(F("AUTH CRAM-MD5")); |
| 635 | + client.println(F("AUTH CRAM-MD5")); |
| 636 | + |
| 637 | + // read back the base64 encoded digest. |
| 638 | + // |
| 639 | + response = awaitSMTPResponse(client,"334","No digest error"); |
| 640 | + if (!response.status) { |
| 641 | + client.flush(); |
| 642 | + client.stop(); |
| 643 | + return response; |
| 644 | + }; |
| 645 | + _serverResponce = _serverResponce.substring(4); // '334<space>' |
| 646 | + |
| 647 | + size_t b64l = _serverResponce.length()-1; // C vs C++ counting of \0 |
| 648 | + const unsigned char * b64 = (const unsigned char *)_serverResponce.c_str(); |
| 649 | + DEBUG_PRINTLN("B64digest="+String((char *)b64) + " Len=" + String((int)b64l)); |
| 650 | + |
| 651 | + unsigned char digest[256]; |
| 652 | + size_t len; |
| 653 | + |
| 654 | + int e = mbedtls_base64_decode(digest, sizeof(digest), &len, b64, b64l); |
| 655 | + if (e || len < 3 || len >= 256) { |
| 656 | + response.code = F("999"); |
| 657 | + response.desc = F("Invalid digest"); |
| 658 | + response.status = false; |
| 659 | + client.flush(); |
| 660 | + client.stop(); |
| 661 | + return response; |
| 662 | + }; |
| 663 | + |
| 664 | + // calculate HMAC with the password as the key of this digest. |
| 665 | + // |
| 666 | + mbedtls_md_context_t ctx; |
| 667 | + mbedtls_md_type_t md_type = MBEDTLS_MD_MD5; |
| 668 | + unsigned char md5[16]; |
| 669 | + |
| 670 | + mbedtls_md_init(&ctx); |
| 671 | + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1); |
| 672 | + mbedtls_md_hmac_starts(&ctx, |
| 673 | + (const unsigned char *)this->email_password, strlen(this->email_password)); |
| 674 | + mbedtls_md_hmac_update(&ctx, digest, len); |
| 675 | + mbedtls_md_hmac_finish(&ctx, md5); |
| 676 | + mbedtls_md_free(&ctx); |
| 677 | + |
| 678 | + // build an output string of the username followed by the __lowercase__ hex of the md5 |
| 679 | + // |
| 680 | + String rsp = String(this->email_login) + " "; |
| 681 | + for(int i = 0; i < sizeof(md5); i++) { |
| 682 | + unsigned char c = md5[i]; |
| 683 | + char h[16+1] = "0123456789abcdef"; |
| 684 | + rsp += String(h[ (c >> 4) &0xF]) + String(h[ (c >> 0) &0xF]); |
| 685 | + }; |
| 686 | + |
| 687 | + // And submit this to the server as a login string. |
| 688 | + DEBUG_PRINTLN(encode64((char*)rsp.c_str())); |
| 689 | + client.println(encode64((char*)rsp.c_str())); |
| 690 | + |
| 691 | + // now exepct the normal login confirmation to continue. |
| 692 | + } |
| 693 | +#endif |
| 694 | + else{ |
628 | 695 | DEBUG_PRINTLN(F("AUTH LOGIN:"));
|
629 | 696 | client.println(F("AUTH LOGIN"));
|
630 | 697 | awaitSMTPResponse(client);
|
|
0 commit comments