1 20 21 22 package org.snmp4j.agent.mo.snmp; 23 24 import org.snmp4j.agent.*; 25 import org.snmp4j.agent.mo.*; 26 import org.snmp4j.agent.request.*; 27 import org.snmp4j.event.*; 28 import org.snmp4j.mp.*; 29 import org.snmp4j.security.*; 30 import org.snmp4j.smi.*; 31 import org.snmp4j.PDU; 32 import org.snmp4j.agent.mo.DefaultMOTable.ChangeSet; 33 34 51 public class UsmMIB 52 implements 53 MOGroup, 54 CounterListener, 55 MOValueValidationListener, 56 UsmUserListener { 57 58 private static final OID noAuthProtocol = 59 new OID(new int[] {1,3,6,1,6,3,10,1,1,1}); 60 private static final OID noPrivProtocol = 61 new OID(new int[] {1,3,6,1,6,3,10,1,2,1}); 62 63 private static final OID usmUserSpinLockOID = 64 new OID(new int[] { 1,3,6,1,6,3,15,1,2,1,0 }); 65 private static final OID usmUserEntryOID = 66 new OID(new int[] { 1,3,6,1,6,3,15,1,2,2,1 }); 67 68 69 static final int colUsmUserSecurityName = 0; 70 static final int colUsmUserCloneFrom = 1; 71 static final int colUsmUserAuthProtocol = 2; 72 static final int colUsmUserAuthKeyChange = 3; 73 static final int colUsmUserOwnAuthKeyChange = 4; 74 static final int colUsmUserPrivProtocol = 5; 75 static final int colUsmUserPrivKeyChange = 6; 76 static final int colUsmUserOwnPrivKeyChange = 7; 77 static final int colUsmUserPublic = 8; 78 static final int colUsmUserStorageType = 9; 79 static final int colUsmUserStatus = 10; 80 81 private static final int[][] keyChangeColumns = 82 { {colUsmUserAuthKeyChange, colUsmUserOwnAuthKeyChange}, 83 {colUsmUserPrivKeyChange, colUsmUserOwnPrivKeyChange} 84 }; 85 private USM usm; 86 private SecurityProtocols securityProtocols; 87 88 private static final OID usmStatsPrefix = 89 new OID(SnmpConstants.usmStatsUnsupportedSecLevels.getValue(), 0, 90 SnmpConstants.usmStatsUnsupportedSecLevels.size()-2); 91 92 private static final OID[] usmStatOIDs = new OID[] { 93 SnmpConstants.usmStatsUnsupportedSecLevels, 94 SnmpConstants.usmStatsNotInTimeWindows, 95 SnmpConstants.usmStatsUnknownUserNames, 96 SnmpConstants.usmStatsUnknownEngineIDs, 97 SnmpConstants.usmStatsWrongDigests, 98 SnmpConstants.usmStatsDecryptionErrors 99 }; 100 101 private MOScalar[] usmStats; 102 private TestAndIncr usmUserSpinLock; 103 private DefaultMOTable usmUserEntry; 104 private UsmTableModel usmUserTableModel; 105 106 116 public UsmMIB(USM usm, SecurityProtocols securityProtocols) { 117 this.usm = usm; 118 this.securityProtocols = securityProtocols; 119 usm.getCounterSupport().addCounterListener(this); 120 createUsmStats(); 121 createUsmUser(); 122 } 123 124 private void createUsmUser() { 125 usmUserSpinLock = new TestAndIncr(usmUserSpinLockOID); 126 MOTableSubIndex[] usmUserSubIndexes = new MOTableSubIndex[] { 127 new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 5, 32), 128 new MOTableSubIndex(SMIConstants.SYNTAX_OCTET_STRING, 1, 32) 129 }; 130 MOColumn[] usmUserColumns = new MOColumn[] { 131 new SnmpAdminString(colUsmUserSecurityName + 3, 132 MOAccessImpl.ACCESS_READ_ONLY, 133 null, false), 134 new UsmRowPointer(colUsmUserCloneFrom + 3, 135 MOAccessImpl.ACCESS_READ_CREATE, 136 null, true), 137 new AutonomousType(colUsmUserAuthProtocol + 3, 138 MOAccessImpl.ACCESS_READ_CREATE, 139 noAuthProtocol, true), 140 new UsmKeyChange(colUsmUserAuthKeyChange + 3, 141 MOAccessImpl.ACCESS_READ_CREATE, 142 UsmKeyChange.AUTH_KEY_CHANGE), 143 new UsmOwnKeyChange(colUsmUserOwnAuthKeyChange + 3, 144 MOAccessImpl.ACCESS_READ_CREATE, 145 UsmKeyChange.AUTH_KEY_CHANGE), 146 new AutonomousType(colUsmUserPrivProtocol + 3, 147 MOAccessImpl.ACCESS_READ_CREATE, 148 noPrivProtocol, true), 149 new UsmKeyChange(colUsmUserPrivKeyChange + 3, 150 MOAccessImpl.ACCESS_READ_CREATE, 151 UsmKeyChange.PRIV_KEY_CHANGE), 152 new UsmOwnKeyChange(colUsmUserOwnPrivKeyChange + 3, 153 MOAccessImpl.ACCESS_READ_CREATE, 154 UsmKeyChange.PRIV_KEY_CHANGE), 155 new SnmpAdminString(colUsmUserPublic + 3, 156 MOAccessImpl.ACCESS_READ_CREATE, 157 new OctetString(), true, 0, 32), 158 new StorageType(colUsmUserStorageType + 3, 159 MOAccessImpl.ACCESS_READ_CREATE, 160 new Integer32(StorageType.nonVolatile), true), 161 new RowStatus(colUsmUserStatus + 3, MOAccessImpl.ACCESS_READ_CREATE) 162 }; 163 MOTableIndex usmUserIndex = new MOTableIndex(usmUserSubIndexes, false); 164 usmUserTableModel = new UsmTableModel(usmUserIndex); 165 usmUserEntry = new DefaultMOTable(usmUserEntryOID, usmUserIndex, 166 usmUserColumns, usmUserTableModel); 167 ((AutonomousType) 168 usmUserColumns[colUsmUserAuthProtocol]).addMOValueValidationListener(this); 169 ((AutonomousType) 170 usmUserColumns[colUsmUserPrivProtocol]).addMOValueValidationListener(this); 171 ((UsmRowPointer) 172 usmUserColumns[colUsmUserCloneFrom]).setTargetTable(usmUserEntry); 173 } 174 175 private void createUsmStats() { 176 usmStats = new MOScalar[usmStatOIDs.length]; 177 for (int i=0; i<usmStats.length; i++) { 178 usmStats[i] = new MOScalar(usmStatOIDs[i], MOAccessImpl.ACCESS_READ_ONLY, 179 new Counter32(0)); 180 } 181 } 182 183 public void registerMOs(MOServer server, OctetString context) throws 184 DuplicateRegistrationException { 185 for (int i=0; i < usmStats.length; i++) { 186 server.register(usmStats[i], context); 187 } 188 server.register(usmUserSpinLock, context); 189 server.register(usmUserEntry, context); 190 } 191 192 public void unregisterMOs(MOServer server, OctetString context) { 193 for (int i=0; i < usmStats.length; i++) { 194 server.unregister(usmStats[i], context); 195 } 196 server.unregister(usmUserSpinLock, context); 197 server.unregister(usmUserEntry, context); 198 } 199 200 public void incrementCounter(CounterEvent event) { 201 if ((event.getOid().startsWith(usmStatsPrefix)) && 202 (event.getOid().size() > usmStatsPrefix.size())) { 203 Counter32 current = (Counter32) 204 usmStats[event.getOid().get(usmStatsPrefix.size())-1].getValue(); 205 current.increment(); 206 event.setCurrentValue((Counter32)current.clone()); 207 } 208 } 209 210 211 public void validate(MOValueValidationEvent validationEvent) { 212 if (validationEvent.getSource() instanceof MOColumn) { 213 MOColumn col = (MOColumn) validationEvent.getSource(); 214 switch (col.getColumnID()-4) { 215 case colUsmUserAuthProtocol: { 216 OID value = (OID)validationEvent.getNewValue(); 217 if (!noAuthProtocol.equals(value)) { 218 AuthenticationProtocol authProtocol = 219 SecurityProtocols.getInstance(). 220 getAuthenticationProtocol((OID) validationEvent.getNewValue()); 221 if (authProtocol == null) { 222 validationEvent.setValidationStatus(SnmpConstants. 223 SNMP_ERROR_WRONG_VALUE); 224 } 225 } 226 break; 227 } 228 case colUsmUserPrivProtocol: { 229 OID value = (OID)validationEvent.getNewValue(); 230 if (!noPrivProtocol.equals(value)) { 231 PrivacyProtocol privProtocol = 232 SecurityProtocols.getInstance().getPrivacyProtocol(value); 233 if (privProtocol == null) { 234 validationEvent.setValidationStatus(SnmpConstants. 235 SNMP_ERROR_WRONG_VALUE); 236 } 237 } 238 break; 239 } 240 } 241 } 242 } 243 244 private Variable[] getValuesFromUsmUser(UsmUserEntry user) { 245 Variable[] row = new Variable[usmUserEntry.getColumnCount()]; 246 int n = 0; 247 row[n++] = user.getUsmUser().getSecurityName(); 248 row[n++] = null; 249 row[n++] = user.getUsmUser().getAuthenticationProtocol(); 250 row[n++] = null; 251 row[n++] = null; 252 row[n++] = user.getUsmUser().getPrivacyProtocol(); 253 row[n++] = null; 254 row[n++] = null; 255 row[n++] = new OctetString(); 256 row[n++] = new Integer32(StorageType.nonVolatile); 257 row[n++] = new Integer32(RowStatus.active); 258 return row; 259 } 260 261 private OID createIndex(OctetString engineID, OctetString userName) { 262 if (engineID.length() == 0) { 263 engineID = usm.getLocalEngineID(); 264 } 265 OID index = engineID.toSubIndex(false); 266 index.append(userName.toSubIndex(false)); 267 return index; 268 } 269 270 public void usmUserChange(UsmUserEvent event) { 271 switch (event.getType()) { 272 case UsmUserEvent.USER_ADDED: { 273 Variable[] values = getValuesFromUsmUser(event.getUser()); 274 OID index = createIndex(event.getUser().getEngineID(), 275 event.getUser().getUserName()); 276 MOMutableRow2PC row = (MOMutableRow2PC) 277 usmUserTableModel.createRow(index, values); 278 usmUserTableModel.addRow(row); 279 break; 280 } 281 case UsmUserEvent.USER_REMOVED: { 282 OID index = createIndex(event.getUser().getEngineID(), 283 event.getUser().getUserName()); 284 usmUserTableModel.removeRow(index); 285 } 286 } 287 } 288 289 private static byte[] getKey(UsmUserEntry entry, int authVsPriv) { 290 return (authVsPriv == 0) ? 291 entry.getAuthenticationKey() : 292 entry.getPrivacyKey(); 293 } 294 295 public class UsmTableModel extends DefaultMOMutableTableModel { 296 297 private MOTableIndex indexDef; 298 299 public UsmTableModel(MOTableIndex indexDef) { 300 super(); 301 this.indexDef = indexDef; 302 } 303 304 public MOTableRow createRow(OID index, Variable[] values) { 305 return new UsmTableRow(this, index, values); 306 } 307 308 public MOTableIndex getIndexDef() { 309 return indexDef; 310 } 311 } 312 313 private static boolean isKeyChanged(MOTableRow changeSet, int keyChangeColumn) { 314 OctetString value = (OctetString) changeSet.getValue(keyChangeColumn); 315 if ((value != null) && (value.length() > 0)) { 316 return true; 317 } 318 return false; 319 } 320 321 private static boolean isKeyChanged(MOTableRow changeSet) { 322 return ((isKeyChanged(changeSet, colUsmUserOwnAuthKeyChange)) || 323 (isKeyChanged(changeSet, colUsmUserAuthKeyChange)) || 324 (isKeyChanged(changeSet, colUsmUserOwnPrivKeyChange)) || 325 (isKeyChanged(changeSet, colUsmUserPrivKeyChange))); 326 } 327 328 public class UsmTableRow extends DefaultMOMutableRow2PC { 329 330 private UsmTableModel tableModel; 331 private boolean cloned = false; 332 333 public UsmTableRow(UsmTableModel model, OID index, Variable[] values) { 334 super(index, values); 335 this.tableModel = model; 336 } 337 338 public void setCloned(boolean cloned) { 339 this.cloned = cloned; 340 } 341 342 public boolean isCloned() { 343 return cloned; 344 } 345 346 public MOTableIndex getIndexDef() { 347 return tableModel.getIndexDef(); 348 } 349 350 public AuthenticationProtocol getAuthProtocol(MOTableRow changeSet) 351 { 352 OID authOID = getAuthProtocolOID(changeSet); 353 AuthenticationProtocol a = 354 securityProtocols.getAuthenticationProtocol(authOID); 355 return a; 356 } 357 358 public PrivacyProtocol getPrivProtocol(MOTableRow changeSet) 359 { 360 OID privOID = getPrivProtocolOID(changeSet); 361 PrivacyProtocol p = 362 securityProtocols.getPrivacyProtocol(privOID); 363 return p; 364 } 365 366 public OID getPrivProtocolOID(MOTableRow preparedChanges) 367 { 368 OID privID = null; 369 if (preparedChanges.getValue(colUsmUserCloneFrom) == null) { 370 privID = (OID) preparedChanges.getValue(colUsmUserPrivProtocol); 371 } 372 if (privID == null) { 373 privID = (OID) getValue(colUsmUserPrivProtocol); 374 } 375 return privID; 376 } 377 378 public void prepare(SubRequest subRequest, 379 MOTableRow preparedChanges, int column) { 380 switch (column) { 381 case colUsmUserAuthProtocol: { 382 OID authProtocol = (OID) subRequest.getVariableBinding().getVariable(); 383 if (!authProtocol.equals(noAuthProtocol)) { 384 subRequest.getStatus().setErrorStatus(PDU.inconsistentValue); 385 } 386 else { 387 OID privProtocol = null; 388 Variable privProtocolVariable = 389 preparedChanges.getValue(colUsmUserPrivProtocol); 390 if (privProtocolVariable instanceof OID) { 391 privProtocol = (OID) privProtocolVariable; 392 } 393 else if (privProtocolVariable == null) { 394 privProtocol = (OID) getValue(colUsmUserPrivProtocol); 395 } 396 if ((privProtocol == null) || 397 (!privProtocol.equals(noPrivProtocol))) { 398 subRequest.getStatus().setErrorStatus(PDU.inconsistentValue); 399 } 400 } 401 break; 402 } 403 case colUsmUserPrivProtocol: { 404 OID privProtocol = (OID)subRequest.getVariableBinding().getVariable(); 405 if (!privProtocol.equals(noPrivProtocol)) { 406 subRequest.getStatus().setErrorStatus(PDU.inconsistentValue); 407 } 408 break; 409 } 410 } 411 } 412 413 private OID getCloneFromIndex(MOTableRow changeSet) { 414 OID cloneFrom = (OID) changeSet.getValue(colUsmUserCloneFrom); 415 if (cloneFrom == null) { 416 cloneFrom = (OID) getValue(colUsmUserCloneFrom); 417 } 418 if ((cloneFrom == null) || (cloneFrom.size() <= usmUserEntryOID.size())) { 419 return null; 420 } 421 return new OID(cloneFrom.getValue(), usmUserEntryOID.size()+1, 422 cloneFrom.size() - (usmUserEntryOID.size()+1)); 423 } 424 425 public synchronized void commitRow(SubRequest subRequest, 426 MOTableRow changeSet) { 427 if (subRequest.hasError()) { 428 return; 429 } 430 Variable[] indexValues = getIndexDef().getIndexValues(getIndex()); 431 OctetString engineID = (OctetString) indexValues[0]; 432 OctetString userName = (OctetString) indexValues[1]; 433 UsmUserEntry oldUserEntry; 434 OID cloneFromUserIndex = getCloneFromIndex(changeSet); 435 if (cloneFromUserIndex != null) { 436 Variable[] cloneFromIndexValues = 437 getIndexDef().getIndexValues(cloneFromUserIndex); 438 OctetString cloneFromEngineID = (OctetString) cloneFromIndexValues[0]; 439 OctetString cloneFromUserName = (OctetString) cloneFromIndexValues[1]; 440 441 oldUserEntry = usm.getUser(cloneFromEngineID, cloneFromUserName); 442 if (oldUserEntry != null) { 444 setValue(colUsmUserAuthProtocol, 445 oldUserEntry.getUsmUser().getAuthenticationProtocol()); 446 setValue(colUsmUserPrivProtocol, 447 oldUserEntry.getUsmUser().getPrivacyProtocol()); 448 } 449 } 450 else { 451 oldUserEntry = usm.getUser(engineID, userName); 452 } 453 Integer32 newStatus = 454 (Integer32)changeSet.getValue(colUsmUserStatus); 455 if (((newStatus != null) && 456 ((newStatus.getValue() == RowStatus.active) || 457 (newStatus.getValue() == RowStatus.createAndGo))) || 458 ((getValue(colUsmUserStatus) != null) && 459 (((Integer32)getValue(colUsmUserStatus)).getValue() == RowStatus.active) && 460 (isKeyChanged(changeSet)))) { 461 if (cloneFromUserIndex != null) { 462 setUserObject(oldUserEntry); 464 } 465 if (oldUserEntry == null) { 466 subRequest.getStatus().setErrorStatus(PDU.commitFailed); 467 return; 468 } 469 OctetString[] newKeys = new OctetString[2]; 470 OctetString[] oldKeys = new OctetString[2]; 471 472 AuthenticationProtocol a = getAuthProtocol(changeSet); 473 if (a != null) { 474 for (int p=0; p<2; p++) { 475 oldKeys[p] = new OctetString(getKey(oldUserEntry, p)); 476 for (int i = 0; i < keyChangeColumns[p].length; i++) { 477 OctetString keyChange = 478 (OctetString)getValue(keyChangeColumns[p][i]); 479 if ((keyChange != null) && (keyChange.length() > 0)) { 480 int keyLength = a.getDigestLength(); 481 482 483 if (p == 1) { 484 PrivacyProtocol privProtocol = getPrivProtocol(changeSet); 486 keyLength = 487 Math.min(keyLength, privProtocol.getMaxKeyLength()); 488 } 489 newKeys[p] = 490 KeyChange.changeKey(a, oldKeys[p], 491 keyChange, keyLength); 492 break; } 494 } 495 } 496 } 497 UsmUserEntry newEntry = 498 new UsmUserEntry(engineID.getValue(), userName, 499 getAuthProtocolOID(changeSet), 500 (newKeys[0] == null) ? 501 ((oldKeys[0] == null) ? null : oldKeys[0].getValue()) 502 : newKeys[0].getValue(), 503 getPrivProtocolOID(changeSet), 504 (newKeys[1] == null) ? 505 ((oldKeys[1] == null) ? null : oldKeys[1].getValue()) 506 : newKeys[1].getValue()); 507 usm.updateUser(newEntry); 508 setValue(colUsmUserCloneFrom, null); 509 setValue(colUsmUserAuthKeyChange, null); 510 setValue(colUsmUserOwnAuthKeyChange, null); 511 setValue(colUsmUserPrivKeyChange, null); 512 setValue(colUsmUserOwnPrivKeyChange, null); 513 } 514 if (newStatus != null) { 515 switch (newStatus.getValue()) { 516 case RowStatus.createAndWait: 517 case RowStatus.createAndGo: { 518 setValue(colUsmUserSecurityName, userName); 519 break; 520 } 521 } 522 } 523 } 524 525 public OID getAuthProtocolOID(MOTableRow changeSet) { 526 OID authID = null; 527 if (changeSet.getValue(colUsmUserCloneFrom) == null) { 528 authID = (OID) changeSet.getValue(colUsmUserAuthProtocol); 529 } 530 if (authID == null) { 531 authID = (OID) getValue(colUsmUserAuthProtocol); 532 } 533 return authID; 534 } 535 536 public void cleanupRow(SubRequest subRequest, ChangeSet changeSet) { 537 setUserObject(null); 538 } 539 540 public void undoRow(SubRequest subRequest, ChangeSet changeSet) { 541 if (getUserObject() != null) { 542 usm.updateUser((UsmUserEntry)getUserObject()); 543 } 544 } 545 546 } 547 548 class UsmRowPointer extends RowPointer { 549 550 public UsmRowPointer(int columnID, MOAccess access, OID defaultValue, 551 boolean mutableInService) { 552 super(columnID, access, defaultValue, mutableInService); 553 } 554 555 556 557 public void prepare(SubRequest subRequest, MOTableRow row, 558 MOTableRow changeSet, int column) { 559 super.prepare(subRequest, row, changeSet, column); 560 if (!subRequest.hasError()) { 561 OID rowPointer = (OID) subRequest.getVariableBinding().getVariable(); 562 MOTableCellInfo cell = getTargetTable().getCellInfo(rowPointer); 563 if (cell.getIndex().equals(row.getIndex())) { 564 subRequest.getStatus().setErrorStatus(PDU.inconsistentValue); 566 } 567 } 568 } 569 570 public Variable getValue(MOTableRow row, int column) { 571 return SnmpConstants.zeroDotZero; 572 } 573 } 574 575 public void rowStatusChanged(RowStatusEvent event) { 576 } 577 } 578 | Popular Tags |