Coverage Report - org.jscsi.target.connection.phase.TargetLoginPhase
 
Classes in this File Line Coverage Branch Coverage Complexity
TargetLoginPhase
0%
0/52
0%
0/20
7.5
 
 1  
 package org.jscsi.target.connection.phase;
 2  
 
 3  
 
 4  
 import java.io.IOException;
 5  
 import java.security.DigestException;
 6  
 
 7  
 import javax.naming.OperationNotSupportedException;
 8  
 
 9  
 import org.jscsi.exception.InternetSCSIException;
 10  
 import org.jscsi.parser.BasicHeaderSegment;
 11  
 import org.jscsi.parser.ProtocolDataUnit;
 12  
 import org.jscsi.parser.login.LoginRequestParser;
 13  
 import org.jscsi.parser.login.LoginStage;
 14  
 import org.jscsi.target.connection.Connection;
 15  
 import org.jscsi.target.connection.stage.login.LoginOperationalParameterNegotiationStage;
 16  
 import org.jscsi.target.connection.stage.login.SecurityNegotiationStage;
 17  
 import org.jscsi.target.connection.stage.login.TargetLoginStage;
 18  
 import org.jscsi.target.settings.ConnectionSettingsNegotiator;
 19  
 import org.jscsi.target.settings.SettingsException;
 20  
 
 21  
 
 22  
 /**
 23  
  * Objects of this class represent the Target Login Phase of a connection.
 24  
  * 
 25  
  * @see TargetPhase
 26  
  * @author Andreas Ergenzinger
 27  
  */
 28  
 public final class TargetLoginPhase extends TargetPhase {
 29  
 
 30  
     /**
 31  
      * The current stage of this phase
 32  
      */
 33  
     private TargetLoginStage stage;
 34  
 
 35  
     /**
 36  
      * This variable indicates if the initiator is to be considered as authenticated, i.e. if it has given sufficient
 37  
      * proof of its identity to proceed to the next (Target Full Feature) phase.
 38  
      * <p>
 39  
      * Currently the jSCSI Target does not support any authentication methods and this value is initialized to
 40  
      * <code>true</code> for all initiators.
 41  
      */
 42  0
     private boolean authenticated = true;// TODO false if authentication
 43  
                                          // required
 44  
 
 45  
     /**
 46  
      * This variable will be <code>true</code> until the first call of {@link #getFirstPduAndSetToFalse()} has happened.
 47  
      * <p>
 48  
      * This value will be <code>true</code> if the currently processed PDU is the first PDU sent by the initiator over
 49  
      * this phase's connection. This means that it must contain all text parameters necessary for either starting a
 50  
      * discovery session or a normal session.
 51  
      */
 52  0
     private boolean firstPdu = true;
 53  
 
 54  
     /**
 55  
      * The constructor.
 56  
      * 
 57  
      * @param connection {@inheritDoc}
 58  
      */
 59  
     public TargetLoginPhase (Connection connection) {
 60  0
         super(connection);
 61  0
     }
 62  
 
 63  
     /**
 64  
      * Starts the login phase.
 65  
      * 
 66  
      * @param pdu {@inheritDoc}
 67  
      * @return {@inheritDoc}
 68  
      * @throws OperationNotSupportedException {@inheritDoc}
 69  
      * @throws IOException {@inheritDoc}
 70  
      * @throws InterruptedException {@inheritDoc}
 71  
      * @throws InternetSCSIException {@inheritDoc}
 72  
      * @throws DigestException {@inheritDoc}
 73  
      * @throws SettingsException {@inheritDoc}
 74  
      */
 75  
     @Override
 76  
     public boolean execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {
 77  
 
 78  
         // begin login negotiation
 79  0
         final ConnectionSettingsNegotiator negotiator = connection.getConnectionSettingsNegotiator();
 80  0
         while (!negotiator.beginNegotiation()) {
 81  
             // do nothing, just wait for permission to begin, method is blocking
 82  
         }
 83  
 
 84  0
         boolean loginSuccessful = true;// will determine if settings are
 85  
                                        // committed
 86  
 
 87  
         try {
 88  
             // if possible, enter LOPN Stage
 89  0
             BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
 90  0
             LoginRequestParser parser = (LoginRequestParser) bhs.getParser();
 91  
 
 92  
             LoginStage nextStageNumber;// will store return value from the last
 93  
                                        // login stage
 94  
 
 95  
             // Security Negotiation Stage (optional)
 96  0
             if (parser.getCurrentStageNumber() == LoginStage.SECURITY_NEGOTIATION) {
 97  
                 // complete SNS
 98  0
                 stage = new SecurityNegotiationStage(this);
 99  0
                 stage.execute(pdu);
 100  0
                 nextStageNumber = stage.getNextStageNumber();
 101  
 
 102  0
                 if (nextStageNumber != null)
 103  0
                     authenticated = true;
 104  
                 else {
 105  0
                     loginSuccessful = false;
 106  0
                     return false;
 107  
                 }
 108  
 
 109  0
                 if (nextStageNumber == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) {
 110  
                     // receive first PDU from LOPNS
 111  0
                     pdu = connection.receivePdu();
 112  0
                     bhs = pdu.getBasicHeaderSegment();
 113  0
                     parser = (LoginRequestParser) bhs.getParser();
 114  0
                 } else if (nextStageNumber == LoginStage.FULL_FEATURE_PHASE) {
 115  
                     // we are done here
 116  0
                     return true;
 117  
                 } else {
 118  
                     // should be unreachable, since SNS may not return NSG==SNS
 119  0
                     loginSuccessful = false;
 120  0
                     return false;
 121  
                 }
 122  
             }
 123  
 
 124  
             // Login Operational Parameter Negotiation Stage (also optional, but
 125  
             // either SNS or LOPNS must be passed before proceeding to FFP)
 126  0
             if (parser != null && authenticated && parser.getCurrentStageNumber() == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) {
 127  0
                 stage = new LoginOperationalParameterNegotiationStage(this);
 128  0
                 stage.execute(pdu);
 129  0
                 nextStageNumber = stage.getNextStageNumber();
 130  0
                 if (nextStageNumber == LoginStage.FULL_FEATURE_PHASE) return true;
 131  
             }
 132  
             // else
 133  0
             loginSuccessful = false;
 134  0
             return false;
 135  0
         } catch (DigestException e) {
 136  0
             loginSuccessful = false;
 137  0
             throw e;
 138  0
         } catch (IOException e) {
 139  0
             loginSuccessful = false;
 140  0
             throw e;
 141  0
         } catch (InterruptedException e) {
 142  0
             loginSuccessful = false;
 143  0
             throw e;
 144  0
         } catch (InternetSCSIException e) {
 145  0
             loginSuccessful = false;
 146  0
             throw e;
 147  0
         } catch (SettingsException e) {
 148  0
             loginSuccessful = false;
 149  0
             throw e;
 150  
         } finally {
 151  
             // commit or roll back changes and release exclusive negotiator lock
 152  0
             negotiator.finishNegotiation(loginSuccessful);
 153  
         }
 154  
     }
 155  
 
 156  
     /**
 157  
      * This method will return <code>true</code> if currently processed PDU is the first PDU sent by the initiator over
 158  
      * this phase's connection. Subsequent calls will always return <code>false</code>.
 159  
      * 
 160  
      * @return <code>true</code> if and only if this method is called for the first time
 161  
      */
 162  
     public boolean getFirstPduAndSetToFalse () {
 163  0
         if (!firstPdu) return false;
 164  0
         firstPdu = false;
 165  0
         return true;
 166  
     }
 167  
 
 168  
     public final boolean getAuthenticated () {
 169  0
         return authenticated;
 170  
     }
 171  
 }