Browse Source

[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 years ago
parent
commit
8a16fd05dc
1 changed files with 47 additions and 23 deletions
  1. 47
    23
      src/net/tcp/iscsi.c

+ 47
- 23
src/net/tcp/iscsi.c View File

36
 #include <ipxe/settings.h>
36
 #include <ipxe/settings.h>
37
 #include <ipxe/features.h>
37
 #include <ipxe/features.h>
38
 #include <ipxe/base16.h>
38
 #include <ipxe/base16.h>
39
+#include <ipxe/base64.h>
39
 #include <ipxe/iscsi.h>
40
 #include <ipxe/iscsi.h>
40
 
41
 
41
 /** @file
42
 /** @file
56
 #define EPERM_INITIATOR_AUTHORISATION ( EPERM | EUNIQ_02 )
57
 #define EPERM_INITIATOR_AUTHORISATION ( EPERM | EUNIQ_02 )
57
 #define EPROTO_INVALID_CHAP_ALGORITHM ( EPROTO | EUNIQ_01 )
58
 #define EPROTO_INVALID_CHAP_ALGORITHM ( EPROTO | EUNIQ_01 )
58
 #define EPROTO_INVALID_CHAP_IDENTIFIER ( EPROTO | EUNIQ_02 )
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
 #define EPROTO_INVALID_CHAP_RESPONSE ( EPROTO | EUNIQ_04 )
61
 #define EPROTO_INVALID_CHAP_RESPONSE ( EPROTO | EUNIQ_04 )
61
 
62
 
62
 /** iSCSI initiator name (explicitly specified) */
63
 /** iSCSI initiator name (explicitly specified) */
613
 	return xfer_deliver_iob ( &iscsi->socket, iobuf );
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
  * Handle iSCSI TargetAddress text value
653
  * Handle iSCSI TargetAddress text value
618
  *
654
  *
737
  */
773
  */
738
 static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
774
 static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
739
 				       const char *value ) {
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
 	unsigned int i;
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
 	/* Process challenge */
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
 		DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
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
 	chap_update ( &iscsi->chap, buf, len );
789
 	chap_update ( &iscsi->chap, buf, len );
759
 
790
 
760
 	/* Build CHAP response */
791
 	/* Build CHAP response */
812
  */
843
  */
813
 static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
844
 static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
814
 				       const char *value ) {
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
 	size_t len;
847
 	size_t len;
817
 	int rc;
848
 	int rc;
818
 
849
 
832
 		      ( sizeof ( iscsi->chap_challenge ) - 1 ) );
863
 		      ( sizeof ( iscsi->chap_challenge ) - 1 ) );
833
 	chap_respond ( &iscsi->chap );
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
 	/* Process response */
866
 	/* Process response */
843
-	rc = base16_decode ( ( value + 2 ), buf );
867
+	rc = iscsi_large_binary_decode ( value, buf );
844
 	if ( rc < 0 ) {
868
 	if ( rc < 0 ) {
845
 		DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
869
 		DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
846
 		       iscsi, value, strerror ( rc ) );
870
 		       iscsi, value, strerror ( rc ) );

Loading…
Cancel
Save