use of jcifs.spnego.SpnegoToken in project jcifs by codelibs.
the class SpnegoContext method negotitate.
private SpnegoToken negotitate(byte[] inputBuf, int offset, int len) throws CIFSException {
SpnegoToken spToken = getToken(inputBuf, offset, len);
byte[] inputToken = null;
if (spToken instanceof NegTokenInit) {
NegTokenInit tinit = (NegTokenInit) spToken;
ASN1ObjectIdentifier[] rm = tinit.getMechanisms();
this.remoteMechs = rm;
ASN1ObjectIdentifier prefMech = rm[0];
// only use token if the optimistic mechanism is supported
if (this.mechContext.isSupported(prefMech)) {
inputToken = tinit.getMechanismToken();
} else {
ASN1ObjectIdentifier found = null;
for (ASN1ObjectIdentifier mech : rm) {
if (this.mechContext.isSupported(mech)) {
found = mech;
break;
}
}
if (found == null) {
throw new SmbException("Server does advertise any supported mechanism");
}
}
} else if (spToken instanceof NegTokenTarg) {
NegTokenTarg targ = (NegTokenTarg) spToken;
if (this.firstResponse) {
if (!this.mechContext.isSupported(targ.getMechanism())) {
throw new SmbException("Server chose an unsupported mechanism " + targ.getMechanism());
}
this.selectedMech = targ.getMechanism();
if (targ.getResult() == NegTokenTarg.REQUEST_MIC) {
this.requireMic = true;
}
this.firstResponse = false;
} else {
if (targ.getMechanism() != null && !targ.getMechanism().equals(this.selectedMech)) {
throw new SmbException("Server switched mechanism");
}
}
inputToken = targ.getMechanismToken();
} else {
throw new SmbException("Invalid token");
}
if (spToken instanceof NegTokenTarg && this.mechContext.isEstablished()) {
// already established, but server hasn't completed yet
NegTokenTarg targ = (NegTokenTarg) spToken;
if (targ.getResult() == NegTokenTarg.ACCEPT_INCOMPLETE && targ.getMechanismToken() == null && targ.getMechanismListMIC() != null) {
// this indicates that mechlistMIC is required by the server
verifyMechListMIC(targ.getMechanismListMIC());
return new NegTokenTarg(NegTokenTarg.UNSPECIFIED_RESULT, null, null, calculateMechListMIC());
} else if (targ.getResult() != NegTokenTarg.ACCEPT_COMPLETED) {
throw new SmbException("SPNEGO negotiation did not complete");
}
verifyMechListMIC(targ.getMechanismListMIC());
this.completed = true;
return null;
}
if (inputToken == null) {
return initialToken();
}
byte[] mechMIC = null;
byte[] responseToken = this.mechContext.initSecContext(inputToken, 0, inputToken.length);
if (spToken instanceof NegTokenTarg) {
NegTokenTarg targ = (NegTokenTarg) spToken;
if (targ.getResult() == NegTokenTarg.ACCEPT_COMPLETED && this.mechContext.isEstablished()) {
// server sent final token
verifyMechListMIC(targ.getMechanismListMIC());
if (!this.disableMic || this.requireMic) {
mechMIC = calculateMechListMIC();
}
this.completed = true;
} else if (this.mechContext.isMICAvailable() && (!this.disableMic || this.requireMic)) {
// we need to send our final data
mechMIC = calculateMechListMIC();
} else if (targ.getResult() == NegTokenTarg.REJECTED) {
throw new SmbException("SPNEGO mechanism was rejected");
}
}
if (responseToken == null && this.mechContext.isEstablished()) {
return null;
}
return new NegTokenTarg(NegTokenTarg.UNSPECIFIED_RESULT, null, responseToken, mechMIC);
}
Aggregations