1 20 21 package org.snmp4j.security; 22 23 import java.io.*; 24 import java.nio.ByteBuffer ; 25 import java.util.Vector ; 26 27 import org.snmp4j.log.*; 28 import org.snmp4j.asn1.*; 29 import org.snmp4j.asn1.BER.*; 30 import org.snmp4j.event.*; 31 import org.snmp4j.mp.*; 32 import org.snmp4j.smi.*; 33 34 44 public class USM implements SecurityModel { 45 46 private static final int MAXLEN_USMUSERNAME = 32; 47 48 private static final LogAdapter logger = LogFactory.getLogger(USM.class); 49 50 private UsmUserTable userTable; 52 53 private UsmTimeTable timeTable; 54 55 private OctetString localEngineID; 56 private boolean engineDiscoveryEnabled = true; 57 58 private SecurityProtocols securityProtocols; 59 private transient Vector usmUserListeners; 60 private CounterSupport counterSupport; 61 62 73 public USM(SecurityProtocols securityProtocols, 74 OctetString localEngineID, int engineBoots) { 75 this.localEngineID = localEngineID; 76 timeTable = new UsmTimeTable(localEngineID, engineBoots); 77 userTable = new UsmUserTable(); 78 this.securityProtocols = securityProtocols; 79 counterSupport = CounterSupport.getInstance(); 80 } 81 82 public int getID() { 83 return SECURITY_MODEL_USM; 84 } 85 86 95 public void setLocalEngine(OctetString localEngineID, 96 int engineBoots, int engineTime) { 97 timeTable.removeEntry(this.localEngineID); 98 this.localEngineID = localEngineID; 99 timeTable.addEntry(new UsmTimeEntry(localEngineID, engineBoots, engineTime)); 100 } 101 102 108 public OctetString getLocalEngineID() { 109 return localEngineID; 110 } 111 112 117 public void setEngineBoots(int engineBoots) { 118 this.timeTable.setEngineBoots(engineBoots); 119 } 120 121 126 public int getEngineBoots() { 127 return this.timeTable.getEngineBoots(); 128 } 129 130 142 public int getEngineTime() { 143 return this.timeTable.getEngineTime(); 144 } 145 146 public SecurityParameters newSecurityParametersInstance() { 147 return new UsmSecurityParameters(); 148 } 149 150 public SecurityStateReference newSecurityStateReference() { 151 return new UsmSecurityStateReference(); 152 } 153 154 private static byte[] buildMessageBuffer(BERInputStream scopedPDU) 155 throws IOException 156 { 157 scopedPDU.mark(16); 159 int readLengthBytes = (int)scopedPDU.getPosition(); 160 MutableByte mutableByte = new MutableByte(); 161 int length = BER.decodeHeader(scopedPDU, mutableByte); 162 readLengthBytes = (int)scopedPDU.getPosition() - readLengthBytes; 163 byte[] buf = new byte[length + readLengthBytes]; 164 scopedPDU.reset(); 165 166 int offset = 0; 167 int avail = scopedPDU.available(); 168 while ((offset < buf.length) && (avail > 0)) { 169 int read = scopedPDU.read(buf, offset, buf.length - offset); 170 if (read < 0) { 171 break; 172 } 173 offset += read; 174 } 175 return buf; 176 } 177 178 private static byte[] buildWholeMessage(Integer32 snmpVersion, 179 byte[] scopedPdu, 180 byte[] globalData, 181 UsmSecurityParameters 182 usmSecurityParameters) 183 throws IOException 184 { 185 int length = 186 snmpVersion.getBERLength() + 187 globalData.length + 188 usmSecurityParameters.getBERLength() + 189 scopedPdu.length; 190 int totalLength = BER.getBERLengthOfLength(length) + length + 1; 191 192 ByteArrayOutputStream os = new ByteArrayOutputStream(totalLength); 193 BER.encodeHeader(os, BER.SEQUENCE, length); 194 snmpVersion.encodeBER(os); 195 os.write(globalData); 196 usmSecurityParameters.encodeBER(os); 197 os.write(scopedPdu); 198 int secParamsPos = 1 + snmpVersion.getBERLength() + 199 BER.getBERLengthOfLength(length) + globalData.length; 200 usmSecurityParameters.setSecurityParametersPosition(secParamsPos); 201 return os.toByteArray(); 202 } 203 204 public int generateRequestMessage(int snmpVersion, 205 byte[] globalData, 206 int maxMessageSize, 207 int securityModel, 208 byte[] securityEngineID, 209 byte[] securityName, 210 int securityLevel, 211 BERInputStream scopedPDU, 212 SecurityParameters securityParameters, 213 BEROutputStream wholeMsg) throws IOException { 214 215 return generateResponseMessage(snmpVersion, 216 globalData, 217 maxMessageSize, 218 securityModel, 219 securityEngineID, 220 securityName, 221 securityLevel, 222 scopedPDU, 223 null, 224 securityParameters, 225 wholeMsg); 226 } 227 228 public UsmUserEntry getUser(OctetString engineID, OctetString securityName) { 229 if (logger.isDebugEnabled()) { 230 logger.debug("getUser(engineID="+engineID.toHexString()+ 231 ", securityName="+securityName.toString()+")"); 232 } 233 UsmUserEntry entry = userTable.getUser(engineID, securityName); 234 if (entry == null) { 235 entry = userTable.getUser(securityName); 236 if ((entry == null) && (securityName.length() > 0)) { 237 if (logger.isDebugEnabled()) { 238 logger.debug("USM.getUser - User '"+securityName+"' unknown"); 239 } 240 return null; 241 } 242 else { 243 if ((entry == null) || (engineID.length() == 0)) { 244 entry = new UsmUserEntry(); 246 entry.setUserName(securityName); 247 entry.setUsmUser(new UsmUser(securityName, null, null, null, null)); 248 return entry; 249 } 250 else { 251 OID authProtocolOID = entry.getUsmUser().getAuthenticationProtocol(); 253 OID privProtocolOID = entry.getUsmUser().getPrivacyProtocol(); 254 if (authProtocolOID != null) { 255 byte[] authKey; 256 if (entry.getUsmUser().isLocalized()) { 257 authKey = 258 entry.getUsmUser().getAuthenticationPassphrase().getValue(); 259 } 260 else { 261 authKey = securityProtocols.passwordToKey(authProtocolOID, 262 entry.getUsmUser().getAuthenticationPassphrase(), 263 engineID.getValue()); 264 } 265 byte[] privKey = null; 266 if (privProtocolOID != null) { 267 if (entry.getUsmUser().isLocalized()) { 268 privKey = entry.getUsmUser().getPrivacyPassphrase().getValue(); 269 } 270 else { 271 privKey = securityProtocols.passwordToKey(privProtocolOID, 272 authProtocolOID, 273 entry.getUsmUser().getPrivacyPassphrase(), 274 engineID.getValue()); 275 } 276 } 277 entry = addLocalizedUser(engineID.getValue(), securityName, 278 authProtocolOID, authKey, 279 privProtocolOID, privKey); 280 } 281 } 282 } 283 } 284 return entry; 285 } 286 287 public int generateResponseMessage(int snmpVersion, 288 byte[] globalData, 289 int maxMessageSize, 290 int securityModel, 291 byte[] securityEngineID, 292 byte[] securityName, 293 int securityLevel, 294 BERInputStream scopedPDU, 295 SecurityStateReference 296 securityStateReference, 297 SecurityParameters securityParameters, 298 BEROutputStream wholeMsg) throws IOException { 299 300 UsmSecurityParameters usmSecurityParams = 301 (UsmSecurityParameters) securityParameters; 302 if (securityStateReference != null) { 303 UsmSecurityStateReference usmSecurityStateReference = 305 (UsmSecurityStateReference) securityStateReference; 306 if (usmSecurityStateReference.getSecurityEngineID() == null) { 307 usmSecurityParams.setAuthoritativeEngineID(securityEngineID); 308 usmSecurityStateReference.setSecurityEngineID(securityEngineID); 309 } 310 if (usmSecurityStateReference.getSecurityName() == null) { 311 OctetString userName = new OctetString(securityName); 312 usmSecurityStateReference.setSecurityName(userName.getValue()); 313 usmSecurityParams.setUserName(userName); 314 315 OctetString secName = 316 getSecurityName(new OctetString(securityEngineID), userName); 317 318 if ((secName != null) && 319 (secName.length() <= MAXLEN_USMUSERNAME)) { 320 usmSecurityParams.setUserName(secName); 321 } 322 323 } 324 else { 325 usmSecurityParams.setUserName(new OctetString(usmSecurityStateReference.getSecurityName())); 326 } 327 usmSecurityParams.setAuthenticationProtocol(usmSecurityStateReference. 328 getAuthenticationProtocol()); 329 usmSecurityParams.setPrivacyProtocol(usmSecurityStateReference. 330 getPrivacyProtocol()); 331 usmSecurityParams.setAuthenticationKey(usmSecurityStateReference. 332 getAuthenticationKey()); 333 usmSecurityParams.setPrivacyKey(usmSecurityStateReference.getPrivacyKey()); 334 } 335 else { 336 OctetString secEngineID = new OctetString(); 337 if (securityEngineID != null) { 338 secEngineID.setValue(securityEngineID); 339 } 340 OctetString secName = new OctetString(securityName); 341 342 UsmUserEntry user; 343 if (secEngineID.length() == 0) { 344 if (isEngineDiscoveryEnabled()) { 345 user = new UsmUserEntry(); 346 } 347 else { 348 if (logger.isDebugEnabled()) { 349 logger.debug("Engine ID unknown and discovery disabled"); 350 } 351 return SnmpConstants.SNMPv3_USM_UNKNOWN_ENGINEID; 352 } 353 } 354 else { 355 user = getUser(secEngineID, secName); 356 } 357 if (user == null) { 358 if (logger.isDebugEnabled()) { 359 logger.debug("Security name not found for engineID=" + 360 secEngineID.toHexString() + ", securityName=" + 361 secName.toHexString()); 362 } 363 return SnmpConstants.SNMPv3_USM_UNKNOWN_SECURITY_NAME; 364 } 365 AuthenticationProtocol auth = 366 securityProtocols.getAuthenticationProtocol(user.getUsmUser().getAuthenticationProtocol()); 367 PrivacyProtocol priv = 368 securityProtocols.getPrivacyProtocol(user.getUsmUser().getPrivacyProtocol()); 369 usmSecurityParams.setAuthenticationProtocol(auth); 370 usmSecurityParams.setPrivacyProtocol(priv); 371 usmSecurityParams.setAuthenticationKey(user.getAuthenticationKey()); 372 usmSecurityParams.setPrivacyKey(user.getPrivacyKey()); 373 usmSecurityParams.setUserName(user.getUsmUser().getSecurityName()); 374 usmSecurityParams.setAuthoritativeEngineID(secEngineID.getValue()); 375 } 376 377 if (usmSecurityParams.getAuthoritativeEngineID().length > MPv3.MAXLEN_ENGINE_ID) { 379 logger.error("Engine ID too long: "+ 380 usmSecurityParams.getAuthoritativeEngineID().length+">"+ 381 MPv3.MAXLEN_ENGINE_ID+ " for "+ 382 new OctetString(usmSecurityParams.getAuthoritativeEngineID()) 383 .toHexString()); 384 return SnmpConstants.SNMPv3_USM_ERROR; 385 } 386 if (securityName.length > MAXLEN_USMUSERNAME) { 387 logger.error("Security name too long: "+ 388 usmSecurityParams.getAuthoritativeEngineID().length+">"+ 389 MAXLEN_USMUSERNAME+ " for "+ 390 new OctetString(securityName).toHexString()); 391 return SnmpConstants.SNMPv3_USM_ERROR; 392 } 393 394 if (securityLevel >= SecurityLevel.AUTH_NOPRIV) { 395 if (securityStateReference != null) { 396 usmSecurityParams.setAuthoritativeEngineBoots(getEngineBoots()); 398 usmSecurityParams.setAuthoritativeEngineTime(getEngineTime()); 399 } 400 else { 401 OctetString secEngineID = new OctetString(securityEngineID); 403 UsmTimeEntry entry = timeTable.getTime(secEngineID); 404 if (entry == null) { 405 entry = 406 new UsmTimeEntry(secEngineID, 407 usmSecurityParams.getAuthoritativeEngineBoots(), 408 usmSecurityParams. 409 getAuthoritativeEngineTime()); 410 411 timeTable.addEntry(entry); 412 } 413 else { 414 usmSecurityParams.setAuthoritativeEngineBoots(entry.getEngineBoots()); 415 usmSecurityParams.setAuthoritativeEngineTime(entry. 416 getLatestReceivedTime()); 417 } 418 } 419 } 420 421 if ((securityLevel >= SecurityLevel.AUTH_NOPRIV) && 422 (usmSecurityParams.getAuthenticationProtocol() == null)) { 423 return SnmpConstants.SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL; 424 } 425 426 byte[] scopedPduBytes = buildMessageBuffer(scopedPDU); 427 428 if (securityLevel == SecurityLevel.AUTH_PRIV) { 429 if (usmSecurityParams.getPrivacyProtocol() == null) { 430 if (logger.isDebugEnabled()) { 431 logger.debug("Unsupported security level (missing or unsupported privacy protocol)"); 432 } 433 return SnmpConstants.SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL; 434 } 435 logger.debug("RFC3414 §3.1.4.a Outgoing message needs to be encrypted"); 436 437 DecryptParams decryptParams = new DecryptParams(); 438 byte[] encryptedScopedPdu = 439 usmSecurityParams.getPrivacyProtocol(). 440 encrypt(scopedPduBytes, 0, scopedPduBytes.length, 441 usmSecurityParams.getPrivacyKey(), 442 usmSecurityParams.getAuthoritativeEngineBoots(), 443 usmSecurityParams.getAuthoritativeEngineTime(), 444 decryptParams); 445 if (encryptedScopedPdu == null) { 446 if (logger.isDebugEnabled()) { 447 logger.debug("Encryption error"); 448 } 449 return SnmpConstants.SNMPv3_USM_ENCRYPTION_ERROR; 450 } 451 usmSecurityParams.setPrivacyParameters(new OctetString(decryptParams. 452 array)); 453 OctetString encryptedString = new OctetString(encryptedScopedPdu); 454 BEROutputStream os = 455 new BEROutputStream(ByteBuffer.allocate(encryptedString.getBERLength())); 456 encryptedString.encodeBER(os); 457 scopedPduBytes = os.getBuffer().array(); 458 } 459 else { 460 logger.debug("RFC3414 §3.1.4.b Outgoing message is not encrypted"); 461 usmSecurityParams.setPrivacyParameters(new OctetString()); 462 } 463 464 byte[] wholeMessage; 465 if (securityLevel >= SecurityLevel.AUTH_NOPRIV) { 466 467 byte[] blank = 468 new byte[AuthenticationProtocol.MESSAGE_AUTHENTICATION_CODE_LENGTH]; 469 usmSecurityParams.setAuthenticationParameters(new OctetString(blank)); 470 wholeMessage = 471 buildWholeMessage(new Integer32(snmpVersion), 472 scopedPduBytes, globalData, usmSecurityParams); 473 474 int authParamsPos = 475 usmSecurityParams.getAuthParametersPosition() + 476 usmSecurityParams.getSecurityParametersPosition(); 477 478 boolean authOK = usmSecurityParams.getAuthenticationProtocol(). 479 authenticate(usmSecurityParams.getAuthenticationKey(), 480 wholeMessage, 481 0, 482 wholeMessage.length, 483 new ByteArrayWindow(wholeMessage, 484 authParamsPos, 485 AuthenticationProtocol. 486 MESSAGE_AUTHENTICATION_CODE_LENGTH)); 487 488 if (!authOK) { 489 if (logger.isDebugEnabled()) { 490 logger.debug("Outgoing message could not be authenticated"); 491 } 492 return SnmpConstants.SNMPv3_USM_AUTHENTICATION_ERROR; 493 } 494 } 495 else { 496 usmSecurityParams.setAuthoritativeEngineBoots(0); 498 usmSecurityParams.setAuthenticationParameters(new OctetString()); 499 usmSecurityParams.setAuthoritativeEngineTime(0); 500 501 wholeMessage = 503 buildWholeMessage(new Integer32(snmpVersion), 504 scopedPduBytes, globalData, usmSecurityParams); 505 } 506 ByteBuffer buf = 507 (ByteBuffer )ByteBuffer.wrap(wholeMessage).position(wholeMessage.length); 508 wholeMsg.setBuffer(buf); 509 return SnmpConstants.SNMPv3_USM_OK; 511 } 512 513 private OctetString getSecurityName(OctetString engineID, 514 OctetString userName) { 515 if (userName.length() == 0) { 516 return userName; 517 } 518 UsmUserEntry user = userTable.getUser(engineID, userName); 519 if (user != null) { 520 return user.getUsmUser().getSecurityName(); 521 } 522 else if (isEngineDiscoveryEnabled()) { 523 user = userTable.getUser(userName); 524 if (user != null) { 525 return user.getUsmUser().getSecurityName(); 526 } 527 } 528 return null; 529 } 530 531 public int processIncomingMsg(int snmpVersion, int maxMessageSize, SecurityParameters securityParameters, SecurityModel securityModel, int securityLevel, BERInputStream wholeMsg, OctetString securityEngineID, OctetString securityName, BEROutputStream scopedPDU, Integer32 maxSizeResponseScopedPDU, SecurityStateReference securityStateReference, StatusInformation statusInfo 544 ) throws IOException { 545 546 UsmSecurityParameters usmSecurityParameters = 547 (UsmSecurityParameters) securityParameters; 548 UsmSecurityStateReference usmSecurityStateReference = 549 (UsmSecurityStateReference) securityStateReference; 550 securityEngineID.setValue(usmSecurityParameters.getAuthoritativeEngineID()); 551 552 byte[] message = buildMessageBuffer(wholeMsg); 553 554 if ((securityEngineID.length() == 0) || 555 (timeTable.checkEngineID(securityEngineID, 556 isEngineDiscoveryEnabled()) != 557 SnmpConstants.SNMPv3_USM_OK)) { 558 if (logger.isDebugEnabled()) { 560 logger.debug("RFC3414 §3.2.3 Unknown engine ID: " + 561 securityEngineID.toHexString()); 562 } 563 securityEngineID.setValue(usmSecurityParameters. 564 getAuthoritativeEngineID()); 565 securityName.setValue(usmSecurityParameters.getUserName().getValue()); 566 567 if (statusInfo != null) { 568 CounterEvent event = new CounterEvent(this, 569 SnmpConstants. 570 usmStatsUnknownEngineIDs); 571 fireIncrementCounter(event); 572 statusInfo.setSecurityLevel(new Integer32(securityLevel)); 573 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 574 event.getCurrentValue())); 575 } 576 return SnmpConstants.SNMPv3_USM_UNKNOWN_ENGINEID; 577 } 578 579 securityName.setValue(usmSecurityParameters.getUserName().getValue()); 580 581 int scopedPDUPosition = usmSecurityParameters.getScopedPduPosition(); 582 583 if ((usmSecurityParameters.getUserName().length() > 0) || 585 (securityLevel > SecurityLevel.NOAUTH_NOPRIV)) { 586 OctetString secName = getSecurityName(securityEngineID, 587 usmSecurityParameters.getUserName()); 588 if (secName == null) { 589 if (logger.isDebugEnabled()) { 590 logger.debug("RFC3414 §3.2.4 Unknown security name: " + 591 securityName.toHexString()); 592 } 593 if (statusInfo != null) { 594 CounterEvent event = new CounterEvent(this, 595 SnmpConstants.usmStatsUnknownUserNames); 596 fireIncrementCounter(event); 597 statusInfo.setSecurityLevel(new Integer32(SecurityLevel.NOAUTH_NOPRIV)); 598 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 599 event.getCurrentValue())); 600 } 601 return SnmpConstants.SNMPv3_USM_UNKNOWN_SECURITY_NAME; 602 } 603 } 604 else { 605 if (logger.isDebugEnabled()) { 606 logger.debug("Accepting zero length security name"); 607 } 608 securityName.setValue(new byte[0]); 609 } 610 611 if ((usmSecurityParameters.getUserName().length() > 0) || 612 (securityLevel > SecurityLevel.NOAUTH_NOPRIV)) { 613 UsmUserEntry user = getUser(securityEngineID, securityName); 614 if (user == null) { 615 if (logger.isDebugEnabled()) { 616 logger.debug("RFC3414 §3.2.4 Unknown security name: " + 617 securityName.toHexString()+ " for engine ID "+ 618 securityEngineID.toHexString()); 619 } 620 CounterEvent event = 621 new CounterEvent(this, SnmpConstants.usmStatsUnknownUserNames); 622 fireIncrementCounter(event); 623 if (statusInfo != null) { 624 statusInfo.setSecurityLevel(new Integer32(SecurityLevel.NOAUTH_NOPRIV)); 625 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 626 event.getCurrentValue())); 627 } 628 return SnmpConstants.SNMPv3_USM_UNKNOWN_SECURITY_NAME; 629 } 630 631 usmSecurityStateReference.setUserName(user.getUserName().getValue()); 632 633 AuthenticationProtocol auth = 634 securityProtocols.getAuthenticationProtocol( 635 user.getUsmUser().getAuthenticationProtocol()); 636 PrivacyProtocol priv = 637 securityProtocols.getPrivacyProtocol( 638 user.getUsmUser().getPrivacyProtocol()); 639 640 if (((securityLevel >= SecurityLevel.AUTH_NOPRIV) && (auth == null)) || 641 (((securityLevel >= SecurityLevel.AUTH_PRIV) && (priv == null)))) { 642 if (logger.isDebugEnabled()) { 643 logger.debug("RFC3414 §3.2.5 - Unsupported security level: " + 644 securityLevel); 645 } 646 CounterEvent event = 647 new CounterEvent(this, SnmpConstants.usmStatsUnsupportedSecLevels); 648 fireIncrementCounter(event); 649 statusInfo.setSecurityLevel(new Integer32(SecurityLevel.NOAUTH_NOPRIV)); 650 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 651 event.getCurrentValue())); 652 return SnmpConstants.SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL; 653 } 654 if (securityLevel >= SecurityLevel.AUTH_NOPRIV) { 655 if (statusInfo != null) { 656 int authParamsPos = 657 usmSecurityParameters.getAuthParametersPosition() + 658 usmSecurityParameters.getSecurityParametersPosition(); 659 boolean authentic = 660 auth.isAuthentic(user.getAuthenticationKey(), 661 message, 0, message.length, 662 new ByteArrayWindow(message, authParamsPos, 663 AuthenticationProtocol.MESSAGE_AUTHENTICATION_CODE_LENGTH)); 664 if (!authentic) { 665 if (logger.isDebugEnabled()) { 666 logger.debug( 667 "RFC3414 §3.2.6 Wrong digest -> authentication failure: " + 668 usmSecurityParameters.getAuthenticationParameters().toHexString()); 669 } 670 CounterEvent event = 671 new CounterEvent(this, SnmpConstants.usmStatsWrongDigests); 672 fireIncrementCounter(event); 673 statusInfo.setSecurityLevel(new Integer32(SecurityLevel.NOAUTH_NOPRIV)); 674 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 675 event.getCurrentValue())); 676 return SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE; 677 } 678 usmSecurityStateReference.setAuthenticationKey(user.getAuthenticationKey()); 679 usmSecurityStateReference.setPrivacyKey(user.getPrivacyKey()); 680 usmSecurityStateReference.setAuthenticationProtocol(auth); 681 usmSecurityStateReference.setPrivacyProtocol(priv); 682 int status = timeTable.checkTime(new UsmTimeEntry(securityEngineID, 684 usmSecurityParameters.getAuthoritativeEngineBoots(), 685 usmSecurityParameters.getAuthoritativeEngineTime())); 686 687 switch (status) { 688 case SnmpConstants.SNMPv3_USM_NOT_IN_TIME_WINDOW: { 689 logger.debug("RFC3414 §3.2.7.a Not in time window; engineID='" + 690 securityEngineID + 691 "', engineBoots=" + 692 usmSecurityParameters.getAuthoritativeEngineBoots() + 693 ", engineTime=" + 694 usmSecurityParameters.getAuthoritativeEngineTime()); 695 CounterEvent event = 696 new CounterEvent(this, SnmpConstants.usmStatsNotInTimeWindows); 697 fireIncrementCounter(event); 698 statusInfo.setSecurityLevel(new Integer32(SecurityLevel.AUTH_NOPRIV)); 699 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 700 event.getCurrentValue())); 701 return status; 702 } 703 case SnmpConstants.SNMPv3_USM_UNKNOWN_ENGINEID: { 704 if (logger.isDebugEnabled()) { 705 logger.debug("RFC3414 §3.2.7.b - Unkown engine ID: " + 706 securityEngineID); 707 } 708 CounterEvent event = 709 new CounterEvent(this, SnmpConstants.usmStatsNotInTimeWindows); 710 fireIncrementCounter(event); 711 statusInfo.setSecurityLevel(new Integer32(SecurityLevel.AUTH_NOPRIV)); 712 statusInfo.setErrorIndication(new VariableBinding(event.getOid(), 713 event.getCurrentValue())); 714 return status; 715 716 } 717 } 718 } 719 if (securityLevel >= SecurityLevel.AUTH_PRIV) { 720 OctetString privParams = usmSecurityParameters.getPrivacyParameters(); 721 DecryptParams decryptParams = new DecryptParams(privParams.getValue(), 722 0, privParams.length()); 723 try { 724 int scopedPDUHeaderLength = message.length - scopedPDUPosition; 725 ByteBuffer bis = ByteBuffer.wrap(message, scopedPDUPosition, 726 scopedPDUHeaderLength); 727 BERInputStream scopedPDUHeader = new BERInputStream(bis); 728 long headerStartingPosition = scopedPDUHeader.getPosition(); 729 int scopedPDULength = 730 BER.decodeHeader(scopedPDUHeader, new MutableByte()); 731 int scopedPDUPayloadPosition = 732 scopedPDUPosition + 733 (int)(scopedPDUHeader.getPosition() - headerStartingPosition); 734 scopedPDUHeader.close(); 735 scopedPDUHeader = null; 736 byte[] scopedPduBytes = 737 priv.decrypt(message, scopedPDUPayloadPosition, scopedPDULength, 738 user.getPrivacyKey(), 739 usmSecurityParameters.getAuthoritativeEngineBoots(), 740 usmSecurityParameters.getAuthoritativeEngineTime(), 741 decryptParams); 742 ByteBuffer buf = ByteBuffer.wrap(scopedPduBytes); 743 scopedPDU.setFilledBuffer(buf); 744 } 745 catch (Exception ex) { 746 logger.debug("RFC 3414 §3.2.8 Decryption error: "+ex.getMessage()); 747 return SnmpConstants.SNMPv3_USM_DECRYPTION_ERROR; 748 } 749 } 750 else { 751 int scopedPduLength = message.length - scopedPDUPosition; 752 ByteBuffer buf = 753 ByteBuffer.wrap(message, scopedPDUPosition, scopedPduLength); 754 scopedPDU.setFilledBuffer(buf); 755 } 756 } 757 else { 758 int scopedPduLength = message.length - scopedPDUPosition; 759 ByteBuffer buf = 760 ByteBuffer.wrap(message, scopedPDUPosition, scopedPduLength); 761 scopedPDU.setFilledBuffer(buf); 762 } 763 } 764 else { 765 int scopedPduLength = message.length - scopedPDUPosition; 766 ByteBuffer buf = 767 ByteBuffer.wrap(message, scopedPDUPosition, scopedPduLength); 768 scopedPDU.setFilledBuffer(buf); 769 } 770 int maxSecParamsOverhead = 772 usmSecurityParameters.getBERMaxLength(securityLevel); 773 maxSizeResponseScopedPDU.setValue(maxMessageSize - 774 maxSecParamsOverhead); 775 776 usmSecurityStateReference.setSecurityName(securityName.getValue()); 777 return SnmpConstants.SNMPv3_USM_OK; 778 } 779 780 protected void fireIncrementCounter(CounterEvent e) { 781 counterSupport.fireIncrementCounter(e); 782 } 783 784 791 public void addUser(OctetString userName, UsmUser user) { 792 addUser(userName, new OctetString(), user); 793 } 794 795 808 public void addUser(OctetString userName, OctetString engineID, UsmUser user) { 809 byte[] authKey = null; 810 byte[] privKey = null; 811 if ((engineID != null) && (engineID.length() > 0)) { 812 if (user.getAuthenticationProtocol() != null) { 813 if (user.isLocalized()) { 814 authKey = user.getAuthenticationPassphrase().getValue(); 815 } 816 else { 817 authKey = 818 securityProtocols.passwordToKey(user.getAuthenticationProtocol(), 819 user.getAuthenticationPassphrase(), 820 engineID.getValue()); 821 } 822 if (user.getPrivacyProtocol() != null) { 823 if (user.isLocalized()) { 824 privKey = user.getPrivacyPassphrase().getValue(); 825 } 826 else { 827 privKey = 828 securityProtocols.passwordToKey(user.getPrivacyProtocol(), 829 user.getAuthenticationProtocol(), 830 user.getPrivacyPassphrase(), 831 engineID.getValue()); 832 } 833 } 834 } 835 } 836 OctetString userEngineID; 837 if (user.isLocalized()) { 838 userEngineID = user.getLocalizationEngineID(); 839 } 840 else { 841 userEngineID = (engineID == null) ? new OctetString() : engineID; 842 } 843 UsmUserEntry entry = 844 new UsmUserEntry(userName, userEngineID, user); 845 entry.setAuthenticationKey(authKey); 846 entry.setPrivacyKey(privKey); 847 userTable.addUser(entry); 848 fireUsmUserChange(new UsmUserEvent(this, entry, UsmUserEvent.USER_ADDED)); 849 } 850 851 860 public void updateUser(UsmUserEntry entry) { 861 UsmUserEntry oldEntry = userTable.addUser(entry); 862 fireUsmUserChange(new UsmUserEvent(this, entry, 863 (oldEntry == null) ? 864 UsmUserEvent.USER_ADDED: 865 UsmUserEvent.USER_CHANGED)); 866 } 867 868 876 public void setUsers(UsmUser[] users) { 877 if ((users == null) || (users.length == 0)) { 878 userTable.clear(); 879 } 880 else { 881 Vector v = new Vector (users.length); 882 for (int i=0; i<users.length; i++) { 883 UsmUserEntry entry = 884 new UsmUserEntry(users[i].getSecurityName(), 885 (UsmUser)users[i].clone()); 886 v.add(entry); 887 } 888 userTable.setUsers(v); 889 } 890 } 891 892 902 public UsmUserTable getUserTable() { 903 return userTable; 904 } 905 906 913 public UsmTimeTable getTimeTable() { 914 return timeTable; 915 } 916 917 929 public UsmUser removeUser(OctetString engineID, OctetString userName) { 930 UsmUserEntry entry = userTable.removeUser(engineID, userName); 931 if (entry != null) { 932 fireUsmUserChange(new UsmUserEvent(this, entry, UsmUserEvent.USER_REMOVED)); 933 return entry.getUsmUser(); 934 } 935 return null; 936 } 937 938 941 public void removeAllUsers() { 942 userTable.clear(); 943 fireUsmUserChange(new UsmUserEvent(this, null, UsmUserEvent.USER_REMOVED)); 944 } 945 946 963 public UsmUserEntry addLocalizedUser(byte[] engineID, 964 OctetString userName, 965 OID authProtocol, byte[] authKey, 966 OID privProtocol, byte[] privKey) { 967 UsmUserEntry newEntry = new UsmUserEntry(engineID, userName, 968 authProtocol, authKey, 969 privProtocol, privKey); 970 userTable.addUser(newEntry); 971 fireUsmUserChange(new UsmUserEvent(this, newEntry, 972 UsmUserEvent.USER_ADDED)); 973 return newEntry; 974 } 975 976 983 public boolean isEngineDiscoveryEnabled() { 984 return engineDiscoveryEnabled; 985 } 986 987 993 public void setEngineDiscoveryEnabled(boolean engineDiscoveryEnabled) { 994 this.engineDiscoveryEnabled = engineDiscoveryEnabled; 995 } 996 997 1002 public synchronized void removeUsmUserListener(UsmUserListener l) { 1003 if (usmUserListeners != null && usmUserListeners.contains(l)) { 1004 Vector v = (Vector ) usmUserListeners.clone(); 1005 v.removeElement(l); 1006 usmUserListeners = v; 1007 } 1008 } 1009 1010 1018 public synchronized void addUsmUserListener(UsmUserListener l) { 1019 Vector v = (usmUserListeners == null) ? new Vector (2) : 1020 (Vector ) usmUserListeners.clone(); 1021 if (!v.contains(l)) { 1022 v.addElement(l); 1023 usmUserListeners = v; 1024 } 1025 } 1026 1027 1036 public void removeEngineTime(OctetString engineID) { 1037 timeTable.removeEntry(engineID); 1038 } 1039 1040 1045 protected void fireUsmUserChange(UsmUserEvent e) { 1046 if (usmUserListeners != null) { 1047 Vector listeners = usmUserListeners; 1048 int count = listeners.size(); 1049 for (int i = 0; i < count; i++) { 1050 ((UsmUserListener) listeners.elementAt(i)).usmUserChange(e); 1051 } 1052 } 1053 } 1054 1055 1062 public CounterSupport getCounterSupport() { 1063 return counterSupport; 1064 } 1065 1066 1073 public SecurityProtocols getSecurityProtocols() { 1074 return securityProtocols; 1075 } 1076 1077 1083 public void setCounterSupport(CounterSupport counterSupport) { 1084 if (counterSupport == null) { 1085 throw new NullPointerException (); 1086 } 1087 this.counterSupport = counterSupport; 1088 } 1089} 1090 | Popular Tags |