Friday Feb 28, 2014

A Bug in Kerberos used by Java's HTTP

Sorry, I didn't notice a thread on Oracle's forum until recently JDK-8028351 was reported to us directly. After some investigation, the bug is resolved in 7u60/8. Hopefully it's not too late for our customers.

A web page that is behind "Windows Authentication" is in fact protected by Kerberos and NTLM, and is accessible whichever auth scheme a client supports. In JDK 7, Kerberos works out-of-the-box on a Windows machine that already joins a domain (well, not exactly, see below), so it's always tried first. However, without the allowtgtsessionkey registry key being set, Java still needs a password to login. There is no way to get this password (unless you program JAAS directly) so Java tries the empty password. Obviously, the KDC (Windows domain controller) does not like it and blocks the user if it's tried multiple times.

The thread mentions the .java.login.config trick. When Java wants to use that file but cannot find it, it just fails without trying to login at all. The bug report mentions that disabling kerberos pre-authentication is also a workaround. In this case, no encrypted timestamp is sent so the KDC has no chance to know the client does not have the correct password.

In all these cases, Kerberos always fails and Java falls back to NTLM and the web page is still reached. However, the terrible thing about the empty password case is that you can read the page when you first access it, but if you access it again and again, your account is finally blocked and even NTLM does not work anymore.

Wednesday Apr 24, 2013

Re-read [capaths]


[capaths] does not have the same meaning in JDK and the rest of the world (See references at the bottom).

In JDK, each line describes a relation and one needs to consult multiple relations to create a path. In the rest of the world, each line itself is a path.

So, suppose shared keys are between A and B, B and C, and, C and D. For a client in A, in order to visit a service in D, it needs A -> B -> C -> D.

In JDK, the capaths is written as

A = {
   B = .     # I can go B directly
   C = B     # To go C, I need to go B first
   D = C     # To go D, I need to go C first

In the rest of the world, it's

A = {
   B = .    # I can go B directly
   C = B    # To go C, I need to go B. Done
   D = B C  # To go D, I need to go B and then C. Done

and the last line is often written into multiple lines

D = B
D = C

although this becomes not so clear.


When a sub-tag has multiple values (either on a single line or multiple lines), it is interpreted differently.

A = {
   B = C D
  • For the rest of the world, it's a series of realms that the client needs to walk thru to the server. The client in A needs to go to C and then D to reach B
  • For Java, it's a list of alternatives that can lead to the server. In order for a client A to go to B, it must reach C or D first.

and the Java way is wrong.


There will be a behavior change anyway, but we must preserve as much as we can. That is to say, if there are no sub-tags with multiple values, we do the same as before. If there are, we should treat it correctly like the rest of the world.

Here is a way to unify the two different designs. For

cRealm = {
   sRealm = A ... B

"A ... B" should be regarded as a (possibly partial) path from cRealm to sRealm.

The key point here is the "possibly partial" modifier. By partial, it means the path could be only the tail, i.e. you need to find zero or more realms "C ... D" to build the full path "C ... D A ... B", where C directly shares keys with cRealm.

Now, the rest of the world always gives the full path, and JDK gives the shortest-available partial path. Unified.

How to build the full path then? Given the previous example

A = {
   B = .     # I can go B directly
   C = B     # To go C, I need to go B first
   D = C     # To go D, I need to go C first

From D = C, we get partial path for A to D as C -> D. Here A cannot directly go to C, so we start building. We have C = B, we have a partial path for A to C as B -> C. Merging the partial paths give a longer path from A to D being B -> C -> D. B = . shows B is a direct link, and we have the full path.

There are still some rules:

  1. . can only appear in a single-valued sub-tag
  2. No loops
  3. No dups in multiple values of the same subtag
  4. Neither cRealm nor sRealm can appear in path

If any rule is broken, the output is undefined. The current implementation is that the value is ignored.


From the discussion above, we can say that previous JDK releases still work if there is no multiple-value sub-tags. This means you can always rewrite "A = B C" to two lines "A = C" and "C = B". Both the old JDK and future JDK will recognize it. Unfortunately, the rest of the world does not like this format, say, MIT's krb5.

And, the Hierarchy Case

The hierarchy algorithm is also wrong: When two realms have completely no common components, Java now regards it as a direct link. However, the correct path should go down to the last component of cRealm, and then go up from the last component of sRealm to the full sRealm.

For example, a path from A.COM to B.ORG will be A.COM -> COM -> ORG -> B.ORG.


Saturday Jan 05, 2013

A Test for 2013

I want to see if this blog and its commenting system still works.

Update: Aha, I have to manually approve each comment.

Tuesday Nov 08, 2011

Old Versions of Cisco AnyConnect and Java 6u29

In Oracle Java 6u14, we introduced blacklist support. The blacklist "is a list of signed jars that contain serious security vulnerabilities that can be exploited by untrusted applets or applications". Once a signed jar is listed here, it will never be loaded. Recently, in 6u29, we added more entries into the list. Some of them are for the Cisco AnyConnect Mobility Client, and you can see why this is a very serious problem on Cisco's own support page.

Unfortunately, it seems quite a lot of AnyConnect servers out there are not updated to the latest version. Some are not that ancient, which do no harm to a Windows client, but can still be exploited if the client is on a non-Windows system like Linux or Apple MacOS X. Read the Cisco page above for details.

Therefore, 6u29 users will see an error when trying to install AnyConnect clients from such a server, for example, this report to Cisco. AnyConnect admins, please update your server as soon as possible.

Please note that this is not a vulnerability in Oracle's JRE. On the contrary, 6u29 protects you from any possible exploit of this issue to damage your system.

Tuesday May 24, 2011

Kerberos Programming on Windows

This article was published as some time in 2009, but the original link does not exist anymore. It's copied here mainly for archive purpose and a lot of thing have changed since. I might or might not update it.

This article talks about Kerberos programming on Windows, especially in a Kerberos environment of Windows Active Directory (AD), with all clients and services running on Windows platforms in AD domains. The typical client/server environment described here is Windows XP and Windows Server 2003. We may talk about other scenarios if necessary.

Note: Kerberos programming in Java is done through the JGSS-API. Please make sure you're familiar with basic JGSS concepts and programming styles. Read the Java SE documentation of JGSS section first.

Basic Setup

There are three roles in Kerberos: the KDC, the client, and the server. We're talking about writing Java programs on the client or the server, or both.

First, you must have a Windows Active Directory server running, and all clients and servers joining this AD domain. In order for Java to recognize this environment, extra configurations are needed on both the client and the server side.

Realm and KDC Info

There are two ways to inform a Java program what the Kerberos realm and KDC are:
  1. krb5.ini configuration file
    • krb5.ini should contain the realm info and hostname of the KDC for this realm. For example:
      default_realm = MY.REALM
      MY.REALM = {
          kdc =
    • The file location can be specified by system property Otherwise, Java will try to locate this file in these locations (ordered by):
      1. %JAVA_HOME%/lib/security/krb5.conf
      2. %WINDOWS_ROOT%/krb5.ini
  2. System properties and
Please note that these two configurations cannot be provided at the same time.

In JDK 7, when neither of the two ways above is used. Java will try to read the realm and KDC settings from Windows environment variables.

JAAS login config file

Since JGSS uses JAAS to acquire the initial Kerberos credentials, a JAAS login config file is always needed. The location of this file should be specified inside the file or using the system property Read here for details.

The login module required here is, we'll talk about the details in later sections for the client side and the server side respectively.

In JDK 7, when no JAAS login config file is specified, pre-defined entries are created for the client side and server side respectively:

For the client side: {

For the server side: {

TGT accessibility

By default, Windows does not allow the session key of a TGT to be accessed. Please add the following registry key on the client side, so that the session key for TGT is accessible and Java can use it to acquire additional service tickets.

For Windows XP and Windows 2000, the registry key and value should be:

Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01

For Windows 2003 and Windows Vista, the registry key and value should be:

Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01

Programming the client side

The Initial Credentials

JGSS uses JAAS to get the initial credentials (in the case of Kerberos, the initial TGT). Java tries to get it in this order:
  1. File credentials cache (%HOME%\krb5cc_userid for Windows)
  2. Native credentials cache (LSA, or Local Security Authority, for Windows)
  3. Read key from a keytab file and use AS_REQ to acquire credentials from KDC
  4. Prompt for username and password and use AS_REQ to acquire credentials from KDC
Not all of them will be tried. The actual behavior depends on what's specified in Krb5LoginModule of your JAAS long config file:
  • If useTicketCache=true, 1, 2 will be tried
  • If useKeyTab=true, 3 will be tried
  • If doNotPrompt=true, 4 will not be tried
Note that all of these parameters' default values are false. They can be specified in any combination.

The most common case on a Windows client is that the user has already logged on to the system as an AD account, which means there's a native credential cached in LSA. This goes the 2nd way above. However, if the client platform is not Windows, or, although it's Windows but the user is not logged on as an AD account, there's no LSA cache available. Please check the availability of an LSA cache using the MS klist.exe tool (Attention: not the klist.exe comes with Java) or kerbtray.exe (for GUI lovers) provided by Microsoft.

Therefore, the typical JAAS login config file for client should look like this: {
This means the ticket cache (LSA) should be used automatically, doNotPrompt=false means when the cache is not available, username and password will be prompted using a CallbackHandler.

Attention: Unfortunately, there's no way to inform Java that LSA should be looked up ahead of the file cache. So, you should always make sure that the %HOME%\krb5cc_userid file does not exist when you want to use the LSA. This file is generated by the kinit.exe command, so don't run it if you wish to use the credentials from the LSA cache.

On the other hand, if you want your program working even if the LSA cache is not available, normally you choose one of the following:

  1. Run kinit.exe (comes with Java) before running the Java app, this will create a credentials cache file %HOME%\krb5cc_userid, which goes the 1st way. The JAAS login config file is the same as the typical style. If you create the credentials cache file into a different pathname, specify the location using ticketCache="c:/path/to/file" inside the JAAS login config file.
  2. Feed username and password to the Java program directly using a CallbackHandler, which goes the 4th way. Please specify doNotPrompt=false in the JAAS login config file. You can provide an instance of CallbackHandler at the creation time of LoginContext if the JAAS call style is used (see the next section), or Java will create a new instance of the type specified by the security property auth.login.defaultCallbackHandler. For direct JGSS without JAAS, if this security property is not given, the internal text-based callback handler will be used.

JGSS calls

There are 2 ways to start JGSS:
  1. Use JAAS to generate a Subject that contains the initial credentials, and call JGSS from this subject:
    LoginContext lc = new LoginContext(name, callback);
    lc.login(); lc.commit();
    Subject.doAs(lc.getSubject(), /* JGSS-API calls... */)

    In this case, you can choose whatever login entry name in the JAAS login config file. Read more for details.

  2. Direct JGSS:
    /* JGSS-API calls... */
    In this case, the JAAS config file's entry name MUST be the standard entry name (, and you must set on the Java command line. Read here for details.

Other APIs that use JGSS

In Java, there are 2 other APIs that call JGSS-API internally.
  1. SASL using JGSS as the mechanism. Read here and here for details.
  2. HTTP/SPNEGO. Read here for details. Please note that the system property is now default false for HTTP/SPNEGO now.
Please note that when initial credentials are not available from the cache (neither from a file nor the LSA), HTTP/SPNEGO behaves different in username and password providing. Instead of the JAAS callback model, is used. Read the doc mentioned above.

Programming the server side

Service name

The biggest difference here from the client side is that there's no such concept as a native keytab, which means a JGSS server program cannot simply "RunAs" a Windows service account and uses the encryption key for that account. To make server side JGSS programming on Windows available, a special step is needed to create a mapping service name and a keytab file, by using the Microsoft provided tool ktpass.exe.

For example, if the AD domain name is AD.LOCAL, and you'd like to run a service called myservice on the host, you can perform these steps on your AD server:

  1. Create a normal user account (say myservicemachine) inside AD.LOCAL, any password is OK.
  2. Call "ktpass -princ myservice/ -mapuser myservicemachine@AD.LOCAL -out x.keytab +rndPass" to create a SPN mapping to the user account, and generate a keytab file x.keytab. The password is regenerated with a random value so the password you give in step 1 is useless.
Now, put the x.keytab file into a secret place that only your service application can read. The server side JAAS login config file would look like: {
Here you need to provide the location of the keytab file. Otherwise, Java will try to locate this file in these locations (ordered by):
  1. default_keytab_name in the [libdefaults] section of krb5.ini, or
  2. %HOME%/krb5.keytab
Note: isInitiator=false is specified here so that the application acts as a pure server side program that will never try to authenticate itself to the KDC. This is useful when it cannot communicate directly with the KDC.

JGSS calls

Just like the client side, you can use JAAS to create a Subject and call JGSS-APIs through this subject, or calls JGSS methods directly. In the latter case, please specify


To enable delegations, both configurations and programming on needed.

Configuration at client side (the delegated)

In order for the credentials of the client to be delegatable to a service, if the initial TGT is acquired the Java way, please add forwardable=true into the [libdefaults] section of krb5.ini. If from LSA, make sure the "Account is sensitive and cannot be delegated" is NOT set in AD account settings.

Configuration at server side (the delegator)

In order to use the delegated credentials from the client, we suggest the service needs to be configured to be allowed receiving delegations. For a computer account, find the delegation tab, or for a user account, find the account tab, check "Trusted for delegation". The turns on the OK-AS-DELEGATE for the service ticket. A Windows native client program needs this flag to enable delegation. A Java client MAY respect this flag later (currenrly NO except for HTTP/SPNEGO).


Please call GSSContext.requestCredDeleg(true) on the client side. Read here for details.

Trusts between Domains

If you have already setup cross realms trusts in multiple AD domains, please add the [domain_realm] section into the client side's krb5.conf file so that Java can correctly locate the realm for a requested service. Like this:
[domain_realm] = THIS.COM = THAT.COM
With this configuration, when a client on THIS.COM tries to connect to a service service/, Java can correctly figured out that the service belongs to another realm THAT.COM and perform proper inter-realm authentications.

Other Windows Platforms

This article talks about Kerberos programming on the Windows platform. The typical KDC is Windows Server 2003. The typical client is Windows XP, and the typical server is Windows Server 2003 or Windows XP. There're some minor issues for other flavors of Windows versions.

Windows 2000 Server

Note that before SP4 of Windows 2000, there's no need to specify the allowtgtsessionkey registry key.

Windows Server 2008

In Windows 2008, the AES etype is supported. In order to use AES256 as the encryption etype, please download and enable Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Read the "Other downloads" section for details.

In Windows 2008, you cannot request a service ticket for a normal user, since Windows only allows user2user communications with a normal user using a special Microsoft defined Kerberos extension. In fact, Windows KDC simply does not issue a service ticket targeting a normal user.

There's a workaround to allow normal service ticket for a normal user on Windows 2008. Call setspn -a service/host username, a SPN will be created for this user. After this step, the client can acquire a normal service ticket targeting either the username or the SPN. This will also lure out the delegation tab for a user so that you can allows delegation on the user.


These options are most useful in debugging a JGSS program:
  1. Add on Java command line
  2. Add debug=true into JAAS login config file
  3. Inspect networking packets using a sniffer
Also, remember to always use the latest version of JRE/JDK. Some bugs may have already been fixed. The new versions may also show better debug information.

Frequently Asked Questions (FAQ)

Note: Please remember to always read the JGSS troubleshooting guide first. Some of the following case are included in that guide, and some are Windows-specific.
  • JGSS complains that my JAAS config file has errors: Make sure it has correct format, the semi-colons are always there. Sometimes you need to put "" around a file name or principal name
  • I have a keytab, but JGSS still asks me for password: Make sure the keytab path is correct. Maybe you need to provide a full path, maybe you need to add "" around it. Also, use "/" or "\\" as path separator.
  • The client seems not login as an AD account: Sometimes you forgot to login as an AD account, or, if there are any network problems and your Windows client automatically goes to offline login mode. Use the Microsoft klist.exe or kerbtray.exe to see if a TGT is available in the LSA.
  • The debug output shows native TGT is loaded, but does not use it: This happens when the session key inside TGT is not readable. For clients before Vista, use kerbtray.exe to see if encryption type for session key is null. For Vista, look at the debug output to see if the key are all zero. If so, please setup the allowtgtsessionkey registry key.
  • Kerberos is never called (no Kerberos debug info after I add Make sure various configurations are in place, which includes JAAS login conf file, krb5.ini file (or kdc/realm system properties). Also, if you don't use JAAS explicitly, make sure is set to false.
  • Delegation in HTTP/SPNEGO fails: Make sure in Windows AD computer settings, the allow delegation box is checked.
  • Credentials not available: You don't have a native cache. Try to re-login as an AD account, or, consider the LSA-less way, say, -kinit.exe= or callback.
  • Checksum failed (or other encryption/decryption errors): If you are using username/password callbacks, possibly the password is wrong. If you are using a keytab (on the server side), possibly the keytab contains a bad key.
  • The Kerberos principal is not mine: Make sure there's no krb5cc_userid file inside your home directory. Java always uses this credential cache even if the user is logged in an AD user. Remove it.
  • EType not supported: Latest Java (update releases of all versions) already supports RC4-HMAC, which is the default etype used on Windows. You needn't specify default etypes for either the session key or ticket in krb5.ini.
  • Cannot find server name in Kerberos database: Have you mapped the service principal name(SPN) correctly? Please note that an SPN cannot be mapped to multiple accounts. Also, you must use the full qualified domain name in the ktpass command.
  • Server name (as seen in the debug output) is not FQDN (full qualified domain name), or becomes simply numeric IP address: Make sure DNS is correctly configured. JGSS uses InetAddress.getCanonicalHostName() to get the FQDN of the server's hostname. Write a tiny program to check it.
  • Cannot access Windows services like IIS: Make sure "Do not require pre-authentication" is not checked in AD user setting. Windows native services needs pre-authentication to provide PAC info in tickets.
  • Cross realm failed: Read into debug outputs, especially the TGS-REQ info. Make sure the service principal name is correct. If the Windows DNS server is not configured correctly, it may not return the correct full qualified host name.
  • Invalid option setting in ticket request: There are some options inside the [libdefaults] section of krb5.ini (say, forwardable=true, proxiable=true etc) which are used to provide KDCOptions when requesting a TGT using the AS-REQ message. In this case, when a TGT is returned, its TicketFlags are compared to the options here. Since in this paper we're mainly talking about TGT from the Windows LSA cache, these options are useless. Proving too many of them will only bring conflicts with your native TGT.

Known Issues

If an AD account is also added into local administrator group on the client PC, Microsoft restricts such client from getting the session key for tickets (even if you set the allowtgtsessionkey registry key to 1). The workaround is: Just forget you're a logged in user, call kinit.exe. Do not depends on LSA credential cache.

In a recent hotfix (should be included in Vista SP1), this restriction is lifted for normal service tickets. However, it still applies to TGT. Since Java uses TGT to acquire tickets for other services (the standard Kerberos process), this update provides no benefit to JGSS programming on Windows. Furthermore, even if the implementation of Java is changed to read service tickets from the LSA cache, it still cannot perform delegation, since a TGT is always needed in that case.

Useful Tools

  2. Any network packet sniffer. For example, Windows Netmon, Wireshark.
  3. Web browsers, with HTTP header viewer (for example, LiveHTTPHeaders for Firefox, and iehttpheaders for IE) are useful in debugging HTTP/SPNEGO programs.


  1. RFC 4120, 4121, 3961, 3962
  2. MSDN doc on Kerberos and Active Directory

Monday Mar 21, 2011

Some Kerberos Compiler Warnings on Windows

There is a rather old bug on native code compiler warnings on Windows. I have been the responsible engineer for some time but never really started working on it. Unfortunately, some warnings result in a real runtime error now. Sorry.

Here is the changeset for it.

As you can see, we used the swprintf function in a not-so-standard way. The correct signature of the function is swprintf(buffer, size, format, args...) but we didn't provide the size argument. In the age of VC++ 2003, there were already warnings, but the runtime accepted this "overloaded" form and it ran fine. Starting from jdk7b108, we start using VC++ 2010 to build jdk7, the same warnings still show, but this time the runtime does not accept the form anymore, and a JVM crash is observed.

The lesson is never ignore compiler warnings.

The fix would be integrated in jdk7 builds in several weeks, and I've uploaded a copy here (32 bit build) in case anyone wants to try it out. I build it in a VirtualBox guest and hope it contains no virus.

Friday Mar 18, 2011

Jarsigner with Timestamping Behind a Firewall

We've supported timestamping in jarsigner for a long time. By providing a -tsa option to the command when signing a jar file, a timestamping block will be added to the signed jar. This makes an application to be accepted by Java Plugin in a future time when the signer's certificate already expires.

In a lot of enterprise environments, you need to go through a firewall to access the Internet, here, the TSA (Time Stamping Authority). We've noticed this some time ago. Therefore, when a connection to the TSA is not available, jarsigner would print out a message like this:

jarsigner: unable to sign jar: no response from the Timestamping Authority. When connecting from behind a firewall then an HTTP proxy may need to be specified. Supply the following options to jarsigner:
We thought this is very helpful, but there are still some customer feedbacks saying it does not work. It turns out that when a TSA server provides its service through an HTTPS website, in order to specify the proxy setting, you should use another pair of system property names:
Detailed of proxy support in Java can be found here.

In order for people using other languages to reach this page, here are the same messages in Simplified Chinese and Japanese:

jarsigner: 无法对 jar 进行签名: 时间戳颁发机构没有响应。 如果要从防火墙后面连接, 则可能需要指定 HTTP 代理。请为 jarsigner 提供以下选项:
jarsigner: jarに署名できません: タイムスタンプ局からのレスポンスがありません。 ファイアウォールを介して接続するときは、必要に応じてHTTPプロキシを指定してください。 jarsignerに次のオプションを指定してください:
(Best wishes for people in Japan. Hope this earthquake/tsunami/nuclear crisis can be over soon.)

Wednesday Mar 16, 2011

Fixed-width Font Widened on Bold

So here is a screenshot of a JDK source file I am working on now, in NetBeans:

It seems there is an extra space before the "// ok" comment on line 52 which makes the comments non-aligned. So I removed it. But then when I read the diff, it shows:

@@ -49,7 +49,7 @@
      \* Constructs an AS-REQ message.
                                                 // Can be null? has default?
-    public KrbAsReq(EncryptionKey pakey,        // ok
+    public KrbAsReq(EncryptionKey pakey,       // ok
                       KDCOptions options,       // ok, new KDCOptions()
                       PrincipalName cname,      // NO and must have realm
                       PrincipalName sname,      // ok, krgtgt@CREALM
Bad, so they were aligned, but after my change, they are not.

I am really confused by this. Is there anything wrong with the hg repository? or the diff command? or my console? Or, is there a hidden TAB character? I checked and checked but nothing seems wrong.

Finally I have to count the spaces one by one. Good heavens! It turns out that the font used in NetBeans — Lucida Sans Typewriter — has different widths between normal and bold typefaces.

Isn't this ridiculous? A fixed-width font's width should be fixed whenever it's shown in normal, or bold, or italic. I believe all modern IDEs use these styles to show different types of source tokens.

Anyway, I changed the font to the simple "monospaced" and everything looks normal now. Maybe the Lucida Sans Typewriter font is not fixed-width at all, it just looks like one.

Monday Mar 14, 2011

Cool Mercurial Bundles

Although OpenJDK is mostly in open source state but there are still some code repositories closed. When I work from home and need to update these repositories, I'll have to connect to the Oracle VPN to access them. I always hesitate to use VPN at home because I won't be able to see other machines on the LAN (especially, VirtualBox guests using this machine as the host) and I don't like accessing the Internet using the Oracle proxy servers. My solution is to create a VirtualBox guest for VPN exclusively.

But then I see a problem, there is a VirtualBox bug saying that symlinks in a shared folder shows incorrectly inside the guest. Now I share the OpenJDK forest in read-write mode to the guest, when trying to run hg pull -R jdk/src/closed inside the guest, it would complain

abort: Is a directory: /mnt/root/openjdk7/jdk/src/closed/.hg/wlock
This is bad.

So I go take a look at the Mercurial commands and notice this cool feature: bundles. A bundle looks like a code repository as a single file, which can contain the whole history or only part of it. Now in the guest I would call

hg inc -R jdk/src/closed --bundle jsc
to create a bundle file to contain all incoming changesets of the jdk/src/closed repo. Note that there is no problem creating a normal file from within the guest in a shared folder. Then I can go back to the host machine, and call this
hg fetch -R jdk/src/closed bundle://jsc
Cool, a bundle-schemed URI. In fact, I can now make the shared folder as read-only, and create another another smaller read-write shared folder only for file transmission from guest to host. Mecurial has dedicated commands like bundle and unbundle to deal with bundles, but I'm not eager to look into their details now.

Something else to say, I wrap the calls into a script, and it's a single script that can be called on both guest and host. In fact, this script does not perform any real mercurial/file actions, all it does is to iterate thru repository names and call echo to output command lines on the screen (plus #comments). I often write scripts in this way so that I can take a second look at the output commands for safety. After making sure they are OK I can simply copy and paste (drag thru and middle-click) lines I want to run to execute them. In this case, I run the "hg inc" lines on the guest and "hg fetch" lines on the host.

Thursday Jan 06, 2011

PolicyTool Tiny Behavior Change

PolicyTool is the only GUI tool included in the JRE, which is used to generate a policy file for Java security permission management. You can use the tool to create a policy file or edit an existing one.

The "Save As" command of the tool opens a file save dialog, let you choose a file, and save the current policy into that file. When the file you choose already exists, the tool will issue a warning asking you if you want to overwrite it.

Here comes the problem, back in the old days, the file save dialog is drawn by Java itself, and it does not care about file overwriting at all. Therefore, it's the PolicyTool itself showing the prompt of overwrite warning. Nowadays, the file save dialog is loaded using the standard dialog of the native platforms, say, Windows style, GTK style, Mac style, etc, etc. This is nice, because people are familiar with those dialogs on their platforms and each of them provides some nice features on locating and navigating through the file system. But, there is one issue, as far as I know, all of these Save As dialogs already provide the overwrite warning feature internally, that is to say, when you click OK there, before the dialog closes, it warns you about possible file overwriting. Now in PolicyTool, you see the warning and click YES, the save file dialog is closed, but then, PolicyTool warns you again and you have to click another YES button. This is quite confusing as well as frustrating.

Therefore we remove PolicyTool's warning dialog in JDK 7. The client/awt guys are also looking through all Save As dialogs on different platforms, to make sure the behavior is the same.

The lesson is: there is much more to care about in an API design. A spec can be never too complicated. I mean the java.awt.FileDialog class.

Tuesday Jan 04, 2011

I'm Still Here

Haven't written anything on this blog for a long time. I'm still in the Java SE core libraries team and we even have some new people. Oracle LEC in China was finished last September, JSRs for Java SE 7 and 8 were approved late last year and we are now busy adding the final bits for JDK 7 and testing it heavily. It's also time to think of what features I can add in JDK 8.

Thursday Mar 04, 2010

allow_weak_crypto for Kerberos

I just added allow_weak_crypto support in OpenJDK. With this property set to false, des-cbc-md5 and des-cbc-crc etypes are not supported, even if you include them i permitted_enctypes or default_{tkt|tgs}_enctypes settings.

Please note that in MIT krb5-1.8, the default value for this property is false, which means the DES-related enctypes are disabled out-of-box. In Java, we choose to keep it true for compatibility reasons, which we've always cared most.

Wednesday Jan 27, 2010


The future begins today. Let's embrace it.

Thursday Jan 21, 2010


Linked from James Gosling's blog.

Tuesday Dec 15, 2009


We're doing some experiments in JDK 7 to add more JGSS APIs. Currently they're defined into the vendor-specific package, but we'd like to enhance them and finally get them into the standard org.ietf.jgss package.

Basically, we defined a new ExtendedGSSContext interface. Now it has 3 methods:
  • requestDelegPolicy(boolean state): Requests that the delegation policy be respected. When a true value is requested, the underlying context would use the delegation policy defined by the environment as a hint to determine whether credentials delegation should be performed. This method is mainly used to deal with the Kerberos OK-AS-DELEGATE flag.
  • getDelegPolicyState(): Returns the delegation policy response.
  • inquireSecContext(InquireType type): Returns the mechanism-specific attribute associated with type. Currently we're supporting four types for the Kerberos 5 mechanism: KRB5_GET_TKT_FLAGS for flags in a service ticket, KRB5_GET_SESSION_KEY for the session key of an established session, KRB5_GET_AUTHZ_DATA for authorization data in a service ticket (mainly used on AD for the PAC info), and KRB5_GET_AUTHTIME for the authtime in a service ticket.
We haven't created method names like getTicketFlags or getSessionKey because we believe these information are mechanism-specific and not general enough on the GSS level. Even the getSessionKey method only returns Kerberos 5-specific keys, where the etype values are only defined in Kerberos 5. A disadvantage side of this design is that the method must return Object and the result needs to be casted to other type depending on the input type value.

Full spec is at OpenJDK code repository, and implementation in other parts of the code repo.

This blog has a comments managing system that requires me to approve each comment manually. Please do not re-post and I will reply it (if I have an answer) when I get pinged.


Top Tags
« December 2016