예제 #1
0
  /**
   * Build a list of realm that can be traversed to obtain credentials from the initiating realm
   * cRealm for a service in the target realm sRealm.
   *
   * @param cRealm the initiating realm
   * @param sRealm the target realm, not the same as cRealm
   * @returns array of realms including cRealm as the first element
   */
  private static String[] parseHierarchy(String cRealm, String sRealm) {

    String[] cComponents = cRealm.split("\\.");
    String[] sComponents = sRealm.split("\\.");

    int cPos = cComponents.length;
    int sPos = sComponents.length;

    boolean hasCommon = false;
    for (sPos--, cPos--;
        sPos >= 0 && cPos >= 0 && sComponents[sPos].equals(cComponents[cPos]);
        sPos--, cPos--) {
      hasCommon = true;
    }

    // For those with common components:
    //                            length  pos
    // SITES1.SALES.EXAMPLE.COM   4       1
    //   EVERYWHERE.EXAMPLE.COM   3       0

    // For those without common components:
    //                     length  pos
    // DEVEL.EXAMPLE.COM   3       2
    // PROD.EXAMPLE.ORG    3       2

    LinkedList<String> path = new LinkedList<>();

    // Un-common ones for client side
    for (int i = 0; i <= cPos; i++) {
      path.addLast(subStringFrom(cComponents, i));
    }

    // Common one
    if (hasCommon) {
      path.addLast(subStringFrom(cComponents, cPos + 1));
    }

    // Un-common ones for server side
    for (int i = sPos; i >= 0; i--) {
      path.addLast(subStringFrom(sComponents, i));
    }

    // Remove sRealm from path. Note that it might be added at last loop
    // or as a common component, if sRealm is a parent of cRealm
    path.removeLast();

    return path.toArray(new String[path.size()]);
  }
예제 #2
0
  /**
   * Parses the [capaths] stanza of the configuration file for a list of realms to traverse to
   * obtain credentials from the initiating realm cRealm to the target realm sRealm.
   *
   * <p>For a given client realm C there is a tag C in [capaths] whose subtag S has a value which is
   * a (possibly partial) path from C to S. When the path is partial, it contains only the tail of
   * the full path. Values of other subtags will be used to build the full path. The value "." means
   * a direct path from C to S. If realm S does not appear as a subtag, there is no path defined
   * here.
   *
   * <p>The implementation ignores all values which equals to C or S, or a "." in multiple values,
   * or any duplicated realm names.
   *
   * <p>When a path value has more than two realms, they can be specified with multiple key-value
   * pairs each having a single value, but the order must not change.
   *
   * <p>For example:
   *
   * <p>[capaths] TIVOLI.COM = { IBM.COM = IBM_LDAPCENTRAL.COM MOONLITE.ORG IBM_LDAPCENTRAL.COM =
   * LDAPCENTRAL.NET LDAPCENTRAL.NET = . }
   *
   * <p>TIVOLI.COM has a direct path to LDAPCENTRAL.NET, which has a direct path to
   * IBM_LDAPCENTRAL.COM. It also has a partial path to IBM.COM being "IBM_LDAPCENTRAL.COM
   * MOONLITE.ORG". Merging these info together, a full path from TIVOLI.COM to IBM.COM will be
   *
   * <p>TIVOLI.COM -> LDAPCENTRAL.NET -> IBM_LDAPCENTRAL.COM -> IBM_LDAPCENTRAL.COM -> MOONLITE.ORG
   *
   * <p>Please note the sRealm IBM.COM does not appear in the path.
   *
   * @param cRealm the initiating realm
   * @param sRealm the target realm, not the same as cRealm
   * @returns array of realms including at least cRealm as the first element
   * @throws KrbException if the config does not contain a sub-stanza for cRealm in [capaths] or the
   *     sub-stanza does not contain sRealm as a tag
   */
  private static String[] parseCapaths(String cRealm, String sRealm) throws KrbException {

    // This line could throw a KrbException
    Config cfg = Config.getInstance();

    if (!cfg.exists("capaths", cRealm, sRealm)) {
      throw new KrbException("No conf");
    }

    LinkedList<String> path = new LinkedList<>();

    String head = sRealm;
    while (true) {
      String value = cfg.getAll("capaths", cRealm, head);
      if (value == null) {
        break;
      }
      String[] more = value.split("\\s+");
      boolean changed = false;
      for (int i = more.length - 1; i >= 0; i--) {
        if (path.contains(more[i])
            || more[i].equals(".")
            || more[i].equals(cRealm)
            || more[i].equals(sRealm)
            || more[i].equals(head)) {
          // Ignore invalid values
          continue;
        }
        changed = true;
        path.addFirst(more[i]);
      }
      if (!changed) break;
      head = path.getFirst();
    }
    path.addFirst(cRealm);
    return path.toArray(new String[path.size()]);
  }