[gPXE-devel] [PATCHv2 2/2] [iscsi] Add base64 support for CHAP.
Piotr Jaroszyński
p.jaroszynski at gmail.com
Fri Apr 2 21:10:26 EDT 2010
Signed-off-by: Piotr Jaroszyński <p.jaroszynski at gmail.com>
---
src/net/tcp/iscsi.c | 89 +++++++++++++++++++++++++++------------------------
1 files changed, 47 insertions(+), 42 deletions(-)
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index b13a107..c6708ae 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -35,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <gpxe/tcpip.h>
#include <gpxe/settings.h>
#include <gpxe/features.h>
+#include <gpxe/base64.h>
#include <gpxe/iscsi.h>
/** @file
@@ -731,6 +732,38 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
return 0;
}
+static int iscsi_decode_hex ( const char * encoded, char * raw )
+{
+ char *endp;
+ char buf[3];
+ unsigned int i;
+
+ buf[2] = 0;
+
+ for ( i = 0 ; ( encoded[0] && encoded[1] ) ; encoded += 2, i++ ) {
+ memcpy ( buf, encoded, 2 );
+ raw[i] = strtoul ( buf, &endp, 16 );
+ if ( *endp != '\0' ) {
+ return -1;
+ }
+ }
+
+ return i;
+}
+
+static int iscsi_decode_large_binary ( const char * encoded, char * raw )
+{
+ if ( encoded[0] != '0' )
+ return -1;
+
+ if ( ( encoded[1] == 'x' ) || ( encoded[1] == 'X' ) )
+ return iscsi_decode_hex ( encoded + 2, raw );
+ if ( ( encoded[1] == 'b' ) || ( encoded[1] == 'B' ) )
+ return base64_decode ( encoded + 2, raw );
+
+ return -1;
+}
+
/**
* Handle iSCSI CHAP_C text value
*
@@ -740,31 +773,17 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
*/
static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
const char *value ) {
- char buf[3];
- char *endp;
- uint8_t byte;
unsigned int i;
+ char raw[ base64_decode_buf_len ( strlen ( value ) ) ];
+ int len;
- /* Check and strip leading "0x" */
- if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) {
+ if ( ( len = iscsi_decode_large_binary ( value, raw ) ) < 0 ) {
DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge \"%s\"\n",
iscsi, value );
return -EPROTO_INVALID_CHAP_CHALLENGE;
}
- value += 2;
- /* Process challenge an octet at a time */
- for ( ; ( value[0] && value[1] ) ; value += 2 ) {
- memcpy ( buf, value, 2 );
- buf[2] = 0;
- byte = strtoul ( buf, &endp, 16 );
- if ( *endp != '\0' ) {
- DBGC ( iscsi, "iSCSI %p saw invalid CHAP challenge "
- "byte \"%s\"\n", iscsi, buf );
- return -EPROTO_INVALID_CHAP_CHALLENGE;
- }
- chap_update ( &iscsi->chap, &byte, sizeof ( byte ) );
- }
+ chap_update ( &iscsi->chap, raw, len );
/* Build CHAP response */
DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
@@ -821,11 +840,9 @@ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
*/
static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
const char *value ) {
- char buf[3];
- char *endp;
- uint8_t byte;
- unsigned int i;
int rc;
+ char raw[ base64_decode_buf_len ( strlen ( value ) ) ];
+ size_t len;
/* Generate CHAP response for verification */
chap_finish ( &iscsi->chap );
@@ -843,38 +860,26 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
( sizeof ( iscsi->chap_challenge ) - 1 ) );
chap_respond ( &iscsi->chap );
- /* Check and strip leading "0x" */
- if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) {
+ if ( ( rc = iscsi_decode_large_binary ( value, raw ) ) < 0 ) {
DBGC ( iscsi, "iSCSI %p saw invalid CHAP response \"%s\"\n",
iscsi, value );
return -EPROTO_INVALID_CHAP_RESPONSE;
}
- value += 2;
+
+ len = rc;
/* Check CHAP response length */
- if ( strlen ( value ) != ( 2 * iscsi->chap.response_len ) ) {
+ if ( len != iscsi->chap.response_len ) {
DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
iscsi );
return -EPROTO_INVALID_CHAP_RESPONSE;
}
- /* Process response an octet at a time */
- for ( i = 0 ; ( value[0] && value[1] ) ; value += 2, i++ ) {
- memcpy ( buf, value, 2 );
- buf[2] = 0;
- byte = strtoul ( buf, &endp, 16 );
- if ( *endp != '\0' ) {
- DBGC ( iscsi, "iSCSI %p saw invalid CHAP response "
- "byte \"%s\"\n", iscsi, buf );
- return -EPROTO_INVALID_CHAP_RESPONSE;
- }
- if ( byte != iscsi->chap.response[i] ) {
- DBGC ( iscsi, "iSCSI %p saw incorrect CHAP "
- "response\n", iscsi );
- return -EACCES_INCORRECT_TARGET_PASSWORD;
- }
+ if ( memcmp ( raw, iscsi->chap.response, len ) != 0 ) {
+ DBGC ( iscsi, "iSCSI %p saw incorrect CHAP "
+ "response\n", iscsi );
+ return -EACCES_INCORRECT_TARGET_PASSWORD;
}
- assert ( i == iscsi->chap.response_len );
/* Mark session as authenticated */
iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK;
--
1.7.0.3
More information about the gPXE-devel
mailing list