[iscsi] Rewrite unrelicensable portions of iscsi.c
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
2d707ac964
commit
c1ac466838
@ -15,14 +15,19 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* You can also choose to distribute this program under the terms of
|
||||||
|
* the Unmodified Binary Distribution Licence (as given in the file
|
||||||
|
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER );
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
@ -127,7 +132,7 @@ FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 );
|
|||||||
#define EPROTO_INVALID_LARGE_BINARY \
|
#define EPROTO_INVALID_LARGE_BINARY \
|
||||||
__einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )
|
__einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )
|
||||||
#define EINFO_EPROTO_INVALID_LARGE_BINARY \
|
#define EINFO_EPROTO_INVALID_LARGE_BINARY \
|
||||||
__einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary" )
|
__einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )
|
||||||
#define EPROTO_INVALID_CHAP_RESPONSE \
|
#define EPROTO_INVALID_CHAP_RESPONSE \
|
||||||
__einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )
|
__einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )
|
||||||
#define EINFO_EPROTO_INVALID_CHAP_RESPONSE \
|
#define EINFO_EPROTO_INVALID_CHAP_RESPONSE \
|
||||||
@ -823,17 +828,6 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
|
|||||||
return xfer_deliver_iob ( &iscsi->socket, iobuf );
|
return xfer_deliver_iob ( &iscsi->socket, iobuf );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate maximum length of decoded large binary value
|
|
||||||
*
|
|
||||||
* @v encoded Encoded large binary value
|
|
||||||
* @v max_raw_len Maximum length of raw data
|
|
||||||
*/
|
|
||||||
static inline size_t
|
|
||||||
iscsi_large_binary_decoded_max_len ( const char *encoded ) {
|
|
||||||
return ( strlen ( encoded ) ); /* Decoding never expands data */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode large binary value
|
* Decode large binary value
|
||||||
*
|
*
|
||||||
@ -843,19 +837,17 @@ iscsi_large_binary_decoded_max_len ( const char *encoded ) {
|
|||||||
*/
|
*/
|
||||||
static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw ) {
|
static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw ) {
|
||||||
|
|
||||||
if ( encoded[0] != '0' )
|
/* Check for initial '0x' or '0b' and decode as appropriate */
|
||||||
return -EPROTO_INVALID_LARGE_BINARY;
|
if ( *(encoded++) == '0' ) {
|
||||||
|
switch ( tolower ( *(encoded++) ) ) {
|
||||||
switch ( encoded[1] ) {
|
case 'x' :
|
||||||
case 'x' :
|
return base16_decode ( encoded, raw );
|
||||||
case 'X' :
|
case 'b' :
|
||||||
return base16_decode ( ( encoded + 2 ), raw );
|
return base64_decode ( encoded, raw );
|
||||||
case 'b' :
|
}
|
||||||
case 'B' :
|
|
||||||
return base64_decode ( ( encoded + 2 ), raw );
|
|
||||||
default:
|
|
||||||
return -EPROTO_INVALID_LARGE_BINARY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -EPROTO_INVALID_LARGE_BINARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -982,19 +974,19 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
|
|||||||
*/
|
*/
|
||||||
static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
|
static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
|
||||||
const char *value ) {
|
const char *value ) {
|
||||||
uint8_t buf[ iscsi_large_binary_decoded_max_len ( value ) ];
|
uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
size_t len;
|
int len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Process challenge */
|
/* Process challenge */
|
||||||
rc = iscsi_large_binary_decode ( value, buf );
|
len = iscsi_large_binary_decode ( value, buf );
|
||||||
if ( rc < 0 ) {
|
if ( len < 0 ) {
|
||||||
|
rc = len;
|
||||||
DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
|
DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
|
||||||
iscsi, value, strerror ( rc ) );
|
iscsi, value, strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
len = rc;
|
|
||||||
chap_update ( &iscsi->chap, buf, len );
|
chap_update ( &iscsi->chap, buf, len );
|
||||||
|
|
||||||
/* Build CHAP response */
|
/* Build CHAP response */
|
||||||
@ -1052,8 +1044,8 @@ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
|
|||||||
*/
|
*/
|
||||||
static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
|
static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
|
||||||
const char *value ) {
|
const char *value ) {
|
||||||
uint8_t buf[ iscsi_large_binary_decoded_max_len ( value ) ];
|
uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
|
||||||
size_t len;
|
int len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Generate CHAP response for verification */
|
/* Generate CHAP response for verification */
|
||||||
@ -1073,16 +1065,16 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
|
|||||||
chap_respond ( &iscsi->chap );
|
chap_respond ( &iscsi->chap );
|
||||||
|
|
||||||
/* Process response */
|
/* Process response */
|
||||||
rc = iscsi_large_binary_decode ( value, buf );
|
len = iscsi_large_binary_decode ( value, buf );
|
||||||
if ( rc < 0 ) {
|
if ( len < 0 ) {
|
||||||
|
rc = len;
|
||||||
DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
|
DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
|
||||||
iscsi, value, strerror ( rc ) );
|
iscsi, value, strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
len = rc;
|
|
||||||
|
|
||||||
/* Check CHAP response */
|
/* Check CHAP response */
|
||||||
if ( len != iscsi->chap.response_len ) {
|
if ( len != ( int ) iscsi->chap.response_len ) {
|
||||||
DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
|
DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
|
||||||
iscsi );
|
iscsi );
|
||||||
return -EPROTO_INVALID_CHAP_RESPONSE;
|
return -EPROTO_INVALID_CHAP_RESPONSE;
|
||||||
|
Reference in New Issue
Block a user