001: package examples.authorization;
002:
003: import javax.sip.*;
004: import javax.sip.address.*;
005: import javax.sip.header.*;
006: import javax.sip.message.*;
007: import java.util.*;
008: import java.text.ParseException;
009: import gov.nist.javax.sip.header.ProxyAuthenticate;
010: import gov.nist.javax.sip.header.SIPHeaderNames;
011:
012: /**
013: * This class is a UAC template. Shootist is the guy that shoots and shootme is
014: * the guy that gets shot.
015: *
016: * @author M. Ranganathan
017: * @author Kathleen McCallum
018: */
019:
020: public class ShootistAuth implements SipListener {
021:
022: private static SipProvider sipProvider;
023: private static AddressFactory addressFactory;
024: private static MessageFactory messageFactory;
025: private static HeaderFactory headerFactory;
026: private static SipStack sipStack;
027: private ContactHeader contactHeader;
028: private ListeningPoint udpListeningPoint;
029: private ClientTransaction inviteTid;
030: private Dialog dialog;
031: long invco = 1;
032: String peerHostPort = "127.0.0.1:5070";
033: String transport = "udp";
034: String USER_AUTH = "auth";
035: String PASS_AUTH = "pass";
036: String realm = "nist.gov";
037:
038: public void processRequest(RequestEvent requestReceivedEvent) {
039: Request request = requestReceivedEvent.getRequest();
040: ServerTransaction serverTransactionId = requestReceivedEvent
041: .getServerTransaction();
042:
043: System.out.println("\n\nRequest " + request.getMethod()
044: + " received at " + sipStack.getStackName()
045: + " with server transaction id " + serverTransactionId);
046:
047: // We are the UAC so the only request we get is the BYE.
048: if (request.getMethod().equals(Request.BYE))
049: processBye(request, serverTransactionId);
050: }
051:
052: public void processBye(Request request,
053: ServerTransaction serverTransactionId) {
054: try {
055: System.out.println("shootist: got a bye .");
056: if (serverTransactionId == null) {
057: System.out.println("shootist: null TID.");
058: return;
059: }
060: Dialog dialog = serverTransactionId.getDialog();
061: System.out.println("Dialog State = " + dialog.getState());
062: Response response = messageFactory.createResponse(200,
063: request);
064: serverTransactionId.sendResponse(response);
065: System.out.println("shootist: Sending OK.");
066: System.out.println("Dialog State = " + dialog.getState());
067:
068: } catch (Exception ex) {
069: ex.printStackTrace();
070: System.exit(0);
071:
072: }
073: }
074:
075: public void processResponse(ResponseEvent responseReceivedEvent) {
076: System.out.println("Got a response");
077: Response response = (Response) responseReceivedEvent
078: .getResponse();
079: ClientTransaction tid = responseReceivedEvent
080: .getClientTransaction();
081: CSeqHeader cseq = (CSeqHeader) response
082: .getHeader(CSeqHeader.NAME);
083:
084: System.out.println("Response received : Status Code = "
085: + response.getStatusCode() + " " + cseq);
086: if (tid == null) {
087: System.out.println("Stray response -- dropping ");
088: return;
089: }
090: System.out.println("transaction state is " + tid.getState());
091: System.out.println("Dialog = " + tid.getDialog());
092: System.out.println("Dialog State is "
093: + tid.getDialog().getState());
094:
095: try {
096: if (response.getStatusCode() == Response.OK) {
097: if (cseq.getMethod().equals(Request.INVITE)) {
098: Dialog dialog = inviteTid.getDialog();
099: Request ackRequest = dialog
100: .createRequest(Request.ACK);
101: System.out.println("Sending ACK");
102: dialog.sendAck(ackRequest);
103: } else if (cseq.getMethod().equals(Request.CANCEL)) {
104: if (dialog.getState() == DialogState.CONFIRMED) {
105: // oops cancel went in too late. Need to hang up the
106: // dialog.
107: System.out
108: .println("Sending BYE -- cancel went in too late !!");
109: Request byeRequest = dialog
110: .createRequest(Request.BYE);
111: ClientTransaction ct = sipProvider
112: .getNewClientTransaction(byeRequest);
113: dialog.sendRequest(ct);
114: }
115: }
116: } else if (response.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED
117: || response.getStatusCode() == Response.UNAUTHORIZED) {
118: URI uriReq = tid.getRequest().getRequestURI();
119: Request authrequest = this
120: .processResponseAuthorization(response, uriReq);
121:
122: inviteTid = sipProvider
123: .getNewClientTransaction(authrequest);
124: inviteTid.sendRequest();
125: System.out.println("INVITE AUTHORIZATION sent:\n"
126: + authrequest);
127: invco++;
128: }
129: } catch (Exception ex) {
130: ex.printStackTrace();
131: System.exit(0);
132: }
133:
134: }
135:
136: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
137:
138: System.out.println("Transaction Time out");
139: }
140:
141: public void sendCancel() {
142: try {
143: System.out.println("Sending cancel");
144: Request cancelRequest = inviteTid.createCancel();
145: ClientTransaction cancelTid = sipProvider
146: .getNewClientTransaction(cancelRequest);
147: cancelTid.sendRequest();
148: } catch (Exception ex) {
149: ex.printStackTrace();
150: }
151: }
152:
153: public Request processResponseAuthorization(Response response,
154: URI uriReq) {
155: Request requestauth = null;
156: try {
157: System.out.println("processResponseAuthorization()");
158: String schema = ((ProxyAuthenticate) (response
159: .getHeader(SIPHeaderNames.PROXY_AUTHENTICATE)))
160: .getScheme();
161: String nonce = ((ProxyAuthenticate) (response
162: .getHeader(SIPHeaderNames.PROXY_AUTHENTICATE)))
163: .getNonce();
164: ProxyAuthorizationHeader proxyAuthheader = headerFactory
165: .createProxyAuthorizationHeader(schema);
166: proxyAuthheader.setRealm(realm);
167: proxyAuthheader.setNonce(nonce);
168: proxyAuthheader.setAlgorithm("MD5");
169: proxyAuthheader.setUsername(USER_AUTH);
170: proxyAuthheader.setURI(uriReq);
171: DigestClientAuthenticationMethod digest = new DigestClientAuthenticationMethod();
172:
173: String callId = ((CallIdHeader) response
174: .getHeader(CallIdHeader.NAME)).getCallId();
175: requestauth = this .createInvite(callId);
176:
177: digest.initialize(realm, USER_AUTH, uriReq.toString(),
178: nonce, PASS_AUTH, ((CSeqHeader) response
179: .getHeader(CSeqHeader.NAME)).getMethod(),
180: null, "MD5");
181: System.out.println("Proxy Response antes de modificarlo : "
182: + proxyAuthheader.getResponse());
183: String respuestaM = digest.generateResponse();
184: proxyAuthheader.setResponse(respuestaM);
185:
186: requestauth.addHeader(proxyAuthheader);
187: } catch (ParseException pa) {
188: System.out
189: .println("processResponseAuthorization() ParseException:");
190: System.out.println(pa.getMessage());
191: pa.printStackTrace();
192: } catch (Exception ex) {
193: System.out
194: .println("processResponseAuthorization() Exception:");
195: System.out.println(ex.getMessage());
196: ex.printStackTrace();
197: }
198: return requestauth;
199: }
200:
201: public Request createInvite(String callId) throws ParseException,
202: InvalidArgumentException {
203: String fromName = "BigGuy";
204: String fromSipAddress = "here.com";
205: String fromDisplayName = "The Master Blaster";
206:
207: String toSipAddress = "there.com";
208: String toUser = "LittleGuy";
209: String toDisplayName = "The Little Blister";
210:
211: // create >From Header
212: SipURI fromAddress = addressFactory.createSipURI(fromName,
213: fromSipAddress);
214:
215: Address fromNameAddress = addressFactory
216: .createAddress(fromAddress);
217: fromNameAddress.setDisplayName(fromDisplayName);
218: FromHeader fromHeader = headerFactory.createFromHeader(
219: fromNameAddress, "12345");
220:
221: // create To Header
222: SipURI toAddress = addressFactory.createSipURI(toUser,
223: toSipAddress);
224: Address toNameAddress = addressFactory.createAddress(toAddress);
225: toNameAddress.setDisplayName(toDisplayName);
226: ToHeader toHeader = headerFactory.createToHeader(toNameAddress,
227: null);
228:
229: // create Request URI
230: SipURI requestURI = addressFactory.createSipURI(toUser,
231: peerHostPort);
232:
233: // Create ViaHeaders
234: ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
235: ViaHeader viaHeader = headerFactory.createViaHeader(
236: "127.0.0.1", sipProvider.getListeningPoint(transport)
237: .getPort(), transport, null);
238: // add via headers
239: viaHeaders.add(viaHeader);
240:
241: // Create ContentTypeHeader
242: ContentTypeHeader contentTypeHeader = headerFactory
243: .createContentTypeHeader("application", "sdp");
244:
245: // Create a new CallId header
246: CallIdHeader callIdHeader;
247: callIdHeader = sipProvider.getNewCallId();
248: if (callId.trim().length() > 0)
249: callIdHeader.setCallId(callId);
250:
251: // Create a new Cseq header
252: CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(invco,
253: Request.INVITE);
254:
255: // Create a new MaxForwardsHeader
256: MaxForwardsHeader maxForwards = headerFactory
257: .createMaxForwardsHeader(70);
258:
259: // Create the request.
260: Request request = messageFactory.createRequest(requestURI,
261: Request.INVITE, callIdHeader, cSeqHeader, fromHeader,
262: toHeader, viaHeaders, maxForwards);
263: // Create contact headers
264: String host = "127.0.0.1";
265:
266: SipURI contactUrl = addressFactory.createSipURI(fromName, host);
267: contactUrl.setPort(udpListeningPoint.getPort());
268:
269: // Create the contact name address.
270: SipURI contactURI = addressFactory.createSipURI(fromName, host);
271: contactURI.setPort(sipProvider.getListeningPoint(transport)
272: .getPort());
273:
274: Address contactAddress = addressFactory
275: .createAddress(contactURI);
276:
277: // Add the contact address.
278: contactAddress.setDisplayName(fromName);
279:
280: contactHeader = headerFactory
281: .createContactHeader(contactAddress);
282: request.addHeader(contactHeader);
283:
284: String sdpData = "v=0\r\n"
285: + "o=4855 13760799956958020 13760799956958020"
286: + " IN IP4 129.6.55.78\r\n"
287: + "s=mysession session\r\n" + "p=+46 8 52018010\r\n"
288: + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n"
289: + "m=audio 6022 RTP/AVP 0 4 18\r\n"
290: + "a=rtpmap:0 PCMU/8000\r\n"
291: + "a=rtpmap:4 G723/8000\r\n"
292: + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
293: byte[] contents = sdpData.getBytes();
294:
295: request.setContent(contents, contentTypeHeader);
296:
297: Header callInfoHeader = headerFactory.createHeader("Call-Info",
298: "<http://www.antd.nist.gov>");
299: request.addHeader(callInfoHeader);
300:
301: return request;
302: }
303:
304: public void init() {
305: SipFactory sipFactory = null;
306: sipStack = null;
307: sipFactory = SipFactory.getInstance();
308: sipFactory.setPathName("gov.nist");
309:
310: Properties properties = new Properties();
311: properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort
312: + "/" + transport);
313: properties.setProperty("javax.sip.STACK_NAME", "shootistAuth");
314: properties.setProperty("gov.nist.javax.sip.MAX_MESSAGE_SIZE",
315: "1048576");
316: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
317: "shootistAuthdebug.txt");
318: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
319: "shootistAuthlog.txt");
320: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "16");
321: // Drop the client connection after we are done with the transaction.
322: properties.setProperty(
323: "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", "false");
324:
325: try {
326: // Create SipStack object
327: sipStack = sipFactory.createSipStack(properties);
328: System.out.println("createSipStack " + sipStack);
329: } catch (PeerUnavailableException e) {
330: // could not find gov.nist.jain.protocol.ip.sip.SipStackImpl in the
331: // classpath
332: e.printStackTrace();
333: System.err.println(e.getMessage());
334: System.exit(0);
335: }
336: try {
337: headerFactory = sipFactory.createHeaderFactory();
338: addressFactory = sipFactory.createAddressFactory();
339: messageFactory = sipFactory.createMessageFactory();
340: udpListeningPoint = sipStack.createListeningPoint(
341: "127.0.0.1", 5060, "udp");
342: sipProvider = sipStack.createSipProvider(udpListeningPoint);
343: ShootistAuth listener = this ;
344: sipProvider.addSipListener(listener);
345:
346: } catch (PeerUnavailableException e) {
347: e.printStackTrace();
348: System.err.println(e.getMessage());
349: System.exit(0);
350: } catch (Exception e) {
351: System.out.println("Creating Listener Points");
352: System.out.println(e.getMessage());
353: e.printStackTrace();
354: }
355:
356: try {
357: System.out.println("ShootistAuth Process ");
358: Request request = this .createInvite("");
359: // Create the client transaction.
360: inviteTid = sipProvider.getNewClientTransaction(request);
361: // send the request out.
362: inviteTid.sendRequest();
363: System.out.println("INVITE with no Authorization sent:\n"
364: + request);
365: dialog = inviteTid.getDialog();
366:
367: } catch (Exception e) {
368: System.out.println("Creating call CreateInvite()");
369: System.out.println(e.getMessage());
370: e.printStackTrace();
371: }
372: }
373:
374: public static void main(String args[]) {
375: new ShootistAuth().init();
376:
377: }
378:
379: public void processIOException(IOExceptionEvent exceptionEvent) {
380: System.out.println("IOException happened for "
381: + exceptionEvent.getHost() + " port = "
382: + exceptionEvent.getPort());
383:
384: }
385:
386: public void processTransactionTerminated(
387: TransactionTerminatedEvent transactionTerminatedEvent) {
388: System.out.println("Transaction terminated event recieved");
389: }
390:
391: public void processDialogTerminated(
392: DialogTerminatedEvent dialogTerminatedEvent) {
393: System.out.println("dialogTerminatedEvent");
394:
395: }
396: }
|