Pārlūkot izejas kodu

[iscsi] Allow base64 encoding in large binary values

Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Piotr Jaroszyński 14 gadus atpakaļ
vecāks
revīzija
8a16fd05dc
1 mainītis faili ar 47 papildinājumiem un 23 dzēšanām
  1. 47
    23
      src/net/tcp/iscsi.c

+ 47
- 23
src/net/tcp/iscsi.c Parādīt failu

@@ -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 ) );

Notiek ielāde…
Atcelt
Saglabāt