use of javax.sip.message.Request in project Openfire by igniterealtime.
the class SipSecurityManager method handleChallenge.
/**
* Uses securityAuthority to determinie a set of valid user credentials for
* the specified Response (Challenge) and appends it to the challenged
* request so that it could be retransmitted.
* <p/>
* Fredrik Wickstrom reported that dialog cseq counters are not incremented
* when resending requests. He later uncovered additional problems and
* proposed a way to fix them (his proposition was taken into account).
*
* @param challenge the 401/407 challenge response
* @param challengedTransaction the transaction established by the challenged request
* @return a transaction containing a reoriginated request with the
* necessary authorization header.
* @throws SipSecurityException
*/
public ClientTransaction handleChallenge(Response challenge, ClientTransaction challengedTransaction) throws SipSecurityException, SipException, InvalidArgumentException, ParseException {
try {
String branchID = challengedTransaction.getBranchId();
Request challengedRequest = challengedTransaction.getRequest();
Request reoriginatedRequest = (Request) challengedRequest.clone();
ListIterator authHeaders = null;
if (challenge == null || reoriginatedRequest == null)
throw new NullPointerException("A null argument was passed to handle challenge.");
if (challenge.getStatusCode() == Response.UNAUTHORIZED)
authHeaders = challenge.getHeaders(WWWAuthenticateHeader.NAME);
else if (challenge.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED)
authHeaders = challenge.getHeaders(ProxyAuthenticateHeader.NAME);
if (authHeaders == null)
throw new SecurityException("Could not find WWWAuthenticate or ProxyAuthenticate headers");
// Remove all authorization headers from the request (we'll re-add
// them
// from cache)
reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);
// rfc 3261 says that the cseq header should be augmented for the
// new
// request. do it here so that the new dialog (created together with
// the new client transaction) takes it into account.
// Bug report - Fredrik Wickstrom
CSeqHeader cSeq = (CSeqHeader) reoriginatedRequest.getHeader((CSeqHeader.NAME));
cSeq.setSequenceNumber(cSeq.getSequenceNumber() + 1);
ClientTransaction retryTran = transactionCreator.getNewClientTransaction(reoriginatedRequest);
WWWAuthenticateHeader authHeader = null;
CredentialsCacheEntry ccEntry = null;
while (authHeaders.hasNext()) {
authHeader = (WWWAuthenticateHeader) authHeaders.next();
String realm = authHeader.getRealm();
// Check whether we have cached credentials for authHeader's
// realm
// make sure that if such credentials exist they get removed.
// The
// challenge means that there's something wrong with them.
ccEntry = cachedCredentials.remove(realm);
// Try to guess user name and facilitate user
UserCredentials defaultCredentials = new UserCredentials();
FromHeader from = (FromHeader) reoriginatedRequest.getHeader(FromHeader.NAME);
URI uri = from.getAddress().getURI();
if (uri.isSipURI()) {
Log.debug("handleChallenge", SIPConfig.getAuthUserName());
String user = SIPConfig.getAuthUserName() != null ? SIPConfig.getAuthUserName() : ((SipURI) uri).getUser();
defaultCredentials.setAuthUserName(user == null ? SIPConfig.getUserName() : user);
}
boolean ccEntryHasSeenTran = false;
if (ccEntry != null)
ccEntryHasSeenTran = ccEntry.processResponse(branchID);
// get a new pass
if (// we don't have credentials for the
ccEntry == null || // specified realm
((!authHeader.isStale() && ccEntryHasSeenTran))) {
if (ccEntry == null) {
ccEntry = new CredentialsCacheEntry();
ccEntry.userCredentials = defaultCredentials;
}
// put the returned user name in the properties file
// so that it appears as a default one next time user is
// prompted for pass
SIPConfig.setUserName(ccEntry.userCredentials.getUserName());
} else // encode and send what we have
if (ccEntry != null && (!ccEntryHasSeenTran || authHeader.isStale())) {
}
// if user canceled or sth else went wrong
if (ccEntry.userCredentials == null)
throw new SecurityException("Unable to authenticate with realm " + realm);
AuthorizationHeader authorization = this.getAuthorization(reoriginatedRequest.getMethod(), reoriginatedRequest.getRequestURI().toString(), reoriginatedRequest.getContent() == null ? "" : reoriginatedRequest.getContent().toString(), authHeader, ccEntry.userCredentials);
ccEntry.processRequest(retryTran.getBranchId());
cachedCredentials.cacheEntry(realm, ccEntry);
reoriginatedRequest.addHeader(authorization);
// if there was trouble with the user - make sure we fix it
if (uri.isSipURI()) {
((SipURI) uri).setUser(ccEntry.userCredentials.getUserName());
Address add = from.getAddress();
add.setURI(uri);
from.setAddress(add);
reoriginatedRequest.setHeader(from);
if (challengedRequest.getMethod().equals(Request.REGISTER)) {
ToHeader to = (ToHeader) reoriginatedRequest.getHeader(ToHeader.NAME);
add.setURI(uri);
to.setAddress(add);
reoriginatedRequest.setHeader(to);
}
// very ugly but very necessary
sipManCallback.setCurrentlyUsedURI(uri.toString());
Log.debug("URI: " + uri.toString());
}
// if this is a register - fix to as well
}
return retryTran;
} catch (Exception e) {
Log.debug("ERRO REG: " + e.toString());
return null;
}
}
use of javax.sip.message.Request in project Openfire by igniterealtime.
the class RegisterProcessing method register.
synchronized void register(String registrarAddress, int registrarPort, String registrarTransport, int expires) throws CommunicationsException {
try {
isUnregistering = false;
// From
FromHeader fromHeader = sipManCallback.getFromHeader(true);
Address fromAddress = fromHeader.getAddress();
sipManCallback.fireRegistering(fromAddress.toString());
// Request URI
SipURI requestURI = null;
try {
requestURI = sipManCallback.addressFactory.createSipURI(null, registrarAddress);
} catch (ParseException ex) {
throw new CommunicationsException("Bad registrar address:" + registrarAddress, ex);
} catch (NullPointerException ex) {
// Do not throw an exc, we should rather silently notify the
// user
// throw new CommunicationsException("A registrar address was
// not specified!", ex);
sipManCallback.fireUnregistered(fromAddress.getURI().toString() + " (registrar not specified)");
return;
}
requestURI.setPort(registrarPort);
try {
requestURI.setTransportParam(registrarTransport);
} catch (ParseException ex) {
throw new CommunicationsException(registrarTransport + " is not a valid transport!", ex);
}
// Call ID Header
CallIdHeader callIdHeader = sipManCallback.sipProvider.getNewCallId();
// CSeq Header
CSeqHeader cSeqHeader = null;
try {
cSeqHeader = sipManCallback.headerFactory.createCSeqHeader(1, Request.REGISTER);
} catch (ParseException ex) {
// Should never happen
Log.error("register", ex);
} catch (InvalidArgumentException ex) {
// Should never happen
Log.error("register", ex);
}
// To Header
ToHeader toHeader = null;
try {
toHeader = sipManCallback.headerFactory.createToHeader(fromAddress, null);
} catch (ParseException ex) {
// throw was missing - reported by Eero Vaarnas
throw new CommunicationsException("Could not create a To header " + "for address:" + fromHeader.getAddress(), ex);
}
// User Agent Header
UserAgentHeader uaHeader = null;
ArrayList<String> userAgentList = new ArrayList<String>();
userAgentList.add(SIPConfig.getStackName());
try {
uaHeader = sipManCallback.headerFactory.createUserAgentHeader(userAgentList);
} catch (ParseException ex) {
// throw was missing - reported by Eero Vaarnas
throw new CommunicationsException("Could not create a To header " + "for address:" + fromHeader.getAddress(), ex);
}
// Via Headers
ArrayList viaHeaders = sipManCallback.getLocalViaHeaders();
// MaxForwardsHeader
MaxForwardsHeader maxForwardsHeader = sipManCallback.getMaxForwardsHeader();
// Request
Request request = null;
try {
request = sipManCallback.messageFactory.createRequest(requestURI, Request.REGISTER, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwardsHeader);
request.setHeader(uaHeader);
} catch (ParseException ex) {
// throw was missing - reported by Eero Vaarnas
throw new CommunicationsException("Could not create the register request!", ex);
}
// Expires Header
ExpiresHeader expHeader = null;
for (int retry = 0; retry < 2; retry++) {
try {
expHeader = sipManCallback.headerFactory.createExpiresHeader(expires);
} catch (InvalidArgumentException ex) {
if (retry == 0) {
expires = 3600;
continue;
}
throw new CommunicationsException("Invalid registrations expiration parameter - " + expires, ex);
}
}
request.addHeader(expHeader);
// Contact Header should contain IP - bug report - Eero Vaarnas
ContactHeader contactHeader = sipManCallback.getRegistrationContactHeader();
request.addHeader(contactHeader);
// Transaction
ClientTransaction regTrans = null;
try {
regTrans = sipManCallback.sipProvider.getNewClientTransaction(request);
} catch (TransactionUnavailableException ex) {
// throw was missing - reported by Eero Vaarnas
throw new CommunicationsException("Could not create a register transaction!\n" + "Check that the Registrar address is correct!");
}
try {
regTrans.sendRequest();
}// we sometimes get a null pointer exception here so catch them all
catch (Exception ex) {
// throw was missing - reported by Eero Vaarnas
throw new CommunicationsException("Could not send out the register request!", ex);
}
this.registerRequest = request;
} catch (Exception e) {
Log.error("register", e);
}
}
use of javax.sip.message.Request in project camel by apache.
the class SipPublisher method process.
public void process(Exchange exchange) throws Exception {
String requestMethod = exchange.getIn().getHeader("REQUEST_METHOD", String.class);
if (requestMethod == null) {
throw new CamelExchangeException("Missing mandatory Header: REQUEST_HEADER", exchange);
}
Object body = exchange.getIn().getBody();
Request request = configuration.createSipRequest(sequenceNumber, requestMethod, body);
provider.sendRequest(request);
}
use of javax.sip.message.Request in project camel by apache.
the class SipPresenceAgentListener method processPublish.
private void processPublish(RequestEvent requestEvent, ServerTransaction serverTransactionId) {
try {
Request request = requestEvent.getRequest();
LOG.debug("SipPresenceAgentListener: Received a Publish request, sending OK");
LOG.debug("SipPresenceAgentListener request: {}", request);
EventHeader eventHeader = (EventHeader) requestEvent.getRequest().getHeader(EventHeader.NAME);
Response response = sipPresenceAgent.getConfiguration().getMessageFactory().createResponse(202, request);
sipPresenceAgent.getProvider().sendResponse(response);
// Send notification to subscriber
sendNotification(eventHeader, false, request.getContent());
} catch (Exception e) {
LOG.error("Exception thrown during publish/notify processing in the Sip Presence Agent Listener", e);
}
}
use of javax.sip.message.Request in project camel by apache.
the class SipSubscriptionListener method processNotify.
public synchronized void processNotify(RequestEvent requestEvent, ServerTransaction serverTransactionId) {
LOG.debug("Notification received at Subscriber");
SipProvider provider = (SipProvider) requestEvent.getSource();
Request notify = requestEvent.getRequest();
try {
if (serverTransactionId == null) {
LOG.info("ServerTransaction is null. Creating new Server transaction");
serverTransactionId = provider.getNewServerTransaction(notify);
}
Dialog dialog = serverTransactionId.getDialog();
if (dialog != subscriberDialog) {
forkedDialog = dialog;
}
//Dispatch the response along the route
dispatchExchange(notify.getContent());
// Send back an success response
Response response = sipSubscriber.getConfiguration().getMessageFactory().createResponse(200, notify);
response.addHeader(sipSubscriber.getConfiguration().getContactHeader());
serverTransactionId.sendResponse(response);
SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) notify.getHeader(SubscriptionStateHeader.NAME);
// Subscription is terminated?
if (subscriptionState.getState().equalsIgnoreCase(SubscriptionStateHeader.TERMINATED)) {
LOG.info("Subscription state is terminated. Deleting the current dialog");
dialog.delete();
}
} catch (Exception e) {
LOG.error("Exception thrown during Notify processing in the SipSubscriptionListener.", e);
}
}
Aggregations