Re: authorization in register
Ryan Mitchell <[email protected]> Fri, 13 Jul 2007 10:03:36 -0700
| Newsgroups | gmane.comp.voip.nist-sip |
|---|---|
| Message-ID | <[email protected]> |
Hello Roberto,
The following is an excerpt from a larger system, so don't expect it to
compile, but I picked out the lines to show the essential details. I
originally figured out the authentication bits from the examples
included with the NIST/JAIN source code. The same code works for INVITE
407 challenges as well, using
ProxyAuthorizationHeader/ProxyAuthenticateHeader where appropriate.
Hopefully my comments are readable. There are not many comments in
makeAuthHeader() because I mostly copied this from other examples.
Below I have hardcoded username & password. In the real application I
have something like a User class where I call user.calcA1(mdigest,
realm) to get the A1 string. This way the user object can avoid
exposing the password to the rest of the system; better yet just
pre-compute A1 for the user and store that in the database so you don't
have plaintext passwords anywhere.
/** Create & resend new request with authorization response to the
challenge given in resp. */
void handleResponse(Response resp, ClientTransaction ct, SipProvider
sipProvider) {
int rc = resp.getStatusCode(); // verify rc==Response.UNAUTHORIZED
// add this header to the new request to resend to the server
AuthorizationHeader authHeader = makeAuthHeader(resp, ct.getRequest());
// create new request - don't try to reuse the original
Request req = (Request)ct.getRequest().clone();
// before adding new authHeader, check if one already exists ...
sometimes SIP servers/proxies
// will erroneously reject a request that contains an
AuthorizationHeader with 401/407 instead
// of 403 -- so make sure we don't get into an infinite loop.
Header ah_ = req.getHeader(AuthorizationHeader.NAME);
if (ah_ != null && authHeader.equals(ah_)) {
// give up, notify user of problem ...
return;
}
req.addHeader(authHeader);
// inc cseq
CSeqHeader cseq = (CSeqHeader)resp.getHeader(CSeqHeader.NAME);
cseq.setSeqNumber(cseq.getSeqNumber() + 1);
req.setHeader(cseq);
cit = sipProvider.getNewClientTransaction(req);
cit.sendRequest();
}
AuthorizationHeader makeAuthHeader(Response resp, Request req) {
// Authenticate header with challenge we need to reply to
WWWAuthenticateHeader ah_c =
(WWWAuthenticateHeader)resp.getHeader(WWWAuthenticateHeader.NAME);
// Authorization header we will build with response to challenge
AuthorizationHeader ah_r =
headerFactory.createAuthorizationHeader(ah_c.getScheme());
// assemble data we need to create response string
URI request_uri = req.getRequestURI();
String request_method = req.getMethod();
String nonce = ah_c.getNonce();
String algrm = ah_c.getAlgorithm();
String realm = ah_c.getRealm();
String username = "krusty";
String password = "pw1234";
MessageDigest mdigest = MessageDigest.getInstance(algrm);
// A1
String A1 = username + ":" + realm + ":" + password;
String HA1 = Str.toHexString(mdigest.digest(A1.getBytes()));
// A2
String A2 = request_method.toUpperCase() + ":" + request_uri ;
String HA2 = Str.toHexString(mdigest.digest(A2.getBytes()));
// KD
String KD = HA1 + ":" + nonce + ":" + HA2;
String response = Str.toHexString(mdigest.digest(KD.getBytes()));
ah_r.setRealm(realm);
ah_r.setNonce(nonce);
ah_r.setUsername(uap.getUsername());
ah_r.setURI(request_uri);
ah_r.setAlgorithm(algrm);
ah_r.setResponse(response);
return ah_r;
}
/**
* From Nist/JAIN examples:
* convert an array of bytes to an hexadecimal string
* @return a string (length = 2 * b.length)
* @param b bytes array to convert to a hexadecimal
* string
*/
static String toHexString(byte b[]) {
int pos = 0;
char[] c = new char[b.length*2];
for (int i=0; i< b.length; i++) {
c[pos++] = toHex[(b[i] >> 4) & 0x0F];
c[pos++] = toHex[b[i] & 0x0f];
}
return new String(c);
}
private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
Roberto Mier Escandón wrote:
> Hi all
>
> I have a simple question. Has anybody an example code for creating a
> second REGISTER message with Authorization header when a 401
> unauthorized response is received to a first REGISTER message?. This
> is, Is there a simply way with nist-sip of creating the Authorization
> header in the second register?
>
> Thank you
>
> _______________________________________________
> nist-sip mailing list
> [email protected]
> http://www-x.antd.nist.gov/mailman/listinfo/nist-sip
>
--
Ryan Mitchell <[email protected]>
Telecom Logic, LLC
503-943-2980