[iscsi] Use generic base16 functions for iSCSI
authorMichael Brown <mcb30@ipxe.org>
Fri, 28 May 2010 15:21:56 +0000 (16:21 +0100)
committerPiotr Jaroszyński <p.jaroszynski@gmail.com>
Sat, 29 May 2010 14:21:20 +0000 (16:21 +0200)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
src/net/tcp/iscsi.c

index b13a107..fa9fb98 100644 (file)
@@ -35,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <gpxe/tcpip.h>
 #include <gpxe/settings.h>
 #include <gpxe/features.h>
+#include <gpxe/base16.h>
 #include <gpxe/iscsi.h>
 
 /** @file
@@ -481,7 +482,6 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
 static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
                                               void *data, size_t len ) {
        unsigned int used = 0;
-       unsigned int i;
        const char *auth_method;
 
        if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
@@ -508,26 +508,23 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
        }
        
        if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
+               char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
                assert ( iscsi->initiator_username != NULL );
+               base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
+                               buf );
                used += ssnprintf ( data + used, len - used,
-                                   "CHAP_N=%s%cCHAP_R=0x",
-                                   iscsi->initiator_username, 0 );
-               for ( i = 0 ; i < iscsi->chap.response_len ; i++ ) {
-                       used += ssnprintf ( data + used, len - used, "%02x",
-                                           iscsi->chap.response[i] );
-               }
-               used += ssnprintf ( data + used, len - used, "%c", 0 );
+                                   "CHAP_N=%s%cCHAP_R=0x%s%c",
+                                   iscsi->initiator_username, 0, buf, 0 );
        }
 
        if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
+               size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
+               char buf[ base16_encoded_len ( challenge_len ) + 1 ];
+               base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
+                               buf );
                used += ssnprintf ( data + used, len - used,
-                                   "CHAP_I=%d%cCHAP_C=0x",
-                                   iscsi->chap_challenge[0], 0 );
-               for ( i = 1 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
-                       used += ssnprintf ( data + used, len - used, "%02x",
-                                           iscsi->chap_challenge[i] );
-               }
-               used += ssnprintf ( data + used, len - used, "%c", 0 );
+                                   "CHAP_I=%d%cCHAP_C=0x%s%c",
+                                   iscsi->chap_challenge[0], 0, buf, 0 );
        }
 
        if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) {
@@ -740,10 +737,9 @@ 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;
+       uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
        unsigned int i;
+       int len;
 
        /* Check and strip leading "0x" */
        if ( ( value[0] != '0' ) || ( value[1] != 'x' ) ) {
@@ -751,20 +747,15 @@ static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
                       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 ) );
+
+       /* Process challenge */
+       len = base16_decode ( ( value + 2 ), buf );
+       if ( len < 0 ) {
+               DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
+                      iscsi, value, strerror ( len ) );
+               return len;
        }
+       chap_update ( &iscsi->chap, buf, len );
 
        /* Build CHAP response */
        DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
@@ -821,10 +812,8 @@ 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;
+       uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
+       size_t len;
        int rc;
 
        /* Generate CHAP response for verification */
@@ -849,32 +838,27 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
                       iscsi, value );
                return -EPROTO_INVALID_CHAP_RESPONSE;
        }
-       value += 2;
 
-       /* Check CHAP response length */
-       if ( strlen ( value ) != ( 2 * iscsi->chap.response_len ) ) {
+       /* Process response */
+       rc = base16_decode ( ( value + 2 ), buf );
+       if ( rc < 0 ) {
+               DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
+                      iscsi, value, strerror ( rc ) );
+               return rc;
+       }
+       len = rc;
+
+       /* Check CHAP response */
+       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 ( buf, iscsi->chap.response, len ) != 0 ) {
+               DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
+                      iscsi, value );
+               return -EACCES_INCORRECT_TARGET_PASSWORD;
        }
-       assert ( i == iscsi->chap.response_len );
 
        /* Mark session as authenticated */
        iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK;