001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.admin.std.meta; 028 029 030 031 import org.opends.server.admin.AdministratorAction; 032 import org.opends.server.admin.BooleanPropertyDefinition; 033 import org.opends.server.admin.ClassPropertyDefinition; 034 import org.opends.server.admin.client.AuthorizationException; 035 import org.opends.server.admin.client.CommunicationException; 036 import org.opends.server.admin.client.ConcurrentModificationException; 037 import org.opends.server.admin.client.ManagedObject; 038 import org.opends.server.admin.client.MissingMandatoryPropertiesException; 039 import org.opends.server.admin.client.OperationRejectedException; 040 import org.opends.server.admin.condition.Conditions; 041 import org.opends.server.admin.DefaultBehaviorProvider; 042 import org.opends.server.admin.DefinedDefaultBehaviorProvider; 043 import org.opends.server.admin.GenericConstraint; 044 import org.opends.server.admin.ManagedObjectAlreadyExistsException; 045 import org.opends.server.admin.ManagedObjectDefinition; 046 import org.opends.server.admin.PropertyOption; 047 import org.opends.server.admin.PropertyProvider; 048 import org.opends.server.admin.server.ConfigurationChangeListener; 049 import org.opends.server.admin.server.ServerManagedObject; 050 import org.opends.server.admin.std.client.FileBasedKeyManagerProviderCfgClient; 051 import org.opends.server.admin.std.server.FileBasedKeyManagerProviderCfg; 052 import org.opends.server.admin.std.server.KeyManagerProviderCfg; 053 import org.opends.server.admin.StringPropertyDefinition; 054 import org.opends.server.admin.Tag; 055 import org.opends.server.admin.UndefinedDefaultBehaviorProvider; 056 import org.opends.server.types.DN; 057 058 059 060 /** 061 * An interface for querying the File Based Key Manager Provider 062 * managed object definition meta information. 063 * <p> 064 * The File Based Key Manager Provider can be used to obtain the 065 * server certificate from a key store file on the local file system. 066 */ 067 public final class FileBasedKeyManagerProviderCfgDefn extends ManagedObjectDefinition<FileBasedKeyManagerProviderCfgClient, FileBasedKeyManagerProviderCfg> { 068 069 // The singleton configuration definition instance. 070 private static final FileBasedKeyManagerProviderCfgDefn INSTANCE = new FileBasedKeyManagerProviderCfgDefn(); 071 072 073 074 // The "java-class" property definition. 075 private static final ClassPropertyDefinition PD_JAVA_CLASS; 076 077 078 079 // The "key-store-file" property definition. 080 private static final StringPropertyDefinition PD_KEY_STORE_FILE; 081 082 083 084 // The "key-store-pin" property definition. 085 private static final StringPropertyDefinition PD_KEY_STORE_PIN; 086 087 088 089 // The "key-store-pin-environment-variable" property definition. 090 private static final StringPropertyDefinition PD_KEY_STORE_PIN_ENVIRONMENT_VARIABLE; 091 092 093 094 // The "key-store-pin-file" property definition. 095 private static final StringPropertyDefinition PD_KEY_STORE_PIN_FILE; 096 097 098 099 // The "key-store-pin-property" property definition. 100 private static final StringPropertyDefinition PD_KEY_STORE_PIN_PROPERTY; 101 102 103 104 // The "key-store-type" property definition. 105 private static final StringPropertyDefinition PD_KEY_STORE_TYPE; 106 107 108 109 // Build the "java-class" property definition. 110 static { 111 ClassPropertyDefinition.Builder builder = ClassPropertyDefinition.createBuilder(INSTANCE, "java-class"); 112 builder.setOption(PropertyOption.MANDATORY); 113 builder.setOption(PropertyOption.ADVANCED); 114 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.COMPONENT_RESTART, INSTANCE, "java-class")); 115 DefaultBehaviorProvider<String> provider = new DefinedDefaultBehaviorProvider<String>("org.opends.server.extensions.FileBasedKeyManagerProvider"); 116 builder.setDefaultBehaviorProvider(provider); 117 builder.addInstanceOf("org.opends.server.api.KeyManagerProvider"); 118 PD_JAVA_CLASS = builder.getInstance(); 119 INSTANCE.registerPropertyDefinition(PD_JAVA_CLASS); 120 } 121 122 123 124 // Build the "key-store-file" property definition. 125 static { 126 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "key-store-file"); 127 builder.setOption(PropertyOption.MANDATORY); 128 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "key-store-file")); 129 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); 130 builder.setPattern(".*", "FILE"); 131 PD_KEY_STORE_FILE = builder.getInstance(); 132 INSTANCE.registerPropertyDefinition(PD_KEY_STORE_FILE); 133 } 134 135 136 137 // Build the "key-store-pin" property definition. 138 static { 139 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "key-store-pin"); 140 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "key-store-pin")); 141 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); 142 PD_KEY_STORE_PIN = builder.getInstance(); 143 INSTANCE.registerPropertyDefinition(PD_KEY_STORE_PIN); 144 } 145 146 147 148 // Build the "key-store-pin-environment-variable" property definition. 149 static { 150 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "key-store-pin-environment-variable"); 151 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "key-store-pin-environment-variable")); 152 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); 153 builder.setPattern(".*", "STRING"); 154 PD_KEY_STORE_PIN_ENVIRONMENT_VARIABLE = builder.getInstance(); 155 INSTANCE.registerPropertyDefinition(PD_KEY_STORE_PIN_ENVIRONMENT_VARIABLE); 156 } 157 158 159 160 // Build the "key-store-pin-file" property definition. 161 static { 162 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "key-store-pin-file"); 163 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "key-store-pin-file")); 164 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); 165 builder.setPattern(".*", "FILE"); 166 PD_KEY_STORE_PIN_FILE = builder.getInstance(); 167 INSTANCE.registerPropertyDefinition(PD_KEY_STORE_PIN_FILE); 168 } 169 170 171 172 // Build the "key-store-pin-property" property definition. 173 static { 174 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "key-store-pin-property"); 175 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "key-store-pin-property")); 176 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); 177 builder.setPattern(".*", "STRING"); 178 PD_KEY_STORE_PIN_PROPERTY = builder.getInstance(); 179 INSTANCE.registerPropertyDefinition(PD_KEY_STORE_PIN_PROPERTY); 180 } 181 182 183 184 // Build the "key-store-type" property definition. 185 static { 186 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "key-store-type"); 187 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "key-store-type")); 188 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>()); 189 builder.setPattern(".*", "STRING"); 190 PD_KEY_STORE_TYPE = builder.getInstance(); 191 INSTANCE.registerPropertyDefinition(PD_KEY_STORE_TYPE); 192 } 193 194 195 196 // Register the tags associated with this managed object definition. 197 static { 198 INSTANCE.registerTag(Tag.valueOf("security")); 199 } 200 201 202 203 // Register the constraints associated with this managed object definition. 204 static { 205 INSTANCE.registerConstraint(new GenericConstraint(INSTANCE, 1, Conditions.implies(Conditions.contains("enabled", "true"), Conditions.or(Conditions.isPresent("key-store-pin-property"), Conditions.isPresent("key-store-pin-environment-variable"), Conditions.isPresent("key-store-pin-file"), Conditions.isPresent("key-store-pin"))))); 206 } 207 208 209 210 /** 211 * Get the File Based Key Manager Provider configuration definition 212 * singleton. 213 * 214 * @return Returns the File Based Key Manager Provider configuration 215 * definition singleton. 216 */ 217 public static FileBasedKeyManagerProviderCfgDefn getInstance() { 218 return INSTANCE; 219 } 220 221 222 223 /** 224 * Private constructor. 225 */ 226 private FileBasedKeyManagerProviderCfgDefn() { 227 super("file-based-key-manager-provider", KeyManagerProviderCfgDefn.getInstance()); 228 } 229 230 231 232 /** 233 * {@inheritDoc} 234 */ 235 public FileBasedKeyManagerProviderCfgClient createClientConfiguration( 236 ManagedObject<? extends FileBasedKeyManagerProviderCfgClient> impl) { 237 return new FileBasedKeyManagerProviderCfgClientImpl(impl); 238 } 239 240 241 242 /** 243 * {@inheritDoc} 244 */ 245 public FileBasedKeyManagerProviderCfg createServerConfiguration( 246 ServerManagedObject<? extends FileBasedKeyManagerProviderCfg> impl) { 247 return new FileBasedKeyManagerProviderCfgServerImpl(impl); 248 } 249 250 251 252 /** 253 * {@inheritDoc} 254 */ 255 public Class<FileBasedKeyManagerProviderCfg> getServerConfigurationClass() { 256 return FileBasedKeyManagerProviderCfg.class; 257 } 258 259 260 261 /** 262 * Get the "enabled" property definition. 263 * <p> 264 * Indicates whether the File Based Key Manager Provider is enabled 265 * for use. 266 * 267 * @return Returns the "enabled" property definition. 268 */ 269 public BooleanPropertyDefinition getEnabledPropertyDefinition() { 270 return KeyManagerProviderCfgDefn.getInstance().getEnabledPropertyDefinition(); 271 } 272 273 274 275 /** 276 * Get the "java-class" property definition. 277 * <p> 278 * The fully-qualified name of the Java class that provides the File 279 * Based Key Manager Provider implementation. 280 * 281 * @return Returns the "java-class" property definition. 282 */ 283 public ClassPropertyDefinition getJavaClassPropertyDefinition() { 284 return PD_JAVA_CLASS; 285 } 286 287 288 289 /** 290 * Get the "key-store-file" property definition. 291 * <p> 292 * Specifies the path to the file that contains the private key 293 * information. This may be an absolute path, or a path that is 294 * relative to the OpenDS Directory Server instance root. 295 * <p> 296 * Changes to this property will take effect the next time that the 297 * key manager is accessed. 298 * 299 * @return Returns the "key-store-file" property definition. 300 */ 301 public StringPropertyDefinition getKeyStoreFilePropertyDefinition() { 302 return PD_KEY_STORE_FILE; 303 } 304 305 306 307 /** 308 * Get the "key-store-pin" property definition. 309 * <p> 310 * Specifies the clear-text PIN needed to access the File Based Key 311 * Manager Provider . 312 * 313 * @return Returns the "key-store-pin" property definition. 314 */ 315 public StringPropertyDefinition getKeyStorePinPropertyDefinition() { 316 return PD_KEY_STORE_PIN; 317 } 318 319 320 321 /** 322 * Get the "key-store-pin-environment-variable" property definition. 323 * <p> 324 * Specifies the name of the environment variable that contains the 325 * clear-text PIN needed to access the File Based Key Manager 326 * Provider . 327 * 328 * @return Returns the "key-store-pin-environment-variable" property definition. 329 */ 330 public StringPropertyDefinition getKeyStorePinEnvironmentVariablePropertyDefinition() { 331 return PD_KEY_STORE_PIN_ENVIRONMENT_VARIABLE; 332 } 333 334 335 336 /** 337 * Get the "key-store-pin-file" property definition. 338 * <p> 339 * Specifies the path to the text file whose only contents should be 340 * a single line containing the clear-text PIN needed to access the 341 * File Based Key Manager Provider . 342 * 343 * @return Returns the "key-store-pin-file" property definition. 344 */ 345 public StringPropertyDefinition getKeyStorePinFilePropertyDefinition() { 346 return PD_KEY_STORE_PIN_FILE; 347 } 348 349 350 351 /** 352 * Get the "key-store-pin-property" property definition. 353 * <p> 354 * Specifies the name of the Java property that contains the 355 * clear-text PIN needed to access the File Based Key Manager 356 * Provider . 357 * 358 * @return Returns the "key-store-pin-property" property definition. 359 */ 360 public StringPropertyDefinition getKeyStorePinPropertyPropertyDefinition() { 361 return PD_KEY_STORE_PIN_PROPERTY; 362 } 363 364 365 366 /** 367 * Get the "key-store-type" property definition. 368 * <p> 369 * Specifies the format for the data in the key store file. 370 * <p> 371 * Valid values should always include 'JKS' and 'PKCS12', but 372 * different implementations may allow other values as well. If no 373 * value is provided, the JVM-default value is used. Changes to this 374 * configuration attribute will take effect the next time that the 375 * key manager is accessed. 376 * 377 * @return Returns the "key-store-type" property definition. 378 */ 379 public StringPropertyDefinition getKeyStoreTypePropertyDefinition() { 380 return PD_KEY_STORE_TYPE; 381 } 382 383 384 385 /** 386 * Managed object client implementation. 387 */ 388 private static class FileBasedKeyManagerProviderCfgClientImpl implements 389 FileBasedKeyManagerProviderCfgClient { 390 391 // Private implementation. 392 private ManagedObject<? extends FileBasedKeyManagerProviderCfgClient> impl; 393 394 395 396 // Private constructor. 397 private FileBasedKeyManagerProviderCfgClientImpl( 398 ManagedObject<? extends FileBasedKeyManagerProviderCfgClient> impl) { 399 this.impl = impl; 400 } 401 402 403 404 /** 405 * {@inheritDoc} 406 */ 407 public Boolean isEnabled() { 408 return impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition()); 409 } 410 411 412 413 /** 414 * {@inheritDoc} 415 */ 416 public void setEnabled(boolean value) { 417 impl.setPropertyValue(INSTANCE.getEnabledPropertyDefinition(), value); 418 } 419 420 421 422 /** 423 * {@inheritDoc} 424 */ 425 public String getJavaClass() { 426 return impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition()); 427 } 428 429 430 431 /** 432 * {@inheritDoc} 433 */ 434 public void setJavaClass(String value) { 435 impl.setPropertyValue(INSTANCE.getJavaClassPropertyDefinition(), value); 436 } 437 438 439 440 /** 441 * {@inheritDoc} 442 */ 443 public String getKeyStoreFile() { 444 return impl.getPropertyValue(INSTANCE.getKeyStoreFilePropertyDefinition()); 445 } 446 447 448 449 /** 450 * {@inheritDoc} 451 */ 452 public void setKeyStoreFile(String value) { 453 impl.setPropertyValue(INSTANCE.getKeyStoreFilePropertyDefinition(), value); 454 } 455 456 457 458 /** 459 * {@inheritDoc} 460 */ 461 public String getKeyStorePin() { 462 return impl.getPropertyValue(INSTANCE.getKeyStorePinPropertyDefinition()); 463 } 464 465 466 467 /** 468 * {@inheritDoc} 469 */ 470 public void setKeyStorePin(String value) { 471 impl.setPropertyValue(INSTANCE.getKeyStorePinPropertyDefinition(), value); 472 } 473 474 475 476 /** 477 * {@inheritDoc} 478 */ 479 public String getKeyStorePinEnvironmentVariable() { 480 return impl.getPropertyValue(INSTANCE.getKeyStorePinEnvironmentVariablePropertyDefinition()); 481 } 482 483 484 485 /** 486 * {@inheritDoc} 487 */ 488 public void setKeyStorePinEnvironmentVariable(String value) { 489 impl.setPropertyValue(INSTANCE.getKeyStorePinEnvironmentVariablePropertyDefinition(), value); 490 } 491 492 493 494 /** 495 * {@inheritDoc} 496 */ 497 public String getKeyStorePinFile() { 498 return impl.getPropertyValue(INSTANCE.getKeyStorePinFilePropertyDefinition()); 499 } 500 501 502 503 /** 504 * {@inheritDoc} 505 */ 506 public void setKeyStorePinFile(String value) { 507 impl.setPropertyValue(INSTANCE.getKeyStorePinFilePropertyDefinition(), value); 508 } 509 510 511 512 /** 513 * {@inheritDoc} 514 */ 515 public String getKeyStorePinProperty() { 516 return impl.getPropertyValue(INSTANCE.getKeyStorePinPropertyPropertyDefinition()); 517 } 518 519 520 521 /** 522 * {@inheritDoc} 523 */ 524 public void setKeyStorePinProperty(String value) { 525 impl.setPropertyValue(INSTANCE.getKeyStorePinPropertyPropertyDefinition(), value); 526 } 527 528 529 530 /** 531 * {@inheritDoc} 532 */ 533 public String getKeyStoreType() { 534 return impl.getPropertyValue(INSTANCE.getKeyStoreTypePropertyDefinition()); 535 } 536 537 538 539 /** 540 * {@inheritDoc} 541 */ 542 public void setKeyStoreType(String value) { 543 impl.setPropertyValue(INSTANCE.getKeyStoreTypePropertyDefinition(), value); 544 } 545 546 547 548 /** 549 * {@inheritDoc} 550 */ 551 public ManagedObjectDefinition<? extends FileBasedKeyManagerProviderCfgClient, ? extends FileBasedKeyManagerProviderCfg> definition() { 552 return INSTANCE; 553 } 554 555 556 557 /** 558 * {@inheritDoc} 559 */ 560 public PropertyProvider properties() { 561 return impl; 562 } 563 564 565 566 /** 567 * {@inheritDoc} 568 */ 569 public void commit() throws ManagedObjectAlreadyExistsException, 570 MissingMandatoryPropertiesException, ConcurrentModificationException, 571 OperationRejectedException, AuthorizationException, 572 CommunicationException { 573 impl.commit(); 574 } 575 576 } 577 578 579 580 /** 581 * Managed object server implementation. 582 */ 583 private static class FileBasedKeyManagerProviderCfgServerImpl implements 584 FileBasedKeyManagerProviderCfg { 585 586 // Private implementation. 587 private ServerManagedObject<? extends FileBasedKeyManagerProviderCfg> impl; 588 589 // The value of the "enabled" property. 590 private final boolean pEnabled; 591 592 // The value of the "java-class" property. 593 private final String pJavaClass; 594 595 // The value of the "key-store-file" property. 596 private final String pKeyStoreFile; 597 598 // The value of the "key-store-pin" property. 599 private final String pKeyStorePin; 600 601 // The value of the "key-store-pin-environment-variable" property. 602 private final String pKeyStorePinEnvironmentVariable; 603 604 // The value of the "key-store-pin-file" property. 605 private final String pKeyStorePinFile; 606 607 // The value of the "key-store-pin-property" property. 608 private final String pKeyStorePinProperty; 609 610 // The value of the "key-store-type" property. 611 private final String pKeyStoreType; 612 613 614 615 // Private constructor. 616 private FileBasedKeyManagerProviderCfgServerImpl(ServerManagedObject<? extends FileBasedKeyManagerProviderCfg> impl) { 617 this.impl = impl; 618 this.pEnabled = impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition()); 619 this.pJavaClass = impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition()); 620 this.pKeyStoreFile = impl.getPropertyValue(INSTANCE.getKeyStoreFilePropertyDefinition()); 621 this.pKeyStorePin = impl.getPropertyValue(INSTANCE.getKeyStorePinPropertyDefinition()); 622 this.pKeyStorePinEnvironmentVariable = impl.getPropertyValue(INSTANCE.getKeyStorePinEnvironmentVariablePropertyDefinition()); 623 this.pKeyStorePinFile = impl.getPropertyValue(INSTANCE.getKeyStorePinFilePropertyDefinition()); 624 this.pKeyStorePinProperty = impl.getPropertyValue(INSTANCE.getKeyStorePinPropertyPropertyDefinition()); 625 this.pKeyStoreType = impl.getPropertyValue(INSTANCE.getKeyStoreTypePropertyDefinition()); 626 } 627 628 629 630 /** 631 * {@inheritDoc} 632 */ 633 public void addFileBasedChangeListener( 634 ConfigurationChangeListener<FileBasedKeyManagerProviderCfg> listener) { 635 impl.registerChangeListener(listener); 636 } 637 638 639 640 /** 641 * {@inheritDoc} 642 */ 643 public void removeFileBasedChangeListener( 644 ConfigurationChangeListener<FileBasedKeyManagerProviderCfg> listener) { 645 impl.deregisterChangeListener(listener); 646 } 647 /** 648 * {@inheritDoc} 649 */ 650 public void addChangeListener( 651 ConfigurationChangeListener<KeyManagerProviderCfg> listener) { 652 impl.registerChangeListener(listener); 653 } 654 655 656 657 /** 658 * {@inheritDoc} 659 */ 660 public void removeChangeListener( 661 ConfigurationChangeListener<KeyManagerProviderCfg> listener) { 662 impl.deregisterChangeListener(listener); 663 } 664 665 666 667 /** 668 * {@inheritDoc} 669 */ 670 public boolean isEnabled() { 671 return pEnabled; 672 } 673 674 675 676 /** 677 * {@inheritDoc} 678 */ 679 public String getJavaClass() { 680 return pJavaClass; 681 } 682 683 684 685 /** 686 * {@inheritDoc} 687 */ 688 public String getKeyStoreFile() { 689 return pKeyStoreFile; 690 } 691 692 693 694 /** 695 * {@inheritDoc} 696 */ 697 public String getKeyStorePin() { 698 return pKeyStorePin; 699 } 700 701 702 703 /** 704 * {@inheritDoc} 705 */ 706 public String getKeyStorePinEnvironmentVariable() { 707 return pKeyStorePinEnvironmentVariable; 708 } 709 710 711 712 /** 713 * {@inheritDoc} 714 */ 715 public String getKeyStorePinFile() { 716 return pKeyStorePinFile; 717 } 718 719 720 721 /** 722 * {@inheritDoc} 723 */ 724 public String getKeyStorePinProperty() { 725 return pKeyStorePinProperty; 726 } 727 728 729 730 /** 731 * {@inheritDoc} 732 */ 733 public String getKeyStoreType() { 734 return pKeyStoreType; 735 } 736 737 738 739 /** 740 * {@inheritDoc} 741 */ 742 public Class<? extends FileBasedKeyManagerProviderCfg> configurationClass() { 743 return FileBasedKeyManagerProviderCfg.class; 744 } 745 746 747 748 /** 749 * {@inheritDoc} 750 */ 751 public DN dn() { 752 return impl.getDN(); 753 } 754 755 } 756 }