|
@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
36
|
36
|
#include <ipxe/settings.h>
|
37
|
37
|
#include <ipxe/features.h>
|
38
|
38
|
#include <ipxe/base16.h>
|
|
39
|
+#include <ipxe/base64.h>
|
39
|
40
|
#include <ipxe/iscsi.h>
|
40
|
41
|
|
41
|
42
|
/** @file
|
|
@@ -56,7 +57,7 @@ FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 );
|
56
|
57
|
#define EPERM_INITIATOR_AUTHORISATION ( EPERM | EUNIQ_02 )
|
57
|
58
|
#define EPROTO_INVALID_CHAP_ALGORITHM ( EPROTO | EUNIQ_01 )
|
58
|
59
|
#define EPROTO_INVALID_CHAP_IDENTIFIER ( EPROTO | EUNIQ_02 )
|
59
|
|
-#define EPROTO_INVALID_CHAP_CHALLENGE ( EPROTO | EUNIQ_03 )
|
|
60
|
+#define EPROTO_INVALID_LARGE_BINARY ( EPROTO | EUNIQ_03 )
|
60
|
61
|
#define EPROTO_INVALID_CHAP_RESPONSE ( EPROTO | EUNIQ_04 )
|
61
|
62
|
|
62
|
63
|
/** iSCSI initiator name (explicitly specified) */
|
|
@@ -613,6 +614,41 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
|
613
|
614
|
return xfer_deliver_iob ( &iscsi->socket, iobuf );
|
614
|
615
|
}
|
615
|
616
|
|
|
617
|
+/**
|
|
618
|
+ * Calculate maximum length of decoded large binary value
|
|
619
|
+ *
|
|
620
|
+ * @v encoded Encoded large binary value
|
|
621
|
+ * @v max_raw_len Maximum length of raw data
|
|
622
|
+ */
|
|
623
|
+static inline size_t
|
|
624
|
+iscsi_large_binary_decoded_max_len ( const char *encoded ) {
|
|
625
|
+ return ( strlen ( encoded ) ); /* Decoding never expands data */
|
|
626
|
+}
|
|
627
|
+
|
|
628
|
+/**
|
|
629
|
+ * Decode large binary value
|
|
630
|
+ *
|
|
631
|
+ * @v encoded Encoded large binary value
|
|
632
|
+ * @v raw Raw data
|
|
633
|
+ * @ret len Length of raw data, or negative error
|
|
634
|
+ */
|
|
635
|
+static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw ) {
|
|
636
|
+
|
|
637
|
+ if ( encoded[0] != '0' )
|
|
638
|
+ return -EPROTO_INVALID_LARGE_BINARY;
|
|
639
|
+
|
|
640
|
+ switch ( encoded[1] ) {
|
|
641
|
+ case 'x' :
|
|
642
|
+ case 'X' :
|
|
643
|
+ return base16_decode ( ( encoded + 2 ), raw );
|
|
644
|
+ case 'b' :
|
|
645
|
+ case 'B' :
|
|
646
|
+ return base64_decode ( ( encoded + 2 ), raw );
|
|
647
|
+ default:
|
|
648
|
+ return -EPROTO_INVALID_LARGE_BINARY;
|
|
649
|
+ }
|
|
650
|
+}
|
|
651
|
+
|
616
|
652
|
/**
|
617
|
653
|
* Handle iSCSI TargetAddress text value
|
618
|
654
|
*
|
|
@@ -737,24 +773,19 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
|
737
|
773
|
*/
|
738
|
774
|
static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
|
739
|
775
|
const char *value ) {
|
740
|
|
- uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
|
|
776
|
+ uint8_t buf[ iscsi_large_binary_decoded_max_len ( value ) ];
|
741
|
777
|
unsigned int i;
|
742
|
|
- int len;
|
743
|
|
-
|
744
|
|
- /* Check and strip leading "0x" */
|
745
|
|
- if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) {
|
746
|
|
- DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge \"%s\"\n",
|
747
|
|
- iscsi, value );
|
748
|
|
- return -EPROTO_INVALID_CHAP_CHALLENGE;
|
749
|
|
- }
|
|
778
|
+ size_t len;
|
|
779
|
+ int rc;
|
750
|
780
|
|
751
|
781
|
/* Process challenge */
|
752
|
|
- len = base16_decode ( ( value + 2 ), buf );
|
753
|
|
- if ( len < 0 ) {
|
|
782
|
+ rc = iscsi_large_binary_decode ( value, buf );
|
|
783
|
+ if ( rc < 0 ) {
|
754
|
784
|
DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
|
755
|
|
- iscsi, value, strerror ( len ) );
|
756
|
|
- return len;
|
|
785
|
+ iscsi, value, strerror ( rc ) );
|
|
786
|
+ return rc;
|
757
|
787
|
}
|
|
788
|
+ len = rc;
|
758
|
789
|
chap_update ( &iscsi->chap, buf, len );
|
759
|
790
|
|
760
|
791
|
/* Build CHAP response */
|
|
@@ -812,7 +843,7 @@ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
|
812
|
843
|
*/
|
813
|
844
|
static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
|
814
|
845
|
const char *value ) {
|
815
|
|
- uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
|
|
846
|
+ uint8_t buf[ iscsi_large_binary_decoded_max_len ( value ) ];
|
816
|
847
|
size_t len;
|
817
|
848
|
int rc;
|
818
|
849
|
|
|
@@ -832,15 +863,8 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
|
832
|
863
|
( sizeof ( iscsi->chap_challenge ) - 1 ) );
|
833
|
864
|
chap_respond ( &iscsi->chap );
|
834
|
865
|
|
835
|
|
- /* Check and strip leading "0x" */
|
836
|
|
- if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) {
|
837
|
|
- DBGC ( iscsi, "iSCSI %p saw invalid CHAP response \"%s\"\n",
|
838
|
|
- iscsi, value );
|
839
|
|
- return -EPROTO_INVALID_CHAP_RESPONSE;
|
840
|
|
- }
|
841
|
|
-
|
842
|
866
|
/* Process response */
|
843
|
|
- rc = base16_decode ( ( value + 2 ), buf );
|
|
867
|
+ rc = iscsi_large_binary_decode ( value, buf );
|
844
|
868
|
if ( rc < 0 ) {
|
845
|
869
|
DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
|
846
|
870
|
iscsi, value, strerror ( rc ) );
|