From: Lev V. <le...@za...> - 2014-09-17 12:24:54
|
Greetings scst developers, I am looking at SCST CHAP code, specifically at chap_initiator_auth_check_response and chap_target_auth_create_response. In chap_initiator_auth_check_response, the target authenticates the initiator, by verifying its CHAP_R response. To verify the response, target looks up the appropriate IncomingUser entry in the target configuration, with username matching the CHAP_N value that it received from initiator: if (config_account_query(conn->tid, ISCSI_USER_DIR_INCOMING, value, pass) < 0) { ... There may be several IncomingUser entries in SCST target configuration. After the target authenticated the initiator, the target checks whether initiator wants to authenticate the target. This happens in chap_target_auth_create_response. Here, target looks up the CHAP_I value in initiator's response. If the value is not found, target assumes that initiator does not want to authenticate the target. If the value is found, target generates the CHAP_R entry by fetching the OutgoingUser entry: user = account_get_first(conn->tid, ISCSI_USER_DIR_OUTGOING); There may be at most one OutgoingUser entry in SCST target configuration. I wonder whether IncomingUser and OutgoingUser usage should be switched. I mean that in chap_initiator_auth_check_response() we should use the (only) OutgoingUser entry, while in chap_target_auth_create_response() we should find the appropriate initiator's IncomingUser entry. This is my reasoning: If CHAP is enabled, first we want the target to authenticate the initiator (this is also according to [1]). For that, target must verify that initiator knows the correct secret, which is the target's secret. So there should be one such secret per target, which exactly matches the fact that there is a single OutgoingUser entry. Second, we want the initiator to authenticate the target. For that, initiator must verify that target knows the correct secret of the initiator. So there should be a per-initiator secret, which exactly matches the fact that there are multiple IncomingUser entries. This also indirectly confirmed by Linux initiator, in which: # To set a CHAP username and password for target(s) # authentication by the initiator, uncomment the following lines: #node.session.auth.username_in = username_in #node.session.auth.password_in = password_in "in" perhaps suggesting "Incoming" or "Initiator". I will also mention the Windows initiator, in which for mutual authentication, the "CHAP_N" field is always the initiator IQN. This is what SCST must have in OutgoingUser for mutual CHAP to work correctly with Windows initiator. But this means that only one Windows initiator can have mutual authentication with SCST. I know that SCST was forked from IET, and IET has the same logic in chap.c WRT IncomingUser/OutgoingUser. So perhaps this confusion comes from IET? Thanks, Alex. [1] quoting iSCSI RFC 3720: In the next example, only the initiator is authenticated by the target via CHAP: I-> Login (CSG,NSG=0,1 T=0) InitiatorName=iqn.1999-07.com.os:hostid.77 TargetName=iqn.1999-07.com.example:diskarray.sn.88 AuthMethod=KRB5,CHAP,None T-> Login-PR (CSG,NSG=0,0 T=0) AuthMethod=CHAP I-> Login (CSG,NSG=0,0 T=0) CHAP_A=<A1,A2> This example shows that on first step target authenticates the initiator. While the second (optional) step is when initiator authenticates the target. --- Это сообщение свободно от вирусов и вредоносного ПО благодаря защите от вирусов avast! http://www.avast.com |