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:
009: /**
010: * This class is a UAC template. Shootist is the guy that shoots and shootme is
011: * the guy that gets shot and asks for authorization.
012: *
013: * @author M. Ranganathan
014: * @author Kathleen McCallum
015: */
016:
017: public class ShootmeAuth implements SipListener {
018:
019: private static AddressFactory addressFactory;
020: private static MessageFactory messageFactory;
021: private static HeaderFactory headerFactory;
022: private static SipStack sipStack;
023: private static final String myAddress = "127.0.0.1";
024: private static final int myPort = 5070;
025: protected ServerTransaction inviteTid;
026: private Response okResponse;
027: private Request inviteRequest;
028: private Dialog dialog;
029: DigestServerAuthenticationMethod dsam;
030:
031: class MyTimerTask extends TimerTask {
032: ShootmeAuth shootme;
033:
034: public MyTimerTask(ShootmeAuth shootme) {
035: this .shootme = shootme;
036:
037: }
038:
039: public void run() {
040: shootme.sendInviteOK();
041: }
042: }
043:
044: protected static final String usageString = "java "
045: + "examples.shootist.Shootist \n"
046: + ">>>> is your class path set to the root?";
047:
048: private static void usage() {
049: System.out.println(usageString);
050: System.exit(0);
051:
052: }
053:
054: public void processRequest(RequestEvent requestEvent) {
055: Request request = requestEvent.getRequest();
056: ServerTransaction serverTransactionId = requestEvent
057: .getServerTransaction();
058:
059: System.out.println("\n\nRequest " + request.getMethod()
060: + " received at " + sipStack.getStackName()
061: + " with server transaction id " + serverTransactionId);
062:
063: if (request.getMethod().equals(Request.INVITE)) {
064: processInvite(requestEvent, serverTransactionId);
065: } else if (request.getMethod().equals(Request.ACK)) {
066: processAck(requestEvent, serverTransactionId);
067: } else if (request.getMethod().equals(Request.BYE)) {
068: processBye(requestEvent, serverTransactionId);
069: } else if (request.getMethod().equals(Request.CANCEL)) {
070: processCancel(requestEvent, serverTransactionId);
071: }
072:
073: }
074:
075: public void processResponse(ResponseEvent responseEvent) {
076: }
077:
078: /**
079: * Process the ACK request. Send the bye and complete the call flow.
080: */
081: public void processAck(RequestEvent requestEvent,
082: ServerTransaction serverTransaction) {
083: System.out.println("shootme: got an ACK! ");
084: System.out.println("Dialog State = " + dialog.getState());
085: }
086:
087: /**
088: * Process the invite request.
089: */
090: public void processInvite(RequestEvent requestEvent,
091: ServerTransaction serverTransaction) {
092: SipProvider sipProvider = (SipProvider) requestEvent
093: .getSource();
094: Request request = requestEvent.getRequest();
095: try {
096: // Verify AUTHORIZATION !!!!!!!!!!!!!!!!
097: dsam = new DigestServerAuthenticationMethod();
098: dsam.initialize(); // it should read values from file, now all static
099: if (!checkProxyAuthorization(request)) {
100: Response responseauth = messageFactory
101: .createResponse(
102: Response.PROXY_AUTHENTICATION_REQUIRED,
103: request);
104:
105: ProxyAuthenticateHeader proxyAuthenticate = headerFactory
106: .createProxyAuthenticateHeader(dsam.getScheme());
107: proxyAuthenticate.setParameter("realm", dsam
108: .getRealm(null));
109: proxyAuthenticate.setParameter("nonce", dsam
110: .generateNonce());
111: //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain());
112: proxyAuthenticate.setParameter("opaque", "");
113: proxyAuthenticate.setParameter("stale", "FALSE");
114: proxyAuthenticate.setParameter("algorithm", dsam
115: .getAlgorithm());
116: responseauth.setHeader(proxyAuthenticate);
117:
118: if (serverTransaction != null)
119: serverTransaction.sendResponse(responseauth);
120: else
121: sipProvider.sendResponse(responseauth);
122:
123: System.out
124: .println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"
125: + responseauth.toString());
126: }
127: System.out
128: .println("shootme: got an Invite with Authorization, sending Trying");
129: // System.out.println("shootme: " + request);
130: Response response = messageFactory.createResponse(
131: Response.TRYING, request);
132: ServerTransaction st = requestEvent.getServerTransaction();
133:
134: if (st == null) {
135: st = sipProvider.getNewServerTransaction(request);
136: }
137: dialog = st.getDialog();
138:
139: st.sendResponse(response);
140:
141: this .okResponse = messageFactory.createResponse(
142: Response.OK, request);
143: Address address = addressFactory
144: .createAddress("Shootme <sip:" + myAddress + ":"
145: + myPort + ">");
146: ContactHeader contactHeader = headerFactory
147: .createContactHeader(address);
148: response.addHeader(contactHeader);
149: ToHeader toHeader = (ToHeader) okResponse
150: .getHeader(ToHeader.NAME);
151: toHeader.setTag("4321"); // Application is supposed to set.
152: okResponse.addHeader(contactHeader);
153: this .inviteTid = st;
154: // Defer sending the OK to simulate the phone ringing.
155: // Answered in 1 second ( this guy is fast at taking calls)
156: this .inviteRequest = request;
157:
158: new Timer().schedule(new MyTimerTask(this ), 1000);
159: } catch (Exception ex) {
160: ex.printStackTrace();
161: System.exit(0);
162: }
163: }
164:
165: private void sendInviteOK() {
166: try {
167: if (inviteTid.getState() != TransactionState.COMPLETED) {
168: System.out.println("shootme: Dialog state before 200: "
169: + inviteTid.getDialog().getState());
170: inviteTid.sendResponse(okResponse);
171: System.out.println("shootme: Dialog state after 200: "
172: + inviteTid.getDialog().getState());
173: }
174: } catch (SipException ex) {
175: ex.printStackTrace();
176: } catch (InvalidArgumentException ex) {
177: ex.printStackTrace();
178: }
179: }
180:
181: /**
182: * Process the bye request.
183: */
184: public void processBye(RequestEvent requestEvent,
185: ServerTransaction serverTransactionId) {
186: SipProvider sipProvider = (SipProvider) requestEvent
187: .getSource();
188: Request request = requestEvent.getRequest();
189: try {
190: System.out.println("shootme: got a bye sending OK.");
191: Response response = messageFactory.createResponse(200,
192: request);
193: serverTransactionId.sendResponse(response);
194: System.out.println("Dialog State is "
195: + serverTransactionId.getDialog().getState());
196:
197: } catch (Exception ex) {
198: ex.printStackTrace();
199: System.exit(0);
200:
201: }
202: }
203:
204: public void processCancel(RequestEvent requestEvent,
205: ServerTransaction serverTransactionId) {
206: SipProvider sipProvider = (SipProvider) requestEvent
207: .getSource();
208: Request request = requestEvent.getRequest();
209: try {
210: System.out.println("shootme: got a cancel.");
211: if (serverTransactionId == null) {
212: System.out.println("shootme: null tid.");
213: return;
214: }
215: Response response = messageFactory.createResponse(200,
216: request);
217: serverTransactionId.sendResponse(response);
218: if (dialog.getState() != DialogState.CONFIRMED) {
219: response = messageFactory.createResponse(
220: Response.REQUEST_TERMINATED, inviteRequest);
221: inviteTid.sendResponse(response);
222: }
223:
224: } catch (Exception ex) {
225: ex.printStackTrace();
226: System.exit(0);
227:
228: }
229: }
230:
231: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
232: Transaction transaction;
233: if (timeoutEvent.isServerTransaction()) {
234: transaction = timeoutEvent.getServerTransaction();
235: } else {
236: transaction = timeoutEvent.getClientTransaction();
237: }
238: System.out.println("state = " + transaction.getState());
239: System.out.println("dialog = " + transaction.getDialog());
240: System.out.println("dialogState = "
241: + transaction.getDialog().getState());
242: System.out.println("Transaction Time out");
243: }
244:
245: public boolean checkProxyAuthorization(Request request) {
246: // Let Acks go through unchallenged.
247: boolean retorno;
248: ProxyAuthorizationHeader proxyAuthorization = (ProxyAuthorizationHeader) request
249: .getHeader(ProxyAuthorizationHeader.NAME);
250:
251: if (proxyAuthorization == null) {
252: System.out
253: .println("Authentication failed: ProxyAuthorization header missing!");
254: return false;
255: } else {
256: String username = proxyAuthorization
257: .getParameter("username");
258: //String password=proxyAuthorization.getParameter("password");
259:
260: try {
261: boolean res = dsam.doAuthenticate(username,
262: proxyAuthorization, request);
263: if (res)
264: System.out
265: .println("Authentication passed for user: "
266: + username);
267: else
268: System.out
269: .println("Authentication failed for user: "
270: + username);
271: return res;
272: } catch (Exception e) {
273: e.printStackTrace();
274: return false;
275: }
276: }
277: }
278:
279: public void init() {
280: SipFactory sipFactory = null;
281: sipStack = null;
282: sipFactory = SipFactory.getInstance();
283: sipFactory.setPathName("gov.nist");
284: Properties properties = new Properties();
285: properties.setProperty("javax.sip.STACK_NAME", "shootme");
286: // You need 16 for logging traces. 32 for debug + traces.
287: // Your code will limp at 32 but it is best for debugging.
288: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
289: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
290: "shootmedebug.txt");
291: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
292: "shootmelog.txt");
293:
294: try {
295: // Create SipStack object
296: sipStack = sipFactory.createSipStack(properties);
297: System.out.println("sipStack = " + sipStack);
298: } catch (PeerUnavailableException e) {
299: // could not find
300: // gov.nist.jain.protocol.ip.sip.SipStackImpl
301: // in the classpath
302: e.printStackTrace();
303: System.err.println(e.getMessage());
304: if (e.getCause() != null)
305: e.getCause().printStackTrace();
306: System.exit(0);
307: }
308:
309: try {
310: headerFactory = sipFactory.createHeaderFactory();
311: addressFactory = sipFactory.createAddressFactory();
312: messageFactory = sipFactory.createMessageFactory();
313: ListeningPoint lp = sipStack.createListeningPoint(
314: "127.0.0.1", myPort, "udp");
315:
316: ShootmeAuth listener = this ;
317:
318: SipProvider sipProvider = sipStack.createSipProvider(lp);
319: System.out.println("udp provider " + sipProvider);
320: sipProvider.addSipListener(listener);
321:
322: } catch (Exception ex) {
323: System.out.println(ex.getMessage());
324: ex.printStackTrace();
325: usage();
326: }
327: }
328:
329: public static void main(String args[]) {
330: new ShootmeAuth().init();
331: }
332:
333: public void processIOException(IOExceptionEvent exceptionEvent) {
334: System.out.println("IOException");
335:
336: }
337:
338: public void processTransactionTerminated(
339: TransactionTerminatedEvent transactionTerminatedEvent) {
340: System.out.println("Transaction terminated event recieved");
341:
342: }
343:
344: public void processDialogTerminated(
345: DialogTerminatedEvent dialogTerminatedEvent) {
346: System.out.println("Dialog terminated event recieved");
347:
348: }
349:
350: }
|