Commit 6cfed42b5e83a589b290a47322535af519241c61
1 parent
fc73565d
Slight refactor of unit-test-client
Showing
1 changed file
with
89 additions
and
79 deletions
tests/unit-test-client.c
| @@ -30,6 +30,8 @@ enum { | @@ -30,6 +30,8 @@ enum { | ||
| 30 | RTU | 30 | RTU |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | +int test_raw_request(modbus_t *, int); | ||
| 34 | + | ||
| 33 | int main(int argc, char *argv[]) | 35 | int main(int argc, char *argv[]) |
| 34 | { | 36 | { |
| 35 | uint8_t *tab_rp_bits; | 37 | uint8_t *tab_rp_bits; |
| @@ -699,85 +701,8 @@ int main(int argc, char *argv[]) | @@ -699,85 +701,8 @@ int main(int argc, char *argv[]) | ||
| 699 | } | 701 | } |
| 700 | 702 | ||
| 701 | /** RAW REQUEST */ | 703 | /** RAW REQUEST */ |
| 702 | - printf("\nTEST RAW REQUESTS:\n"); | ||
| 703 | - { | ||
| 704 | - int j; | ||
| 705 | - const int RAW_REQ_LENGTH = 6; | ||
| 706 | - uint8_t raw_req[] = { | ||
| 707 | - (use_backend == RTU) ? SERVER_ID : 0xFF, | ||
| 708 | - 0x03, 0x00, 0x01, 0x0, 0x05, | ||
| 709 | - }; | ||
| 710 | - int req_length; | ||
| 711 | - uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH]; | ||
| 712 | - int tab_function[] = {0x01, 0x02, 0x03, 0x04}; | ||
| 713 | - int tab_nb_max[] = { | ||
| 714 | - MODBUS_MAX_READ_BITS + 1, | ||
| 715 | - MODBUS_MAX_READ_BITS + 1, | ||
| 716 | - MODBUS_MAX_READ_REGISTERS + 1, | ||
| 717 | - MODBUS_MAX_READ_REGISTERS + 1 | ||
| 718 | - }; | ||
| 719 | - | ||
| 720 | - req_length = modbus_send_raw_request(ctx, raw_req, | ||
| 721 | - RAW_REQ_LENGTH * sizeof(uint8_t)); | ||
| 722 | - | ||
| 723 | - printf("* modbus_send_raw_request: "); | ||
| 724 | - if ((use_backend == RTU && req_length == (RAW_REQ_LENGTH + 2)) || | ||
| 725 | - ((use_backend == TCP || use_backend == TCP_PI) && | ||
| 726 | - req_length == (RAW_REQ_LENGTH + 6))) { | ||
| 727 | - printf("OK\n"); | ||
| 728 | - } else { | ||
| 729 | - printf("FAILED (%d)\n", req_length); | ||
| 730 | - goto close; | ||
| 731 | - } | ||
| 732 | - | ||
| 733 | - printf("* modbus_receive_confirmation: "); | ||
| 734 | - rc = modbus_receive_confirmation(ctx, rsp); | ||
| 735 | - if ((use_backend == RTU && rc == 15) || | ||
| 736 | - ((use_backend == TCP || use_backend == TCP_PI) && | ||
| 737 | - rc == 19)) { | ||
| 738 | - printf("OK\n"); | ||
| 739 | - } else { | ||
| 740 | - printf("FAILED (%d)\n", rc); | ||
| 741 | - goto close; | ||
| 742 | - } | ||
| 743 | - | ||
| 744 | - /* Try to crash server with raw requests to bypass checks of client. */ | ||
| 745 | - | ||
| 746 | - /* Address */ | ||
| 747 | - raw_req[2] = 0; | ||
| 748 | - raw_req[3] = 0; | ||
| 749 | - | ||
| 750 | - /* Try to read more values than a response could hold for all data | ||
| 751 | - * types. | ||
| 752 | - */ | ||
| 753 | - for (i=0; i<4; i++) { | ||
| 754 | - raw_req[1] = tab_function[i]; | ||
| 755 | - | ||
| 756 | - for (j=0; j<2; j++) { | ||
| 757 | - if (j == 0) { | ||
| 758 | - /* Try to read zero values on first iteration */ | ||
| 759 | - raw_req[4] = 0x00; | ||
| 760 | - raw_req[5] = 0x00; | ||
| 761 | - } else { | ||
| 762 | - /* Try to read max values + 1 on second iteration */ | ||
| 763 | - raw_req[4] = (tab_nb_max[i] >> 8) & 0xFF; | ||
| 764 | - raw_req[5] = tab_nb_max[i] & 0xFF; | ||
| 765 | - } | ||
| 766 | - | ||
| 767 | - req_length = modbus_send_raw_request(ctx, raw_req, | ||
| 768 | - RAW_REQ_LENGTH * sizeof(uint8_t)); | ||
| 769 | - printf("* try an exploit on function %d: ", tab_function[i]); | ||
| 770 | - rc = modbus_receive_confirmation(ctx, rsp); | ||
| 771 | - if (rc == 9 && | ||
| 772 | - rsp[7] == (0x80 + tab_function[i]) && | ||
| 773 | - rsp[8] == MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE) { | ||
| 774 | - printf("OK\n"); | ||
| 775 | - } else { | ||
| 776 | - printf("FAILED\n"); | ||
| 777 | - goto close; | ||
| 778 | - } | ||
| 779 | - } | ||
| 780 | - } | 704 | + if (test_raw_request(ctx, use_backend) == -1) { |
| 705 | + goto close; | ||
| 781 | } | 706 | } |
| 782 | 707 | ||
| 783 | printf("\nALL TESTS PASS WITH SUCCESS.\n"); | 708 | printf("\nALL TESTS PASS WITH SUCCESS.\n"); |
| @@ -793,3 +718,88 @@ close: | @@ -793,3 +718,88 @@ close: | ||
| 793 | 718 | ||
| 794 | return 0; | 719 | return 0; |
| 795 | } | 720 | } |
| 721 | + | ||
| 722 | +int test_raw_request(modbus_t *ctx, int use_backend) | ||
| 723 | +{ | ||
| 724 | + int rc; | ||
| 725 | + int i, j; | ||
| 726 | + const int RAW_REQ_LENGTH = 6; | ||
| 727 | + uint8_t raw_req[] = { | ||
| 728 | + (use_backend == RTU) ? SERVER_ID : 0xFF, | ||
| 729 | + 0x03, 0x00, 0x01, 0x0, 0x05, | ||
| 730 | + }; | ||
| 731 | + int req_length; | ||
| 732 | + uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH]; | ||
| 733 | + int tab_function[] = {0x01, 0x02, 0x03, 0x04}; | ||
| 734 | + int tab_nb_max[] = { | ||
| 735 | + MODBUS_MAX_READ_BITS + 1, | ||
| 736 | + MODBUS_MAX_READ_BITS + 1, | ||
| 737 | + MODBUS_MAX_READ_REGISTERS + 1, | ||
| 738 | + MODBUS_MAX_READ_REGISTERS + 1 | ||
| 739 | + }; | ||
| 740 | + | ||
| 741 | + printf("\nTEST RAW REQUESTS:\n"); | ||
| 742 | + | ||
| 743 | + req_length = modbus_send_raw_request(ctx, raw_req, | ||
| 744 | + RAW_REQ_LENGTH * sizeof(uint8_t)); | ||
| 745 | + | ||
| 746 | + printf("* modbus_send_raw_request: "); | ||
| 747 | + if ((use_backend == RTU && req_length == (RAW_REQ_LENGTH + 2)) || | ||
| 748 | + ((use_backend == TCP || use_backend == TCP_PI) && | ||
| 749 | + req_length == (RAW_REQ_LENGTH + 6))) { | ||
| 750 | + printf("OK\n"); | ||
| 751 | + } else { | ||
| 752 | + printf("FAILED (%d)\n", req_length); | ||
| 753 | + return -1; | ||
| 754 | + } | ||
| 755 | + | ||
| 756 | + printf("* modbus_receive_confirmation: "); | ||
| 757 | + rc = modbus_receive_confirmation(ctx, rsp); | ||
| 758 | + if ((use_backend == RTU && rc == 15) || | ||
| 759 | + ((use_backend == TCP || use_backend == TCP_PI) && | ||
| 760 | + rc == 19)) { | ||
| 761 | + printf("OK\n"); | ||
| 762 | + } else { | ||
| 763 | + printf("FAILED (%d)\n", rc); | ||
| 764 | + return -1; | ||
| 765 | + } | ||
| 766 | + | ||
| 767 | + /* Try to crash server with raw requests to bypass checks of client. */ | ||
| 768 | + | ||
| 769 | + /* Address */ | ||
| 770 | + raw_req[2] = 0; | ||
| 771 | + raw_req[3] = 0; | ||
| 772 | + | ||
| 773 | + /* Try to read more values than a response could hold for all data | ||
| 774 | + * types. | ||
| 775 | + */ | ||
| 776 | + for (i=0; i<4; i++) { | ||
| 777 | + raw_req[1] = tab_function[i]; | ||
| 778 | + | ||
| 779 | + for (j=0; j<2; j++) { | ||
| 780 | + if (j == 0) { | ||
| 781 | + /* Try to read zero values on first iteration */ | ||
| 782 | + raw_req[4] = 0x00; | ||
| 783 | + raw_req[5] = 0x00; | ||
| 784 | + } else { | ||
| 785 | + /* Try to read max values + 1 on second iteration */ | ||
| 786 | + raw_req[4] = (tab_nb_max[i] >> 8) & 0xFF; | ||
| 787 | + raw_req[5] = tab_nb_max[i] & 0xFF; | ||
| 788 | + } | ||
| 789 | + | ||
| 790 | + req_length = modbus_send_raw_request(ctx, raw_req, | ||
| 791 | + RAW_REQ_LENGTH * sizeof(uint8_t)); | ||
| 792 | + printf("* try an exploit on function %d: ", tab_function[i]); | ||
| 793 | + rc = modbus_receive_confirmation(ctx, rsp); | ||
| 794 | + if (rc == 9 && | ||
| 795 | + rsp[7] == (0x80 + tab_function[i]) && | ||
| 796 | + rsp[8] == MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE) { | ||
| 797 | + printf("OK\n"); | ||
| 798 | + } else { | ||
| 799 | + printf("FAILED\n"); | ||
| 800 | + return -1; | ||
| 801 | + } | ||
| 802 | + } | ||
| 803 | + } | ||
| 804 | + return 0; | ||
| 805 | +} |