Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This returns false #2

Open
davecramer opened this issue Dec 10, 2021 · 12 comments
Open

This returns false #2

davecramer opened this issue Dec 10, 2021 · 12 comments

Comments

@davecramer
Copy link

So unfortunately this is not equivalent to using the native version

@davecramer
Copy link
Author

So fixing this so that it actually works results in

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark Mode Cnt Score Error Units
KrbTicketBenchmark.baseLine avgt 5 0.002 ± 0.001 us/op
KrbTicketBenchmark.internalJDKApi avgt 5 600.553 ± 113.247 us/op
KrbTicketBenchmark.jdk17CompatibleApi avgt 5 1095.521 ± 291.325 us/op
KrbTicketBenchmark.baseLine ss 9.325 us/op
KrbTicketBenchmark.internalJDKApi ss 120620.415 us/op
KrbTicketBenchmark.jdk17CompatibleApi ss 100214.173 us/op

@jerboaa
Copy link
Owner

jerboaa commented Dec 10, 2021

@davecramer I've tested this on Linux and when run on linux, it doesn't enter that code-path. Even if I throw the exception, it's not being hit. Apparently it does for you? Is this a plaform issue, perhaps?

@jerboaa
Copy link
Owner

jerboaa commented Dec 10, 2021

Edit: I revise, yes it's entered when the cache doesn't exist. But that's fine, we only want an equivalence of the internal API not a full login.

$ cat TestKrbTicketCache.java
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class TestKrbTicketCache {

    private static String CONFIG_ITEM_NAME = "ticketCache";
    private static String KRBLOGIN_MODULE = "com.sun.security.auth.module.Krb5LoginModule";

    /**
     * Equivalent of:
     * 
     * {@code
     * 
     * ticketCache {
     * com.sun.security.auth.module.Krb5LoginModule required
     * refreshKrb5Config=false
     * useTicketCache=true
     * doNotPrompt=true
     * useKeyTab=false
     * renewTGT=false
     * isInitiator=false debug=true; };
     * 
     * }
     *
     */
    static class CustomKrbConfig extends Configuration {

        @Override
        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            if (CONFIG_ITEM_NAME.equals(name)) {
                Map<String, String> options = new HashMap<>();
                options.put("refreshKrb5Config", Boolean.FALSE.toString());
                options.put("useTicketCache", Boolean.TRUE.toString());
                options.put("doNotPrompt", Boolean.TRUE.toString());
                options.put("useKeyTab", Boolean.FALSE.toString());
                options.put("isInitiator", Boolean.FALSE.toString());
                options.put("renewTGT", Boolean.FALSE.toString());
                options.put("debug", Boolean.FALSE.toString());
                return new AppConfigurationEntry[] {
                        new AppConfigurationEntry(KRBLOGIN_MODULE,
                                LoginModuleControlFlag.REQUIRED, options) };
            }
            return null;
        }

    }

    private static void setupConfiguration() {
        Configuration.setConfiguration(new CustomKrbConfig());
    }

    boolean credentialCacheExists() {
        LoginContext lc = null;
        try {
            lc = new LoginContext(CONFIG_ITEM_NAME, new CallbackHandler() {

                @Override
                public void handle(Callback[] callbacks)
                        throws IOException, UnsupportedCallbackException {
                    // config has doNotPrompt, so it should never happen
                    throw new RuntimeException("Should not happen!");
                }

            });
            lc.login();
        } catch (LoginException e) {
            System.out.println("LoginException: cache not existing?");
            return false;
        }
        Subject sub = lc.getSubject();
        return sub != null;
    }

    public static void main(String[] args) throws Exception {
        setupConfiguration();
        TestKrbTicketCache test = new TestKrbTicketCache();
        System.out.println("cache exists: " + ( test.credentialCacheExists() ? "yes" : "no"));
    }

}
$ cat TestKrbInternalAPI.java
public class TestKrbInternalAPI {
    
    public static boolean credentialCacheExists() {
        try {
          sun.security.krb5.Credentials credentials =
              sun.security.krb5.Credentials.acquireTGTFromCache(null, null);
          return credentials != null;
        } catch (Exception ex) {
          return false;
        }
      }


    public static void main(String[] args) {
        System.out.println("cache exists: " + ( TestKrbInternalAPI.credentialCacheExists() ? "yes" : "no"));
    }

}

Now let's run them (comparing results):

$ kinit -c "FILE:/tmp/krb5cc_$(id -u)"
Password for <redacted>:
$ java -showversion TestKrbTicketCache 
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment 18.9 (build 11.0.13+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8, mixed mode, sharing)
cache exists: yes
$ java -showversion TestKrbInternalAPI 
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment 18.9 (build 11.0.13+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8, mixed mode, sharing)
cache exists: yes
$ kdestroy -c "FILE:/tmp/krb5cc_$(id -u)"
$ java -showversion TestKrbInternalAPI 
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment 18.9 (build 11.0.13+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8, mixed mode, sharing)
cache exists: no
$ java -showversion TestKrbTicketCache 
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment 18.9 (build 11.0.13+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8, mixed mode, sharing)
LoginException: cache not existing?
cache exists: no

@davecramer
Copy link
Author

Thx, for this, tested this and it seems to work.

@davecramer
Copy link
Author

OK, here's the rub. Yes it runs fine but for some reason if I load a jaas.conf file ahead of time it does not. Which is why I did all the work to make it compatible.

java  -Djava.security.auth.login.config=/vagrant/test-gss/jaas.conf TestKrbInternalAPI
cache exists: yes
vagrant@ubuntu-focal:~$ java  -Djava.security.auth.login.config=/vagrant/test-gss/jaas.conf TestKrbTicketCache
LoginException: cache not existing?
cache exists: no
vagrant@ubuntu-focal:~$ cat /vagrant/test-gss/jaas.conf
pgjdbc {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true
    doNotPrompt=true
    renewTGT=false
    useTicketCache=true
    useKeyTab=true
    isInitiator=false
    debug=true;
};

BTW, I really do appreciate the effort you are putting into this.

Cheers,

Dave

@davecramer
Copy link
Author

So it turns out it never did work on my version of linux. I have a non standard location for the cache.

@jerboaa
Copy link
Owner

jerboaa commented Dec 13, 2021

So it turns out it never did work on my version of linux. I have a non standard location for the cache.

Yes, that's a bit of a nuisance.

@jerboaa
Copy link
Owner

jerboaa commented Dec 13, 2021

Also there is a ticketCache Krb5LoginModule-specific option[1] which could be used if you feel inclined to look up another ticket cache option too. But I'm not sure KCM-style ticket caches are supported in upstream OpenJDK.

[1] https://docs.oracle.com/javase/8/docs/api/javax/security/auth/login/Configuration.html

@davecramer
Copy link
Author

Finding all the options is pretty difficult. The documentation for these things are buried in the code ...

@davecramer
Copy link
Author

@jerboaa I have committed the change that removes the native code. I would really appreciate someone testing this. if possible

@jerboaa
Copy link
Owner

jerboaa commented Dec 20, 2021

@davecramer great, thanks! Unfortunately, I'm not in a good position to test it (prior release). What I can do is test this with native-image after it's been integrated in a release and quarkus updates its dep on the newer driver release (see quarkusio/quarkus#21359 which brought this to our attention). Perhaps someone on pgjdbc/pgjdbc#2023 can test it?

@davecramer
Copy link
Author

@jerboaa that's a start. Sadly getting testers is tough in my world. Testing usually occurs when I break stuff :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants