1 /* 2 * Conditions Of Use 3 * 4 * This software was developed by employees of the National Institute of 5 * Standards and Technology (NIST), an agency of the Federal Government. 6 * Pursuant to title 15 Untied States Code Section 105, works of NIST 7 * employees are not subject to copyright protection in the United States 8 * and are considered to be in the public domain. As a result, a formal 9 * license is not needed to use the software. 10 * 11 * This software is provided by NIST as a service and is expressly 12 * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15 * AND DATA ACCURACY. NIST does not warrant or make any representations 16 * regarding the use of the software or the results thereof, including but 17 * not limited to the correctness, accuracy, reliability or usefulness of 18 * the software. 19 * 20 * Permission to use this software is contingent upon your acceptance 21 * of the terms of this agreement. 22 * 23 */ 24 /***************************************************************************** 25 * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * 26 ******************************************************************************/ 27 package gov.nist.javax.sip.header; 28 29 import gov.nist.core.*; 30 import gov.nist.javax.sip.header.ims.ParameterNamesIms; 31 32 import java.text.ParseException; 33 /* 34 * 2005/06/12: geir.hedemark (at) telio.no: Changed behaviour of qop parameter in 35 * Authorization header - removed quoting of string according to 36 * RFC3261, BNF element "message-qop" (as opposed to "qop-options", 37 * which is quoted. 38 */ 39 40 /** 41 * The generic AuthenticationHeader 42 * 43 * @author Olivier Deruelle 44 * @author M. Ranganathan <br/> 45 * @since 1.1 46 * @version 1.2 $Revision: 1.13 $ $Date: 2009/10/18 13:46:32 $ 47 * 48 * 49 */ 50 public abstract class AuthenticationHeader extends ParametersHeader { 51 52 public static final String DOMAIN = ParameterNames.DOMAIN; 53 54 public static final String REALM = ParameterNames.REALM; 55 56 public static final String OPAQUE = ParameterNames.OPAQUE; 57 58 public static final String ALGORITHM = ParameterNames.ALGORITHM; 59 60 public static final String QOP = ParameterNames.QOP; 61 62 public static final String STALE = ParameterNames.STALE; 63 64 public static final String SIGNATURE = ParameterNames.SIGNATURE; 65 66 public static final String RESPONSE = ParameterNames.RESPONSE; 67 68 public static final String SIGNED_BY = ParameterNames.SIGNED_BY; 69 70 public static final String NC = ParameterNames.NC; 71 72 public static final String URI = ParameterNames.URI; 73 74 public static final String USERNAME = ParameterNames.USERNAME; 75 76 public static final String CNONCE = ParameterNames.CNONCE; 77 78 public static final String NONCE = ParameterNames.NONCE; 79 80 public static final String IK = ParameterNamesIms.IK; 81 public static final String CK = ParameterNamesIms.CK; 82 public static final String INTEGRITY_PROTECTED = ParameterNamesIms.INTEGRITY_PROTECTED; 83 84 protected String scheme; 85 86 public AuthenticationHeader(String name) { 87 super(name); 88 parameters.setSeparator(Separators.COMMA); // oddball 89 this.scheme = ParameterNames.DIGEST; 90 } 91 92 public AuthenticationHeader() { 93 super(); 94 parameters.setSeparator(Separators.COMMA); 95 } 96 97 /** 98 * set the specified parameter. Bug reported by Dominic Sparks. 99 * 100 * @param name -- 101 * name of the parameter 102 * @param value -- 103 * value of the parameter. 104 */ 105 public void setParameter(String name, String value) throws ParseException { 106 NameValue nv = super.parameters.getNameValue(name.toLowerCase()); 107 if (nv == null) { 108 nv = new NameValue(name, value); 109 if (name.equalsIgnoreCase(ParameterNames.QOP) 110 || name.equalsIgnoreCase(ParameterNames.REALM) 111 || name.equalsIgnoreCase(ParameterNames.CNONCE) 112 || name.equalsIgnoreCase(ParameterNames.NONCE) 113 || name.equalsIgnoreCase(ParameterNames.USERNAME) 114 || name.equalsIgnoreCase(ParameterNames.DOMAIN) 115 || name.equalsIgnoreCase(ParameterNames.OPAQUE) 116 || name.equalsIgnoreCase(ParameterNames.NEXT_NONCE) 117 || name.equalsIgnoreCase(ParameterNames.URI) 118 || name.equalsIgnoreCase(ParameterNames.RESPONSE ) 119 ||name.equalsIgnoreCase(ParameterNamesIms.IK) 120 || name.equalsIgnoreCase(ParameterNamesIms.CK) 121 || name.equalsIgnoreCase(ParameterNamesIms.INTEGRITY_PROTECTED)) { 122 if (((this instanceof Authorization) || (this instanceof ProxyAuthorization)) 123 && name.equalsIgnoreCase(ParameterNames.QOP)) { 124 // NOP, QOP not quoted in authorization headers 125 } else { 126 nv.setQuotedValue(); 127 } 128 if (value == null) 129 throw new NullPointerException("null value"); 130 if (value.startsWith(Separators.DOUBLE_QUOTE)) 131 throw new ParseException(value 132 + " : Unexpected DOUBLE_QUOTE", 0); 133 } 134 super.setParameter(nv); 135 } else 136 nv.setValueAsObject(value); 137 138 } 139 140 /** 141 * This is only used for the parser interface. 142 * 143 * @param challenge -- 144 * the challenge from which the parameters are extracted. 145 */ 146 public void setChallenge(Challenge challenge) { 147 this.scheme = challenge.scheme; 148 super.parameters = challenge.authParams; 149 } 150 151 /** 152 * Encode in canonical form. 153 * 154 * @return canonical string. 155 */ 156 public String encodeBody() { 157 this.parameters.setSeparator(Separators.COMMA); 158 return this.scheme + SP + parameters.encode(); 159 } 160 161 /** 162 * Sets the scheme of the challenge information for this 163 * AuthenticationHeaderHeader. For example, Digest. 164 * 165 * @param scheme - 166 * the new string value that identifies the challenge information 167 * scheme. 168 */ 169 public void setScheme(String scheme) { 170 this.scheme = scheme; 171 } 172 173 /** 174 * Returns the scheme of the challenge information for this 175 * AuthenticationHeaderHeader. 176 * 177 * @return the string value of the challenge information. 178 */ 179 public String getScheme() { 180 return scheme; 181 } 182 183 /** 184 * Sets the Realm of the WWWAuthenicateHeader to the <var>realm</var> 185 * parameter value. Realm strings MUST be globally unique. It is RECOMMENDED 186 * that a realm string contain a hostname or domain name. Realm strings 187 * SHOULD present a human-readable identifier that can be rendered to a 188 * user. 189 * 190 * @param realm 191 * the new Realm String of this WWWAuthenicateHeader. 192 * @throws ParseException 193 * which signals that an error has been reached unexpectedly 194 * while parsing the realm. 195 */ 196 public void setRealm(String realm) throws ParseException { 197 if (realm == null) 198 throw new NullPointerException( 199 "JAIN-SIP Exception, " 200 + " AuthenticationHeader, setRealm(), The realm parameter is null"); 201 setParameter(ParameterNames.REALM, realm); 202 } 203 204 /** 205 * Returns the Realm value of this WWWAuthenicateHeader. This convenience 206 * method returns only the realm of the complete Challenge. 207 * 208 * @return the String representing the Realm information, null if value is 209 * not set. 210 * @since v1.1 211 */ 212 public String getRealm() { 213 return getParameter(ParameterNames.REALM); 214 } 215 216 /** 217 * Sets the Nonce of the WWWAuthenicateHeader to the <var>nonce</var> 218 * parameter value. 219 * 220 * @param nonce - 221 * the new nonce String of this WWWAuthenicateHeader. 222 * @throws ParseException 223 * which signals that an error has been reached unexpectedly 224 * while parsing the nonce value. 225 * @since v1.1 226 */ 227 public void setNonce(String nonce) throws ParseException { 228 if (nonce == null) 229 throw new NullPointerException( 230 "JAIN-SIP Exception, " 231 + " AuthenticationHeader, setNonce(), The nonce parameter is null"); 232 setParameter(NONCE, nonce); 233 } 234 235 /** 236 * Returns the Nonce value of this WWWAuthenicateHeader. 237 * 238 * @return the String representing the nonce information, null if value is 239 * not set. 240 * @since v1.1 241 */ 242 public String getNonce() { 243 return getParameter(ParameterNames.NONCE); 244 } 245 246 /** 247 * Sets the URI of the WWWAuthenicateHeader to the <var>uri</var> parameter 248 * value. 249 * 250 * @param uri - 251 * the new URI of this AuthenicationHeader. 252 * @since v1.1 253 * 254 * Note that since 1.2 this is no longer applicable to the WWW-Authenticate 255 * and Proxy-Authenticate headers 256 */ 257 public void setURI(javax.sip.address.URI uri) { 258 if (uri != null) { 259 NameValue nv = new NameValue(ParameterNames.URI, uri); 260 nv.setQuotedValue(); 261 super.parameters.set(nv); 262 } else { 263 throw new NullPointerException("Null URI"); 264 } 265 } 266 267 /** 268 * Returns the URI value of this WWWAuthenicateHeader, for example 269 * DigestURI. 270 * 271 * @return the URI representing the URI information, null if value is not 272 * set. 273 * @since v1.1 274 * 275 * Note that since 1.2 this is no longer applicable to the WWW-Authenticate 276 * and Proxy-Authenticate headers 277 */ 278 public javax.sip.address.URI getURI() { 279 return getParameterAsURI(ParameterNames.URI); 280 } 281 282 /** 283 * Sets the Algorithm of the WWWAuthenicateHeader to the new <var>algorithm</var> 284 * parameter value. 285 * 286 * @param algorithm - 287 * the new algorithm String of this WWWAuthenicateHeader. 288 * @throws ParseException 289 * which signals that an error has been reached unexpectedly 290 * while parsing the algorithm value. 291 * @since v1.1 292 */ 293 public void setAlgorithm(String algorithm) throws ParseException { 294 if (algorithm == null) 295 throw new NullPointerException("null arg"); 296 setParameter(ParameterNames.ALGORITHM, algorithm); 297 } 298 299 /** 300 * Returns the Algorithm value of this WWWAuthenicateHeader. 301 * 302 * @return the String representing the Algorithm information, null if the 303 * value is not set. 304 * @since v1.1 305 */ 306 public String getAlgorithm() { 307 return getParameter(ParameterNames.ALGORITHM); 308 } 309 310 /** 311 * Sets the Qop value of the WWWAuthenicateHeader to the new <var>qop</var> 312 * parameter value. 313 * 314 * @param qop - 315 * the new Qop string of this WWWAuthenicateHeader. 316 * @throws ParseException 317 * which signals that an error has been reached unexpectedly 318 * while parsing the Qop value. 319 * @since v1.1 320 */ 321 public void setQop(String qop) throws ParseException { 322 if (qop == null) 323 throw new NullPointerException("null arg"); 324 setParameter(ParameterNames.QOP, qop); 325 } 326 327 /** 328 * Returns the Qop value of this WWWAuthenicateHeader. 329 * 330 * @return the string representing the Qop information, null if the value is 331 * not set. 332 * @since v1.1 333 */ 334 public String getQop() { 335 return getParameter(ParameterNames.QOP); 336 } 337 338 /** 339 * Sets the Opaque value of the WWWAuthenicateHeader to the new <var>opaque</var> 340 * parameter value. 341 * 342 * @param opaque - 343 * the new Opaque string of this WWWAuthenicateHeader. 344 * @throws ParseException 345 * which signals that an error has been reached unexpectedly 346 * while parsing the opaque value. 347 * @since v1.1 348 */ 349 public void setOpaque(String opaque) throws ParseException { 350 if (opaque == null) 351 throw new NullPointerException("null arg"); 352 setParameter(ParameterNames.OPAQUE, opaque); 353 } 354 355 /** 356 * Returns the Opaque value of this WWWAuthenicateHeader. 357 * 358 * @return the String representing the Opaque information, null if the value 359 * is not set. 360 * @since v1.1 361 */ 362 public String getOpaque() { 363 return getParameter(ParameterNames.OPAQUE); 364 } 365 366 /** 367 * Sets the Domain of the WWWAuthenicateHeader to the <var>domain</var> 368 * parameter value. 369 * 370 * @param domain - 371 * the new Domain string of this WWWAuthenicateHeader. 372 * @throws ParseException 373 * which signals that an error has been reached unexpectedly 374 * while parsing the domain. 375 * @since v1.1 376 */ 377 public void setDomain(String domain) throws ParseException { 378 if (domain == null) 379 throw new NullPointerException("null arg"); 380 setParameter(ParameterNames.DOMAIN, domain); 381 } 382 383 /** 384 * Returns the Domain value of this WWWAuthenicateHeader. 385 * 386 * @return the String representing the Domain information, null if value is 387 * not set. 388 * @since v1.1 389 */ 390 public String getDomain() { 391 return getParameter(ParameterNames.DOMAIN); 392 } 393 394 /** 395 * Sets the value of the stale parameter of the WWWAuthenicateHeader to the 396 * <var>stale</var> parameter value. 397 * 398 * @param stale - 399 * the Boolean.valueOf value of the stale parameter. 400 * @since v1.1 401 */ 402 public void setStale(boolean stale) { 403 setParameter(new NameValue(ParameterNames.STALE, Boolean.valueOf(stale))); 404 } 405 406 /** 407 * Returns the boolean value of the state paramater of this 408 * WWWAuthenicateHeader. 409 * 410 * @return the boolean representing if the challenge is stale. 411 * @since v1.1 412 */ 413 public boolean isStale() { 414 return this.getParameterAsBoolean(ParameterNames.STALE); 415 } 416 417 /** 418 * Set the CNonce. 419 * 420 * @param cnonce -- 421 * a nonce string. 422 */ 423 public void setCNonce(String cnonce) throws ParseException { 424 this.setParameter(ParameterNames.CNONCE, cnonce); 425 } 426 427 /** 428 * Get the CNonce. 429 * 430 * @return the cnonce value. 431 */ 432 public String getCNonce() { 433 return getParameter(ParameterNames.CNONCE); 434 } 435 436 public int getNonceCount() { 437 return this.getParameterAsHexInt(ParameterNames.NC); 438 439 } 440 441 /** 442 * Set the nonce count pakrameter. Bug fix sent in by Andreas Bystrm 443 */ 444 445 public void setNonceCount(int param) throws java.text.ParseException { 446 if (param < 0) 447 throw new ParseException("bad value", 0); 448 449 String nc = Integer.toHexString(param); 450 451 String base = "00000000"; 452 nc = base.substring(0, 8 - nc.length()) + nc; 453 this.setParameter(ParameterNames.NC, nc); 454 455 } 456 457 /** 458 * Get the RESPONSE value (or null if it does not exist). 459 * 460 * @return String response parameter value. 461 */ 462 public String getResponse() { 463 return (String) getParameterValue(ParameterNames.RESPONSE); 464 } 465 466 /** 467 * Set the Response. 468 * 469 * @param response 470 * to set. 471 */ 472 public void setResponse(String response) throws ParseException { 473 if (response == null) 474 throw new NullPointerException("Null parameter"); 475 // Bug fix from Andreas Bystrm 476 this.setParameter(RESPONSE, response); 477 } 478 479 /** 480 * Returns the Username value of this AuthorizationHeader. This convenience 481 * method returns only the username of the complete Response. 482 * 483 * @return the String representing the Username information, null if value 484 * is not set. 485 * 486 * 487 * 488 */ 489 public String getUsername() { 490 return (String) getParameter(ParameterNames.USERNAME); 491 } 492 493 /** 494 * Sets the Username of the AuthorizationHeader to the <var>username</var> 495 * parameter value. 496 * 497 * @param username 498 * the new Username String of this AuthorizationHeader. 499 * 500 * @throws ParseException 501 * which signals that an error has been reached 502 * 503 * unexpectedly while parsing the username. 504 * 505 * 506 * 507 */ 508 public void setUsername(String username) throws ParseException { 509 this.setParameter(ParameterNames.USERNAME, username); 510 } 511 512 public void setIK(String ik) throws ParseException { 513 if (ik == null) 514 throw new NullPointerException( 515 "JAIN-SIP Exception, " 516 + " AuthenticationHeader, setIk(), The auth-param IK parameter is null"); 517 setParameter(IK, ik); 518 } 519 520 public String getIK() { 521 return getParameter(ParameterNamesIms.IK); 522 } 523 524 public void setCK(String ck) throws ParseException { 525 if (ck == null) 526 throw new NullPointerException( 527 "JAIN-SIP Exception, " 528 + " AuthenticationHeader, setCk(), The auth-param CK parameter is null"); 529 setParameter(CK, ck); 530 } 531 532 public String getCK() { 533 return getParameter(ParameterNamesIms.CK); 534 } 535 536 537 public void setIntegrityProtected(String integrityProtected) throws ParseException 538 { 539 if (integrityProtected == null) 540 throw new NullPointerException( 541 "JAIN-SIP Exception, " 542 + " AuthenticationHeader, setIntegrityProtected(), The integrity-protected parameter is null"); 543 544 setParameter(INTEGRITY_PROTECTED, integrityProtected); 545 } 546 547 548 549 public String getIntegrityProtected() { 550 return getParameter(ParameterNamesIms.INTEGRITY_PROTECTED); 551 } 552 553 } 554