Mercurial > hg > icedtea8-forest > jdk
changeset 12347:5ce54ea88194 icedtea-3.3.0pre01
Merge jdk8u112-b16
line wrap: on
line diff
--- a/.hgtags Tue Nov 08 05:26:12 2016 +0000 +++ b/.hgtags Thu Jan 12 06:59:38 2017 +0000 @@ -677,3 +677,19 @@ b1304d71a2ec04ae6fa0a46120a5beba40a6f5ba jdk8u111-b12 3f1a07c3a600abdc2eb204f9b67984e6b920846e jdk8u111-b13 0cc71de3df184547da673a87c307def4c8da54d4 icedtea-3.2.0 +ab26fe28f9ed9c7d0a03ce47d1306427f86f27e9 jdk8u111-b14 +47e20a90bdbb2327289e330606b73a9fe4dc857e jdk8u112-b00 +96393e490afd4acba5b92c5ede68dc9bbb60a38e jdk8u112-b01 +b44d695f738baba091370828b84ae2c4cd715c1b jdk8u112-b02 +1af2eacbc17462f080d70e71c53e073ab0640f32 jdk8u112-b03 +a11ab21bb7991509846e0e45ad3792896c4fe98c jdk8u112-b04 +ecb2bae7905e2fd6f9b837521ee82a2cbb34602c jdk8u112-b06 +c66f5a825a0f0b5fb833bc7f50f327aec43e213b jdk8u112-b07 +89375f5c2c4c2bdc2340d7af1977dc1607908840 jdk8u112-b08 +820ef12b2a56b2a5fe1027a1f77ce81549978534 jdk8u112-b09 +c86d82567b1200bdb2d2a757f676179a637c4244 jdk8u112-b10 +532df0329e8070a75ae229310aa87ae530fa1eee jdk8u112-b11 +2a44e743f1654e39109233322e639bcfeca42e8d jdk8u112-b12 +16c649b70dc3d437ab16ff8125a50125deda2bc9 jdk8u112-b13 +d2d8b67021a0f41e0eabd711bfd87a943dc0a8d5 jdk8u112-b14 +60767ec3909b3d0cb26dd7b3f952c62053719dda jdk8u112-b15
--- a/LICENSE Tue Nov 08 05:26:12 2016 +0000 +++ b/LICENSE Thu Jan 12 06:59:38 2017 +0000 @@ -3,7 +3,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -287,8 +287,8 @@ more details. You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place, Suite 330, Boston, MA 02111-1307 USA + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail.
--- a/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package sun.lwawt.macosx; +import sun.lwawt.LWWindowPeer; + import java.awt.*; import java.beans.*; import java.lang.reflect.Field; @@ -421,6 +423,8 @@ } public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) { + if (a == null) return null; + return invokeAndWait(new Callable<AccessibleAction>() { public AccessibleAction call() throws Exception { final AccessibleContext ac = a.getAccessibleContext(); @@ -667,4 +671,28 @@ } }, c); } + + /** + * @return AWTView ptr, a peer of the CPlatformView associated with the toplevel container of the Accessible, if any + */ + private static long getAWTView(Accessible a) { + Accessible ax = CAccessible.getSwingAccessible(a); + if (!(ax instanceof Component)) return 0; + + return invokeAndWait(new Callable<Long>() { + public Long call() throws Exception { + Component cont = (Component) ax; + while (cont != null && !(cont instanceof Window)) { + cont = cont.getParent(); + } + if (cont != null) { + LWWindowPeer peer = (LWWindowPeer) cont.getPeer(); + if (peer != null) { + return ((CPlatformWindow) peer.getPlatformWindow()).getContentView().getAWTView(); + } + } + return 0L; + } + }, (Component)ax); + } }
--- a/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -264,6 +264,8 @@ final double localY = boundsUnion.getY(); final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen(); + if (componentLocation == null) return ret; + final double screenX = componentLocation.getX() + localX; final double screenY = componentLocation.getY() + localY;
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Thu Jan 12 06:59:38 2017 +0000 @@ -34,6 +34,7 @@ import java.awt.event.InputEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.KeyEvent; +import java.util.Locale; /** * Translates NSEvents/NPCocoaEvents into AWT events. @@ -173,6 +174,16 @@ } } + // If Pinyin Simplified input method is selected, CAPS_LOCK key is supposed to switch + // input to latin letters. + // It is necessary to use testCharIgnoringModifiers instead of testChar for event + // generation in such case to avoid uppercase letters in text components. + LWCToolkit lwcToolkit = (LWCToolkit)Toolkit.getDefaultToolkit(); + if (lwcToolkit.getLockingKeyState(KeyEvent.VK_CAPS_LOCK) && + Locale.SIMPLIFIED_CHINESE.equals(lwcToolkit.getDefaultKeyboardLocale())) { + testChar = testCharIgnoringModifiers; + } + jkeyCode = out[0]; jkeyLocation = out[1]; jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(eventType) :
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Jan 12 06:59:38 2017 +0000 @@ -427,9 +427,6 @@ @Override // PlatformWindow public void dispose() { - if (owner != null) { - CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr()); - } contentView.dispose(); nativeDispose(getNSWindowPtr()); CPlatformWindow.super.dispose(); @@ -526,25 +523,6 @@ public void setVisible(boolean visible) { final long nsWindowPtr = getNSWindowPtr(); - // Process parent-child relationship when hiding - if (!visible) { - // Unparent my children - for (Window w : target.getOwnedWindows()) { - WindowPeer p = (WindowPeer)w.getPeer(); - if (p instanceof LWWindowPeer) { - CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow(); - if (pw != null && pw.isVisible()) { - CWrapper.NSWindow.removeChildWindow(nsWindowPtr, pw.getNSWindowPtr()); - } - } - } - - // Unparent myself - if (owner != null && owner.isVisible()) { - CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr); - } - } - // Configure stuff updateIconImages(); updateFocusabilityForAutoRequestFocus(false); @@ -618,19 +596,19 @@ // Manage parent-child relationship when showing if (visible) { - // Add myself as a child + // Order myself above my parent if (owner != null && owner.isVisible()) { - CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove); + CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr()); applyWindowLevel(target); } - // Add my own children to myself + // Order my own children above myself for (Window w : target.getOwnedWindows()) { WindowPeer p = (WindowPeer)w.getPeer(); if (p instanceof LWWindowPeer) { CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow(); if (pw != null && pw.isVisible()) { - CWrapper.NSWindow.addChildWindow(nsWindowPtr, pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove); + CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, nsWindowPtr); pw.applyWindowLevel(w); } } @@ -1059,8 +1037,8 @@ // Order the window to front of the stack of child windows final long nsWindowSelfPtr = getNSWindowPtr(); final long nsWindowOwnerPtr = owner.getNSWindowPtr(); - CWrapper.NSWindow.removeChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr); - CWrapper.NSWindow.addChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove); + CWrapper.NSWindow.orderFront(nsWindowOwnerPtr); + CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr); } applyWindowLevel(target);
--- a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java Thu Jan 12 06:59:38 2017 +0000 @@ -221,15 +221,6 @@ synchronized (lock) { final long nsWindowPtr = getNSWindowPtr(); - // Process parent-child relationship when hiding - if (!visible) { - // Unparent myself - if (owner != null && owner.isVisible()) { - CWrapper.NSWindow.removeChildWindow( - owner.getNSWindowPtr(), nsWindowPtr); - } - } - // Actually show or hide the window if (visible) { CWrapper.NSWindow.orderFront(nsWindowPtr); @@ -241,10 +232,10 @@ // Manage parent-child relationship when showing if (visible) { - // Add myself as a child + // Order myself above my parent if (owner != null && owner.isVisible()) { - CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), - nsWindowPtr, CWrapper.NSWindow.NSWindowAbove); + CWrapper.NSWindow.orderWindow(nsWindowPtr, + CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr()); // do not allow security warning to be obscured by other windows applyWindowLevel(ownerWindow);
--- a/src/macosx/native/sun/awt/AWTView.h Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/AWTView.h Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,8 @@ - (void) deliverJavaMouseEvent: (NSEvent *) event; - (jobject) awtComponent:(JNIEnv *)env; ++ (AWTView *) awtView:(JNIEnv *)env ofAccessible:(jobject)jaccessible; + // Input method-related events - (void)setInputMethod:(jobject)inputMethod; - (void)abandonInput;
--- a/src/macosx/native/sun/awt/AWTView.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/AWTView.m Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #import "LWCToolkit.h" #import "JavaComponentAccessibility.h" #import "JavaTextAccessibility.h" +#import "JavaAccessibilityUtilities.h" #import "GeomUtilities.h" #import "OSVersion.h" #import "CGLLayer.h" @@ -132,7 +133,7 @@ self.cglLayer = nil; JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - (*env)->DeleteGlobalRef(env, m_cPlatformView); + (*env)->DeleteWeakGlobalRef(env, m_cPlatformView); m_cPlatformView = NULL; if (fInputMethodLOCKABLE != NULL) @@ -402,7 +403,12 @@ static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); + + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverMouseEvent, jEvent); + (*env)->DeleteLocalRef(env, jlocal); + } } - (void) resetTrackingArea { @@ -463,7 +469,12 @@ static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView, "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent); + + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverKeyEvent, jevent); + (*env)->DeleteLocalRef(env, jlocal); + } if (characters != NULL) { (*env)->DeleteLocalRef(env, characters); @@ -478,7 +489,12 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h); + + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverResize, x,y,w,h); + (*env)->DeleteLocalRef(env, jlocal); + } } @@ -507,7 +523,12 @@ */ static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView"); static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V"); - JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent); + + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + JNFCallVoidMethod(env, jlocal, jm_deliverWindowDidExposeEvent); + (*env)->DeleteLocalRef(env, jlocal); + } /* } */ @@ -515,8 +536,10 @@ } -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint { - if ((codePoint >= 0x3000) && (codePoint <= 0x303F)) { - // Code point is in 'CJK Symbols and Punctuation' Unicode block. + if (((codePoint >= 0x3000) && (codePoint <= 0x303F)) || + ((codePoint >= 0xFF00) && (codePoint <= 0xFFEF))) { + // Code point is in 'CJK Symbols and Punctuation' or + // 'Halfwidth and Fullwidth Forms' Unicode block. return YES; } return NO; @@ -535,7 +558,13 @@ } return NULL; } - jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer); + + jobject peer = NULL; + jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView); + if (!(*env)->IsSameObject(env, jlocal, NULL)) { + peer = JNFGetObjectField(env, jlocal, jf_Peer); + (*env)->DeleteLocalRef(env, jlocal); + } static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer"); static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;"); if (peer == NULL) { @@ -543,12 +572,27 @@ JNFDumpJavaStack(env); return NULL; } - return JNFGetObjectField(env, peer, jf_Target); + jobject comp = JNFGetObjectField(env, peer, jf_Target); + (*env)->DeleteLocalRef(env, peer); + return comp; +} + ++ (AWTView *) awtView:(JNIEnv*)env ofAccessible:(jobject)jaccessible +{ + static JNF_STATIC_MEMBER_CACHE(jm_getAWTView, sjc_CAccessibility, "getAWTView", "(Ljavax/accessibility/Accessible;)J"); + + jlong jptr = JNFCallStaticLongMethod(env, jm_getAWTView, jaccessible); + if (jptr == 0) return nil; + + return (AWTView *)jlong_to_ptr(jptr); } - (id)getAxData:(JNIEnv*)env { - return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease]; + jobject jcomponent = [self awtComponent:env]; + id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease]; + (*env)->DeleteLocalRef(env, jcomponent); + return ax; } - (NSArray *)accessibilityAttributeNames @@ -1291,7 +1335,7 @@ JNF_COCOA_ENTER(env); NSRect rect = NSMakeRect(originX, originY, width, height); - jobject cPlatformView = (*env)->NewGlobalRef(env, obj); + jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
--- a/src/macosx/native/sun/awt/AWTWindow.h Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/AWTWindow.h Thu Jan 12 06:59:38 2017 +0000 @@ -46,6 +46,7 @@ NSWindow *nsWindow; AWTWindow *ownerWindow; jint preFullScreenLevel; + BOOL isMinimizing; } // An instance of either AWTWindow_Normal or AWTWindow_Panel @@ -59,6 +60,7 @@ @property (nonatomic) jint styleBits; @property (nonatomic) BOOL isEnabled; @property (nonatomic) jint preFullScreenLevel; +@property (nonatomic) BOOL isMinimizing; - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
--- a/src/macosx/native/sun/awt/AWTWindow.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/AWTWindow.m Thu Jan 12 06:59:38 2017 +0000 @@ -184,6 +184,7 @@ @synthesize isEnabled; @synthesize ownerWindow; @synthesize preFullScreenLevel; +@synthesize isMinimizing; - (void) updateMinMaxSize:(BOOL)resizable { if (resizable) { @@ -308,6 +309,7 @@ [self.nsWindow release]; // the property retains the object already self.isEnabled = YES; + self.isMinimizing = NO; self.javaPlatformWindow = platformWindow; self.styleBits = bits; self.ownerWindow = owner; @@ -427,6 +429,68 @@ [super dealloc]; } +// Tests wheather the corresponding Java paltform window is visible or not ++ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window { + BOOL isVisible = NO; + + if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) { + AWTWindow *awtWindow = (AWTWindow *)[window delegate]; + [AWTToolkit eventCountPlusPlus]; + + JNIEnv *env = [ThreadUtilities getJNIEnv]; + jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env]; + if (platformWindow != NULL) { + static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z"); + isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO; + (*env)->DeleteLocalRef(env, platformWindow); + + } + } + return isVisible; +} + +// Orders window's childs based on the current focus state +- (void) orderChildWindows:(BOOL)focus { +AWT_ASSERT_APPKIT_THREAD; + + if (self.isMinimizing) { + // Do not perform any ordering, if iconify is in progress + return; + } + + NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator]; + NSWindow *window; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isJavaPlatformWindowVisible:window]) { + AWTWindow *awtWindow = (AWTWindow *)[window delegate]; + AWTWindow *owner = awtWindow.ownerWindow; + if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) { + // Do not order 'always on top' windows + continue; + } + while (awtWindow.ownerWindow != nil) { + if (awtWindow.ownerWindow == self) { + if (focus) { + // Move the childWindow to floating level + // so it will appear in front of its + // parent which owns the focus + [window setLevel:NSFloatingWindowLevel]; + } else { + // Focus owner has changed, move the childWindow + // back to normal window level + [window setLevel:NSNormalWindowLevel]; + } + // The childWindow should be displayed in front of + // its nearest parentWindow + [window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]]; + break; + } + awtWindow = awtWindow.ownerWindow; + } + } + } +} + // NSWindow overrides - (BOOL) canBecomeKeyWindow { AWT_ASSERT_APPKIT_THREAD; @@ -509,6 +573,30 @@ // window exposing in _setVisible:(BOOL) } +// Hides/shows window's childs during iconify/de-iconify operation +- (void) iconifyChildWindows:(BOOL)iconify { +AWT_ASSERT_APPKIT_THREAD; + + NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator]; + NSWindow *window; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isJavaPlatformWindowVisible:window]) { + AWTWindow *awtWindow = (AWTWindow *)[window delegate]; + while (awtWindow.ownerWindow != nil) { + if (awtWindow.ownerWindow == self) { + if (iconify) { + [window orderOut:window]; + } else { + [window orderFront:window]; + } + break; + } + awtWindow = awtWindow.ownerWindow; + } + } + } +} + - (void) _deliverIconify:(BOOL)iconify { AWT_ASSERT_APPKIT_THREAD; @@ -522,16 +610,28 @@ } } +- (void)windowWillMiniaturize:(NSNotification *)notification { +AWT_ASSERT_APPKIT_THREAD; + + self.isMinimizing = YES; + // Excplicitly make myself a key window to avoid possible + // negative visual effects during iconify operation + [self.nsWindow makeKeyAndOrderFront:self.nsWindow]; + [self iconifyChildWindows:YES]; +} + - (void)windowDidMiniaturize:(NSNotification *)notification { AWT_ASSERT_APPKIT_THREAD; [self _deliverIconify:JNI_TRUE]; + self.isMinimizing = NO; } - (void)windowDidDeminiaturize:(NSNotification *)notification { AWT_ASSERT_APPKIT_THREAD; [self _deliverIconify:JNI_FALSE]; + [self iconifyChildWindows:NO]; } - (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite { @@ -577,6 +677,7 @@ [AWTWindow setLastKeyWindow:nil]; [self _deliverWindowFocusEvent:YES oppositeWindow: opposite]; + [self orderChildWindows:YES]; } - (void) windowDidResignKey: (NSNotification *) notification { @@ -604,6 +705,7 @@ } [self _deliverWindowFocusEvent:NO oppositeWindow: opposite]; + [self orderChildWindows:NO]; } - (void) windowDidBecomeMain: (NSNotification *) notification {
--- a/src/macosx/native/sun/awt/JavaAccessibilityAction.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/JavaAccessibilityAction.m Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,9 +35,9 @@ { self = [super init]; if (self) { - fAccessibleAction = JNFNewGlobalRef(env, accessibleAction); + fAccessibleAction = JNFNewWeakGlobalRef(env, accessibleAction); fIndex = index; - fComponent = JNFNewGlobalRef(env, component); + fComponent = JNFNewWeakGlobalRef(env, component); } return self; } @@ -46,10 +46,10 @@ { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fAccessibleAction); + JNFDeleteWeakGlobalRef(env, fAccessibleAction); fAccessibleAction = NULL; - JNFDeleteGlobalRef(env, fComponent); + JNFDeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super dealloc]; @@ -59,10 +59,10 @@ { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fAccessibleAction); + JNFDeleteWeakGlobalRef(env, fAccessibleAction); fAccessibleAction = NULL; - JNFDeleteGlobalRef(env, fComponent); + JNFDeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super finalize]; @@ -75,7 +75,18 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; - return JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fComponent)); // AWT_THREADING Safe (AWTRunLoopMode) + jobject fCompLocal = (*env)->NewLocalRef(env, fComponent); + if ((*env)->IsSameObject(env, fCompLocal, NULL)) { + return @"unknown"; + } + NSString *str = nil; + jobject jstr = JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fCompLocal); + if (jstr != NULL) { + NSString *str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode) + (*env)->DeleteLocalRef(env, jstr); + } + (*env)->DeleteLocalRef(env, fCompLocal); + return str == nil ? @"unknown" : str; } - (void)perform @@ -96,9 +107,9 @@ { self = [super init]; if (self) { - fTabGroup = JNFNewGlobalRef(env, tabGroup); + fTabGroup = JNFNewWeakGlobalRef(env, tabGroup); fIndex = index; - fComponent = JNFNewGlobalRef(env, component); + fComponent = JNFNewWeakGlobalRef(env, component); } return self; } @@ -107,10 +118,10 @@ { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fTabGroup); + JNFDeleteWeakGlobalRef(env, fTabGroup); fTabGroup = NULL; - JNFDeleteGlobalRef(env, fComponent); + JNFDeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super dealloc]; @@ -120,10 +131,10 @@ { JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fTabGroup); + JNFDeleteWeakGlobalRef(env, fTabGroup); fTabGroup = NULL; - JNFDeleteGlobalRef(env, fComponent); + JNFDeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super finalize];
--- a/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,9 @@ jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode) if (axRole == NULL) return @"unknown"; - return JNFJavaToNSString(env, axRole); + NSString* str = JNFJavaToNSString(env, axRole); + (*env)->DeleteLocalRef(env, axRole); + return str; } jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component) @@ -126,21 +128,27 @@ { static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;"); jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL); - return containsAxState(env, axContext, axVertState, component); + BOOL vertical = containsAxState(env, axContext, axVertState, component); + (*env)->DeleteLocalRef(env, axVertState); + return vertical; } BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component) { static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;"); jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL); - return containsAxState(env, axContext, axHorizState, component); + BOOL horizontal = containsAxState(env, axContext, axHorizState, component); + (*env)->DeleteLocalRef(env, axHorizState); + return horizontal; } BOOL isShowing(JNIEnv *env, jobject axContext, jobject component) { static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;"); jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING); - return containsAxState(env, axContext, axVisibleState, component); + BOOL showing = containsAxState(env, axContext, axVisibleState, component); + (*env)->DeleteLocalRef(env, axVisibleState); + return showing; } NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
--- a/src/macosx/native/sun/awt/JavaComponentAccessibility.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/JavaComponentAccessibility.m Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,6 @@ static NSMutableDictionary *sAttributeNamesForRoleCache = nil; static NSObject *sAttributeNamesLOCK = nil; - @interface TabGroupAccessibility : JavaComponentAccessibility { NSInteger _numTabs; } @@ -137,8 +136,11 @@ fView = [view retain]; fJavaRole = [javaRole retain]; - fAccessible = JNFNewGlobalRef(env, accessible); - fComponent = JNFNewGlobalRef(env, [(AWTView *)fView awtComponent:env]); + fAccessible = (*env)->NewWeakGlobalRef(env, accessible); + + jobject jcomponent = [(AWTView *)fView awtComponent:env]; + fComponent = (*env)->NewWeakGlobalRef(env, jcomponent); + (*env)->DeleteLocalRef(env, jcomponent); fIndex = index; @@ -166,10 +168,10 @@ JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fAccessible); + (*env)->DeleteWeakGlobalRef(env, fAccessible); fAccessible = NULL; - JNFDeleteGlobalRef(env, fComponent); + (*env)->DeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [fParent release]; @@ -198,10 +200,10 @@ JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; - JNFDeleteGlobalRef(env, fAccessible); + (*env)->DeleteWeakGlobalRef(env, fAccessible); fAccessible = NULL; - JNFDeleteGlobalRef(env, fComponent); + (*env)->DeleteWeakGlobalRef(env, fComponent); fComponent = NULL; [super finalize]; @@ -293,7 +295,7 @@ + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored { - jobjectArray jchildrenAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) + jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) if (jchildrenAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles); @@ -308,14 +310,21 @@ NSString *childJavaRole = nil; if (jchildJavaRole != NULL) { - childJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jchildJavaRole, sjf_key)); + jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key); + childJavaRole = JNFJavaToNSString(env, jkey); + (*env)->DeleteLocalRef(env, jkey); } JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView]; + + (*env)->DeleteLocalRef(env, jchild); + (*env)->DeleteLocalRef(env, jchildJavaRole); + [children addObject:child]; childIndex++; } - + (*env)->DeleteLocalRef(env, jchildrenAndRoles); + return children; } @@ -324,7 +333,7 @@ jobject jcomponent = [(AWTView *)view awtComponent:env]; jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent); NSString *javaRole = getJavaRole(env, jaccessible, jcomponent); - + (*env)->DeleteLocalRef(env, jcomponent); return [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view]; } @@ -339,7 +348,10 @@ jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env]; if (jCAX == NULL) return nil; JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr)); - if (value != nil) return [[value retain] autorelease]; + if (value != nil) { + (*env)->DeleteLocalRef(env, jCAX); + return [[value retain] autorelease]; + } // otherwise, create a new instance JavaComponentAccessibility *newChild = nil; @@ -362,6 +374,7 @@ // must hard CFRetain() pointer poked into Java object CFRetain(newChild); JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild)); + (*env)->DeleteLocalRef(env, jCAX); // return autoreleased instance return [newChild autorelease]; @@ -394,7 +407,7 @@ // Get all the other accessibility attributes states we need in one swell foop. // javaRole isn't pulled in because we need protected access to AccessibleRole.key - jbooleanArray attributeStates = JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) + jbooleanArray attributeStates = (jbooleanArray)JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (attributeStates == NULL) return nil; jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0); if (attributeStatesArray == NULL) { @@ -489,6 +502,7 @@ JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent]; [fActions setObject:action forKey:[self isMenu] ? NSAccessibilityPickAction : NSAccessibilityPressAction]; [action release]; + (*env)->DeleteLocalRef(env, axAction); } } @@ -499,7 +513,9 @@ - (id)parent { + static JNF_CLASS_CACHE(sjc_Window, "java/awt/Window"); static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;"); + static JNF_STATIC_MEMBER_CACHE(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;"); if(fParent == nil) { JNIEnv* env = [ThreadUtilities getJNIEnv]; @@ -509,10 +525,21 @@ if (jparent == NULL) { fParent = fView; } else { - fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:fView]; + AWTView *view = fView; + jobject jax = JNFCallStaticObjectMethod(env, sjm_getSwingAccessible, fAccessible); + + if (JNFIsInstanceOf(env, jax, &sjc_Window)) { + // In this case jparent is an owner toplevel and we should retrieve its own view + view = [AWTView awtView:env ofAccessible:jparent]; + } + if (view != nil) { + fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:view]; + } if (fParent == nil) { fParent = fView; } + (*env)->DeleteLocalRef(env, jparent); + (*env)->DeleteLocalRef(env, jax ); } [fParent retain]; } @@ -560,7 +587,10 @@ return NO; } - return isShowing(env, [self axContextWithEnv:env], fComponent); + jobject axContext = [self axContextWithEnv:env]; + BOOL showing = isShowing(env, axContext, fComponent); + (*env)->DeleteLocalRef(env, axContext); + return showing; } // the array of names for each role is cached in the sAttributeNamesForRoleCache @@ -737,7 +767,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSString(env, val); + if (val == NULL) { + return @"unknown"; + } + NSString* str = JNFJavaToNSString(env, val); + (*env)->DeleteLocalRef(env, val); + return str; } - (BOOL)accessibilityIsHelpAttributeSettable @@ -753,7 +788,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSNumber(env, axValue); + if (axValue == NULL) { + return [NSNumber numberWithInt:0]; + } + NSNumber* num = JNFJavaToNSNumber(env, axValue); + (*env)->DeleteLocalRef(env, axValue); + return num; } - (BOOL)accessibilityIsMaxValueAttributeSettable @@ -769,7 +809,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSNumber(env, axValue); + if (axValue == NULL) { + return [NSNumber numberWithInt:0]; + } + NSNumber* num = JNFJavaToNSNumber(env, axValue); + (*env)->DeleteLocalRef(env, axValue); + return num; } - (BOOL)accessibilityIsMinValueAttributeSettable @@ -784,13 +829,16 @@ // cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz if (isVertical(env, axContext, fComponent)) { + (*env)->DeleteLocalRef(env, axContext); return NSAccessibilityVerticalOrientationValue; } if (isHorizontal(env, axContext, fComponent)) { + (*env)->DeleteLocalRef(env, axContext); return NSAccessibilityHorizontalOrientationValue; } + (*env)->DeleteLocalRef(env, axContext); return nil; } @@ -822,6 +870,7 @@ // Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent. NSSize size = getAxComponentSize(env, axComponent, fComponent); NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent); + (*env)->DeleteLocalRef(env, axComponent); point.y += size.height; @@ -871,8 +920,9 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent); - if(axRole != NULL) { + if (axRole != NULL) { value = JNFJavaToNSString(env, axRole); + (*env)->DeleteLocalRef(env, axRole); } else { value = @"unknown"; } @@ -907,7 +957,9 @@ - (NSValue *)accessibilitySizeAttribute { JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; + NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)]; + (*env)->DeleteLocalRef(env, axComponent); + return size; } - (BOOL)accessibilityIsSizeAttributeSettable @@ -966,7 +1018,12 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSString(env, val); + if (val == NULL) { + return @"unknown"; + } + NSString* str = JNFJavaToNSString(env, val); + (*env)->DeleteLocalRef(env, val); + return str; } - (BOOL)accessibilityIsTitleAttributeSettable @@ -998,8 +1055,20 @@ // a text value is taken care of in JavaTextAccessibility // cmcnote should coalesce these calls into one java call + NSNumber *num = nil; jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return JNFJavaToNSNumber(env, JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent)); // AWT_THREADING Safe (AWTRunLoop) + if (axValue != NULL) { + jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent); + if (str != NULL) { + num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop) + (*env)->DeleteLocalRef(env, str); + } + (*env)->DeleteLocalRef(env, axValue); + } + if (num == nil) { + num = [NSNumber numberWithInt:0]; + } + return num; } - (BOOL)accessibilityIsValueAttributeSettable @@ -1098,7 +1167,10 @@ id value = nil; if (JNFIsInstanceOf(env, jparent, &jc_Container)) { jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop) - value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; + if (jaccessible != NULL) { + value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView]; + (*env)->DeleteLocalRef(env, jaccessible); + } } if (value == nil) { @@ -1130,6 +1202,7 @@ if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) { value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; } + (*env)->DeleteLocalRef(env, focused); } if (value == nil) { @@ -1236,38 +1309,46 @@ for (i = 0; i < _numTabs; i++) { aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i]; if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) { + (*env)->DeleteLocalRef(env, selAccessible); return aTab; } } - + (*env)->DeleteLocalRef(env, selAccessible); return nil; } - (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored { - jobjectArray jtabsAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) + jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop) if(jtabsAndRoles == NULL) return nil; jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles); - if (arrayLen == 0) return nil; - + if (arrayLen == 0) { + (*env)->DeleteLocalRef(env, jtabsAndRoles); + return nil; + } NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)]; // all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1. - if (jtabJavaRole == NULL) return nil; - - NSString *tabJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jtabJavaRole, sjf_key)); + if (jtabJavaRole == NULL) { + (*env)->DeleteLocalRef(env, jtabsAndRoles); + return nil; + } + jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key); + NSString *tabJavaRole = JNFJavaToNSString(env, jkey); + (*env)->DeleteLocalRef(env, jkey); NSInteger i; NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly for(i = 0; i < arrayLen; i+=2) { jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i); JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease]; + (*env)->DeleteLocalRef(env, jtab); [tabs addObject:tab]; tabIndex++; } - + (*env)->DeleteLocalRef(env, jtabsAndRoles); return tabs; } @@ -1286,7 +1367,9 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; - return [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + id tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + (*env)->DeleteLocalRef(env, axContext); + return tabs; } - (BOOL)accessibilityIsTabsAttributeSettable @@ -1306,7 +1389,9 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; - return [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO]; + (*env)->DeleteLocalRef(env, axContext); + return cont; } - (BOOL)accessibilityIsContentsAttributeSettable @@ -1319,7 +1404,9 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; - return [self currentTabWithEnv:env withAxContext:axContext]; + id val = [self currentTabWithEnv:env withAxContext:axContext]; + (*env)->DeleteLocalRef(env, axContext); + return val; } - (BOOL)accessibilityIsValueAttributeSettable @@ -1336,6 +1423,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; setAxContextSelection(env, axContext, fIndex, fComponent); + (*env)->DeleteLocalRef(env, axContext); } - (NSArray *)accessibilityChildrenAttribute @@ -1371,6 +1459,7 @@ result = children; } } + (*env)->DeleteLocalRef(env, axContext); } else { result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount]; } @@ -1389,7 +1478,7 @@ self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole]; if (self) { if (tabGroup != NULL) { - fTabGroupAxContext = JNFNewGlobalRef(env, tabGroup); + fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup); } else { fTabGroupAxContext = NULL; } @@ -1402,7 +1491,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; if (fTabGroupAxContext != NULL) { - JNFDeleteGlobalRef(env, fTabGroupAxContext); + JNFDeleteWeakGlobalRef(env, fTabGroupAxContext); fTabGroupAxContext = NULL; } @@ -1414,7 +1503,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; if (fTabGroupAxContext != NULL) { - JNFDeleteGlobalRef(env, fTabGroupAxContext); + JNFDeleteWeakGlobalRef(env, fTabGroupAxContext); fTabGroupAxContext = NULL; } @@ -1425,9 +1514,14 @@ { JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axContext = [self axContextWithEnv:env]; + jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent); // Returns the current selection of the page tab list - return [NSNumber numberWithBool:ObjectEquals(env, axContext, getAxContextSelection(env, [self tabGroup], fIndex, fComponent), fComponent)]; + id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)]; + + (*env)->DeleteLocalRef(env, selAccessible); + (*env)->DeleteLocalRef(env, axContext); + return val; } - (void)getActionsWithEnv:(JNIEnv *)env @@ -1442,7 +1536,8 @@ if (fTabGroupAxContext == NULL) { JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env]; - fTabGroupAxContext = JNFNewGlobalRef(env, tabGroupAxContext); + fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext); + (*env)->DeleteLocalRef(env, tabGroupAxContext); } return fTabGroupAxContext; } @@ -1477,8 +1572,10 @@ if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) { jobject elementAxContext = [aElement axContextWithEnv:env]; if (isHorizontal(env, elementAxContext, fComponent)) { + (*env)->DeleteLocalRef(env, elementAxContext); return aElement; } + (*env)->DeleteLocalRef(env, elementAxContext); } } @@ -1504,8 +1601,10 @@ if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) { jobject elementAxContext = [aElement axContextWithEnv:env]; if (isVertical(env, elementAxContext, fComponent)) { + (*env)->DeleteLocalRef(env, elementAxContext); return aElement; } + (*env)->DeleteLocalRef(env, elementAxContext); } }
--- a/src/macosx/native/sun/awt/JavaTextAccessibility.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/awt/JavaTextAccessibility.m Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,9 @@ // if it's static text, the AppKit AXValue is the java accessibleName jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axName != NULL) { - return JNFJavaToNSString(env, axName); + NSString* str = JNFJavaToNSString(env, axName); + (*env)->DeleteLocalRef(env, axName); + return str; } // value is still nil if no accessibleName for static text. Below, try to get the accessibleText. } @@ -120,12 +122,18 @@ // cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923 jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axText == NULL) return nil; - + (*env)->DeleteLocalRef(env, axText); + jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axEditableText == NULL) return nil; static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;"); - NSString *string = JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent)); // AWT_THREADING Safe (AWTRunLoop) + jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent); + NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop) + + (*env)->DeleteLocalRef(env, jrange); + (*env)->DeleteLocalRef(env, axEditableText); + if (string == nil) string = @""; return string; } @@ -139,6 +147,7 @@ JNIEnv* env = [ThreadUtilities getJNIEnv]; jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axEditableText == NULL) return NO; + (*env)->DeleteLocalRef(env, axEditableText); return YES; } @@ -157,7 +166,9 @@ static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) if (axText == NULL) return @""; - return JNFJavaToNSString(env, axText); + NSString* str = JNFJavaToNSString(env, axText); + (*env)->DeleteLocalRef(env, axText); + return str; } - (BOOL)accessibilityIsSelectedTextAttributeSettable @@ -220,7 +231,9 @@ // also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - return [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; + NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; + (*env)->DeleteLocalRef(env, axText); + return num; } - (BOOL)accessibilityIsNumberOfCharactersAttributeSettable @@ -285,7 +298,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D"); - jdoubleArray axBounds = JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) + jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) if (axBounds == NULL) return nil; // We cheat because we know that the array is 4 elements long (x, y, width, height) @@ -324,7 +337,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); - jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) + jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) if (axTextRange == NULL) return nil; return javaIntArrayToNSRangeValue(env,axTextRange); @@ -350,10 +363,12 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;"); - jstring jstringForRange = JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) + jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) if (jstringForRange == NULL) return @""; - return JNFJavaToNSString(env, jstringForRange); + NSString* str = JNFJavaToNSString(env, jstringForRange); + (*env)->DeleteLocalRef(env, jstringForRange); + return str; } // @@ -406,7 +421,7 @@ JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); - jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) + jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) if (axTextRange == NULL) return nil; return javaIntArrayToNSRangeValue(env, axTextRange);
--- a/src/macosx/native/sun/java2d/opengl/CGLLayer.h Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/java2d/opengl/CGLLayer.h Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ @interface CGLLayer : CAOpenGLLayer { @private - JNFJObjectWrapper *javaLayer; + JNFWeakJObjectWrapper *javaLayer; // intermediate buffer, used the RQ lock to synchronize GLuint textureID; @@ -45,7 +45,7 @@ #endif /* REMOTELAYER */ } -@property (nonatomic, retain) JNFJObjectWrapper *javaLayer; +@property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer; @property (readwrite, assign) GLuint textureID; @property (readwrite, assign) GLenum target; @property (readwrite, assign) float textureWidth; @@ -57,7 +57,7 @@ @property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer; #endif -- (id) initWithJavaLayer:(JNFJObjectWrapper *)javaLayer; +- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)javaLayer; - (void) blitTexture; @end
--- a/src/macosx/native/sun/java2d/opengl/CGLLayer.m Tue Nov 08 05:26:12 2016 +0000 +++ b/src/macosx/native/sun/java2d/opengl/CGLLayer.m Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ @synthesize jrsRemoteLayer; #endif -- (id) initWithJavaLayer:(JNFJObjectWrapper *)layer; +- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer; { AWT_ASSERT_APPKIT_THREAD; // Initialize ourselves @@ -133,6 +133,15 @@ { AWT_ASSERT_APPKIT_THREAD; + JNIEnv *env = [ThreadUtilities getJNIEnv]; + static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer"); + static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V"); + + jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env]; + if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) { + return; + } + // Set the current context to the one given to us. CGLSetCurrentContext(glContext); @@ -141,12 +150,7 @@ glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, textureWidth, textureHeight); - - JNIEnv *env = [ThreadUtilities getJNIEnv]; - static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer"); - static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V"); - jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env]; JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext); (*env)->DeleteLocalRef(env, javaLayerLocalRef); @@ -171,7 +175,7 @@ JNF_COCOA_ENTER(env); - JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env]; + JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env]; [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ AWT_ASSERT_APPKIT_THREAD;
--- a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; + /** * This class represents ciphers in cipher block chaining (CBC) mode. @@ -122,31 +124,31 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the encrypted data */ int encrypt(byte[] plain, int plainOffset, int plainLen, byte[] cipher, int cipherOffset) { - int i; + if ((plainLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int endIndex = plainOffset + plainLen; for (; plainOffset < endIndex; plainOffset+=blockSize, cipherOffset += blockSize) { - for (i=0; i<blockSize; i++) { - k[i] = (byte)(plain[i+plainOffset] ^ r[i]); + for (int i = 0; i < blockSize; i++) { + k[i] = (byte)(plain[i + plainOffset] ^ r[i]); } embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); System.arraycopy(cipher, cipherOffset, r, 0, blockSize); @@ -159,14 +161,10 @@ * * <p>The input cipher text <code>cipher</code>, starting at * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. * The result is stored in <code>plain</code>, starting at * <code>plainOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * * <p>It is also the application's responsibility to make sure that * <code>init</code> has been called before this method is called. * (This check is omitted here, to avoid double checking.) @@ -176,23 +174,23 @@ * @param cipherLen the length of the input data * @param plain the buffer for the result * @param plainOffset the offset in <code>plain</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the decrypted data - * - * @exception IllegalBlockSizeException if input data whose length does - * not correspond to the embedded cipher's block size is passed to the - * embedded cipher */ int decrypt(byte[] cipher, int cipherOffset, int cipherLen, byte[] plain, int plainOffset) { - int i; + if ((cipherLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int endIndex = cipherOffset + cipherLen; for (; cipherOffset < endIndex; cipherOffset += blockSize, plainOffset += blockSize) { embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0); - for (i = 0; i < blockSize; i++) { - plain[i+plainOffset] = (byte)(k[i] ^ r[i]); + for (int i = 0; i < blockSize; i++) { + plain[i + plainOffset] = (byte)(k[i] ^ r[i]); } System.arraycopy(cipher, cipherOffset, r, 0, blockSize); }
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java Thu Jan 12 06:59:38 2017 +0000 @@ -717,7 +717,7 @@ len -= blockSize; } // do not count the trailing bytes which do not make up a unit - len = (len > 0 ? (len - (len%unitBytes)) : 0); + len = (len > 0 ? (len - (len % unitBytes)) : 0); // check output buffer capacity if ((output == null) || @@ -729,6 +729,15 @@ int outLen = 0; if (len != 0) { // there is some work to do + if ((input == output) + && (outputOffset < (inputOffset + inputLen)) + && (inputOffset < (outputOffset + buffer.length))) { + // copy 'input' out to avoid its content being + // overwritten prematurely. + input = Arrays.copyOfRange(input, inputOffset, + inputOffset + inputLen); + inputOffset = 0; + } if (len <= buffered) { // all to-be-processed data are from 'buffer' if (decrypting) { @@ -741,37 +750,40 @@ System.arraycopy(buffer, len, buffer, 0, buffered); } } else { // len > buffered - if ((input != output) && (buffered == 0)) { - // all to-be-processed data are from 'input' - // however, note that if 'input' and 'output' are the same, - // then they can't be passed directly to the underlying cipher - // engine operations as data may be overwritten before they - // are read. - if (decrypting) { - outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset); - } else { - outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset); + int inputConsumed = len - buffered; + int temp; + if (buffered > 0) { + int bufferCapacity = buffer.length - buffered; + if (bufferCapacity != 0) { + temp = Math.min(bufferCapacity, inputConsumed); + if (unitBytes != blockSize) { + temp -= ((buffered + temp) % unitBytes); + } + System.arraycopy(input, inputOffset, buffer, buffered, temp); + inputOffset += temp; + inputConsumed -= temp; + inputLen -= temp; + buffered += temp; } - inputOffset += len; - inputLen -= len; - } else { - // assemble the data using both 'buffer' and 'input' - byte[] in = new byte[len]; - int inConsumed = len - buffered; - if (buffered != 0) { - System.arraycopy(buffer, 0, in, 0, buffered); - buffered = 0; + // process 'buffer' + if (decrypting) { + outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset); + } else { + outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset); } - if (inConsumed != 0) { - System.arraycopy(input, inputOffset, in, len - inConsumed, inConsumed); - inputOffset += inConsumed; - inputLen -= inConsumed; + outputOffset += outLen; + buffered = 0; + } + if (inputConsumed > 0) { // still has input to process + if (decrypting) { + outLen += cipher.decrypt(input, inputOffset, inputConsumed, + output, outputOffset); + } else { + outLen += cipher.encrypt(input, inputOffset, inputConsumed, + output, outputOffset); } - if (decrypting) { - outLen = cipher.decrypt(in, 0, len, output, outputOffset); - } else { - outLen = cipher.encrypt(in, 0, len, output, outputOffset); - } + inputOffset += inputConsumed; + inputLen -= inputConsumed; } } // Let's keep track of how many bytes are needed to make @@ -934,8 +946,10 @@ byte[] finalBuf = input; int finalOffset = inputOffset; int finalBufLen = inputLen; - if ((input == output) || (buffered != 0) || - (!decrypting && padding != null)) { + if ((buffered != 0) || (!decrypting && padding != null) || + ((input == output) + && (outputOffset < (inputOffset + inputLen)) + && (inputOffset < (outputOffset + buffer.length)))) { if (decrypting || padding == null) { paddingLen = 0; }
--- a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; /** * This class represents ciphers in cipher-feedback (CFB) mode. @@ -133,66 +134,72 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>plainLen</code> is not + * a multiple of the <code>numBytes</code> * @return the length of the encrypted data */ int encrypt(byte[] plain, int plainOffset, int plainLen, - byte[] cipher, int cipherOffset) - { - int i, len; - len = blockSize - numBytes; + byte[] cipher, int cipherOffset) { + if ((plainLen % numBytes) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + + int nShift = blockSize - numBytes; int loopCount = plainLen / numBytes; - int oddBytes = plainLen % numBytes; - if (len == 0) { - for (; loopCount > 0 ; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i = 0; i < blockSize; i++) - register[i] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); + for (; loopCount > 0 ; + plainOffset += numBytes, cipherOffset += numBytes, + loopCount--) { + embeddedCipher.encryptBlock(register, 0, k, 0); + if (nShift != 0) { + System.arraycopy(register, numBytes, register, 0, nShift); + } + for (int i = 0; i < numBytes; i++) { + register[nShift + i] = cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[i + plainOffset]); } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) - register[i] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - } - } else { - for (; loopCount > 0 ; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<numBytes; i++) - register[i+len] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); + } + return plainLen; + } - } - if (oddBytes != 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<oddBytes; i++) { - register[i+len] = cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - } + /** + * Performs the last encryption operation. + * + * <p>The input plain text <code>plain</code>, starting at + * <code>plainOffset</code> and ending at + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. + * The result is stored in <code>cipher</code>, starting at + * <code>cipherOffset</code>. + * + * @param plain the buffer with the input data to be encrypted + * @param plainOffset the offset in <code>plain</code> + * @param plainLen the length of the input data + * @param cipher the buffer for the result + * @param cipherOffset the offset in <code>cipher</code> + * @return the number of bytes placed into <code>cipher</code> + */ + int encryptFinal(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { + + int oddBytes = plainLen % numBytes; + int len = encrypt(plain, plainOffset, (plainLen - oddBytes), + cipher, cipherOffset); + plainOffset += len; + cipherOffset += len; + if (oddBytes != 0) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < oddBytes; i++) { + cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[i + plainOffset]); } } return plainLen; @@ -203,17 +210,52 @@ * * <p>The input cipher text <code>cipher</code>, starting at * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. * The result is stored in <code>plain</code>, starting at * <code>plainOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. + * @param cipher the buffer with the input data to be decrypted + * @param cipherOffset the offset in <code>cipherOffset</code> + * @param cipherLen the length of the input data + * @param plain the buffer for the result + * @param plainOffset the offset in <code>plain</code> + * @exception ProviderException if <code>cipherLen</code> is not + * a multiple of the <code>numBytes</code> + * @return the length of the decrypted data + */ + int decrypt(byte[] cipher, int cipherOffset, int cipherLen, + byte[] plain, int plainOffset) { + if ((cipherLen % numBytes) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + + int nShift = blockSize - numBytes; + int loopCount = cipherLen / numBytes; + + for (; loopCount > 0; + plainOffset += numBytes, cipherOffset += numBytes, + loopCount--) { + embeddedCipher.encryptBlock(register, 0, k, 0); + if (nShift != 0) { + System.arraycopy(register, numBytes, register, 0, nShift); + } + for (int i = 0; i < numBytes; i++) { + register[i + nShift] = cipher[i + cipherOffset]; + plain[i + plainOffset] + = (byte)(cipher[i + cipherOffset] ^ k[i]); + } + } + return cipherLen; + } + + /** + * Performs the last decryption operation. * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input cipher text <code>cipher</code>, starting at + * <code>cipherOffset</code> and ending at + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. + * The result is stored in <code>plain</code>, starting at + * <code>plainOffset</code>. * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in <code>cipherOffset</code> @@ -222,53 +264,19 @@ * @param plainOffset the offset in <code>plain</code> * @return the length of the decrypted data */ - int decrypt(byte[] cipher, int cipherOffset, int cipherLen, - byte[] plain, int plainOffset) - { - int i, len; - len = blockSize - numBytes; - int loopCount = cipherLen / numBytes; - int oddBytes = cipherLen % numBytes; + int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen, + byte[] plain, int plainOffset) { - if (len == 0) { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i = 0; i < blockSize; i++) { - register[i] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) { - register[i] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } - } - } else { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<numBytes; i++) { - register[i+len] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } - } - if (oddBytes != 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; i<oddBytes; i++) { - register[i+len] = cipher[i+cipherOffset]; - plain[i+plainOffset] - = (byte)(cipher[i+cipherOffset] ^ k[i]); - } + int oddBytes = cipherLen % numBytes; + int len = decrypt(cipher, cipherOffset, (cipherLen - oddBytes), + plain, plainOffset); + cipherOffset += len; + plainOffset += len; + if (oddBytes != 0) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < oddBytes; i++) { + plain[i + plainOffset] + = (byte)(cipher[i + cipherOffset] ^ k[i]); } } return cipherLen;
--- a/src/share/classes/com/sun/crypto/provider/CounterMode.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/CounterMode.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 201313, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ import java.security.InvalidKeyException; + /** * This class represents ciphers in counter (CTR) mode. * @@ -136,14 +137,6 @@ * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param in the buffer with the input data to be encrypted * @param inOffset the offset in <code>plain</code> * @param len the length of the input data @@ -155,30 +148,7 @@ return crypt(in, inOff, len, out, outOff); } - /** - * Performs decryption operation. - * - * <p>The input cipher text <code>cipher</code>, starting at - * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. - * The result is stored in <code>plain</code>, starting at - * <code>plainOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * - * @param in the buffer with the input data to be decrypted - * @param inOff the offset in <code>cipherOffset</code> - * @param len the length of the input data - * @param out the buffer for the result - * @param outOff the offset in <code>plain</code> - * @return the length of the decrypted data - */ + // CTR encrypt and decrypt are identical int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { return crypt(in, inOff, len, out, outOff); }
--- a/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java Thu Jan 12 06:59:38 2017 +0000 @@ -72,6 +72,17 @@ initialize(1024, null); } + private static void checkKeySize(int keysize) + throws InvalidParameterException { + + if ((keysize < 512) || (keysize > 4096) || ((keysize & 0x3F) != 0)) { + throw new InvalidParameterException( + "DH key size must be multiple of 64, and can only range " + + "from 512 to 4096 (inclusive). " + + "The specific key size " + keysize + " is not supported"); + } + } + /** * Initializes this key pair generator for a certain keysize and source of * randomness. @@ -81,12 +92,8 @@ * @param random the source of randomness */ public void initialize(int keysize, SecureRandom random) { - if ((keysize < 512) || (keysize > 4096) || (keysize % 64 != 0)) { - throw new InvalidParameterException("Keysize must be multiple " - + "of 64, and can only range " - + "from 512 to 4096 " - + "(inclusive)"); - } + checkKeySize(keysize); + this.pSize = keysize; this.lSize = 0; this.random = random; @@ -116,11 +123,10 @@ params = (DHParameterSpec)algParams; pSize = params.getP().bitLength(); - if ((pSize < 512) || (pSize > 4096) || - (pSize % 64 != 0)) { - throw new InvalidAlgorithmParameterException - ("Prime size must be multiple of 64, and can only range " - + "from 512 to 4096 (inclusive)"); + try { + checkKeySize(pSize); + } catch (InvalidParameterException ipe) { + throw new InvalidAlgorithmParameterException(ipe.getMessage()); } // exponent size is optional, could be 0
--- a/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java Thu Jan 12 06:59:38 2017 +0000 @@ -60,12 +60,13 @@ private SecureRandom random = null; private static void checkKeySize(int keysize) - throws InvalidAlgorithmParameterException { - if ((keysize != 2048) && (keysize != 4096) && + throws InvalidParameterException { + if ((keysize != 2048) && (keysize != 4096) && ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) { - throw new InvalidAlgorithmParameterException( - "Keysize must be multiple of 64 ranging from " - + "512 to 1024 (inclusive), or 2048, or 4096"); + throw new InvalidParameterException( + "DH key size must be multiple of 64 and range " + + "from 512 to 1024 (inclusive), or 2048, or 4096. " + + "The specific key size " + keysize + " is not supported"); } } @@ -79,11 +80,7 @@ */ protected void engineInit(int keysize, SecureRandom random) { // Re-uses DSA parameters and thus have the same range - try { - checkKeySize(keysize); - } catch (InvalidAlgorithmParameterException ex) { - throw new InvalidParameterException(ex.getMessage()); - } + checkKeySize(keysize); this.primeSize = keysize; this.random = random; } @@ -112,7 +109,11 @@ primeSize = dhParamSpec.getPrimeSize(); // Re-uses DSA parameters and thus have the same range - checkKeySize(primeSize); + try { + checkKeySize(primeSize); + } catch (InvalidParameterException ipe) { + throw new InvalidAlgorithmParameterException(ipe.getMessage()); + } exponentSize = dhParamSpec.getExponentSize(); if (exponentSize <= 0) {
--- a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; /** * This class represents ciphers in electronic codebook (ECB) mode. @@ -96,28 +97,24 @@ /** * Performs encryption operation. * - * <p>The input plain text <code>plain</code>, starting at - * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. - * The result is stored in <code>cipher</code>, starting at - * <code>cipherOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input plain text <code>in</code>, starting at + * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>, + * is encrypted. The result is stored in <code>out</code>, starting at + * <code>outOff</code>. * * @param in the buffer with the input data to be encrypted - * @param inOffset the offset in <code>plain</code> + * @param inOff the offset in <code>plain</code> * @param len the length of the input data * @param out the buffer for the result * @param outOff the offset in <code>cipher</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the encrypted data */ int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } for (int i = len; i >= blockSize; i -= blockSize) { embeddedCipher.encryptBlock(in, inOff, out, outOff); inOff += blockSize; @@ -129,28 +126,24 @@ /** * Performs decryption operation. * - * <p>The input cipher text <code>cipher</code>, starting at - * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. - * The result is stored in <code>plain</code>, starting at - * <code>plainOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input cipher text <code>in</code>, starting at + * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>, + * is decrypted.The result is stored in <code>out</code>, starting at + * <code>outOff</code>. * * @param in the buffer with the input data to be decrypted * @param inOff the offset in <code>cipherOffset</code> * @param len the length of the input data * @param out the buffer for the result * @param outOff the offset in <code>plain</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size * @return the length of the decrypted data */ int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } for (int i = len; i >= blockSize; i -= blockSize) { embeddedCipher.decryptBlock(in, inOff, out, outOff); inOff += blockSize;
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Thu Jan 12 06:59:38 2017 +0000 @@ -403,23 +403,21 @@ * and ending at <code>(inOff + len - 1)</code>, is encrypted. The result * is stored in <code>out</code>, starting at <code>outOfs</code>. * - * <p>It is the application's responsibility to make sure that - * <code>len</code> is a multiple of the embedded cipher's block size, - * otherwise, a ProviderException will be thrown. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param in the buffer with the input data to be encrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data * @param out the buffer for the result * @param outOfs the offset in <code>out</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size + * @return the number of bytes placed into the <code>out</code> buffer */ int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { checkDataLength(processed, len); + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } processAAD(); if (len > 0) { gctrPAndC.update(in, inOfs, len, out, outOfs); @@ -432,9 +430,6 @@ /** * Performs encryption operation for the last time. * - * <p>NOTE: <code>len</code> may not be multiple of the embedded - * cipher's block size for this call. - * * @param in the input buffer with the data to be encrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data @@ -479,23 +474,21 @@ * is decrypted. The result is stored in <code>out</code>, starting at * <code>outOfs</code>. * - * <p>It is the application's responsibility to make sure that - * <code>len</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param in the buffer with the input data to be decrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data * @param out the buffer for the result * @param outOfs the offset in <code>out</code> + * @exception ProviderException if <code>len</code> is not + * a multiple of the block size + * @return the number of bytes placed into the <code>out</code> buffer */ int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) { checkDataLength(ibuffer.size(), len); + if ((len % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } processAAD(); if (len > 0) {
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -864,7 +864,9 @@ if (computed[i] != actual[i]) { throw new IOException( "Keystore was tampered with, or " - + "password was incorrect"); + + "password was incorrect", + new UnrecoverableKeyException( + "Password verification failed")); } } }
--- a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; /** * This class represents ciphers in output-feedback (OFB) mode. @@ -132,17 +133,52 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. + * @param plain the buffer with the input data to be encrypted + * @param plainOffset the offset in <code>plain</code> + * @param plainLen the length of the input data + * @param cipher the buffer for the result + * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>plainLen</code> is not + * a multiple of the <code>numBytes</code> + * @return the length of the encrypted data + */ + int encrypt(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { + + if ((plainLen % numBytes) != 0) { + throw new ProviderException("Internal error in input buffering"); + } + int nShift = blockSize - numBytes; + int loopCount = plainLen / numBytes; + + for (; loopCount > 0; + plainOffset += numBytes, cipherOffset += numBytes, + loopCount--) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < numBytes; i++) { + cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[i + plainOffset]); + if (nShift != 0) { + System.arraycopy(register, numBytes, register, 0, nShift); + } + System.arraycopy(k, 0, register, nShift, numBytes); + } + } + return plainLen; + } + + /** + * Performs last encryption operation. * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * <p>The input plain text <code>plain</code>, starting at + * <code>plainOffset</code> and ending at + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. + * The result is stored in <code>cipher</code>, starting at + * <code>cipherOffset</code>. * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> @@ -151,82 +187,34 @@ * @param cipherOffset the offset in <code>cipher</code> * @return the length of the encrypted data */ - int encrypt(byte[] plain, int plainOffset, int plainLen, - byte[] cipher, int cipherOffset) - { - int i; - int len = blockSize - numBytes; - int loopCount = plainLen / numBytes; + int encryptFinal(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { int oddBytes = plainLen % numBytes; + int len = encrypt(plain, plainOffset, (plainLen - oddBytes), + cipher, cipherOffset); + plainOffset += len; + cipherOffset += len; - if (len == 0) { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<numBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(k, 0, register, 0, numBytes); - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(k, 0, register, 0, numBytes); - } - } else { - for (; loopCount > 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<numBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(register, numBytes, register, 0, len); - System.arraycopy(k, 0, register, len, numBytes); - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i<oddBytes; i++) - cipher[i+cipherOffset] = - (byte)(k[i] ^ plain[i+plainOffset]); - System.arraycopy(register, numBytes, register, 0, len); - System.arraycopy(k, 0, register, len, numBytes); + if (oddBytes != 0) { + embeddedCipher.encryptBlock(register, 0, k, 0); + for (int i = 0; i < oddBytes; i++) { + cipher[i + cipherOffset] = + (byte)(k[i] ^ plain[ i + plainOffset]); } } return plainLen; } - /** - * Performs decryption operation. - * - * <p>The input cipher text <code>cipher</code>, starting at - * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. - * The result is stored in <code>plain</code>, starting at - * <code>plainOffset</code>. - * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the stream unit size - * <code>numBytes</code>, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * - * @param cipher the buffer with the input data to be decrypted - * @param cipherOffset the offset in <code>cipherOffset</code> - * @param cipherLen the length of the input data - * @param plain the buffer for the result - * @param plainOffset the offset in <code>plain</code> - * @return the length of the decrypted data - */ + // OFB encrypt and decrypt are identical int decrypt(byte[] cipher, int cipherOffset, int cipherLen, - byte[] plain, int plainOffset) - { - // OFB encrypt and decrypt are identical + byte[] plain, int plainOffset) { return encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); } + + // OFB encrypt and decrypt are identical + int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen, + byte[] plain, int plainOffset) { + // OFB encrypt and decrypt are identical + return encryptFinal(cipher, cipherOffset, cipherLen, plain, plainOffset); + } }
--- a/src/share/classes/com/sun/crypto/provider/PCBC.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/crypto/provider/PCBC.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.ProviderException; + /** * This class represents ciphers in Plaintext Cipher Block Chaining (PCBC) @@ -118,38 +120,36 @@ * * <p>The input plain text <code>plain</code>, starting at * <code>plainOffset</code> and ending at - * <code>(plainOffset + len - 1)</code>, is encrypted. + * <code>(plainOffset + plainLen - 1)</code>, is encrypted. * The result is stored in <code>cipher</code>, starting at * <code>cipherOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>plainLen</code> is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in <code>plain</code> * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in <code>cipher</code> + * @exception ProviderException if <code>plainLen</code> is not + * a multiple of the block size + * @return the length of the encrypted data */ int encrypt(byte[] plain, int plainOffset, int plainLen, byte[] cipher, int cipherOffset) { + if ((plainLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int i; int endIndex = plainOffset + plainLen; for (; plainOffset < endIndex; plainOffset += blockSize, cipherOffset += blockSize) { - for (i=0; i<blockSize; i++) { - k[i] ^= plain[i+plainOffset]; + for (i = 0; i < blockSize; i++) { + k[i] ^= plain[i + plainOffset]; } embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset); for (i = 0; i < blockSize; i++) { - k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]); + k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]); } } return plainLen; @@ -160,27 +160,25 @@ * * <p>The input cipher text <code>cipher</code>, starting at * <code>cipherOffset</code> and ending at - * <code>(cipherOffset + len - 1)</code>, is decrypted. + * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted. * The result is stored in <code>plain</code>, starting at * <code>plainOffset</code>. * - * <p>It is the application's responsibility to make sure that - * <code>cipherLen</code> is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - * <p>It is also the application's responsibility to make sure that - * <code>init</code> has been called before this method is called. - * (This check is omitted here, to avoid double checking.) - * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in <code>cipherOffset</code> * @param cipherLen the length of the input data * @param plain the buffer for the result * @param plainOffset the offset in <code>plain</code> + * @exception ProviderException if <code>cipherLen</code> is not + * a multiple of the block size + * @return the length of the decrypted data */ int decrypt(byte[] cipher, int cipherOffset, int cipherLen, byte[] plain, int plainOffset) { + if ((cipherLen % blockSize) != 0) { + throw new ProviderException("Internal error in input buffering"); + } int i; int endIndex = cipherOffset + cipherLen; @@ -189,10 +187,10 @@ embeddedCipher.decryptBlock(cipher, cipherOffset, plain, plainOffset); for (i = 0; i < blockSize; i++) { - plain[i+plainOffset] ^= k[i]; + plain[i + plainOffset] ^= k[i]; } for (i = 0; i < blockSize; i++) { - k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]); + k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]); } } return cipherLen;
--- a/src/share/classes/com/sun/java/accessibility/util/package-info.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/java/accessibility/util/package-info.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
--- a/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java Thu Jan 12 06:59:38 2017 +0000 @@ -300,7 +300,7 @@ errEx = e; } - protected abstract AbstractLdapNamingEnumeration<T> getReferredResults( + protected abstract AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults( LdapReferralContext refCtx) throws NamingException; /* @@ -360,7 +360,7 @@ * Merge the entries and/or referrals from the supplied enumeration * with those of the current enumeration. */ - protected void update(AbstractLdapNamingEnumeration<T> ne) { + protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) { // Cleanup previous context first homeCtx.decEnumCount();
--- a/src/share/classes/com/sun/jndi/ldap/DigestClientId.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/DigestClientId.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ final private String[] propvals; final private int myHash; - private int pHash = 0; DigestClientId(int version, String hostname, int port, String protocol, Control[] bindCtls, OutputStream trace, @@ -78,12 +77,9 @@ propvals = new String[SASL_PROPS.length]; for (int i = 0; i < SASL_PROPS.length; i++) { propvals[i] = (String) env.get(SASL_PROPS[i]); - if (propvals[i] != null) { - pHash = pHash * 31 + propvals[i].hashCode(); - } } } - myHash = super.hashCode() + pHash; + myHash = super.hashCode() ^ Arrays.hashCode(propvals); } public boolean equals(Object obj) { @@ -92,7 +88,6 @@ } DigestClientId other = (DigestClientId)obj; return myHash == other.myHash - && pHash == other.pHash && super.equals(obj) && Arrays.equals(propvals, other.propvals); }
--- a/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java Thu Jan 12 06:59:38 2017 +0000 @@ -104,9 +104,9 @@ } @Override - protected LdapBindingEnumeration getReferredResults( + protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults( LdapReferralContext refCtx) throws NamingException{ // repeat the original operation at the new context - return (LdapBindingEnumeration)refCtx.listBindings(listArg); + return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.listBindings(listArg); } }
--- a/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java Thu Jan 12 06:59:38 2017 +0000 @@ -72,9 +72,9 @@ } @Override - protected LdapNamingEnumeration getReferredResults( + protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults( LdapReferralContext refCtx) throws NamingException { // repeat the original operation at the new context - return (LdapNamingEnumeration)refCtx.list(listArg); + return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.list(listArg); } }
--- a/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java Thu Jan 12 06:59:38 2017 +0000 @@ -199,15 +199,15 @@ } @Override - protected LdapSearchEnumeration getReferredResults( + protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults( LdapReferralContext refCtx) throws NamingException { // repeat the original operation at the new context - return (LdapSearchEnumeration)refCtx.search( + return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.search( searchArgs.name, searchArgs.filter, searchArgs.cons); } @Override - protected void update(AbstractLdapNamingEnumeration<SearchResult> ne) { + protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) { super.update(ne); // Update search-specific variables
--- a/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,21 +49,23 @@ socketFactory); this.username = username; + int pwdHashCode = 0; if (passwd == null) { this.passwd = null; - } else if (passwd instanceof String) { - this.passwd = passwd; } else if (passwd instanceof byte[]) { this.passwd = ((byte[])passwd).clone(); + pwdHashCode = Arrays.hashCode((byte[])passwd); } else if (passwd instanceof char[]) { this.passwd = ((char[])passwd).clone(); + pwdHashCode = Arrays.hashCode((char[])passwd); } else { this.passwd = passwd; + pwdHashCode = passwd.hashCode(); } myHash = super.hashCode() - + (username != null ? username.hashCode() : 0) - + (passwd != null ? passwd.hashCode() : 0); + ^ (username != null ? username.hashCode() : 0) + ^ pwdHashCode; } public boolean equals(Object obj) {
--- a/src/share/classes/com/sun/jndi/ldap/pool/Pool.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/pool/Pool.java Thu Jan 12 06:59:38 2017 +0000 @@ -118,7 +118,11 @@ PooledConnectionFactory factory) throws NamingException { d("get(): ", id); - d("size: ", map.size()); + if (debug) { + synchronized (map) { + d("size: ", map.size()); + } + } expungeStaleConnections(); @@ -141,10 +145,9 @@ // Keep the weak reference through the element of a linked list weakRefs.add(weakRef); } + d("get(): size after: ", map.size()); } - d("get(): size after: ", map.size()); - return conns.get(timeout, factory); // get one connection from list } @@ -209,19 +212,24 @@ out.println("maximum pool size: " + maxSize); out.println("preferred pool size: " + prefSize); out.println("initial pool size: " + initSize); - out.println("current pool size: " + map.size()); + + synchronized (map) { + out.println("current pool size: " + map.size()); - for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) { - id = entry.getKey(); - conns = entry.getValue().getConnections(); - out.println(" " + id + ":" + conns.getStats()); + for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) { + id = entry.getKey(); + conns = entry.getValue().getConnections(); + out.println(" " + id + ":" + conns.getStats()); + } } out.println("====== Pool end ====================="); } public String toString() { - return super.toString() + " " + map.toString(); + synchronized (map) { + return super.toString() + " " + map.toString(); + } } private void d(String msg, int i) {
--- a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,10 @@ if (!vmDied) { vmDisconnectEvent(event); } + /* + * Inform jdb command line processor that jdb is being shutdown. JDK-8154144. + */ + ((TTY)notifier).setShuttingDown(true); Env.shutdown(shutdownMessageKey); return false; } else {
--- a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,6 +56,16 @@ */ private static final String progname = "jdb"; + private volatile boolean shuttingDown = false; + + public void setShuttingDown(boolean s) { + shuttingDown = s; + } + + public boolean isShuttingDown() { + return shuttingDown; + } + @Override public void vmStartEvent(VMStartEvent se) { Thread.yield(); // fetch output @@ -750,7 +760,13 @@ while (true) { String ln = in.readLine(); if (ln == null) { - MessageOutput.println("Input stream closed."); + /* + * Jdb is being shutdown because debuggee exited, ignore any 'null' + * returned by readLine() during shutdown. JDK-8154144. + */ + if (!isShuttingDown()) { + MessageOutput.println("Input stream closed."); + } ln = "quit"; }
--- a/src/share/classes/java/awt/SplashScreen.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/java/awt/SplashScreen.java Thu Jan 12 06:59:38 2017 +0000 @@ -250,7 +250,7 @@ assert scale > 0; if (scale > 0 && scale != 1) { bounds.setSize((int) (bounds.getWidth() / scale), - (int) (bounds.getWidth() / scale)); + (int) (bounds.getHeight() / scale)); } return bounds; }
--- a/src/share/classes/java/lang/invoke/MethodHandles.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -915,6 +915,9 @@ * @throws NullPointerException if any argument is null */ public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException { + if (refc.isArray()) { + throw new NoSuchMethodException("no constructor for array class: " + refc.getName()); + } String name = "<init>"; MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); return getDirectConstructor(refc, ctor);
--- a/src/share/classes/java/security/ProtectionDomain.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/java/security/ProtectionDomain.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,16 @@ package java.security; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Map; -import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; import sun.misc.JavaSecurityProtectionDomainAccess; import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; import sun.security.util.Debug; @@ -456,24 +460,14 @@ /** * Used for storing ProtectionDomains as keys in a Map. */ - final class Key {} + static final class Key {} static { SharedSecrets.setJavaSecurityProtectionDomainAccess( new JavaSecurityProtectionDomainAccess() { + @Override public ProtectionDomainCache getProtectionDomainCache() { - return new ProtectionDomainCache() { - private final Map<Key, PermissionCollection> map = - Collections.synchronizedMap - (new WeakHashMap<Key, PermissionCollection>()); - public void put(ProtectionDomain pd, - PermissionCollection pc) { - map.put((pd == null ? null : pd.key), pc); - } - public PermissionCollection get(ProtectionDomain pd) { - return pd == null ? map.get(null) : map.get(pd.key); - } - }; + return new PDCache(); } @Override @@ -482,4 +476,119 @@ } }); } + + /** + * A cache of ProtectionDomains and their Permissions. + * + * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap + * with additional support for checking and removing weak keys that are no + * longer in use. There can be cases where the permission collection may + * have a chain of strong references back to the ProtectionDomain, which + * ordinarily would prevent the entry from being removed from the map. To + * address that, we wrap the permission collection in a SoftReference so + * that it can be reclaimed by the garbage collector due to memory demand. + */ + private static class PDCache implements ProtectionDomainCache { + private final ConcurrentHashMap<WeakProtectionDomainKey, + SoftReference<PermissionCollection>> + pdMap = new ConcurrentHashMap<>(); + private final ReferenceQueue<Key> queue = new ReferenceQueue<>(); + + @Override + public void put(ProtectionDomain pd, PermissionCollection pc) { + processQueue(queue, pdMap); + WeakProtectionDomainKey weakPd = + new WeakProtectionDomainKey(pd, queue); + pdMap.put(weakPd, new SoftReference<>(pc)); + } + + @Override + public PermissionCollection get(ProtectionDomain pd) { + processQueue(queue, pdMap); + WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd); + SoftReference<PermissionCollection> sr = pdMap.get(weakPd); + return (sr == null) ? null : sr.get(); + } + + /** + * Removes weak keys from the map that have been enqueued + * on the reference queue and are no longer in use. + */ + private static void processQueue(ReferenceQueue<Key> queue, + ConcurrentHashMap<? extends + WeakReference<Key>, ?> pdMap) { + Reference<? extends Key> ref; + while ((ref = queue.poll()) != null) { + pdMap.remove(ref); + } + } + } + + /** + * A weak key for a ProtectionDomain. + */ + private static class WeakProtectionDomainKey extends WeakReference<Key> { + /** + * Saved value of the referent's identity hash code, to maintain + * a consistent hash code after the referent has been cleared + */ + private final int hash; + + /** + * A key representing a null ProtectionDomain. + */ + private static final Key NULL_KEY = new Key(); + + /** + * Create a new WeakProtectionDomain with the specified domain and + * registered with a queue. + */ + WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) { + this((pd == null ? NULL_KEY : pd.key), rq); + } + + WeakProtectionDomainKey(ProtectionDomain pd) { + this(pd == null ? NULL_KEY : pd.key); + } + + private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) { + super(key, rq); + hash = key.hashCode(); + } + + private WeakProtectionDomainKey(Key key) { + super(key); + hash = key.hashCode(); + } + + /** + * Returns the identity hash code of the original referent. + */ + @Override + public int hashCode() { + return hash; + } + + /** + * Returns true if the given object is an identical + * WeakProtectionDomainKey instance, or, if this object's referent + * has not been cleared and the given object is another + * WeakProtectionDomainKey instance with an identical non-null + * referent as this one. + */ + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj instanceof WeakProtectionDomainKey) { + Object referent = get(); + return (referent != null) && + (referent == ((WeakProtectionDomainKey)obj).get()); + } else { + return false; + } + } + } }
--- a/src/share/classes/java/security/SecureRandom.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/java/security/SecureRandom.java Thu Jan 12 06:59:38 2017 +0000 @@ -464,7 +464,7 @@ * @param bytes the array to be filled in with random bytes. */ @Override - synchronized public void nextBytes(byte[] bytes) { + public void nextBytes(byte[] bytes) { secureRandomSpi.engineNextBytes(bytes); }
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,8 +125,6 @@ protected MouseMotionListener popupMouseMotionListener; protected KeyListener popupKeyListener; - private MouseWheelListener mouseWheelListener; - // This is used for knowing when to cache the minimum preferred size. // If the data in the list changes, the cached value get marked for recalc. // Added to the current JComboBox model @@ -375,10 +373,6 @@ comboBox.getModel().addListDataListener( listDataListener ); } } - - if ((mouseWheelListener = createMouseWheelListener()) != null) { - comboBox.addMouseWheelListener(mouseWheelListener); - } } /** @@ -425,9 +419,6 @@ comboBox.getModel().removeListDataListener( listDataListener ); } } - if (mouseWheelListener != null) { - comboBox.removeMouseWheelListener(mouseWheelListener); - } } /** @@ -541,10 +532,6 @@ return handler; } - private MouseWheelListener createMouseWheelListener() { - return getHandler(); - } - // // end UI Initialization //====================== @@ -1680,8 +1667,7 @@ // private class Handler implements ActionListener, FocusListener, KeyListener, LayoutManager, - ListDataListener, PropertyChangeListener, - MouseWheelListener { + ListDataListener, PropertyChangeListener { // // PropertyChangeListener // @@ -1965,10 +1951,6 @@ } } } - - public void mouseWheelMoved(MouseWheelEvent e) { - e.consume(); - } } class DefaultKeySelectionManager implements JComboBox.KeySelectionManager, UIResource {
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -345,17 +345,26 @@ // PopupMenuListeners. protected void firePopupMenuWillBecomeVisible() { + if (scrollerMouseWheelListener != null) { + comboBox.addMouseWheelListener(scrollerMouseWheelListener); + } super.firePopupMenuWillBecomeVisible(); // comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method // to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible() } protected void firePopupMenuWillBecomeInvisible() { + if (scrollerMouseWheelListener != null) { + comboBox.removeMouseWheelListener(scrollerMouseWheelListener); + } super.firePopupMenuWillBecomeInvisible(); comboBox.firePopupMenuWillBecomeInvisible(); } protected void firePopupMenuCanceled() { + if (scrollerMouseWheelListener != null) { + comboBox.removeMouseWheelListener(scrollerMouseWheelListener); + } super.firePopupMenuCanceled(); comboBox.firePopupMenuCanceled(); } @@ -997,6 +1006,8 @@ if (e.getStateChange() == ItemEvent.SELECTED) { JComboBox comboBox = (JComboBox)e.getSource(); setListSelection(comboBox.getSelectedIndex()); + } else { + setListSelection(-1); } }
--- a/src/share/classes/javax/swing/plaf/nimbus/skin.laf Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/javax/swing/plaf/nimbus/skin.laf Thu Jan 12 06:59:38 2017 +0000 @@ -13407,7 +13407,7 @@ <cacheSettingsInherited>false</cacheSettingsInherited> <cacheMode>NO_CACHING</cacheMode> <uiproperties> - <uiProperty name="rendererUseListColors" type="BOOLEAN" value="true"/> + <uiProperty name="rendererUseListColors" type="BOOLEAN" value="false"/> <uiProperty name="rendererUseUIBorder" type="BOOLEAN" value="true"/> <uiProperty name="cellNoFocusBorder" type="BORDER"> <border type="empty" top="2" left="5" bottom="2" right="5"/> @@ -13513,10 +13513,10 @@ <uiproperties/> </style> <backgroundStates> - <state stateKeys="Disabled"> + <state stateKeys="Selected"> <style> <textForeground> - <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> + <matte red="255" green="255" blue="255" alpha="255" uiDefaultParentName="nimbusLightBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </textForeground> <textBackground/> <background> @@ -13541,6 +13541,56 @@ </layer> </canvas> </state> + <state stateKeys="Disabled+Selected"> + <style> + <textForeground/> + <textBackground/> + <background> + <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> + </background> + <inherit-background>false</inherit-background> + <uiproperties/> + </style> + <canvas> + <size width="100" height="30"/> + <nextLayerNameIndex>2</nextLayerNameIndex> + <stretchingInsets top="0" bottom="0" left="0" right="0"/> + <layer name="Layer 1"> + <opacity>1.0</opacity> + <fillOpacity>1.0</fillOpacity> + <blendingMode>NORMAL</blendingMode> + <locked>false</locked> + <visible>true</visible> + <shapes/> + <effects/> + </layer> + </canvas> + </state> + <state stateKeys="Disabled"> + <style> + <textForeground> + <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> + </textForeground> + <textBackground/> + <background/> + <inherit-textForeground>false</inherit-textForeground> + <uiproperties/> + </style> + <canvas> + <size width="100" height="30"/> + <nextLayerNameIndex>2</nextLayerNameIndex> + <stretchingInsets top="0" bottom="0" left="0" right="0"/> + <layer name="Layer 1"> + <opacity>1.0</opacity> + <fillOpacity>1.0</fillOpacity> + <blendingMode>NORMAL</blendingMode> + <locked>false</locked> + <visible>true</visible> + <shapes/> + <effects/> + </layer> + </canvas> + </state> </backgroundStates> <foregroundStates/> <borderStates/>
--- a/src/share/classes/javax/swing/text/html/parser/Parser.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/javax/swing/text/html/parser/Parser.java Thu Jan 12 06:59:38 2017 +0000 @@ -1986,57 +1986,69 @@ while (true) { int i = 0; while (!insideComment && i < SCRIPT_END_TAG.length - && (SCRIPT_END_TAG[i] == ch - || SCRIPT_END_TAG_UPPER_CASE[i] == ch)) { + && (SCRIPT_END_TAG[i] == ch + || SCRIPT_END_TAG_UPPER_CASE[i] == ch)) { charsToAdd[i] = (char) ch; ch = readCh(); i++; } if (i == SCRIPT_END_TAG.length) { - - /* '</script>' tag detected */ - /* Here, ch == the first character after </script> */ return; - } else { + } - /* To account for extra read()'s that happened */ - for (int j = 0; j < i; j++) { - addString(charsToAdd[j]); + if (!insideComment && i == 1 && charsToAdd[0] == START_COMMENT.charAt(0)) { + // it isn't end script tag, but may be it's start comment tag? + while (i < START_COMMENT.length() + && START_COMMENT.charAt(i) == ch) { + charsToAdd[i] = (char) ch; + ch = readCh(); + i++; } - - switch (ch) { - case -1: - error("eof.script"); - return; - case '\n': - ln++; + if (i == START_COMMENT.length()) { + insideComment = true; + } + } + if (insideComment) { + while (i < END_COMMENT.length() + && END_COMMENT.charAt(i) == ch) { + charsToAdd[i] = (char) ch; ch = readCh(); - lfCount++; - addString('\n'); - break; - case '\r': - ln++; - if ((ch = readCh()) == '\n') { - ch = readCh(); - crlfCount++; - } else { - crCount++; - } - addString('\n'); - break; - default: - addString(ch); - String str = new String(getChars(0, strpos)); - if (!insideComment && str.endsWith(START_COMMENT)) { - insideComment = true; - } - if (insideComment && str.endsWith(END_COMMENT)) { - insideComment = false; - } + i++; + } + if (i == END_COMMENT.length()) { + insideComment = false; + } + } + + /* To account for extra read()'s that happened */ + for (int j = 0; j < i; j++) { + addString(charsToAdd[j]); + } + switch (ch) { + case -1: + error("eof.script"); + return; + case '\n': + ln++; + ch = readCh(); + lfCount++; + addString('\n'); + break; + case '\r': + ln++; + if ((ch = readCh()) == '\n') { ch = readCh(); - break; - } // switch - } + crlfCount++; + } else { + crCount++; + } + addString('\n'); + break; + default: + addString(ch); + ch = readCh(); + break; + } // switch } // while }
--- a/src/share/classes/sun/font/CompositeFont.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/font/CompositeFont.java Thu Jan 12 06:59:38 2017 +0000 @@ -270,10 +270,21 @@ if (componentNames[slot] == null) { componentNames[slot] = name; } else if (!componentNames[slot].equalsIgnoreCase(name)) { - components[slot] = - (PhysicalFont) fm.findFont2D(componentNames[slot], - style, + /* If a component specifies the file with a bad font, + * the corresponding slot will be initialized by + * default physical font. In such case findFont2D may + * return composite font which cannot be casted to + * physical font. + */ + try { + components[slot] = + (PhysicalFont) fm.findFont2D(componentNames[slot], + style, FontManager.PHYSICAL_FALLBACK); + } catch (ClassCastException cce) { + /* Assign default physical font to the slot */ + components[slot] = fm.getDefaultPhysicalFont(); + } } } deferredInitialisation[slot] = false;
--- a/src/share/classes/sun/font/FontFamily.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/font/FontFamily.java Thu Jan 12 06:59:38 2017 +0000 @@ -335,10 +335,10 @@ case Font.BOLD|Font.ITALIC: if (bolditalic != null) { return bolditalic; + } else if (bold != null && bold.canDoStyle(style)) { + return bold; } else if (italic != null && italic.canDoStyle(style)) { return italic; - } else if (bold != null && bold.canDoStyle(style)) { - return italic; } else if (plain != null && plain.canDoStyle(style)) { return plain; } else {
--- a/src/share/classes/sun/font/ScriptRunData.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/font/ScriptRunData.java Thu Jan 12 06:59:38 2017 +0000 @@ -44,7 +44,7 @@ if (cp >= data[cache] && cp < data[cache+2]) { return data[cache+1]; } - if (cp >= CHAR_START & cp < CHAR_LIMIT) { + if ((cp >= CHAR_START) && (cp < CHAR_LIMIT)) { int probe = dataPower; int index = 0;
--- a/src/share/classes/sun/java2d/opengl/OGLMaskFill.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/java2d/opengl/OGLMaskFill.java Thu Jan 12 06:59:38 2017 +0000 @@ -26,6 +26,7 @@ package sun.java2d.opengl; import java.awt.Composite; +import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitiveMgr; @@ -67,7 +68,14 @@ protected void validateContext(SunGraphics2D sg2d, Composite comp, int ctxflags) { - OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; + OGLSurfaceData dstData; + try { + dstData = (OGLSurfaceData) sg2d.surfaceData; + } catch (ClassCastException e) { + throw new InvalidPipeException("wrong surface data type: " + + sg2d.surfaceData); + } + OGLContext.validateContext(dstData, dstData, sg2d.getCompClip(), comp, null, sg2d.paint, sg2d, ctxflags);
--- a/src/share/classes/sun/java2d/pipe/BufferedContext.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/java2d/pipe/BufferedContext.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN; import java.lang.annotation.Native; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; /** * Base context class for managing state in a single-threaded rendering @@ -87,11 +89,11 @@ */ protected static BufferedContext currentContext; - private AccelSurface validatedSrcData; - private AccelSurface validatedDstData; - private Region validatedClip; - private Composite validatedComp; - private Paint validatedPaint; + private Reference<AccelSurface> validSrcDataRef = new WeakReference<>(null); + private Reference<AccelSurface> validDstDataRef = new WeakReference<>(null); + private Reference<Region> validClipRef = new WeakReference<>(null); + private Reference<Composite> validCompRef = new WeakReference<>(null); + private Reference<Paint> validPaintRef = new WeakReference<>(null); // renamed from isValidatedPaintAColor as part of a work around for 6764257 private boolean isValidatedPaintJustAColor; private int validatedRGB; @@ -127,9 +129,9 @@ int flags) { // assert rq.lock.isHeldByCurrentThread(); - BufferedContext d3dc = dstData.getContext(); - d3dc.validate(srcData, dstData, - clip, comp, xform, paint, sg2d, flags); + BufferedContext context = dstData.getContext(); + context.validate(srcData, dstData, + clip, comp, xform, paint, sg2d, flags); } /** @@ -200,13 +202,15 @@ updatePaint = true; isValidatedPaintJustAColor = true; } - } else if (validatedPaint != paint) { + } else if (validPaintRef.get() != paint) { updatePaint = true; // this should be set when we are switching from paint to color // in which case this condition will be true isValidatedPaintJustAColor = false; } + final AccelSurface validatedSrcData = validSrcDataRef.get(); + final AccelSurface validatedDstData = validDstDataRef.get(); if ((currentContext != this) || (srcData != validatedSrcData) || (dstData != validatedDstData)) @@ -228,11 +232,12 @@ setSurfaces(srcData, dstData); currentContext = this; - validatedSrcData = srcData; - validatedDstData = dstData; + validSrcDataRef = new WeakReference<>(srcData); + validDstDataRef = new WeakReference<>(dstData); } // validate clip + final Region validatedClip = validClipRef.get(); if ((clip != validatedClip) || updateClip) { if (clip != null) { if (updateClip || @@ -248,13 +253,13 @@ } else { resetClip(); } - validatedClip = clip; + validClipRef = new WeakReference<>(clip); } // validate composite (note that a change in the context flags // may require us to update the composite state, even if the // composite has not changed) - if ((comp != validatedComp) || (flags != validatedFlags)) { + if ((comp != validCompRef.get()) || (flags != validatedFlags)) { if (comp != null) { setComposite(comp, flags); } else { @@ -263,7 +268,7 @@ // the paint state is dependent on the composite state, so make // sure we update the color below updatePaint = true; - validatedComp = comp; + validCompRef = new WeakReference<>(comp); validatedFlags = flags; } @@ -297,7 +302,7 @@ } else { BufferedPaints.resetPaint(rq); } - validatedPaint = paint; + validPaintRef = new WeakReference<>(paint); } // mark dstData dirty @@ -315,9 +320,9 @@ * @see RenderQueue#lock * @see RenderQueue#unlock */ - public void invalidateSurfaces() { - validatedSrcData = null; - validatedDstData = null; + private void invalidateSurfaces() { + validSrcDataRef.clear(); + validDstDataRef.clear(); } private void setSurfaces(AccelSurface srcData, @@ -434,9 +439,9 @@ resetClip(); BufferedPaints.resetPaint(rq); invalidateSurfaces(); - validatedComp = null; - validatedClip = null; - validatedPaint = null; + validCompRef.clear(); + validClipRef.clear(); + validPaintRef.clear(); isValidatedPaintJustAColor = false; xformInUse = false; }
--- a/src/share/classes/sun/reflect/annotation/AnnotationType.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/reflect/annotation/AnnotationType.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,16 +118,22 @@ members = new HashMap<String, Method>(methods.length+1, 1.0f); for (Method method : methods) { - if (method.getParameterTypes().length != 0) - throw new IllegalArgumentException(method + " has params"); - String name = method.getName(); - Class<?> type = method.getReturnType(); - memberTypes.put(name, invocationHandlerReturnType(type)); - members.put(name, method); + if (Modifier.isPublic(method.getModifiers()) && + Modifier.isAbstract(method.getModifiers()) && + !method.isSynthetic()) { + if (method.getParameterTypes().length != 0) { + throw new IllegalArgumentException(method + " has params"); + } + String name = method.getName(); + Class<?> type = method.getReturnType(); + memberTypes.put(name, invocationHandlerReturnType(type)); + members.put(name, method); - Object defaultValue = method.getDefaultValue(); - if (defaultValue != null) - memberDefaults.put(name, defaultValue); + Object defaultValue = method.getDefaultValue(); + if (defaultValue != null) { + memberDefaults.put(name, defaultValue); + } + } } // Initialize retention, & inherited fields. Special treatment
--- a/src/share/classes/sun/security/jca/ProviderConfig.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/jca/ProviderConfig.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -255,6 +255,15 @@ disableLoad(); } return null; + } catch (ExceptionInInitializerError err) { + // unexpected exception thrown from static initialization block in provider + // (ex: insufficient permission to initialize provider class) + if (debug != null) { + debug.println("Error loading provider " + ProviderConfig.this); + err.printStackTrace(); + } + disableLoad(); + return null; } } });
--- a/src/share/classes/sun/security/krb5/Config.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/krb5/Config.java Thu Jan 12 06:59:38 2017 +0000 @@ -525,9 +525,9 @@ String previous = null; while ((line = br.readLine()) != null) { line = line.trim(); - if (line.startsWith("#") || line.isEmpty()) { + if (line.isEmpty() || line.startsWith("#") || line.startsWith(";")) { // ignore comments and blank line - // Comments start with #. + // Comments start with '#' or ';' continue; } // In practice, a subsection might look like:
--- a/src/share/classes/sun/security/krb5/KrbKdcRep.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/krb5/KrbKdcRep.java Thu Jan 12 06:59:38 2017 +0000 @@ -62,7 +62,8 @@ throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); } - for (int i = 1; i < 6; i++) { + // We allow KDC to return a non-forwardable ticket if request has -f + for (int i = 2; i < 6; i++) { if (req.reqBody.kdcOptions.get(i) != rep.encKDCRepPart.flags.get(i)) { if (Krb5.DEBUG) {
--- a/src/share/classes/sun/security/krb5/KrbTgsReq.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java Thu Jan 12 06:59:38 2017 +0000 @@ -150,19 +150,11 @@ ctime = KerberosTime.now(); // check if they are valid arguments. The optional fields - // should be consistent with settings in KDCOptions. - - // TODO: Is this necessary? If the TGT is not FORWARDABLE, - // you can still request for a FORWARDABLE ticket, just the - // KDC will give you a non-FORWARDABLE one. Even if you - // cannot use the ticket expected, it still contains info. - // This means there will be problem later. We already have - // flags check in KrbTgsRep. Of course, sometimes the KDC - // will not issue the ticket at all. + // should be consistent with settings in KDCOptions. if (options.get(KDCOptions.FORWARDABLE) && (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + options.set(KDCOptions.FORWARDABLE, false); } if (options.get(KDCOptions.FORWARDED)) { if (!(asCreds.flags.get(KDCOptions.FORWARDABLE)))
--- a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java Thu Jan 12 06:59:38 2017 +0000 @@ -58,6 +58,9 @@ // TODO: we do not support kerberos referral now throw new KrbException("Cross realm impersonation not supported"); } + if (!ccreds.isForwardable()) { + throw new KrbException("S4U2self needs a FORWARDABLE ticket"); + } KrbTgsReq req = new KrbTgsReq( ccreds, ccreds.getClient(), @@ -68,6 +71,9 @@ if (!creds.getClient().equals(client)) { throw new KrbException("S4U2self request not honored by KDC"); } + if (!creds.isForwardable()) { + throw new KrbException("S4U2self ticket must be FORWARDABLE"); + } return creds; }
--- a/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java Thu Jan 12 06:59:38 2017 +0000 @@ -228,29 +228,34 @@ // check native range first if ((minKeySize != -1) && (keySize < minKeySize)) { throw new InvalidAlgorithmParameterException(algorithm + - " key must be at least " + minKeySize + " bits"); + " key must be at least " + minKeySize + " bits. " + + "The specific key size " + keySize + " is not supported"); } if ((maxKeySize != -1) && (keySize > maxKeySize)) { throw new InvalidAlgorithmParameterException(algorithm + - " key must be at most " + maxKeySize + " bits"); + " key must be at most " + maxKeySize + " bits. " + + "The specific key size " + keySize + " is not supported"); } // check our own algorithm-specific limits also if (algorithm.equals("EC")) { if (keySize < 112) { - throw new InvalidAlgorithmParameterException - ("Key size must be at least 112 bit"); + throw new InvalidAlgorithmParameterException( + "EC key size must be at least 112 bit. " + + "The specific key size " + keySize + " is not supported"); } if (keySize > 2048) { // sanity check, nobody really wants keys this large - throw new InvalidAlgorithmParameterException - ("Key size must be at most 2048 bit"); + throw new InvalidAlgorithmParameterException( + "EC key size must be at most 2048 bit. " + + "The specific key size " + keySize + " is not supported"); } } else { // RSA, DH, DSA if (keySize < 512) { - throw new InvalidAlgorithmParameterException - ("Key size must be at least 512 bit"); + throw new InvalidAlgorithmParameterException(algorithm + + " key size must be at least 512 bit. " + + "The specific key size " + keySize + " is not supported"); } if (algorithm.equals("RSA")) { BigInteger tmpExponent = rsaPublicExponent; @@ -271,8 +276,10 @@ if (algorithm.equals("DH") && (params != null)) { // sanity check, nobody really wants keys this large if (keySize > 64 * 1024) { - throw new InvalidAlgorithmParameterException - ("Key size must be at most 65536 bit"); + throw new InvalidAlgorithmParameterException( + "DH key size must be at most 65536 bit. " + + "The specific key size " + + keySize + " is not supported"); } } else { // this restriction is in the spec for DSA @@ -282,7 +289,9 @@ ((keySize > 1024) || ((keySize & 0x3f) != 0))) { throw new InvalidAlgorithmParameterException(algorithm + " key must be multiples of 64 if less than 1024 bits" + - ", or 2048 bits, or 4096 bits"); + ", or 2048 bits, or 4096 bits. " + + "The specific key size " + + keySize + " is not supported"); } } }
--- a/src/share/classes/sun/security/pkcs11/P11KeyStore.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/pkcs11/P11KeyStore.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -752,6 +752,21 @@ } else { login(new PasswordCallbackHandler(password)); } + } catch(LoginException e) { + Throwable cause = e.getCause(); + if (cause instanceof PKCS11Exception) { + PKCS11Exception pe = (PKCS11Exception) cause; + if (pe.getErrorCode() == CKR_PIN_INCORRECT) { + // if password is wrong, the cause of the IOException + // should be an UnrecoverableKeyException + throw new IOException("load failed", + new UnrecoverableKeyException().initCause(e)); + } + } + throw new IOException("load failed", e); + } + + try { if (mapLabels() == true) { // CKA_LABELs are shared by multiple certs writeDisabled = true; @@ -759,7 +774,7 @@ if (debug != null) { dumpTokenMap(); } - } catch (LoginException | KeyStoreException | PKCS11Exception e) { + } catch (KeyStoreException | PKCS11Exception e) { throw new IOException("load failed", e); } }
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Thu Jan 12 06:59:38 2017 +0000 @@ -2051,7 +2051,7 @@ } if (!MessageDigest.isEqual(macData.getDigest(), macResult)) { - throw new SecurityException("Failed PKCS12" + + throw new UnrecoverableKeyException("Failed PKCS12" + " integrity checking"); } } catch (Exception e) {
--- a/src/share/classes/sun/security/ssl/CipherBox.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/CipherBox.java Thu Jan 12 06:59:38 2017 +0000 @@ -1044,40 +1044,6 @@ return nonce; } - /* - * Is this cipher available? - * - * This method can only be called by CipherSuite.BulkCipher.isAvailable() - * to test the availability of a cipher suites. Please DON'T use it in - * other places, otherwise, the behavior may be unexpected because we may - * initialize AEAD cipher improperly in the method. - */ - Boolean isAvailable() { - // We won't know whether a cipher for a particular key size is - // available until the cipher is successfully initialized. - // - // We do not initialize AEAD cipher in the constructor. Need to - // initialize the cipher to ensure that the AEAD mode for a - // particular key size is supported. - if (cipherType == AEAD_CIPHER) { - try { - Authenticator authenticator = - new Authenticator(protocolVersion); - byte[] nonce = authenticator.sequenceNumber(); - byte[] iv = Arrays.copyOf(fixedIv, - fixedIv.length + nonce.length); - System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length); - GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv); - - cipher.init(mode, key, spec, random); - } catch (Exception e) { - return Boolean.FALSE; - } - } // Otherwise, we have initialized the cipher in the constructor. - - return Boolean.TRUE; - } - /** * Sanity check the length of a fragment before decryption. *
--- a/src/share/classes/sun/security/ssl/CipherSuite.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/CipherSuite.java Thu Jan 12 06:59:38 2017 +0000 @@ -75,12 +75,6 @@ // minimum priority for default enabled CipherSuites final static int DEFAULT_SUITES_PRIORITY = 300; - // Flag indicating if CipherSuite availability can change dynamically. - // This is the case when we rely on a JCE cipher implementation that - // may not be available in the installed JCE providers. - // It is true because we might not have an ECC implementation. - final static boolean DYNAMIC_AVAILABILITY = true; - private final static boolean ALLOW_ECC = Debug.getBooleanProperty ("com.sun.net.ssl.enableECC", true); @@ -186,9 +180,6 @@ * Return whether this CipherSuite is available for use. A * CipherSuite may be unavailable even if it is supported * (i.e. allowed == true) if the required JCE cipher is not installed. - * In some configuration, this situation may change over time, call - * CipherSuiteList.clearAvailableCache() before this method to obtain - * the most current status. */ boolean isAvailable() { return allowed && keyExchange.isAvailable() && cipher.isAvailable(); @@ -404,10 +395,6 @@ */ final static class BulkCipher { - // Map BulkCipher -> Boolean(available) - private final static Map<BulkCipher,Boolean> availableCache = - new HashMap<>(8); - // descriptive name including key size, e.g. AES/128 final String description; @@ -451,6 +438,9 @@ // The secure random used to detect the cipher availability. private final static SecureRandom secureRandom; + // runtime availability + private final boolean isAvailable; + static { try { secureRandom = JsseJce.getSecureRandom(); @@ -475,6 +465,17 @@ this.expandedKeySize = expandedKeySize; this.exportable = true; + + // availability of this bulk cipher + // + // Currently all supported ciphers except AES are always available + // via the JSSE internal implementations. We also assume AES/128 of + // CBC mode is always available since it is shipped with the SunJCE + // provider. However, AES/256 is unavailable when the default JCE + // policy jurisdiction files are installed because of key length + // restrictions. + this.isAvailable = + allowed ? isUnlimited(keySize, transformation) : false; } BulkCipher(String transformation, CipherType cipherType, int keySize, @@ -491,6 +492,17 @@ this.expandedKeySize = keySize; this.exportable = false; + + // availability of this bulk cipher + // + // Currently all supported ciphers except AES are always available + // via the JSSE internal implementations. We also assume AES/128 of + // CBC mode is always available since it is shipped with the SunJCE + // provider. However, AES/256 is unavailable when the default JCE + // policy jurisdiction files are installed because of key length + // restrictions. + this.isAvailable = + allowed ? isUnlimited(keySize, transformation) : false; } /** @@ -508,84 +520,27 @@ /** * Test if this bulk cipher is available. For use by CipherSuite. - * - * Currently all supported ciphers except AES are always available - * via the JSSE internal implementations. We also assume AES/128 of - * CBC mode is always available since it is shipped with the SunJCE - * provider. However, AES/256 is unavailable when the default JCE - * policy jurisdiction files are installed because of key length - * restrictions, and AEAD is unavailable when the underlying providers - * do not support AEAD/GCM mode. */ boolean isAvailable() { - if (allowed == false) { - return false; - } - - if ((this == B_AES_256) || - (this.cipherType == CipherType.AEAD_CIPHER)) { - return isAvailable(this); - } - - // always available - return true; - } - - // for use by CipherSuiteList.clearAvailableCache(); - static synchronized void clearAvailableCache() { - if (DYNAMIC_AVAILABILITY) { - availableCache.clear(); - } + return this.isAvailable; } - private static synchronized boolean isAvailable(BulkCipher cipher) { - Boolean b = availableCache.get(cipher); - if (b == null) { - int keySizeInBits = cipher.keySize * 8; - if (keySizeInBits > 128) { // need the JCE unlimited - // strength jurisdiction policy - try { - if (Cipher.getMaxAllowedKeyLength( - cipher.transformation) < keySizeInBits) { - b = Boolean.FALSE; - } - } catch (Exception e) { - b = Boolean.FALSE; - } - } + private static boolean isUnlimited(int keySize, String transformation) { + int keySizeInBits = keySize * 8; + if (keySizeInBits > 128) { // need the JCE unlimited + // strength jurisdiction policy + try { + if (Cipher.getMaxAllowedKeyLength( + transformation) < keySizeInBits) { - if (b == null) { - b = Boolean.FALSE; // may be reset to TRUE if - // the cipher is available - CipherBox temporary = null; - try { - SecretKey key = new SecretKeySpec( - new byte[cipher.expandedKeySize], - cipher.algorithm); - IvParameterSpec iv; - if (cipher.cipherType == CipherType.AEAD_CIPHER) { - iv = new IvParameterSpec( - new byte[cipher.fixedIvSize]); - } else { - iv = new IvParameterSpec(new byte[cipher.ivSize]); - } - temporary = cipher.newCipher( - ProtocolVersion.DEFAULT, - key, iv, secureRandom, true); - b = temporary.isAvailable(); - } catch (NoSuchAlgorithmException e) { - // not available - } finally { - if (temporary != null) { - temporary.dispose(); - } + return false; } + } catch (Exception e) { + return false; } - - availableCache.put(cipher, b); } - return b.booleanValue(); + return true; } @Override
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,24 +74,12 @@ throw new IllegalArgumentException("CipherSuites may not be null"); } cipherSuites = new ArrayList<CipherSuite>(names.length); - // refresh available cache once if a CipherSuite is not available - // (maybe new JCE providers have been installed) - boolean refreshed = false; for (int i = 0; i < names.length; i++) { String suiteName = names[i]; CipherSuite suite = CipherSuite.valueOf(suiteName); if (suite.isAvailable() == false) { - if (refreshed == false) { - // clear the cache so that the isAvailable() call below - // does a full check - clearAvailableCache(); - refreshed = true; - } - // still missing? - if (suite.isAvailable() == false) { - throw new IllegalArgumentException("Cannot support " - + suiteName + " with currently installed providers"); - } + throw new IllegalArgumentException("Cannot support " + + suiteName + " with currently installed providers"); } cipherSuites.add(suite); } @@ -195,16 +183,4 @@ } s.putBytes16(suiteBytes); } - - /** - * Clear cache of available ciphersuites. If we support all ciphers - * internally, there is no need to clear the cache and calling this - * method has no effect. - */ - static synchronized void clearAvailableCache() { - if (CipherSuite.DYNAMIC_AVAILABILITY) { - CipherSuite.BulkCipher.clearAvailableCache(); - JsseJce.clearEcAvailable(); - } - } }
--- a/src/share/classes/sun/security/ssl/JsseJce.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/JsseJce.java Thu Jan 12 06:59:38 2017 +0000 @@ -55,11 +55,6 @@ private final static ProviderList fipsProviderList; - // Flag indicating whether EC crypto is available. - // If null, then we have not checked yet. - // If yes, then all the EC based crypto we need is available. - private static Boolean ecAvailable; - // Flag indicating whether Kerberos crypto is available. // If true, then all the Kerberos-based crypto we need is available. private final static boolean kerberosAvailable; @@ -195,24 +190,8 @@ // no instantiation of this class } - synchronized static boolean isEcAvailable() { - if (ecAvailable == null) { - try { - JsseJce.getSignature(SIGNATURE_ECDSA); - JsseJce.getSignature(SIGNATURE_RAWECDSA); - JsseJce.getKeyAgreement("ECDH"); - JsseJce.getKeyFactory("EC"); - JsseJce.getKeyPairGenerator("EC"); - ecAvailable = true; - } catch (Exception e) { - ecAvailable = false; - } - } - return ecAvailable; - } - - synchronized static void clearEcAvailable() { - ecAvailable = null; + static boolean isEcAvailable() { + return EcAvailability.isAvailable; } static boolean isKerberosAvailable() { @@ -414,4 +393,27 @@ } } + + // lazy initialization holder class idiom for static default parameters + // + // See Effective Java Second Edition: Item 71. + private static class EcAvailability { + // Is EC crypto available? + private final static boolean isAvailable; + + static { + boolean mediator = true; + try { + JsseJce.getSignature(SIGNATURE_ECDSA); + JsseJce.getSignature(SIGNATURE_RAWECDSA); + JsseJce.getKeyAgreement("ECDH"); + JsseJce.getKeyFactory("EC"); + JsseJce.getKeyPairGenerator("EC"); + } catch (Exception e) { + mediator = false; + } + + isAvailable = mediator; + } + } }
--- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Thu Jan 12 06:59:38 2017 +0000 @@ -90,6 +90,30 @@ } /* + * Retrieving the cipher's provider name for the debug purposes + * can throw an exception by itself. + */ + private static String safeProviderName(Cipher cipher) { + try { + return cipher.getProvider().toString(); + } catch (Exception e) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Retrieving The Cipher provider name" + + " caused exception " + e.getMessage()); + } + } + try { + return cipher.toString() + " (provider name not available)"; + } catch (Exception e) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Retrieving The Cipher name" + + " caused exception " + e.getMessage()); + } + } + return "(cipher/provider names not available)"; + } + + /* * Server gets the PKCS #1 (block format 02) data, decrypts * it with its private key. */ @@ -130,15 +154,19 @@ cipher.getProvider().getName()); } catch (InvalidKeyException | UnsupportedOperationException iue) { if (debug != null && Debug.isOn("handshake")) { - System.out.println("The Cipher provider " + - cipher.getProvider().getName() + - " caused exception: " + iue.getMessage()); + System.out.println("The Cipher provider " + + safeProviderName(cipher) + + " caused exception: " + iue.getMessage()); } needFailover = true; } if (needFailover) { + // The cipher might be spoiled by unsuccessful call to init(), + // so request a fresh instance + cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); + // Use DECRYPT_MODE and dispose the previous initialization. cipher.init(Cipher.DECRYPT_MODE, privateKey); boolean failed = false;
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,16 +52,6 @@ private X509TrustManager trustManager; private SecureRandom secureRandom; - // supported and default protocols - private ProtocolList defaultServerProtocolList; - private ProtocolList defaultClientProtocolList; - private ProtocolList supportedProtocolList; - - // supported and default cipher suites - private CipherSuiteList defaultServerCipherSuiteList; - private CipherSuiteList defaultClientCipherSuiteList; - private CipherSuiteList supportedCipherSuiteList; - SSLContextImpl() { ephemeralKeyManager = new EphemeralKeyManager(); clientCache = new SSLSessionContextImpl(); @@ -191,6 +181,8 @@ } return new SSLServerSocketFactoryImpl(this); } + abstract SSLEngine createSSLEngineImpl(); + abstract SSLEngine createSSLEngineImpl(String host, int port); @Override protected SSLEngine engineCreateSSLEngine() { @@ -198,7 +190,7 @@ throw new IllegalStateException( "SSLContextImpl is not initialized"); } - return new SSLEngineImpl(this); + return createSSLEngineImpl(); } @Override @@ -207,7 +199,7 @@ throw new IllegalStateException( "SSLContextImpl is not initialized"); } - return new SSLEngineImpl(this, host, port); + return createSSLEngineImpl(host, port); } @Override @@ -236,78 +228,35 @@ return ephemeralKeyManager; } - abstract SSLParameters getDefaultServerSSLParams(); - abstract SSLParameters getDefaultClientSSLParams(); - abstract SSLParameters getSupportedSSLParams(); // Get supported ProtocolList. - ProtocolList getSuportedProtocolList() { - if (supportedProtocolList == null) { - supportedProtocolList = - new ProtocolList(getSupportedSSLParams().getProtocols()); - } + abstract ProtocolList getSuportedProtocolList(); + + // Get default ProtocolList for server mode. + abstract ProtocolList getServerDefaultProtocolList(); + + // Get default ProtocolList for client mode. + abstract ProtocolList getClientDefaultProtocolList(); - return supportedProtocolList; - } + // Get supported CipherSuiteList. + abstract CipherSuiteList getSupportedCipherSuiteList(); + + // Get default CipherSuiteList for server mode. + abstract CipherSuiteList getServerDefaultCipherSuiteList(); + + // Get default CipherSuiteList for client mode. + abstract CipherSuiteList getClientDefaultCipherSuiteList(); // Get default ProtocolList. ProtocolList getDefaultProtocolList(boolean roleIsServer) { - if (roleIsServer) { - if (defaultServerProtocolList == null) { - defaultServerProtocolList = new ProtocolList( - getDefaultServerSSLParams().getProtocols()); - } - - return defaultServerProtocolList; - } else { - if (defaultClientProtocolList == null) { - defaultClientProtocolList = new ProtocolList( - getDefaultClientSSLParams().getProtocols()); - } - - return defaultClientProtocolList; - } - } - - // Get supported CipherSuiteList. - CipherSuiteList getSupportedCipherSuiteList() { - // The maintenance of cipher suites needs to be synchronized. - synchronized (this) { - // Clear cache of available ciphersuites. - clearAvailableCache(); - - if (supportedCipherSuiteList == null) { - supportedCipherSuiteList = getApplicableCipherSuiteList( - getSuportedProtocolList(), false); - } - - return supportedCipherSuiteList; - } + return roleIsServer ? getServerDefaultProtocolList() + : getClientDefaultProtocolList(); } // Get default CipherSuiteList. CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) { - // The maintenance of cipher suites needs to be synchronized. - synchronized (this) { - // Clear cache of available ciphersuites. - clearAvailableCache(); - - if (roleIsServer) { - if (defaultServerCipherSuiteList == null) { - defaultServerCipherSuiteList = getApplicableCipherSuiteList( - getDefaultProtocolList(true), true); - } - - return defaultServerCipherSuiteList; - } else { - if (defaultClientCipherSuiteList == null) { - defaultClientCipherSuiteList = getApplicableCipherSuiteList( - getDefaultProtocolList(false), true); - } - - return defaultClientCipherSuiteList; - } - } + return roleIsServer ? getServerDefaultCipherSuiteList() + : getClientDefaultCipherSuiteList(); } /** @@ -315,16 +264,24 @@ * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() */ boolean isDefaultProtocolList(ProtocolList protocols) { - return (protocols == defaultServerProtocolList) || - (protocols == defaultClientProtocolList); + return (protocols == getServerDefaultProtocolList()) || + (protocols == getClientDefaultProtocolList()); } + /** + * Return whether a protocol list is the original default enabled + * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() + */ + boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) { + return (cipherSuites == getServerDefaultCipherSuiteList()) || + (cipherSuites == getClientDefaultCipherSuiteList()); + } /* * Return the list of all available CipherSuites with a priority of * minPriority or above. */ - private CipherSuiteList getApplicableCipherSuiteList( + private static CipherSuiteList getApplicableCipherSuiteList( ProtocolList protocols, boolean onlyEnabled) { int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY; @@ -370,22 +327,20 @@ return new CipherSuiteList(suites); } - /** - * Clear cache of available ciphersuites. If we support all ciphers - * internally, there is no need to clear the cache and calling this - * method has no effect. - * - * Note that every call to clearAvailableCache() and the maintenance of - * cipher suites need to be synchronized with this instance. - */ - private void clearAvailableCache() { - if (CipherSuite.DYNAMIC_AVAILABILITY) { - supportedCipherSuiteList = null; - defaultServerCipherSuiteList = null; - defaultClientCipherSuiteList = null; - CipherSuite.BulkCipher.clearAvailableCache(); - JsseJce.clearEcAvailable(); + private static String[] getAvailableProtocols( + ProtocolVersion[] protocolCandidates) { + + List<String> availableProtocols = Collections.<String>emptyList(); + if (protocolCandidates != null && protocolCandidates.length != 0) { + availableProtocols = new ArrayList<>(protocolCandidates.length); + for (ProtocolVersion p : protocolCandidates) { + if (ProtocolVersion.availableProtocols.contains(p)) { + availableProtocols.add(p.name); + } + } } + + return availableProtocols.toArray(new String[0]); } /* @@ -418,39 +373,37 @@ */ /* - * The base abstract SSLContext implementation. + * The base abstract SSLContext implementation for the Transport Layer + * Security (TLS) protocols. * * This abstract class encapsulates supported and the default server - * SSL parameters. + * SSL/TLS parameters. * * @see SSLContext */ - private abstract static class AbstractSSLContext extends SSLContextImpl { - // parameters - private static final SSLParameters defaultServerSSLParams; - private static final SSLParameters supportedSSLParams; + private abstract static class AbstractTLSContext extends SSLContextImpl { + private static final ProtocolList supportedProtocolList; + private static final ProtocolList serverDefaultProtocolList; + + private static final CipherSuiteList supportedCipherSuiteList; + private static final CipherSuiteList serverDefaultCipherSuiteList; static { - // supported SSL parameters - supportedSSLParams = new SSLParameters(); - - // candidates for available protocols - ProtocolVersion[] candidates; - if (SunJSSE.isFIPS()) { - supportedSSLParams.setProtocols(new String[] { + supportedProtocolList = new ProtocolList(new String[] { ProtocolVersion.TLS10.name, ProtocolVersion.TLS11.name, ProtocolVersion.TLS12.name }); - candidates = new ProtocolVersion[] { + serverDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.TLS10, ProtocolVersion.TLS11, ProtocolVersion.TLS12 - }; + })); } else { - supportedSSLParams.setProtocols(new String[] { + supportedProtocolList = new ProtocolList(new String[] { ProtocolVersion.SSL20Hello.name, ProtocolVersion.SSL30.name, ProtocolVersion.TLS10.name, @@ -458,44 +411,50 @@ ProtocolVersion.TLS12.name }); - candidates = new ProtocolVersion[] { + serverDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.SSL20Hello, ProtocolVersion.SSL30, ProtocolVersion.TLS10, ProtocolVersion.TLS11, ProtocolVersion.TLS12 - }; + })); } - defaultServerSSLParams = new SSLParameters(); - defaultServerSSLParams.setProtocols( - getAvailableProtocols(candidates).toArray(new String[0])); + supportedCipherSuiteList = getApplicableCipherSuiteList( + supportedProtocolList, false); // all supported + serverDefaultCipherSuiteList = getApplicableCipherSuiteList( + serverDefaultProtocolList, true); // enabled only } @Override - SSLParameters getDefaultServerSSLParams() { - return defaultServerSSLParams; + ProtocolList getSuportedProtocolList() { + return supportedProtocolList; } @Override - SSLParameters getSupportedSSLParams() { - return supportedSSLParams; + CipherSuiteList getSupportedCipherSuiteList() { + return supportedCipherSuiteList; + } + + @Override + ProtocolList getServerDefaultProtocolList() { + return serverDefaultProtocolList; } - static List<String> getAvailableProtocols( - ProtocolVersion[] protocolCandidates) { + @Override + CipherSuiteList getServerDefaultCipherSuiteList() { + return serverDefaultCipherSuiteList; + } - List<String> availableProtocols = Collections.<String>emptyList(); - if (protocolCandidates != null && protocolCandidates.length != 0) { - availableProtocols = new ArrayList<>(protocolCandidates.length); - for (ProtocolVersion p : protocolCandidates) { - if (ProtocolVersion.availableProtocols.contains(p)) { - availableProtocols.add(p.name); - } - } - } + @Override + SSLEngine createSSLEngineImpl() { + return new SSLEngineImpl(this); + } - return availableProtocols; + @Override + SSLEngine createSSLEngineImpl(String host, int port) { + return new SSLEngineImpl(this, host, port); } } @@ -504,31 +463,36 @@ * * @see SSLContext */ - public static final class TLS10Context extends AbstractSSLContext { - private static final SSLParameters defaultClientSSLParams; + public static final class TLS10Context extends AbstractTLSContext { + private static final ProtocolList clientDefaultProtocolList; + private static final CipherSuiteList clientDefaultCipherSuiteList; static { - // candidates for available protocols - ProtocolVersion[] candidates; if (SunJSSE.isFIPS()) { - candidates = new ProtocolVersion[] { + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.TLS10 - }; + })); } else { - candidates = new ProtocolVersion[] { + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.SSL30, ProtocolVersion.TLS10 - }; + })); } - defaultClientSSLParams = new SSLParameters(); - defaultClientSSLParams.setProtocols( - getAvailableProtocols(candidates).toArray(new String[0])); + clientDefaultCipherSuiteList = getApplicableCipherSuiteList( + clientDefaultProtocolList, true); // enabled only } @Override - SSLParameters getDefaultClientSSLParams() { - return defaultClientSSLParams; + ProtocolList getClientDefaultProtocolList() { + return clientDefaultProtocolList; + } + + @Override + CipherSuiteList getClientDefaultCipherSuiteList() { + return clientDefaultCipherSuiteList; } } @@ -537,33 +501,38 @@ * * @see SSLContext */ - public static final class TLS11Context extends AbstractSSLContext { - private static final SSLParameters defaultClientSSLParams; + public static final class TLS11Context extends AbstractTLSContext { + private static final ProtocolList clientDefaultProtocolList; + private static final CipherSuiteList clientDefaultCipherSuiteList; static { - // candidates for available protocols - ProtocolVersion[] candidates; if (SunJSSE.isFIPS()) { - candidates = new ProtocolVersion[] { + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.TLS10, ProtocolVersion.TLS11 - }; + })); } else { - candidates = new ProtocolVersion[] { + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.SSL30, ProtocolVersion.TLS10, ProtocolVersion.TLS11 - }; + })); } - defaultClientSSLParams = new SSLParameters(); - defaultClientSSLParams.setProtocols( - getAvailableProtocols(candidates).toArray(new String[0])); + clientDefaultCipherSuiteList = getApplicableCipherSuiteList( + clientDefaultProtocolList, true); // enabled only } @Override - SSLParameters getDefaultClientSSLParams() { - return defaultClientSSLParams; + ProtocolList getClientDefaultProtocolList() { + return clientDefaultProtocolList; + } + + @Override + CipherSuiteList getClientDefaultCipherSuiteList() { + return clientDefaultCipherSuiteList; } } @@ -572,35 +541,101 @@ * * @see SSLContext */ - public static final class TLS12Context extends AbstractSSLContext { - private static final SSLParameters defaultClientSSLParams; + public static final class TLS12Context extends AbstractTLSContext { + private static final ProtocolList clientDefaultProtocolList; + private static final CipherSuiteList clientDefaultCipherSuiteList; static { - // candidates for available protocols - ProtocolVersion[] candidates; if (SunJSSE.isFIPS()) { - candidates = new ProtocolVersion[] { + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.TLS10, ProtocolVersion.TLS11, ProtocolVersion.TLS12 - }; + })); } else { - candidates = new ProtocolVersion[] { + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(new ProtocolVersion[] { ProtocolVersion.SSL30, ProtocolVersion.TLS10, ProtocolVersion.TLS11, ProtocolVersion.TLS12 - }; + })); } - defaultClientSSLParams = new SSLParameters(); - defaultClientSSLParams.setProtocols( - getAvailableProtocols(candidates).toArray(new String[0])); + clientDefaultCipherSuiteList = getApplicableCipherSuiteList( + clientDefaultProtocolList, true); // enabled only + } + + @Override + ProtocolList getClientDefaultProtocolList() { + return clientDefaultProtocolList; } @Override - SSLParameters getDefaultClientSSLParams() { - return defaultClientSSLParams; + CipherSuiteList getClientDefaultCipherSuiteList() { + return clientDefaultCipherSuiteList; + } + } + + /* + * The interface for the customized SSL/(D)TLS SSLContext. + * + * @see SSLContext + */ + private static class CustomizedSSLProtocols { + private static final String PROPERTY_NAME = "jdk.tls.client.protocols"; + static IllegalArgumentException reservedException = null; + static ArrayList<ProtocolVersion> + customizedProtocols = new ArrayList<>(); + + // Don't want a java.lang.LinkageError for illegal system property. + // + // Please don't throw exception in this static block. Otherwise, + // java.lang.LinkageError may be thrown during the instantiation of + // the provider service. Instead, please handle the initialization + // exception in the caller's constructor. + static { + String property = AccessController.doPrivileged( + new GetPropertyAction(PROPERTY_NAME)); + if (property != null && property.length() != 0) { + // remove double quote marks from beginning/end of the property + if (property.length() > 1 && property.charAt(0) == '"' && + property.charAt(property.length() - 1) == '"') { + property = property.substring(1, property.length() - 1); + } + } + + if (property != null && property.length() != 0) { + String[] protocols = property.split(","); + for (int i = 0; i < protocols.length; i++) { + protocols[i] = protocols[i].trim(); + // Is it a supported protocol name? + try { + ProtocolVersion pro = + ProtocolVersion.valueOf(protocols[i]); + + if (SunJSSE.isFIPS() && + ((pro.v == ProtocolVersion.SSL30.v) || + (pro.v == ProtocolVersion.SSL20Hello.v))) { + reservedException = new IllegalArgumentException( + PROPERTY_NAME + ": " + pro + + " is not FIPS compliant"); + + break; + } + + // ignore duplicated protocols + if (!customizedProtocols.contains(pro)) { + customizedProtocols.add(pro); + } + } catch (IllegalArgumentException iae) { + reservedException = new IllegalArgumentException( + PROPERTY_NAME + ": " + protocols[i] + + " is not a standard SSL protocol name", iae); + } + } + } } } @@ -609,9 +644,11 @@ * * @see SSLContext */ - private static class CustomizedSSLContext extends AbstractSSLContext { - private static final String PROPERTY_NAME = "jdk.tls.client.protocols"; - private static final SSLParameters defaultClientSSLParams; + private static class CustomizedTLSContext extends AbstractTLSContext { + + private static final ProtocolList clientDefaultProtocolList; + private static final CipherSuiteList clientDefaultCipherSuiteList; + private static IllegalArgumentException reservedException = null; // Don't want a java.lang.LinkageError for illegal system property. @@ -621,86 +658,65 @@ // the provider service. Instead, let's handle the initialization // exception in constructor. static { - // candidates for available protocols - ProtocolVersion[] candidates; - - String property = AccessController.doPrivileged( - new GetPropertyAction(PROPERTY_NAME)); - if (property == null || property.length() == 0) { - // the default enabled client TLS protocols - if (SunJSSE.isFIPS()) { - candidates = new ProtocolVersion[] { - ProtocolVersion.TLS10, - ProtocolVersion.TLS11, - ProtocolVersion.TLS12 - }; - } else { - candidates = new ProtocolVersion[] { - ProtocolVersion.SSL30, - ProtocolVersion.TLS10, - ProtocolVersion.TLS11, - ProtocolVersion.TLS12 - }; - } - } else { - // remove double quote marks from beginning/end of the property - if (property.length() > 1 && property.charAt(0) == '"' && - property.charAt(property.length() - 1) == '"') { - property = property.substring(1, property.length() - 1); + reservedException = CustomizedSSLProtocols.reservedException; + if (reservedException == null) { + ArrayList<ProtocolVersion> + customizedTLSProtocols = new ArrayList<>(); + for (ProtocolVersion protocol : + CustomizedSSLProtocols.customizedProtocols) { + customizedTLSProtocols.add(protocol); } - String[] protocols = null; - if (property != null && property.length() != 0) { - protocols = property.split(","); + // candidates for available protocols + ProtocolVersion[] candidates; + if (customizedTLSProtocols.isEmpty()) { + // Use the default enabled client protocols if no + // customized TLS protocols. + if (SunJSSE.isFIPS()) { + candidates = new ProtocolVersion[] { + ProtocolVersion.TLS10, + ProtocolVersion.TLS11, + ProtocolVersion.TLS12 + }; + } else { + candidates = new ProtocolVersion[] { + ProtocolVersion.SSL30, + ProtocolVersion.TLS10, + ProtocolVersion.TLS11, + ProtocolVersion.TLS12 + }; + } } else { - reservedException = new IllegalArgumentException( - "No protocol specified in " + - PROPERTY_NAME + " system property"); - protocols = new String[0]; + // Use the customized TLS protocols. + candidates = + new ProtocolVersion[customizedTLSProtocols.size()]; + candidates = customizedTLSProtocols.toArray(candidates); } - candidates = new ProtocolVersion[protocols.length]; - for (int i = 0; i < protocols.length; i++) { - protocols[i] = protocols[i].trim(); - // Is it a supported protocol name? - try { - candidates[i] = ProtocolVersion.valueOf(protocols[i]); - } catch (IllegalArgumentException iae) { - reservedException = new IllegalArgumentException( - PROPERTY_NAME + ": " + protocols[i] + - " is not a standard SSL/TLS protocol name", iae); - break; - } - } - - if ((reservedException == null) && SunJSSE.isFIPS()) { - for (ProtocolVersion protocolVersion : candidates) { - if (ProtocolVersion.SSL20Hello.v == protocolVersion.v || - ProtocolVersion.SSL30.v == protocolVersion.v) { - reservedException = new IllegalArgumentException( - PROPERTY_NAME + ": " + protocolVersion + - " is not FIPS compliant"); - } - } - } - } - - defaultClientSSLParams = new SSLParameters(); - if (reservedException == null) { - defaultClientSSLParams.setProtocols( - getAvailableProtocols(candidates).toArray(new String[0])); + clientDefaultProtocolList = new ProtocolList( + getAvailableProtocols(candidates)); + clientDefaultCipherSuiteList = getApplicableCipherSuiteList( + clientDefaultProtocolList, true); // enabled only + } else { + clientDefaultProtocolList = null; // unlikely to be used + clientDefaultCipherSuiteList = null; // unlikely to be used } } - protected CustomizedSSLContext() { + protected CustomizedTLSContext() { if (reservedException != null) { throw reservedException; } } @Override - SSLParameters getDefaultClientSSLParams() { - return defaultClientSSLParams; + ProtocolList getClientDefaultProtocolList() { + return clientDefaultProtocolList; + } + + @Override + CipherSuiteList getClientDefaultCipherSuiteList() { + return clientDefaultCipherSuiteList; } } @@ -709,75 +725,57 @@ * * @see SSLContext */ - public static final class TLSContext extends CustomizedSSLContext { + public static final class TLSContext extends CustomizedTLSContext { // use the default constructor and methods } - /* - * The SSLContext implementation for default "Default" algorithm - * - * @see SSLContext - */ - public static final class DefaultSSLContext extends CustomizedSSLContext { + // lazy initialization holder class idiom for static default parameters + // + // See Effective Java Second Edition: Item 71. + private static final class DefaultManagersHolder { private static final String NONE = "NONE"; private static final String P11KEYSTORE = "PKCS11"; - private static volatile SSLContextImpl defaultImpl; + private static final TrustManager[] trustManagers; + private static final KeyManager[] keyManagers; - private static TrustManager[] defaultTrustManagers; - private static KeyManager[] defaultKeyManagers; + static Exception reservedException = null; - public DefaultSSLContext() throws Exception { + static { + TrustManager[] tmMediator; try { - super.engineInit(getDefaultKeyManager(), - getDefaultTrustManager(), null); + tmMediator = getTrustManagers(); } catch (Exception e) { - if (debug != null && Debug.isOn("defaultctx")) { - System.out.println("default context init failed: " + e); + reservedException = e; + tmMediator = new TrustManager[0]; + } + trustManagers = tmMediator; + + if (reservedException == null) { + KeyManager[] kmMediator; + try { + kmMediator = getKeyManagers(); + } catch (Exception e) { + reservedException = e; + kmMediator = new KeyManager[0]; } - throw e; - } - - if (defaultImpl == null) { - defaultImpl = this; + keyManagers = kmMediator; + } else { + keyManagers = new KeyManager[0]; } } - @Override - protected void engineInit(KeyManager[] km, TrustManager[] tm, - SecureRandom sr) throws KeyManagementException { - throw new KeyManagementException - ("Default SSLContext is initialized automatically"); - } - - static synchronized SSLContextImpl getDefaultImpl() throws Exception { - if (defaultImpl == null) { - new DefaultSSLContext(); - } - return defaultImpl; - } - - private static synchronized TrustManager[] getDefaultTrustManager() - throws Exception { - if (defaultTrustManagers != null) { - return defaultTrustManagers; - } - + private static TrustManager[] getTrustManagers() throws Exception { KeyStore ks = TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx"); TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); - defaultTrustManagers = tmf.getTrustManagers(); - return defaultTrustManagers; + return tmf.getTrustManagers(); } - private static synchronized KeyManager[] getDefaultKeyManager() - throws Exception { - if (defaultKeyManagers != null) { - return defaultKeyManagers; - } + private static KeyManager[] getKeyManagers() throws Exception { final Map<String,String> props = new HashMap<>(); AccessController.doPrivileged( @@ -874,11 +872,75 @@ kmf.init(ks, passwd); } - defaultKeyManagers = kmf.getKeyManagers(); - return defaultKeyManagers; + return kmf.getKeyManagers(); + } + } + + // lazy initialization holder class idiom for static default parameters + // + // See Effective Java Second Edition: Item 71. + private static final class DefaultSSLContextHolder { + + private static final SSLContextImpl sslContext; + static Exception reservedException = null; + + static { + SSLContextImpl mediator = null; + if (DefaultManagersHolder.reservedException != null) { + reservedException = DefaultManagersHolder.reservedException; + } else { + try { + mediator = new DefaultSSLContext(); + } catch (Exception e) { + reservedException = e; + } + } + + sslContext = mediator; } } + /* + * The SSLContext implementation for default "Default" algorithm + * + * @see SSLContext + */ + public static final class DefaultSSLContext extends CustomizedTLSContext { + + // public constructor for SSLContext.getInstance("Default") + public DefaultSSLContext() throws Exception { + if (DefaultManagersHolder.reservedException != null) { + throw DefaultManagersHolder.reservedException; + } + + try { + super.engineInit(DefaultManagersHolder.keyManagers, + DefaultManagersHolder.trustManagers, null); + } catch (Exception e) { + if (debug != null && Debug.isOn("defaultctx")) { + System.out.println("default context init failed: " + e); + } + throw e; + } + } + + @Override + protected void engineInit(KeyManager[] km, TrustManager[] tm, + SecureRandom sr) throws KeyManagementException { + throw new KeyManagementException + ("Default SSLContext is initialized automatically"); + } + + static SSLContextImpl getDefaultImpl() throws Exception { + if (DefaultSSLContextHolder.reservedException != null) { + throw DefaultSSLContextHolder.reservedException; + } + + return DefaultSSLContextHolder.sslContext; + } + } + + }
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java Thu Jan 12 06:59:38 2017 +0000 @@ -137,8 +137,10 @@ customizedDHKeySize = Integer.parseUnsignedInt(property); if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) { throw new IllegalArgumentException( - "Customized DH key size should be positive integer " + - "between 1024 and 2048 bits, inclusive"); + "Unsupported customized DH key size: " + + customizedDHKeySize + ". " + + "The key size can only range from 1024" + + " to 2048 (inclusive)"); } } catch (NumberFormatException nfe) { throw new IllegalArgumentException(
--- a/src/share/classes/sun/tools/native2ascii/Main.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/classes/sun/tools/native2ascii/Main.java Thu Jan 12 06:59:38 2017 +0000 @@ -71,11 +71,8 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; -import java.nio.file.Files; import java.io.UnsupportedEncodingException; import java.nio.charset.UnsupportedCharsetException; -import sun.tools.native2ascii.A2NFilter; -import sun.tools.native2ascii.N2AFilter; /** * Main program of the native2ascii @@ -94,7 +91,7 @@ /** * Run the converter */ - public synchronized boolean convert(String argv[]){ + public synchronized boolean convert(String argv[]) { List<String> v = new ArrayList<>(2); File outputFile = null; boolean createOutputFile = false; @@ -102,14 +99,14 @@ // Parse arguments for (int i = 0; i < argv.length; i++) { if (argv[i].equals("-encoding")) { - if ((i + 1) < argv.length){ + if ((i + 1) < argv.length) { encodingString = argv[++i]; } else { error(getMsg("err.bad.arg")); usage(); return false; } - } else if (argv[i].equals("-reverse")){ + } else if (argv[i].equals("-reverse")) { reverse = true; } else { if (v.size() > 1) { @@ -119,15 +116,18 @@ v.add(argv[i]); } } - if (encodingString == null) - defaultEncoding = Charset.defaultCharset().name(); + if (encodingString == null) { + defaultEncoding = Charset.defaultCharset().name(); + } char[] lineBreak = System.getProperty("line.separator").toCharArray(); + try { initializeConverter(); - if (v.size() == 1) + if (v.size() == 1) { inputFileName = v.get(0); + } if (v.size() == 2) { inputFileName = v.get(0); @@ -137,40 +137,38 @@ if (createOutputFile) { outputFile = new File(outputFileName); - if (outputFile.exists() && !outputFile.canWrite()) { - throw new Exception(formatMsg("err.cannot.write", outputFileName)); - } + if (outputFile.exists() && !outputFile.canWrite()) { + throw new Exception(formatMsg("err.cannot.write", outputFileName)); + } } - if (reverse){ - BufferedReader reader = getA2NInput(inputFileName); - Writer osw = getA2NOutput(outputFileName); - String line; - - while ((line = reader.readLine()) != null) { - osw.write(line.toCharArray()); - osw.write(lineBreak); - if (outputFileName == null) { // flush stdout - osw.flush(); + if (reverse) { + try (BufferedReader reader = getA2NInput(inputFileName); + Writer osw = getA2NOutput(outputFileName);) { + String line; + while ((line = reader.readLine()) != null) { + osw.write(line.toCharArray()); + osw.write(lineBreak); + if (outputFileName == null) { // flush stdout + osw.flush(); + } } } - reader.close(); // Close the stream. - osw.close(); } else { - //N2A - String inLine; - BufferedReader in = getN2AInput(inputFileName); - BufferedWriter out = getN2AOutput(outputFileName); - - while ((inLine = in.readLine()) != null) { - out.write(inLine.toCharArray()); - out.write(lineBreak); - if (outputFileName == null) { // flush stdout - out.flush(); + // N2A + try (BufferedReader in = getN2AInput(inputFileName); + BufferedWriter out = getN2AOutput(outputFileName);) { + String inLine; + while ((inLine = in.readLine()) != null) { + out.write(inLine.toCharArray()); + out.write(lineBreak); + if (outputFileName == null) { // flush stdout + out.flush(); + } } } - out.close(); } + // Since we are done rename temporary file to desired output file if (createOutputFile) { if (outputFile.exists()) { @@ -182,8 +180,7 @@ } tempFile.renameTo(outputFile); } - - } catch(Exception e){ + } catch (Exception e) { error(e.toString()); return false; }
--- a/src/share/lib/security/sunpkcs11-solaris.cfg Tue Nov 08 05:26:12 2016 +0000 +++ b/src/share/lib/security/sunpkcs11-solaris.cfg Thu Jan 12 06:59:38 2017 +0000 @@ -18,6 +18,7 @@ disabledMechanisms = { CKM_DSA_KEY_PAIR_GEN + SecureRandom # the following mechanisms are disabled due to performance issues # (Solaris bug 6337157) CKM_DSA_SHA1
--- a/src/solaris/bin/jexec.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/bin/jexec.c Thu Jan 12 06:59:38 2017 +0000 @@ -331,6 +331,7 @@ off_t end = start + xlen; if (end <= count) { + end -= 4; // make sure there are 4 bytes to read at start while (start < end) { off_t xhid = SH(buf, start); off_t xdlen = SH(buf, start + 2);
--- a/src/solaris/classes/sun/java2d/xr/XRRenderer.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/classes/sun/java2d/xr/XRRenderer.java Thu Jan 12 06:59:38 2017 +0000 @@ -28,6 +28,7 @@ import java.awt.*; import java.awt.geom.*; import sun.awt.SunToolkit; +import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; import sun.java2d.loops.*; import sun.java2d.pipe.Region; @@ -69,7 +70,12 @@ * destination context. */ private final void validateSurface(SunGraphics2D sg2d) { - XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData; + XRSurfaceData xrsd; + try { + xrsd = (XRSurfaceData) sg2d.surfaceData; + } catch (ClassCastException e) { + throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData); + } xrsd.validateAsDestination(sg2d, sg2d.getCompClip()); xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform, sg2d.paint, sg2d);
--- a/src/solaris/classes/sun/security/provider/NativePRNG.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/classes/sun/security/provider/NativePRNG.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ import java.io.*; import java.net.*; import java.security.*; +import java.util.Arrays; + import sun.security.util.Debug; /** @@ -334,7 +336,9 @@ private final static long MAX_BUFFER_TIME = 100; // size of the "next" buffer - private final static int BUFFER_SIZE = 32; + private static final int MAX_BUFFER_SIZE = 65536; + private static final int MIN_BUFFER_SIZE = 32; + private int bufferSize = 256; // Holder for the seedFile. Used if we ever add seed material. File seedFile; @@ -351,7 +355,7 @@ private volatile sun.security.provider.SecureRandom mixRandom; // buffer for next bits - private final byte[] nextBuffer; + private byte[] nextBuffer; // number of bytes left in nextBuffer private int buffered; @@ -359,6 +363,16 @@ // time we read the data into the nextBuffer private long lastRead; + // Count for the number of buffer size changes requests + // Positive value in increase size, negative to lower it. + private int change_buffer = 0; + + // Request limit to trigger an increase in nextBuffer size + private static final int REQ_LIMIT_INC = 1000; + + // Request limit to trigger a decrease in nextBuffer size + private static final int REQ_LIMIT_DEC = -100; + // mutex lock for nextBytes() private final Object LOCK_GET_BYTES = new Object(); @@ -373,7 +387,7 @@ this.seedFile = seedFile; seedIn = new FileInputStream(seedFile); nextIn = new FileInputStream(nextFile); - nextBuffer = new byte[BUFFER_SIZE]; + nextBuffer = new byte[bufferSize]; } // get the SHA1PRNG for mixing @@ -466,9 +480,47 @@ // if not, read new bytes private void ensureBufferValid() throws IOException { long time = System.currentTimeMillis(); - if ((buffered > 0) && (time - lastRead < MAX_BUFFER_TIME)) { - return; + int new_buffer_size = 0; + + // Check if buffer has bytes available that are not too old + if (buffered > 0) { + if (time - lastRead < MAX_BUFFER_TIME) { + return; + } else { + // byte is old, so subtract from counter to shrink buffer + change_buffer--; + } + } else { + // No bytes available, so add to count to increase buffer + change_buffer++; + } + + // If counter has it a limit, increase or decrease size + if (change_buffer > REQ_LIMIT_INC) { + new_buffer_size = nextBuffer.length * 2; + } else if (change_buffer < REQ_LIMIT_DEC) { + new_buffer_size = nextBuffer.length / 2; } + + // If buffer size is to be changed, replace nextBuffer. + if (new_buffer_size > 0) { + if (new_buffer_size <= MAX_BUFFER_SIZE && + new_buffer_size >= MIN_BUFFER_SIZE) { + nextBuffer = new byte[new_buffer_size]; + if (debug != null) { + debug.println("Buffer size changed to " + + new_buffer_size); + } + } else { + if (debug != null) { + debug.println("Buffer reached limit: " + + nextBuffer.length); + } + } + change_buffer = 0; + } + + // Load fresh random bytes into nextBuffer lastRead = time; readFully(nextIn, nextBuffer); buffered = nextBuffer.length; @@ -478,24 +530,40 @@ // read from "next" and XOR with bytes generated by the // mixing SHA1PRNG private void implNextBytes(byte[] data) { - synchronized (LOCK_GET_BYTES) { try { getMixRandom().engineNextBytes(data); - int len = data.length; + int data_len = data.length; int ofs = 0; - while (len > 0) { - ensureBufferValid(); - int bufferOfs = nextBuffer.length - buffered; - while ((len > 0) && (buffered > 0)) { - data[ofs++] ^= nextBuffer[bufferOfs++]; - len--; - buffered--; + int len; + int buf_pos; + int localofs; + byte[] localBuffer; + + while (data_len > 0) { + synchronized (LOCK_GET_BYTES) { + ensureBufferValid(); + buf_pos = nextBuffer.length - buffered; + if (data_len > buffered) { + len = buffered; + buffered = 0; + } else { + len = data_len; + buffered -= len; + } + localBuffer = Arrays.copyOfRange(nextBuffer, buf_pos, + buf_pos + len); } + localofs = 0; + while (len > localofs) { + data[ofs] ^= localBuffer[localofs]; + ofs++; + localofs++; + } + data_len -= len; } - } catch (IOException e) { + } catch (IOException e){ throw new ProviderException("nextBytes() failed", e); } - } + } } - } }
--- a/src/solaris/native/java/net/NetworkInterface.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/native/java/net/NetworkInterface.c Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * questions. */ - #include <errno.h> #include <strings.h> #if defined(_ALLBSD_SOURCE) && defined(__OpenBSD__) @@ -38,14 +37,14 @@ #include <net/if.h> #include <net/if_arp.h> -#ifdef __solaris__ +#if defined(__solaris__) #include <sys/dlpi.h> #include <fcntl.h> #include <stropts.h> #include <sys/sockio.h> #endif -#ifdef __linux__ +#if defined(__linux__) #include <sys/ioctl.h> #include <bits/ioctls.h> #include <sys/utsname.h> @@ -59,10 +58,6 @@ #include <sys/kinfo.h> #endif -#ifdef __linux__ -#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" -#endif - #if defined(_ALLBSD_SOURCE) #include <sys/param.h> #include <sys/ioctl.h> @@ -80,6 +75,10 @@ #include "jni_util.h" #include "net_util.h" +#if defined(__linux__) +#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" +#endif + typedef struct _netaddr { struct sockaddr *addr; struct sockaddr *brdcast; @@ -140,29 +139,32 @@ static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs); #endif -static netif *addif(JNIEnv *env, int sock, const char * if_name, netif *ifs, struct sockaddr* ifr_addrP, int family, short prefix); +static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs, + struct sockaddr *ifr_addrP, int family, short prefix); static void freeif(netif *ifs); static int openSocket(JNIEnv *env, int proto); static int openSocketWithFallback(JNIEnv *env, const char *ifname); -static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, struct sockaddr *brdcast_store); +static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, + struct sockaddr *brdcast_store); static short getSubnet(JNIEnv *env, int sock, const char *ifname); static int getIndex(int sock, const char *ifname); static int getFlags(int sock, const char *ifname, int *flags); -static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf); +static int getMacAddress(JNIEnv *env, int sock, const char *ifname, + const struct in_addr *addr, unsigned char *buf); static int getMTU(JNIEnv *env, int sock, const char *ifname); - -#ifdef __solaris__ -static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family); -static int getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf); +#if defined(__solaris__) +static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family); +static int getMacFromDevice(JNIEnv *env, const char *ifname, + unsigned char *retbuf); #ifndef SIOCGLIFHWADDR -#define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq) +#define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq) #endif #endif @@ -174,31 +176,36 @@ * Method: init * Signature: ()V */ -JNIEXPORT void JNICALL -Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) { - ni_class = (*env)->FindClass(env,"java/net/NetworkInterface"); +JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init + (JNIEnv *env, jclass cls) +{ + ni_class = (*env)->FindClass(env, "java/net/NetworkInterface"); CHECK_NULL(ni_class); ni_class = (*env)->NewGlobalRef(env, ni_class); CHECK_NULL(ni_class); - ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;"); + ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;"); CHECK_NULL(ni_nameID); ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I"); CHECK_NULL(ni_indexID); - ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;"); + ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", + "[Ljava/net/InetAddress;"); CHECK_NULL(ni_addrsID); - ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;"); + ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", + "[Ljava/net/InterfaceAddress;"); CHECK_NULL(ni_bindsID); - ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;"); + ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", + "Ljava/lang/String;"); CHECK_NULL(ni_descID); ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z"); CHECK_NULL(ni_virutalID); - ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;"); + ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", + "[Ljava/net/NetworkInterface;"); CHECK_NULL(ni_childsID); - ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;"); + ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", + "Ljava/net/NetworkInterface;"); CHECK_NULL(ni_parentID); ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V"); CHECK_NULL(ni_ctrID); - ni_iacls = (*env)->FindClass(env, "java/net/InetAddress"); CHECK_NULL(ni_iacls); ni_iacls = (*env)->NewGlobalRef(env, ni_iacls); @@ -221,24 +228,26 @@ CHECK_NULL(ni_ia6ctrID); ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V"); CHECK_NULL(ni_ibctrID); - ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;"); + ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", + "Ljava/net/InetAddress;"); CHECK_NULL(ni_ibaddressID); - ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;"); + ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", + "Ljava/net/Inet4Address;"); CHECK_NULL(ni_ib4broadcastID); ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S"); CHECK_NULL(ni_ib4maskID); - ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex", "I"); + ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex", + "I"); } - /* * Class: java_net_NetworkInterface * Method: getByName0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0 - (JNIEnv *env, jclass cls, jstring name) { - + (JNIEnv *env, jclass cls, jstring name) +{ netif *ifs, *curr; jboolean isCopy; const char* name_utf; @@ -256,9 +265,8 @@ freeif(ifs); return NULL; } - /* - * Search the list of interface based on name - */ + + // Search the list of interface based on name curr = ifs; while (curr != NULL) { if (strcmp(name_utf, curr->name) == 0) { @@ -267,27 +275,26 @@ curr = curr->next; } - /* if found create a NetworkInterface */ + // if found create a NetworkInterface if (curr != NULL) {; obj = createNetworkInterface(env, curr); } - /* release the UTF string and interface list */ + // release the UTF string and interface list (*env)->ReleaseStringUTFChars(env, name, name_utf); freeif(ifs); return obj; } - /* * Class: java_net_NetworkInterface * Method: getByIndex0 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0 - (JNIEnv *env, jclass cls, jint index) { - + (JNIEnv *env, jclass cls, jint index) +{ netif *ifs, *curr; jobject obj = NULL; @@ -300,9 +307,7 @@ return NULL; } - /* - * Search the list of interface based on index - */ + // Search the list of interface based on index curr = ifs; while (curr != NULL) { if (index == curr->index) { @@ -311,7 +316,7 @@ curr = curr->next; } - /* if found create a NetworkInterface */ + // if found create a NetworkInterface if (curr != NULL) {; obj = createNetworkInterface(env, curr); } @@ -326,8 +331,8 @@ * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 - (JNIEnv *env, jclass cls, jobject iaObj) { - + (JNIEnv *env, jclass cls, jobject iaObj) +{ netif *ifs, *curr; #ifdef AF_INET6 @@ -348,14 +353,13 @@ while (curr != NULL) { netaddr *addrP = curr->addr; - /* - * Iterate through each address on the interface - */ + // Iterate through each address on the interface while (addrP != NULL) { if (family == addrP->family) { if (family == AF_INET) { - int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); + int address1 = htonl( + ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); int address2 = getInetAddress_addr(env, iaObj); if (address1 == address2) { @@ -366,7 +370,8 @@ #ifdef AF_INET6 if (family == AF_INET6) { - jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr); + jbyte *bytes = (jbyte *)&( + ((struct sockaddr_in6*)addrP->addr)->sin6_addr); jbyte caddr[16]; int i; getInet6Address_ipaddress(env, iaObj, (char *)caddr); @@ -383,7 +388,6 @@ } } #endif - } if (match) { @@ -398,7 +402,7 @@ curr = curr->next; } - /* if found create a NetworkInterface */ + // if found create a NetworkInterface if (match) {; obj = createNetworkInterface(env, curr); } @@ -407,15 +411,14 @@ return obj; } - /* * Class: java_net_NetworkInterface * Method: getAll * Signature: ()[Ljava/net/NetworkInterface; */ JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll - (JNIEnv *env, jclass cls) { - + (JNIEnv *env, jclass cls) +{ netif *ifs, *curr; jobjectArray netIFArr; jint arr_index, ifCount; @@ -425,7 +428,7 @@ return NULL; } - /* count the interface */ + // count the interface ifCount = 0; curr = ifs; while (curr != NULL) { @@ -433,17 +436,15 @@ curr = curr->next; } - /* allocate a NetworkInterface array */ + // allocate a NetworkInterface array netIFArr = (*env)->NewObjectArray(env, ifCount, cls, NULL); if (netIFArr == NULL) { freeif(ifs); return NULL; } - /* - * Iterate through the interfaces, create a NetworkInterface instance - * for each array element and populate the object. - */ + // Iterate through the interfaces, create a NetworkInterface instance + // for each array element and populate the object. curr = ifs; arr_index = 0; while (curr != NULL) { @@ -455,7 +456,7 @@ return NULL; } - /* put the NetworkInterface into the array */ + // put the NetworkInterface into the array (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj); curr = curr->next; @@ -465,13 +466,14 @@ return netIFArr; } - /* * Class: java_net_NetworkInterface * Method: isUp0 * Signature: (Ljava/lang/String;I)Z */ -JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0(JNIEnv *env, jclass cls, jstring name, jint index) { +JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0 + (JNIEnv *env, jclass cls, jstring name, jint index) +{ int ret = getFlags0(env, name); return ((ret & IFF_UP) && (ret & IFF_RUNNING)) ? JNI_TRUE : JNI_FALSE; } @@ -481,7 +483,9 @@ * Method: isP2P0 * Signature: (Ljava/lang/String;I)Z */ -JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0(JNIEnv *env, jclass cls, jstring name, jint index) { +JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0 + (JNIEnv *env, jclass cls, jstring name, jint index) +{ int ret = getFlags0(env, name); return (ret & IFF_POINTOPOINT) ? JNI_TRUE : JNI_FALSE; } @@ -491,7 +495,9 @@ * Method: isLoopback0 * Signature: (Ljava/lang/String;I)Z */ -JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0(JNIEnv *env, jclass cls, jstring name, jint index) { +JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0 + (JNIEnv *env, jclass cls, jstring name, jint index) +{ int ret = getFlags0(env, name); return (ret & IFF_LOOPBACK) ? JNI_TRUE : JNI_FALSE; } @@ -501,7 +507,9 @@ * Method: supportsMulticast0 * Signature: (Ljava/lang/String;I)Z */ -JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0(JNIEnv *env, jclass cls, jstring name, jint index) { +JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0 + (JNIEnv *env, jclass cls, jstring name, jint index) +{ int ret = getFlags0(env, name); return (ret & IFF_MULTICAST) ? JNI_TRUE : JNI_FALSE; } @@ -511,7 +519,9 @@ * Method: getMacAddr0 * Signature: ([bLjava/lang/String;I)[b */ -JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) { +JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0 + (JNIEnv *env, jclass cls, jbyteArray addrArray, jstring name, jint index) +{ jint addr; jbyte caddr[4]; struct in_addr iaddr; @@ -533,7 +543,6 @@ return NULL; } - if (!IS_NULL(addrArray)) { (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr); addr = ((caddr[0]<<24) & 0xff000000); @@ -543,7 +552,7 @@ iaddr.s_addr = htonl(addr); len = getMacAddress(env, sock, name_utf, &iaddr, mac); } else { - len = getMacAddress(env, sock, name_utf,NULL, mac); + len = getMacAddress(env, sock, name_utf, NULL, mac); } if (len > 0) { ret = (*env)->NewByteArray(env, len); @@ -551,10 +560,10 @@ /* we may have memory to free at the end of this */ goto fexit; } - (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) (mac)); + (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *)(mac)); } fexit: - /* release the UTF string and interface list */ + // release the UTF string and interface list (*env)->ReleaseStringUTFChars(env, name, name_utf); close(sock); @@ -566,8 +575,9 @@ * Method: getMTU0 * Signature: ([bLjava/lang/String;I)I */ - -JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0(JNIEnv *env, jclass class, jstring name, jint index) { +JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0 + (JNIEnv *env, jclass cls, jstring name, jint index) +{ jboolean isCopy; int ret = -1; int sock; @@ -585,7 +595,7 @@ return ret; } - if ((sock =openSocketWithFallback(env, name_utf)) < 0) { + if ((sock = openSocketWithFallback(env, name_utf)) < 0) { (*env)->ReleaseStringUTFChars(env, name, name_utf); return JNI_FALSE; } @@ -628,19 +638,17 @@ (*env)->ReleaseStringUTFChars(env, name, name_utf); if (ret < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFFLAGS failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFFLAGS failed"); return -1; } return flags; } - - - /* - * Create a NetworkInterface object, populate the name and index, and - * populate the InetAddress array based on the IP addresses for this + * Creates a NetworkInterface object, populates the name, the index, and + * populates the InetAddress array based on the IP addresses for this * interface. */ jobject createNetworkInterface(JNIEnv *env, netif *ifs) { @@ -656,9 +664,7 @@ netif *childP; jobject tmp; - /* - * Create a NetworkInterface object and populate it - */ + // Create a NetworkInterface object and populate it netifObj = (*env)->NewObject(env, ni_class, ni_ctrID); CHECK_NULL_RETURN(netifObj, NULL); name = (*env)->NewStringUTF(env, ifs->name); @@ -666,11 +672,10 @@ (*env)->SetObjectField(env, netifObj, ni_nameID, name); (*env)->SetObjectField(env, netifObj, ni_descID, name); (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index); - (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE); + (*env)->SetBooleanField(env, netifObj, ni_virutalID, + ifs->virtual ? JNI_TRUE : JNI_FALSE); - /* - * Count the number of address on this interface - */ + //Count the number of address on this interface addr_count = 0; addrP = ifs->addr; while (addrP != NULL) { @@ -678,10 +683,8 @@ addrP = addrP->next; } - /* - * Create the array of InetAddresses - */ - addrArr = (*env)->NewObjectArray(env, addr_count, ni_iacls, NULL); + // Create the array of InetAddresses + addrArr = (*env)->NewObjectArray(env, addr_count, ni_iacls, NULL); if (addrArr == NULL) { return NULL; } @@ -700,7 +703,8 @@ if (addrP->family == AF_INET) { iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); if (iaObj) { - setInetAddress_addr(env, iaObj, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); + setInetAddress_addr(env, iaObj, htonl( + ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); } else { return NULL; } @@ -711,7 +715,8 @@ jobject ia2Obj = NULL; ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); if (ia2Obj) { - setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); + setInetAddress_addr(env, ia2Obj, htonl( + ((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj); } else { return NULL; @@ -729,7 +734,8 @@ int scope=0; iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); if (iaObj) { - int ret = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr)); + jboolean ret = setInet6Address_ipaddress(env, iaObj, + (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr)); if (ret == JNI_FALSE) { return NULL; } @@ -758,9 +764,7 @@ addrP = addrP->next; } - /* - * See if there is any virtual interface attached to this one. - */ + // See if there is any virtual interface attached to this one. child_count = 0; childP = ifs->childs; while (childP) { @@ -773,10 +777,7 @@ return NULL; } - /* - * Create the NetworkInterface instances for the sub-interfaces as - * well. - */ + // Create the NetworkInterface instances for the sub-interfaces as well. child_index = 0; childP = ifs->childs; while(childP) { @@ -792,7 +793,7 @@ (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr); (*env)->SetObjectField(env, netifObj, ni_childsID, childArr); - /* return the NetworkInterface */ + // return the NetworkInterface return netifObj; } @@ -803,10 +804,7 @@ netif *ifs; int sock; - /* - * Enumerate IPv4 addresses - */ - + // Enumerate IPv4 addresses sock = openSocket(env, AF_INET); if (sock < 0 && (*env)->ExceptionOccurred(env)) { return NULL; @@ -819,19 +817,16 @@ return NULL; } - /* return partial list if an exception occurs in the middle of process ???*/ + // return partial list if an exception occurs in the middle of process ??? - /* - * If IPv6 is available then enumerate IPv6 addresses. - */ + // If IPv6 is available then enumerate IPv6 addresses. #ifdef AF_INET6 - /* User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true, - * so we have to call ipv6_available() - */ + // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true, + // so we have to call ipv6_available() if (ipv6_available()) { - sock = openSocket(env, AF_INET6); + sock = openSocket(env, AF_INET6); if (sock < 0 && (*env)->ExceptionOccurred(env)) { freeif(ifs); return NULL; @@ -851,18 +846,18 @@ return ifs; } -#define CHECKED_MALLOC3(_pointer,_type,_size) \ - do{ \ - _pointer = (_type)malloc( _size ); \ +#define CHECKED_MALLOC3(_pointer, _type, _size) \ + do { \ + _pointer = (_type)malloc(_size); \ if (_pointer == NULL) { \ JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \ return ifs; /* return untouched list */ \ } \ - } while(0) + } while(0) /* - * Free an interface list (including any attached addresses) + * Frees an interface list (including any attached addresses) */ void freeif(netif *ifs) { netif *currif = ifs; @@ -874,24 +869,21 @@ netaddr *next = addrP->next; free(addrP); addrP = next; - } + } - /* - * Don't forget to free the sub-interfaces. - */ - if (currif->childs != NULL) { - freeif(currif->childs); - } + // Don't forget to free the sub-interfaces. + if (currif->childs != NULL) { + freeif(currif->childs); + } - ifs = currif->next; - free(currif); - currif = ifs; + ifs = currif->next; + free(currif); + currif = ifs; } } -netif *addif(JNIEnv *env, int sock, const char * if_name, - netif *ifs, struct sockaddr* ifr_addrP, int family, - short prefix) +netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs, + struct sockaddr *ifr_addrP, int family, short prefix) { netif *currif = ifs, *parent; netaddr *addrP; @@ -904,37 +896,34 @@ char name[IFNAMSIZ], vname[IFNAMSIZ]; #endif - char *name_colonP; + char *name_colonP; int mask; int isVirtual = 0; int addr_size; int flags = 0; - /* - * If the interface name is a logical interface then we - * remove the unit number so that we have the physical - * interface (eg: hme0:1 -> hme0). NetworkInterface - * currently doesn't have any concept of physical vs. - * logical interfaces. - */ + // If the interface name is a logical interface then we remove the unit + // number so that we have the physical interface (eg: hme0:1 -> hme0). + // NetworkInterface currently doesn't have any concept of physical vs. + // logical interfaces. strncpy(name, if_name, ifnam_size); name[ifnam_size - 1] = '\0'; *vname = 0; - /* - * Create and populate the netaddr node. If allocation fails - * return an un-updated list. - */ - /*Allocate for addr and brdcast at once*/ + // Create and populate the netaddr node. If allocation fails + // return an un-updated list. + + // Allocate for addr and brdcast at once #ifdef AF_INET6 - addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in) + : sizeof(struct sockaddr_in6); #else addr_size = sizeof(struct sockaddr_in); #endif - CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr)+2*addr_size); - addrP->addr = (struct sockaddr *)( (char *) addrP+sizeof(netaddr) ); + CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr) + 2 * addr_size); + addrP->addr = (struct sockaddr *)((char *)addrP + sizeof(netaddr)); memcpy(addrP->addr, ifr_addrP, addr_size); addrP->family = family; @@ -943,8 +932,9 @@ addrP->next = 0; if (family == AF_INET) { // Deal with broadcast addr & subnet mask - struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size); - addrP->brdcast = getBroadcast(env, sock, name, brdcast_to ); + struct sockaddr *brdcast_to = + (struct sockaddr *) ((char *)addrP + sizeof(netaddr) + addr_size); + addrP->brdcast = getBroadcast(env, sock, name, brdcast_to); if ((*env)->ExceptionCheck(env) == JNI_TRUE) { return ifs; } @@ -955,36 +945,28 @@ } } - /** - * Deal with virtual interface with colon notation e.g. eth0:1 - */ + // Deal with virtual interface with colon notation e.g. eth0:1 name_colonP = strchr(name, ':'); if (name_colonP != NULL) { - /** - * This is a virtual interface. If we are able to access the parent - * we need to create a new entry if it doesn't exist yet *and* update - * the 'parent' interface with the new records. - */ + // This is a virtual interface. If we are able to access the parent + // we need to create a new entry if it doesn't exist yet *and* update + // the 'parent' interface with the new records. *name_colonP = 0; if (getFlags(sock, name, &flags) < 0 || flags < 0) { - // failed to access parent interface do not create parent. - // We are a virtual interface with no parent. - isVirtual = 1; - *name_colonP = ':'; - } - else{ - // Got access to parent, so create it if necessary. - // Save original name to vname and truncate name by ':' - memcpy(vname, name, sizeof(vname) ); - vname[name_colonP - name] = ':'; + // failed to access parent interface do not create parent. + // We are a virtual interface with no parent. + isVirtual = 1; + *name_colonP = ':'; + } else { + // Got access to parent, so create it if necessary. + // Save original name to vname and truncate name by ':' + memcpy(vname, name, sizeof(vname) ); + vname[name_colonP - name] = ':'; } } - /* - * Check if this is a "new" interface. Use the interface - * name for matching because index isn't supported on - * Solaris 2.6 & 7. - */ + // Check if this is a "new" interface. Use the interface name for + // matching because index isn't supported on Solaris 2.6 & 7. while (currif != NULL) { if (strcmp(name, currif->name) == 0) { break; @@ -992,13 +974,10 @@ currif = currif->next; } - /* - * If "new" then create an netif structure and - * insert it onto the list. - */ + // If "new" then create an netif structure and insert it into the list. if (currif == NULL) { CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size); - currif->name = (char *) currif+sizeof(netif); + currif->name = (char *)currif + sizeof(netif); strncpy(currif->name, name, ifnam_size); currif->name[ifnam_size - 1] = '\0'; currif->index = getIndex(sock, name); @@ -1009,17 +988,13 @@ ifs = currif; } - /* - * Finally insert the address on the interface - */ + // Finally insert the address on the interface addrP->next = currif->addr; currif->addr = addrP; parent = currif; - /** - * Let's deal with the virtual interface now. - */ + // Deal with the virtual interface now. if (vname[0]) { netaddr *tmpaddr; @@ -1034,27 +1009,29 @@ if (currif == NULL) { CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size); - currif->name = (char *) currif + sizeof(netif); + currif->name = (char *)currif + sizeof(netif); strncpy(currif->name, vname, ifnam_size); currif->name[ifnam_size - 1] = '\0'; currif->index = getIndex(sock, vname); currif->addr = NULL; - /* Need to duplicate the addr entry? */ + // Need to duplicate the addr entry? currif->virtual = 1; currif->childs = NULL; currif->next = parent->childs; parent->childs = currif; } - CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr)+2*addr_size); + CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr) + 2 * addr_size); memcpy(tmpaddr, addrP, sizeof(netaddr)); if (addrP->addr != NULL) { - tmpaddr->addr = (struct sockaddr *) ( (char*)tmpaddr + sizeof(netaddr) ) ; + tmpaddr->addr = (struct sockaddr *) + ((char*)tmpaddr + sizeof(netaddr)); memcpy(tmpaddr->addr, addrP->addr, addr_size); } if (addrP->brdcast != NULL) { - tmpaddr->brdcast = (struct sockaddr *) ((char *) tmpaddr + sizeof(netaddr)+addr_size); + tmpaddr->brdcast = (struct sockaddr *) + ((char *)tmpaddr + sizeof(netaddr) + addr_size); memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size); } @@ -1065,19 +1042,18 @@ return ifs; } -/* Open socket for further ioct calls - * proto is AF_INET/AF_INET6 +/* + * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6. */ -static int openSocket(JNIEnv *env, int proto){ +static int openSocket(JNIEnv *env, int proto) { int sock; if ((sock = JVM_Socket(proto, SOCK_DGRAM, 0)) < 0) { - /* - * If EPROTONOSUPPORT is returned it means we don't have - * support for this proto so don't throw an exception. - */ + // If EPROTONOSUPPORT is returned it means we don't have + // support for this proto so don't throw an exception. if (errno != EPROTONOSUPPORT) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "Socket creation failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "Socket creation failed"); } return -1; } @@ -1088,36 +1064,38 @@ /** Linux, AIX **/ #if defined(__linux__) || defined(_AIX) -/* Open socket for further ioct calls, try v4 socket first and - * if it falls return v6 socket - */ #ifdef AF_INET6 -static int openSocketWithFallback(JNIEnv *env, const char *ifname){ +/* + * Opens a socket for further ioct calls. Tries AF_INET socket first and + * if it falls return AF_INET6 socket. + */ +// unused arg ifname and struct if2 +static int openSocketWithFallback(JNIEnv *env, const char *ifname) { int sock; struct ifreq if2; - if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - if (errno == EPROTONOSUPPORT){ - if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); - return -1; - } - } - else{ // errno is not NOSUPPORT - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); - return -1; - } - } + if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if (errno == EPROTONOSUPPORT) { + if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV6 Socket creation failed"); + return -1; + } + } else { // errno is not NOSUPPORT + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV4 Socket creation failed"); + return -1; + } + } - /* Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or IPv6 socket regardless of type - of address of an interface */ - - return sock; + // Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or + // IPv6 socket regardless of type of address of an interface. + return sock; } #else -static int openSocketWithFallback(JNIEnv *env, const char *ifname){ +static int openSocketWithFallback(JNIEnv *env, const char *ifname) { return openSocket(env,AF_INET); } #endif @@ -1130,52 +1108,48 @@ unsigned i; int siocgifconfRequest = SIOCGIFCONF; - #if defined(__linux__) - /* need to do a dummy SIOCGIFCONF to determine the buffer size. - * SIOCGIFCOUNT doesn't work - */ + // need to do a dummy SIOCGIFCONF to determine the buffer size. + // SIOCGIFCOUNT doesn't work ifc.ifc_buf = NULL; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFCONF failed"); return ifs; } #elif defined(_AIX) ifc.ifc_buf = NULL; if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGSIZIFCONF failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGSIZIFCONF failed"); return ifs; } #endif /* __linux__ */ - CHECKED_MALLOC3(buf,char *, ifc.ifc_len); + CHECKED_MALLOC3(buf, char *, ifc.ifc_len); ifc.ifc_buf = buf; #if defined(_AIX) siocgifconfRequest = CSIOCGIFCONF; #endif if (ioctl(sock, siocgifconfRequest, (char *)&ifc) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed"); - (void) free(buf); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFCONF failed"); + free(buf); return ifs; } - /* - * Iterate through each interface - */ + // Iterate through each interface ifreqP = ifc.ifc_req; - for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) { + for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) { #if defined(_AIX) if (ifreqP->ifr_addr.sa_family != AF_INET) continue; #endif - /* - * Add to the list - */ - ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0); + // Add to the list + ifs = addif(env, sock, ifreqP->ifr_name, ifs, + (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET, 0); - /* - * If an exception occurred then free the list - */ + // If an exception occurred then free the list if ((*env)->ExceptionOccurred(env)) { free(buf); freeif(ifs); @@ -1183,37 +1157,37 @@ } } - /* - * Free socket and buffer - */ + // Free socket and buffer free(buf); return ifs; } +#if defined(AF_INET6) && defined(__linux__) + /* - * Enumerates and returns all IPv6 interfaces on Linux + * Enumerates and returns all IPv6 interfaces on Linux. */ - -#if defined(AF_INET6) && defined(__linux__) static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { FILE *f; char addr6[40], devname[21]; char addr6p[8][5]; - int plen, scope, dad_status, if_idx; + int prefix, scope, dad_status, if_idx; uint8_t ipv6addr[16]; if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) { while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) != EOF) { + addr6p[0], addr6p[1], addr6p[2], addr6p[3], + addr6p[4], addr6p[5], addr6p[6], addr6p[7], + &if_idx, &prefix, &scope, &dad_status, devname) != EOF) { struct netif *ifs_ptr = NULL; struct netif *last_ptr = NULL; struct sockaddr_in6 addr; sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); + addr6p[0], addr6p[1], addr6p[2], addr6p[3], + addr6p[4], addr6p[5], addr6p[6], addr6p[7]); inet_pton(AF_INET6, addr6, ipv6addr); memset(&addr, 0, sizeof(struct sockaddr_in6)); @@ -1221,12 +1195,10 @@ addr.sin6_scope_id = if_idx; - ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, AF_INET6, plen); - + ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, + AF_INET6, (short)prefix); - /* - * If an exception occurred then return the list as is. - */ + // If an exception occurred then return the list as is. if ((*env)->ExceptionOccurred(env)) { fclose(f); return ifs; @@ -1239,11 +1211,11 @@ #endif +#if defined(AF_INET6) && defined(_AIX) + /* - * Enumerates and returns all IPv6 interfaces on AIX + * Enumerates and returns all IPv6 interfaces on AIX. */ - -#if defined(AF_INET6) && defined(_AIX) static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { struct ifconf ifc; struct ifreq *ifreqP; @@ -1253,12 +1225,12 @@ unsigned bufsize; char *cp, *cplimit; - /* use SIOCGSIZIFCONF to get size for SIOCGIFCONF */ + // use SIOCGSIZIFCONF to get size for SIOCGIFCONF ifc.ifc_buf = NULL; if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", - "ioctl SIOCGSIZIFCONF failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGSIZIFCONF failed"); return ifs; } bufsize = ifc.ifc_len; @@ -1271,29 +1243,27 @@ ifc.ifc_len = bufsize; ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", - "ioctl CSIOCGIFCONF failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl CSIOCGIFCONF failed"); free(buf); return ifs; } - /* - * Iterate through each interface - */ + // Iterate through each interface ifreqP = ifc.ifc_req; cp = (char *)ifc.ifc_req; cplimit = cp + ifc.ifc_len; - for ( ; cp < cplimit; cp += (sizeof(ifreqP->ifr_name) + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) { + for (; cp < cplimit; + cp += (sizeof(ifreqP->ifr_name) + + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) + { ifreqP = (struct ifreq *)cp; struct ifreq if2; - memset((char *)&if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifreqP->ifr_name); + strncpy(if2.ifr_name, ifreqP->ifr_name, sizeof(if2.ifr_name) - 1); - /* - * Skip interface that aren't UP - */ + // Skip interface that aren't UP if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) { if (!(if2.ifr_flags & IFF_UP)) { continue; @@ -1308,16 +1278,11 @@ s6->sin6_scope_id = if2.ifr_site6; } - /* - * Add to the list - */ + // Add to the list ifs = addif(env, sock, ifreqP->ifr_name, ifs, - (struct sockaddr *)&(ifreqP->ifr_addr), - AF_INET6, 0); + (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET6, 0); - /* - * If an exception occurred then free the list - */ + // If an exception occurred then free the list if ((*env)->ExceptionOccurred(env)) { free(buf); freeif(ifs); @@ -1325,24 +1290,21 @@ } } - /* - * Free socket and buffer - */ + // Free socket and buffer free(buf); return ifs; } #endif -static int getIndex(int sock, const char *name){ - /* - * Try to get the interface index - */ +static int getIndex(int sock, const char *name) { + // Try to get the interface index #if defined(_AIX) return if_nametoindex(name); #else struct ifreq if2; - strcpy(if2.ifr_name, name); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1); if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) { return -1; @@ -1352,38 +1314,41 @@ #endif } -/** +/* * Returns the IPv4 broadcast address of a named interface, if it exists. * Returns 0 if it doesn't have one. */ -static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) { - struct sockaddr *ret = NULL; - struct ifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); - - /* Let's make sure the interface does have a broadcast address */ - if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFFLAGS failed"); - return ret; - } +static struct sockaddr *getBroadcast + (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) +{ + struct sockaddr *ret = NULL; + struct ifreq if2; + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); - if (if2.ifr_flags & IFF_BROADCAST) { - /* It does, let's retrieve it*/ - if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed"); - return ret; - } + // Let's make sure the interface does have a broadcast address. + if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFFLAGS failed"); + return ret; + } - ret = brdcast_store; - memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr)); - } + if (if2.ifr_flags & IFF_BROADCAST) { + // It does, let's retrieve it + if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFBRDADDR failed"); + return ret; + } - return ret; + ret = brdcast_store; + memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr)); + } + + return ret; } -/** +/* * Returns the IPv4 subnet prefix length (aka subnet mask) for the named * interface, if it has one, otherwise return -1. */ @@ -1391,12 +1356,12 @@ unsigned int mask; short ret; struct ifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFNETMASK failed"); return -1; } @@ -1410,12 +1375,15 @@ return ret; } -/** - * Get the Hardware address (usually MAC address) for the named interface. - * return puts the data in buf, and returns the length, in byte, of the +/* + * Gets the Hardware address (usually MAC address) for the named interface. + * On return puts the data in buf, and returns the length, in byte, of the * MAC address. Returns -1 if there is no hardware address on that interface. */ -static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) { +static int getMacAddress + (JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, + unsigned char *buf) +{ #if defined (_AIX) int size; struct kinfo_ndd *nddp; @@ -1434,7 +1402,8 @@ nddp = (struct kinfo_ndd *)malloc(size); if (!nddp) { - JNU_ThrowOutOfMemoryError(env, "Network interface getMacAddress native buffer allocation failed"); + JNU_ThrowOutOfMemoryError(env, + "Network interface getMacAddress native buffer allocation failed"); return -1; } @@ -1455,22 +1424,20 @@ } return -1; - #elif defined(__linux__) static struct ifreq ifr; int i; - - strcpy(ifr.ifr_name, ifname); + memset((char *)&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFHWADDR failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFHWADDR failed"); return -1; } memcpy(buf, &ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); - /* - * All bytes to 0 means no hardware address. - */ + // All bytes to 0 means no hardware address. for (i = 0; i < IFHWADDRLEN; i++) { if (buf[i] != 0) @@ -1483,17 +1450,18 @@ static int getMTU(JNIEnv *env, int sock, const char *ifname) { struct ifreq if2; + memset((char *)&if2, 0, sizeof(if2)); - memset((char *) &if2, 0, sizeof(if2)); if (ifname != NULL) { - strcpy(if2.ifr_name, ifname); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); } else { JNU_ThrowNullPointerException(env, "network interface name is NULL"); return -1; } if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IOCTL SIOCGIFMTU failed"); return -1; } @@ -1502,11 +1470,10 @@ static int getFlags(int sock, const char *ifname, int *flags) { struct ifreq if2; + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); - - if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){ + if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { return -1; } @@ -1518,53 +1485,54 @@ return 0; } -#endif +#endif /* defined(__linux__) || defined(_AIX) */ /** Solaris **/ -#ifdef __solaris__ -/* Open socket for further ioct calls, try v4 socket first and - * if it falls return v6 socket +#if defined(__solaris__) + +/* + * Opens a socket for further ioct calls. Tries AF_INET socket first and + * if it falls return AF_INET6 socket. */ - #ifdef AF_INET6 -static int openSocketWithFallback(JNIEnv *env, const char *ifname){ +static int openSocketWithFallback(JNIEnv *env, const char *ifname) { int sock, alreadyV6 = 0; struct lifreq if2; - if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - if (errno == EPROTONOSUPPORT){ - if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); - return -1; - } + if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if (errno == EPROTONOSUPPORT) { + if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV6 Socket creation failed"); + return -1; + } - alreadyV6=1; - } - else{ // errno is not NOSUPPORT - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); - return -1; - } - } + alreadyV6=1; + } else { // errno is not NOSUPPORT + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV4 Socket creation failed"); + return -1; + } + } + - /** - * Solaris requires that we have an IPv6 socket to query an - * interface without an IPv4 address - check it here. - * POSIX 1 require the kernel to return ENOTTY if the call is - * inappropriate for a device e.g. the NETMASK for a device having IPv6 - * only address but not all devices follow the standard so - * fall back on any error. It's not an ecologically friendly gesture - * but more reliable. - */ + // Solaris requires that we have an IPv6 socket to query an interface + // without an IPv4 address - check it here. POSIX 1 require the kernel to + // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK + // for a device having IPv6 only address but not all devices follow the + // standard so fall back on any error. It's not an ecologically friendly + // gesture but more reliable. - if (! alreadyV6 ){ - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.lifr_name, ifname); + if (!alreadyV6) { + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) { - close(sock); - if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); - return -1; - } + close(sock); + if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV6 Socket creation failed"); + return -1; + } } } @@ -1572,18 +1540,16 @@ } #else -static int openSocketWithFallback(JNIEnv *env, const char *ifname){ +static int openSocketWithFallback(JNIEnv *env, const char *ifname) { return openSocket(env,AF_INET); } #endif /* - * Enumerates and returns all IPv4 interfaces - * (linux verision) + * Enumerates and returns all IPv4 interfaces. */ - static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) { - return enumIPvXInterfaces(env,sock, ifs, AF_INET); + return enumIPvXInterfaces(env,sock, ifs, AF_INET); } #ifdef AF_INET6 @@ -1593,8 +1559,8 @@ #endif /* - Enumerates and returns all interfaces on Solaris - use the same code for IPv4 and IPv6 + * Enumerates and returns all interfaces on Solaris. + * Uses the same code for IPv4 and IPv6. */ static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family) { struct lifconf ifc; @@ -1604,19 +1570,16 @@ struct lifnum numifs; unsigned bufsize; - /* - * Get the interface count - */ + // Get the interface count numifs.lifn_family = family; numifs.lifn_flags = 0; if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFNUM failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFNUM failed"); return ifs; } - /* - * Enumerate the interface configurations - */ + // Enumerate the interface configurations bufsize = numifs.lifn_count * sizeof (struct lifreq); CHECKED_MALLOC3(buf, char *, bufsize); @@ -1625,22 +1588,19 @@ ifc.lifc_len = bufsize; ifc.lifc_buf = buf; if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFCONF failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFCONF failed"); free(buf); return ifs; } - /* - * Iterate through each interface - */ + // Iterate through each interface ifr = ifc.lifc_req; for (n=0; n<numifs.lifn_count; n++, ifr++) { int index = -1; struct lifreq if2; - /* - * Ignore either IPv4 or IPv6 addresses - */ + // Ignore either IPv4 or IPv6 addresses if (ifr->lifr_addr.ss_family != family) { continue; } @@ -1652,12 +1612,12 @@ } #endif - /* add to the list */ - ifs = addif(env, sock,ifr->lifr_name, ifs, (struct sockaddr *)&(ifr->lifr_addr),family, (short) ifr->lifr_addrlen); + // add to the list + ifs = addif(env, sock,ifr->lifr_name, ifs, + (struct sockaddr *)&(ifr->lifr_addr), family, + (short)ifr->lifr_addrlen); - /* - * If an exception occurred we return immediately - */ + // If an exception occurred we return immediately if ((*env)->ExceptionOccurred(env)) { free(buf); return ifs; @@ -1669,13 +1629,11 @@ return ifs; } -static int getIndex(int sock, const char *name){ - /* - * Try to get the interface index - * (Not supported on Solaris 2.6 or 7) - */ +static int getIndex(int sock, const char *name) { + // Try to get the interface index. (Not supported on Solaris 2.6 or 7) struct lifreq if2; - strcpy(if2.lifr_name, name); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.lifr_name, name, sizeof(if2.lifr_name) - 1); if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) { return -1; @@ -1684,27 +1642,30 @@ return if2.lifr_index; } -/** +/* * Returns the IPv4 broadcast address of a named interface, if it exists. * Returns 0 if it doesn't have one. */ -static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) { +static struct sockaddr *getBroadcast + (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) +{ struct sockaddr *ret = NULL; struct lifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.lifr_name, ifname); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); - /* Let's make sure the interface does have a broadcast address */ + // Let's make sure the interface does have a broadcast address if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFFLAGS failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFFLAGS failed"); return ret; } if (if2.lifr_flags & IFF_BROADCAST) { - /* It does, let's retrieve it*/ + // It does, let's retrieve it if (ioctl(sock, SIOCGLIFBRDADDR, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFBRDADDR failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFBRDADDR failed"); return ret; } @@ -1715,7 +1676,7 @@ return ret; } -/** +/* * Returns the IPv4 subnet prefix length (aka subnet mask) for the named * interface, if it has one, otherwise return -1. */ @@ -1723,12 +1684,12 @@ unsigned int mask; short ret; struct lifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.lifr_name, ifname); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFNETMASK failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFNETMASK failed"); return -1; } @@ -1744,15 +1705,16 @@ } - #define DEV_PREFIX "/dev/" -/** +/* * Solaris specific DLPI code to get hardware address from a device. * Unfortunately, at least up to Solaris X, you have to have special * privileges (i.e. be root). */ -static int getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf) { +static int getMacFromDevice + (JNIEnv *env, const char* ifname, unsigned char* retbuf) +{ char style1dev[MAXPATHLEN]; int fd; dl_phys_addr_req_t dlpareq; @@ -1761,17 +1723,12 @@ char buf[128]; int flags = 0; - /** - * Device is in /dev - * e.g.: /dev/bge0 - */ + // Device is in /dev. e.g.: /dev/bge0 strcpy(style1dev, DEV_PREFIX); strcat(style1dev, ifname); if ((fd = open(style1dev, O_RDWR)) < 0) { - /* - * Can't open it. We probably are missing the privilege. - * We'll have to try something else - */ + // Can't open it. We probably are missing the privilege. + // We'll have to try something else return 0; } @@ -1782,7 +1739,8 @@ msg.len = DL_PHYS_ADDR_REQ_SIZE; if (putmsg(fd, &msg, NULL, 0) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "putmsg failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "putmsg failed"); return -1; } @@ -1792,12 +1750,14 @@ msg.len = 0; msg.maxlen = sizeof (buf); if (getmsg(fd, &msg, NULL, &flags) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "getmsg failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "getmsg failed"); return -1; } if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Couldn't obtain phys addr\n"); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Couldn't obtain phys addr\n"); return -1; } @@ -1805,21 +1765,23 @@ return dlpaack->dl_addr_length; } -/** - * Get the Hardware address (usually MAC address) for the named interface. - * return puts the data in buf, and returns the length, in byte, of the +/* + * Gets the Hardware address (usually MAC address) for the named interface. + * On return puts the data in buf, and returns the length, in byte, of the * MAC address. Returns -1 if there is no hardware address on that interface. */ -static int getMacAddress(JNIEnv *env, int sock, const char *ifname, const struct in_addr* addr, unsigned char *buf) { +static int getMacAddress + (JNIEnv *env, int sock, const char *ifname, const struct in_addr* addr, + unsigned char *buf) +{ struct arpreq arpreq; struct sockaddr_in* sin; struct sockaddr_in ipAddr; int len, i; struct lifreq lif; - /* First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails - * try the old way. - */ + // First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails + // try the old way. memset(&lif, 0, sizeof(lif)); strlcpy(lif.lifr_name, ifname, sizeof(lif.lifr_name)); @@ -1830,18 +1792,14 @@ return sp->sdl_alen; } - /** - * On Solaris we have to use DLPI, but it will only work if we have - * privileged access (i.e. root). If that fails, we try a lookup - * in the ARP table, which requires an IPv4 address. - */ + // On Solaris we have to use DLPI, but it will only work if we have + // privileged access (i.e. root). If that fails, we try a lookup + // in the ARP table, which requires an IPv4 address. if ((len = getMacFromDevice(env, ifname, buf)) == 0) { - /*DLPI failed - trying to do arp lookup*/ + // DLPI failed - trying to do arp lookup if (addr == NULL) { - /** - * No IPv4 address for that interface, so can't do an ARP lookup. - */ + // No IPv4 address for that interface, so can't do an ARP lookup. return -1; } @@ -1862,10 +1820,7 @@ memcpy(buf, &arpreq.arp_ha.sa_data[0], len ); } - /* - * All bytes to 0 means no hardware address. - */ - + // All bytes to 0 means no hardware address. for (i = 0; i < len; i++) { if (buf[i] != 0) return len; @@ -1876,56 +1831,57 @@ static int getMTU(JNIEnv *env, int sock, const char *ifname) { struct lifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.lifr_name, ifname); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFMTU failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGLIFMTU failed"); return -1; } - return if2.lifr_mtu; + return if2.lifr_mtu; +} + +static int getFlags(int sock, const char *ifname, int *flags) { + struct lifreq if2; + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); + + if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) { + return -1; + } + + *flags = if2.lifr_flags; + return 0; } -static int getFlags(int sock, const char *ifname, int *flags) { - struct lifreq lifr; - memset((caddr_t)&lifr, 0, sizeof(lifr)); - strcpy((caddr_t)&(lifr.lifr_name), ifname); - - if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) { - return -1; - } - - *flags = lifr.lifr_flags; - return 0; -} - - -#endif +#endif /* __solaris__ */ /** BSD **/ #ifdef _ALLBSD_SOURCE -/* Open socket for further ioct calls, try v4 socket first and - * if it falls return v6 socket + +/* + * Opens a socket for further ioct calls. Tries AF_INET socket first and + * if it falls return AF_INET6 socket. */ - #ifdef AF_INET6 -static int openSocketWithFallback(JNIEnv *env, const char *ifname){ +static int openSocketWithFallback(JNIEnv *env, const char *ifname) { int sock; struct ifreq if2; if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - if (errno == EPROTONOSUPPORT){ - if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); + if (errno == EPROTONOSUPPORT) { + if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV6 Socket creation failed"); return -1; } - } - else{ // errno is not NOSUPPORT - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); + } else { // errno is not NOSUPPORT + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "IPV4 Socket creation failed"); return -1; } } @@ -1934,39 +1890,33 @@ } #else -static int openSocketWithFallback(JNIEnv *env, const char *ifname){ +static int openSocketWithFallback(JNIEnv *env, const char *ifname) { return openSocket(env,AF_INET); } #endif /* - * Enumerates and returns all IPv4 interfaces + * Enumerates and returns all IPv4 interfaces. */ static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) { struct ifaddrs *ifa, *origifa; if (getifaddrs(&origifa) != 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", - "getifaddrs() function failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "getifaddrs() function failed"); return ifs; } for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) { - /* - * Skip non-AF_INET entries. - */ + // Skip non-AF_INET entries. if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET) continue; - /* - * Add to the list. - */ + // Add to the list. ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0); - /* - * If an exception occurred then free the list. - */ + // If an exception occurred then free the list. if ((*env)->ExceptionOccurred(env)) { freeifaddrs(origifa); freeif(ifs); @@ -1974,33 +1924,25 @@ } } - /* - * Free socket and buffer - */ + // Free socket and buffer freeifaddrs(origifa); return ifs; } - -/* - * Enumerates and returns all IPv6 interfaces on Linux - */ - #ifdef AF_INET6 /* * Determines the prefix on BSD for IPv6 interfaces. */ -static -int prefix(void *val, int size) { +static int prefix(void *val, int size) { u_char *name = (u_char *)val; - int byte, bit, plen = 0; + int byte, bit, prefix = 0; - for (byte = 0; byte < size; byte++, plen += 8) + for (byte = 0; byte < size; byte++, prefix += 8) if (name[byte] != 0xff) break; if (byte == size) - return (plen); - for (bit = 7; bit != 0; bit--, plen++) + return prefix; + for (bit = 7; bit != 0; bit--, prefix++) if (!(name[byte] & (1 << bit))) break; for (; bit != 0; bit--) @@ -2010,11 +1952,11 @@ for (; byte < size; byte++) if (name[byte]) return (0); - return (plen); + return prefix; } /* - * Enumerates and returns all IPv6 interfaces on BSD + * Enumerates and returns all IPv6 interfaces on BSD. */ static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { struct ifaddrs *ifa, *origifa; @@ -2022,37 +1964,36 @@ struct in6_ifreq ifr6; if (getifaddrs(&origifa) != 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", - "getifaddrs() function failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "getifaddrs() function failed"); return ifs; } for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) { - /* - * Skip non-AF_INET6 entries. - */ + // Skip non-AF_INET6 entries. if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6) continue; memset(&ifr6, 0, sizeof(ifr6)); strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); - memcpy(&ifr6.ifr_addr, ifa->ifa_addr, MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len)); + memcpy(&ifr6.ifr_addr, ifa->ifa_addr, + MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len)); if (ioctl(sock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) < 0) { - NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", - "ioctl SIOCGIFNETMASK_IN6 failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFNETMASK_IN6 failed"); freeifaddrs(origifa); freeif(ifs); return NULL; } - /* Add to the list. */ + // Add to the list. sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr; ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6, - prefix(&sin6->sin6_addr, sizeof(struct in6_addr))); + (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr))); - /* If an exception occurred then free the list. */ + // If an exception occurred then free the list. if ((*env)->ExceptionOccurred(env)) { freeifaddrs(origifa); freeif(ifs); @@ -2060,22 +2001,19 @@ } } - /* - * Free socket and ifaddrs buffer - */ + // Free socket and ifaddrs buffer freeifaddrs(origifa); return ifs; } #endif -static int getIndex(int sock, const char *name){ +static int getIndex(int sock, const char *name) { #ifdef __FreeBSD__ - /* - * Try to get the interface index - * (Not supported on Solaris 2.6 or 7) - */ + // Try to get the interface index + // (Not supported on Solaris 2.6 or 7) struct ifreq if2; - strcpy(if2.ifr_name, name); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1); if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) { return -1; @@ -2083,46 +2021,47 @@ return if2.ifr_index; #else - /* - * Try to get the interface index using BSD specific if_nametoindex - */ + // Try to get the interface index using BSD specific if_nametoindex int index = if_nametoindex(name); return (index == 0) ? -1 : index; #endif } -/** +/* * Returns the IPv4 broadcast address of a named interface, if it exists. * Returns 0 if it doesn't have one. */ -static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) { - struct sockaddr *ret = NULL; - struct ifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); - - /* Let's make sure the interface does have a broadcast address */ - if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFFLAGS failed"); - return ret; - } +static struct sockaddr *getBroadcast + (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) +{ + struct sockaddr *ret = NULL; + struct ifreq if2; + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); - if (if2.ifr_flags & IFF_BROADCAST) { - /* It does, let's retrieve it*/ - if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed"); - return ret; - } + // Make sure the interface does have a broadcast address + if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFFLAGS failed"); + return ret; + } - ret = brdcast_store; - memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr)); - } + if (if2.ifr_flags & IFF_BROADCAST) { + // It does, let's retrieve it + if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFBRDADDR failed"); + return ret; + } - return ret; + ret = brdcast_store; + memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr)); + } + + return ret; } -/** +/* * Returns the IPv4 subnet prefix length (aka subnet mask) for the named * interface, if it has one, otherwise return -1. */ @@ -2130,12 +2069,12 @@ unsigned int mask; short ret; struct ifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFNETMASK failed"); return -1; } @@ -2149,25 +2088,28 @@ return ret; } -/** - * Get the Hardware address (usually MAC address) for the named interface. +/* + * Gets the Hardware address (usually MAC address) for the named interface. * return puts the data in buf, and returns the length, in byte, of the * MAC address. Returns -1 if there is no hardware address on that interface. */ -static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) { +static int getMacAddress + (JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, + unsigned char *buf) +{ struct ifaddrs *ifa0, *ifa; struct sockaddr *saddr; int i; - /* Grab the interface list */ + // Grab the interface list if (!getifaddrs(&ifa0)) { - /* Cycle through the interfaces */ + // Cycle through the interfaces for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) { saddr = ifa->ifa_addr; - /* Link layer contains the MAC address */ + // Link layer contains the MAC address if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) { struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr; - /* Check the address is the correct length */ + // Check the address is the correct length if (sadl->sdl_alen == ETHER_ADDR_LEN) { memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN); freeifaddrs(ifa0); @@ -2183,12 +2125,12 @@ static int getMTU(JNIEnv *env, int sock, const char *ifname) { struct ifreq if2; - - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed"); + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "ioctl SIOCGIFMTU failed"); return -1; } @@ -2196,22 +2138,20 @@ } static int getFlags(int sock, const char *ifname, int *flags) { - struct ifreq if2; - int ret = -1; + struct ifreq if2; + int ret = -1; + memset((char *)&if2, 0, sizeof(if2)); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); - memset((char *) &if2, 0, sizeof(if2)); - strcpy(if2.ifr_name, ifname); - - if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){ - return -1; - } + if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { + return -1; + } - if (sizeof(if2.ifr_flags) == sizeof(short)) { - *flags = (if2.ifr_flags & 0xffff); - } else { - *flags = if2.ifr_flags; - } - return 0; + if (sizeof(if2.ifr_flags) == sizeof(short)) { + *flags = (if2.ifr_flags & 0xffff); + } else { + *flags = if2.ifr_flags; + } + return 0; } - -#endif +#endif /* __ALLBSD_SOURCE__ */
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c Thu Jan 12 06:59:38 2017 +0000 @@ -992,17 +992,24 @@ (char *)&arg, sizeof(arg)) < 0) { getErrorString(errno, tmpbuf, sizeof(tmpbuf)); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); + close(fd); return; } if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&arg, sizeof(arg)) < 0) { getErrorString(errno, tmpbuf, sizeof(tmpbuf)); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); + close(fd); return; } #endif /* __APPLE__ */ - setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int)); + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof (int)) < 0) { + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); + close(fd); + return; + } #if defined(__linux__) arg = 0; @@ -1024,8 +1031,13 @@ */ if (domain == AF_INET6) { int ttl = 1; - setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl, - sizeof(ttl)); + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, + sizeof (ttl)) < 0) { + getErrorString(errno, tmpbuf, sizeof(tmpbuf)); + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf); + close(fd); + return; + } } #endif /* __linux__ */ @@ -2182,7 +2194,7 @@ caddr[14] = ((address >> 8) & 0xff); caddr[15] = (address & 0xff); } else { - getInet6Address_ipaddress(env, iaObj, caddr); + getInet6Address_ipaddress(env, iaObj, (char *) caddr); } memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr));
--- a/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ return 0; } start = now; + a.dp_timeout = remaining; } } else { return res;
--- a/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ start = t.tv_sec * 1000 + t.tv_usec / 1000; for (;;) { - int res = epoll_wait(epfd, events, numfds, timeout); + int res = epoll_wait(epfd, events, numfds, remaining); if (res < 0 && errno == EINTR) { if (remaining >= 0) { gettimeofday(&t, NULL);
--- a/src/windows/bin/cmdtoargs.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/bin/cmdtoargs.c Thu Jan 12 06:59:38 2017 +0000 @@ -155,6 +155,7 @@ } } dest += copyCh(ch, dest); + slashes = 0; break; default:
--- a/src/windows/classes/sun/awt/windows/fontconfig.properties Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/classes/sun/awt/windows/fontconfig.properties Thu Jan 12 06:59:38 2017 +0000 @@ -40,6 +40,7 @@ allfonts.dingbats=Wingdings allfonts.lucida=Lucida Sans Regular allfonts.symbol=Symbol +allfonts.symbols=Segoe UI Symbol allfonts.thai=Lucida Sans Regular allfonts.georgian=Sylfaen @@ -236,7 +237,7 @@ sequence.allfonts.x-windows-874=alphabetic,thai,dingbats,symbol -sequence.fallback=lucida,\ +sequence.fallback=lucida,symbols,\ chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,\ japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian @@ -298,3 +299,4 @@ filename.Wingdings=WINGDING.TTF filename.Sylfaen=sylfaen.ttf +filename.Segoe_UI_Symbol=SEGUISYM.TTF
--- a/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java Thu Jan 12 06:59:38 2017 +0000 @@ -26,6 +26,7 @@ package sun.java2d.d3d; import java.awt.Composite; +import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitiveMgr; @@ -67,7 +68,13 @@ protected void validateContext(SunGraphics2D sg2d, Composite comp, int ctxflags) { - D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData; + D3DSurfaceData dstData; + try { + dstData = (D3DSurfaceData) sg2d.surfaceData; + } catch (ClassCastException e) { + throw new InvalidPipeException("wrong surface data type: " + + sg2d.surfaceData); + } D3DContext.validateContext(dstData, dstData, sg2d.getCompClip(), comp, null, sg2d.paint, sg2d, ctxflags);
--- a/src/windows/native/java/lang/ProcessEnvironment_md.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/native/java/lang/ProcessEnvironment_md.c Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
--- a/src/windows/native/java/net/Inet4AddressImpl.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/native/java/net/Inet4AddressImpl.c Thu Jan 12 06:59:38 2017 +0000 @@ -292,7 +292,6 @@ } - static BOOL WindowsVersionCheck(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) { OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; @@ -316,7 +315,7 @@ } static jboolean -wxp_ping4(JNIEnv *env, +tcp_ping4(JNIEnv *env, jbyteArray addrArray, jint timeout, jbyteArray ifArray, @@ -471,23 +470,17 @@ ping4(JNIEnv *env, unsigned long src_addr, unsigned long dest_addr, - jint timeout) + jint timeout, + HANDLE hIcmpFile) { // See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx - HANDLE hIcmpFile; DWORD dwRetVal = 0; char SendData[32] = {0}; LPVOID ReplyBuffer = NULL; DWORD ReplySize = 0; jboolean ret = JNI_FALSE; - hIcmpFile = IcmpCreateFile(); - if (hIcmpFile == INVALID_HANDLE_VALUE) { - NET_ThrowNew(env, WSAGetLastError(), "Unable to open handle"); - return JNI_FALSE; - } - ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData); ReplyBuffer = (VOID*) malloc(ReplySize); if (ReplyBuffer == NULL) { @@ -553,6 +546,7 @@ jint dest_addr = 0; jbyte caddr[4]; int sz; + HANDLE hIcmpFile; /** * Convert IP address from byte array to integer @@ -583,8 +577,20 @@ src_addr = htonl(src_addr); } - return ping4(env, src_addr, dest_addr, timeout); + hIcmpFile = IcmpCreateFile(); + if (hIcmpFile == INVALID_HANDLE_VALUE) { + int err = WSAGetLastError(); + if (err == ERROR_ACCESS_DENIED) { + // fall back to TCP echo if access is denied to ICMP + return tcp_ping4(env, addrArray, timeout, ifArray, ttl); + } else { + NET_ThrowNew(env, err, "Unable to create ICMP file handle"); + return JNI_FALSE; + } + } else { + return ping4(env, src_addr, dest_addr, timeout, hIcmpFile); + } } else { - wxp_ping4(env, addrArray, timeout, ifArray, ttl); + tcp_ping4(env, addrArray, timeout, ifArray, ttl); } }
--- a/src/windows/native/java/net/Inet6AddressImpl.c Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/native/java/net/Inet6AddressImpl.c Thu Jan 12 06:59:38 2017 +0000 @@ -360,6 +360,109 @@ #ifdef AF_INET6 +/** + * ping implementation using tcp port 7 (echo) + */ +static jboolean +tcp_ping6(JNIEnv *env, + jint timeout, + jint ttl, + struct sockaddr_in6 him6, + struct sockaddr_in6* netif, + int len) +{ + jint fd; + WSAEVENT hEvent; + int connect_rv = -1; + + fd = NET_Socket(AF_INET6, SOCK_STREAM, 0); + if (fd == SOCKET_ERROR) { + /* note: if you run out of fds, you may not be able to load + * the exception class, and get a NoClassDefFoundError + * instead. + */ + NET_ThrowNew(env, errno, "Can't create socket"); + return JNI_FALSE; + } + + /** + * A TTL was specified, let's set the socket option. + */ + if (ttl > 0) { + setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const char *)&ttl, sizeof(ttl)); + } + + /** + * A network interface was specified, let's bind to it. + */ + if (netif != NULL) { + if (NET_Bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) < 0) { + NET_ThrowNew(env, WSAGetLastError(), "Can't bind socket to interface"); + closesocket(fd); + return JNI_FALSE; + } + } + + /** + * Make the socket non blocking. + */ + hEvent = WSACreateEvent(); + WSAEventSelect(fd, hEvent, FD_READ|FD_CONNECT|FD_CLOSE); + + /* no need to use NET_Connect as non-blocking */ + him6.sin6_port = htons((short) 7); /* Echo port */ + connect_rv = connect(fd, (struct sockaddr *)&him6, len); + + /** + * connection established or refused immediately, either way it means + * we were able to reach the host! + */ + if (connect_rv == 0 || WSAGetLastError() == WSAECONNREFUSED) { + WSACloseEvent(hEvent); + closesocket(fd); + return JNI_TRUE; + } else { + int optlen; + + switch (WSAGetLastError()) { + case WSAEHOSTUNREACH: /* Host Unreachable */ + case WSAENETUNREACH: /* Network Unreachable */ + case WSAENETDOWN: /* Network is down */ + case WSAEPFNOSUPPORT: /* Protocol Family unsupported */ + WSACloseEvent(hEvent); + closesocket(fd); + return JNI_FALSE; + } + + if (WSAGetLastError() != WSAEWOULDBLOCK) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException", + "connect failed"); + WSACloseEvent(hEvent); + closesocket(fd); + return JNI_FALSE; + } + + timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout); + + if (timeout >= 0) { + /* has connection been established? */ + optlen = sizeof(connect_rv); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv, + &optlen) <0) { + connect_rv = WSAGetLastError(); + } + + if (connect_rv == 0 || connect_rv == WSAECONNREFUSED) { + WSACloseEvent(hEvent); + closesocket(fd); + return JNI_TRUE; + } + } + } + WSACloseEvent(hEvent); + closesocket(fd); + return JNI_FALSE; +} /** * ping implementation. @@ -371,9 +474,9 @@ ping6(JNIEnv *env, struct sockaddr_in6* src, struct sockaddr_in6* dest, - jint timeout) + jint timeout, + HANDLE hIcmpFile) { - HANDLE hIcmpFile; DWORD dwRetVal = 0; char SendData[32] = {0}; LPVOID ReplyBuffer = NULL; @@ -381,12 +484,6 @@ IP_OPTION_INFORMATION ipInfo = {255, 0, 0, 0, NULL}; struct sockaddr_in6 sa6Source; - hIcmpFile = Icmp6CreateFile(); - if (hIcmpFile == INVALID_HANDLE_VALUE) { - NET_ThrowNew(env, WSAGetLastError(), "Unable to open handle"); - return JNI_FALSE; - } - ReplySize = sizeof(ICMPV6_ECHO_REPLY) + sizeof(SendData); ReplyBuffer = (VOID*) malloc(ReplySize); if (ReplyBuffer == NULL) { @@ -445,7 +542,7 @@ struct sockaddr_in6* netif = NULL; struct sockaddr_in6 inf6; int len = 0; - int connect_rv = -1; + HANDLE hIcmpFile; /* * If IPv6 is not enable, then we can't reach an IPv6 address, can we? @@ -489,7 +586,21 @@ inf6.sin6_scope_id = if_scope; netif = &inf6; } - return ping6(env, netif, &him6, timeout); + + hIcmpFile = Icmp6CreateFile(); + if (hIcmpFile == INVALID_HANDLE_VALUE) { + int err = WSAGetLastError(); + if (err == ERROR_ACCESS_DENIED) { + // fall back to TCP echo if access is denied to ICMP + return tcp_ping6(env, timeout, ttl, him6, netif, len); + } else { + NET_ThrowNew(env, err, "Unable to create ICMP file handle"); + return JNI_FALSE; + } + } else { + return ping6(env, netif, &him6, timeout, hIcmpFile); + } + #endif /* AF_INET6 */ return JNI_FALSE; }
--- a/src/windows/native/sun/bridge/WinAccessBridge.cpp Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/native/sun/bridge/WinAccessBridge.cpp Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1125,7 +1125,7 @@ PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID); // find vmID, etc. from HWND; ask that VM for the AC w/Focus - HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ; + HWND pkgVMID; if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) { HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID); // ineffecient [[[FIXME]]] if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
--- a/src/windows/native/sun/windows/awt_TrayIcon.cpp Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu Jan 12 06:59:38 2017 +0000 @@ -93,6 +93,12 @@ void AwtTrayIcon::Dispose() { SendTrayMessage(NIM_DELETE); + + // Destroy the icon to avoid leak of GDI objects + if (m_nid.hIcon != NULL) { + ::DestroyIcon(m_nid.hIcon); + } + UnlinkObjects(); if (--sm_instCount == 0) {
--- a/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp Tue Nov 08 05:26:12 2016 +0000 +++ b/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp Thu Jan 12 06:59:38 2017 +0000 @@ -981,6 +981,9 @@ // Only want to call this once per session make_uns_ordered_dither_array(img_oda_alpha, 256); + // workaround JDK-6477756, ignore return value to keep dll in memory + JDK_LoadSystemLibrary("opengl32.dll"); + CATCH_BAD_ALLOC; }
--- a/test/ProblemList.txt Tue Nov 08 05:26:12 2016 +0000 +++ b/test/ProblemList.txt Thu Jan 12 06:59:38 2017 +0000 @@ -237,6 +237,9 @@ # 8026393 sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java generic-all +# 8158827 +sun/security/krb5/auto/tools/KinitConfPlusProps.java windows-all + ############################################################################ # jdk_sound
--- a/test/com/sun/corba/cachedSocket/7056731.sh Tue Nov 08 05:26:12 2016 +0000 +++ b/test/com/sun/corba/cachedSocket/7056731.sh Thu Jan 12 06:59:38 2017 +0000 @@ -102,7 +102,7 @@ sleep 5 # give time for Client to throw exception # JVM_PROC should have exited but just in case, include it. -kill -9 $ORB_PROC $JVM_PROC +kill -9 $ORB_PROC $JVM_PROC $SERVER_PROC grep "ORBUtilSystemException.writeErrorSend" client.$$ result=$?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.PrintStream; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; +import java.util.Random; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +public class Dynamic { + + static final String ALGORITHM = "AES"; + static final String[] MODE = { + "ECb", "CbC", "CTR", "PCBC", "OFB", "OFB150", "cFB", "CFB7", + "cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48", "cfB56", + "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104", "cfB112", + "cfB120", "cfB128", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", + "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", "OFB88", "OFB96", + "OFB104", "OFB112", "OFB120", "OFB128", "GCM" + }; + static final String[] PADDING = { + "NoPadding", "PKCS5Padding", "ISO10126Padding" + }; + static final String SUNJCE = "SunJCE"; + + Cipher ci = null; + byte[] iv = null; + AlgorithmParameterSpec aps = null; + SecretKey key = null; + int keyStrength; + static int DefaultSize = 128; + + public void run(String[] argv) throws Exception { + if (!runAllTest(argv, System.out)) { + throw new Exception("Test Failed"); + } + } + + protected boolean runAllTest(String argv[], PrintStream out) { + boolean result = true; + StringBuilder failedList = new StringBuilder(); + int failedCnt = 0; + int testCount = 0; + int padKinds; // how many kinds of padding mode such as PKCS5padding and + // NoPadding. + + try { + for (int i = 0; i < 3; i++) { + keyStrength = DefaultSize + i * 64; // obtain the key size 128, + // 192, 256 + + for (int j = 0; j < MODE.length; j++) { + if (MODE[j].equalsIgnoreCase("ECB") + || MODE[j].equalsIgnoreCase("PCBC") + || MODE[j].equalsIgnoreCase("CBC")) { + padKinds = PADDING.length; + } else { + padKinds = 1; + } + + for (int k = 0; k < padKinds; k++) { + testCount++; + try { + if (!runTest(ALGORITHM, MODE[j], PADDING[k])) { + result = false; + failedCnt++; + failedList.append(ALGORITHM + "/" + MODE[j] + + "/" + PADDING[k] + " "); + } + } catch (Exception e) { + e.printStackTrace(); + result = false; + failedCnt++; + failedList.append(ALGORITHM + "/" + MODE[j] + "/" + + PADDING[k] + " "); + } + + } + } + } + + if (result) { + out.println("STATUS:Passed. Test " + testCount + + " cases, All Passed"); + return true; + } + out.println("STATUS:Failed. " + failedCnt + " Failed: " + + failedList); + return false; + + } catch (Exception ex) { + ex.printStackTrace(); + out.println("STATUS:Failed. Unexpected Exception: " + ex); + return false; + } + } + + protected boolean runTest(String algo, String mo, String pad) + throws Exception { + boolean result = true; + try { + byte[] plainText = new byte[160000]; + new Random().nextBytes(plainText); + + String transformation = algo + "/" + mo + "/" + pad; + ci = Cipher.getInstance(transformation, SUNJCE); + KeyGenerator kg = KeyGenerator.getInstance(algo, SUNJCE); + if (keyStrength > Cipher.getMaxAllowedKeyLength(transformation)) { + // skip if this key length is larger than what's + // configured in the jce jurisdiction policy files + System.out.println(keyStrength + + " is larger than what's configured " + + "in the jce jurisdiction policy files"); + return result; + } + kg.init(keyStrength); + key = kg.generateKey(); + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } else { + ci.init(Cipher.ENCRYPT_MODE, key); + } + byte[] cipherText = new byte[ci.getOutputSize(plainText.length)]; + int offset = ci.update(plainText, 0, plainText.length, cipherText, + 0); + ci.doFinal(cipherText, offset); + + if (!mo.equalsIgnoreCase("ECB")) { + iv = ci.getIV(); + aps = new IvParameterSpec(iv); + } else { + aps = null; + } + + if (!mo.equalsIgnoreCase("GCM")) { + ci.init(Cipher.DECRYPT_MODE, key, aps); + } else { + ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters()); + } + byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)]; + int len = ci.doFinal(cipherText, 0, cipherText.length, + recoveredText); + + byte[] tmp = new byte[len]; + for (int i = 0; i < len; i++) { + tmp[i] = recoveredText[i]; + } + + result = Arrays.equals(plainText, tmp); + } catch (NoSuchAlgorithmException nsaEx) { + nsaEx.printStackTrace(); + // CFB7 and OFB150 are negative test,SunJCE not support this + // algorithm + result = mo.equalsIgnoreCase("CFB7") + || mo.equalsIgnoreCase("OFB150"); + + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8044193 + * @summary Test AES ciphers with different modes and padding schemes with + * default provider + */ + +public class TestAESWithDefaultProvider extends Dynamic { + public static void main(String argv[]) throws Exception { + new TestAESWithDefaultProvider().run(argv); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,39 @@ +/* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Security; + +/* + * @test + * @bug 8044193 + * @summary Test AES ciphers with different modes and padding schemes after + * remove then add provider. + * @run main/othervm/policy=testAES.policy TestAESWithProviderChange + */ + +public class TestAESWithProviderChange extends Dynamic { + public static void main(String argv[]) throws Exception { + Security.removeProvider(SUNJCE); + Security.addProvider(new com.sun.crypto.provider.SunJCE()); + new TestAESWithProviderChange().run(argv); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.*; +import java.security.Provider; + +/* + * @test + * @bug 8044193 + * @summary Test AES ciphers with different modes and padding schemes after + * remove default provider then add it back. + * @run main/othervm/policy=testAES.policy TestAESWithRemoveAddProvider + */ + +public class TestAESWithRemoveAddProvider extends Dynamic { + public static void main(String argv[]) throws Exception { + Provider pJCE = Security.getProvider(SUNJCE); + Security.removeProvider(SUNJCE); + Security.addProvider(pJCE); + new TestAESWithRemoveAddProvider().run(argv); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,6 @@ +grant +{ + permission java.security.SecurityPermission "removeProvider.SunJCE"; + permission java.security.SecurityPermission "insertProvider.SunJCE"; + permission java.security.SecurityPermission "putProviderProperty.SunJCE"; +};
--- a/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8026943 + * @bug 8026943 8027575 * @summary Verify that same buffer can be used as input and output when * using Cipher objects. * @author Valerie Peng @@ -44,7 +44,7 @@ private static SecretKey KEY = new SecretKeySpec(new byte[16], "AES"); private static byte[] IV = new byte[16]; - private static int[] OFFSETS = { 1, 8, 17 }; + private static int[] OFFSETS = { 1, 8, 9, 16, 17, 32, 33 }; private static final String[] MODES = { "ECB", "CBC", "PCBC", "CTR", "CTS",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.NoSuchAlgorithmException; + +/* + * @test + * @bug 8048601 + * @library ../ + * @summary Test Blowfish cipher with different MODES and padding + */ + +public class TestCipherBlowfish extends TestCipher { + + TestCipherBlowfish() throws NoSuchAlgorithmException { + super("Blowfish", + new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", + "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", + "OFB64"}, + new String[]{"NoPaDDing", "PKCS5Padding"}, + true); + } + + public static void main(String[] args) throws Exception { + new TestCipherBlowfish().runAll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8048601 + * @library ../ + * @summary Test DES/DESede cipher with different MODES and padding + */ + +public class TestCipherDES extends TestCipher { + + TestCipherDES() { + super("DES", + new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", + "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", + "OFB64"}, + new String[]{"NoPaDDing", "PKCS5Padding"}); + } + + public static void main(String[] args) throws Exception { + new TestCipherDES().runAll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8048601 + * @library ../ + * @summary Test DES/DESede cipher with different MODES and padding + */ + +public class TestCipherDESede extends TestCipher { + + TestCipherDESede() { + super("DESede", + new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", + "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", + "OFB64"}, + new String[]{"NoPaDDing", "PKCS5Padding"}); + } + + public static void main(String[] args) throws Exception { + new TestCipherDESede().runAll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/* + * @test + * @bug 8048601 + * @summary Tests for PBE ciphers + */ +public class TestCipherPBE { + + private static final String[] ALGORITHMS = {"PBEWithMD5AndDES", + "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndTripleDES", + "PBEWithMD5AndTripleDES/CBC/PKCS5Padding"}; + + private static final String KEY_ALGO = "pbeWithMD5ANDdes"; + private final byte[] SALT; + private final byte[] PLAIN_TEXT; + + public TestCipherPBE() { + SALT = generateBytes(8); + PLAIN_TEXT = generateBytes(200); + } + + public static void main(String[] args) throws Exception { + + new TestCipherPBE().runAll(); + } + + private void runAll() throws Exception { + for (String algorithm : ALGORITHMS) { + runTest(algorithm); + } + } + + private void runTest(String algorithm) + throws InvalidKeySpecException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, ShortBufferException, + NoSuchPaddingException, IllegalBlockSizeException, + BadPaddingException, InvalidKeyException { + + out.println("=> Testing: " + algorithm); + + try { + // Initialization + AlgorithmParameterSpec algoParamSpec + = new PBEParameterSpec(SALT, 6); + + SecretKey secretKey + = SecretKeyFactory.getInstance(KEY_ALGO).generateSecret( + new PBEKeySpec(("Secret Key Value").toCharArray())); + + Cipher ci = Cipher.getInstance(algorithm); + ci.init(Cipher.ENCRYPT_MODE, secretKey, algoParamSpec); + + // Encryption + byte[] cipherText = ci.doFinal(PLAIN_TEXT); + + // Decryption + ci.init(Cipher.DECRYPT_MODE, secretKey, algoParamSpec); + byte[] recoveredText = ci.doFinal(cipherText); + + if (algorithm.contains("TripleDES")) { + throw new RuntimeException( + "Expected InvalidKeyException exception uncaugh"); + } + + // Comparison + if (!Arrays.equals(PLAIN_TEXT, recoveredText)) { + throw new RuntimeException( + "Test failed: plainText is not equal to recoveredText"); + } + out.println("Test Passed."); + } catch (InvalidKeyException ex) { + if (algorithm.contains("TripleDES")) { + out.println("Expected InvalidKeyException raised"); + } else { + throw new RuntimeException(ex); + } + } + } + + public static byte[] generateBytes(int length) { + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) (i & 0xff); + } + return bytes; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TestCipher.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * This is a abstract class used to test various ciphers + */ +public abstract class TestCipher { + + private final String SUNJCE = "SunJCE"; + private final String ALGORITHM; + private final String[] MODES; + private final String[] PADDINGS; + + /* Used to test cipher with different key strengths + Key size tested is increment of KEYCUTTER from MINIMUM_KEY_SIZE to + maximum allowed keysize. + DES/DESede/Blowfish work with currently selected key sizes. + */ + private final int variousKeySize; + private final int KEYCUTTER = 8; + private final int MINIMUM_KEY_SIZE = 32; + + // Used to assert that Encryption/Decryption works with same buffer + // TEXT_LEN is multiple of blocks in order to work against ciphers w/ NoPadding + private final int TEXT_LEN = 800; + private final int ENC_OFFSET = 6; + private final int STORAGE_OFFSET = 3; + private final int PAD_BYTES = 16; + + private final byte[] IV; + private final byte[] INPUT_TEXT; + + TestCipher(String algo, String[] modes, String[] paddings, + boolean keyStrength) throws NoSuchAlgorithmException { + ALGORITHM = algo; + MODES = modes; + PADDINGS = paddings; + this.variousKeySize + = keyStrength ? Cipher.getMaxAllowedKeyLength(ALGORITHM) : 0; + + IV = generateBytes(8); + INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET); + } + + TestCipher(String algo, String[] modes, String[] paddings) { + ALGORITHM = algo; + MODES = modes; + PADDINGS = paddings; + variousKeySize = 0; + + IV = generateBytes(8); + INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET); + } + + private static byte[] generateBytes(int length) { + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) (i & 0xff); + } + return bytes; + } + + private boolean isKeyStrenthSupported() { + return (variousKeySize != 0); + } + + public void runAll() throws InvalidKeyException, + NoSuchPaddingException, InvalidAlgorithmParameterException, + ShortBufferException, IllegalBlockSizeException, + BadPaddingException, NoSuchAlgorithmException, + NoSuchProviderException { + + for (String mode : MODES) { + for (String padding : PADDINGS) { + if (!isKeyStrenthSupported()) { + runTest(mode, padding, 0); + } else { + int keySize = variousKeySize; + while (keySize >= MINIMUM_KEY_SIZE) { + out.println("With Key Strength: " + keySize); + runTest(mode, padding, keySize); + keySize -= KEYCUTTER; + } + } + } + } + } + + private void runTest(String mo, String pad, int keySize) + throws NoSuchPaddingException, BadPaddingException, + ShortBufferException, IllegalBlockSizeException, + InvalidAlgorithmParameterException, InvalidKeyException, + NoSuchAlgorithmException, NoSuchProviderException { + + String TRANSFORMATION = ALGORITHM + "/" + mo + "/" + pad; + out.println("Testing: " + TRANSFORMATION); + + // Initialization + Cipher ci = Cipher.getInstance(TRANSFORMATION, SUNJCE); + KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM, SUNJCE); + if (keySize != 0) { + kg.init(keySize); + } + SecretKey key = kg.generateKey(); + SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM); + + AlgorithmParameterSpec aps = new IvParameterSpec(IV); + if (mo.equalsIgnoreCase("ECB")) { + ci.init(Cipher.ENCRYPT_MODE, key); + } else { + ci.init(Cipher.ENCRYPT_MODE, key, aps); + } + + // Encryption + + byte[] plainText = INPUT_TEXT.clone(); + + // Generate cipher and save to separate buffer + byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN); + + // Generate cipher and save to same buffer + int enc_bytes = ci.update( + INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET); + enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET); + + if (!equalsBlock( + INPUT_TEXT, STORAGE_OFFSET, enc_bytes, + cipherText, 0, cipherText.length)) { + throw new RuntimeException( + "Different ciphers generated with same buffer"); + } + + // Decryption + if (mo.equalsIgnoreCase("ECB")) { + ci.init(Cipher.DECRYPT_MODE, skeySpec); + } else { + ci.init(Cipher.DECRYPT_MODE, skeySpec, aps); + } + + // Recover text from cipher and save to separate buffer + byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length); + + if (!equalsBlock( + plainText, ENC_OFFSET, TEXT_LEN, + recoveredText, 0, recoveredText.length)) { + throw new RuntimeException( + "Recovered text not same as plain text"); + } else { + out.println("Recovered and plain text are same"); + } + + // Recover text from cipher and save to same buffer + int dec_bytes = ci.update( + INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET); + dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET); + + if (!equalsBlock( + plainText, ENC_OFFSET, TEXT_LEN, + INPUT_TEXT, ENC_OFFSET, dec_bytes)) { + throw new RuntimeException( + "Recovered text not same as plain text with same buffer"); + } else { + out.println("Recovered and plain text are same with same buffer"); + } + + out.println("Test Passed."); + } + + private static boolean equalsBlock(byte[] b1, int off1, int len1, + byte[] b2, int off2, int len2) { + if (len1 != len2) { + return false; + } + for (int i = off1, j = off2, k = 0; k < len1; i++, j++, k++) { + if (b1[i] != b2[j]) { + return false; + } + } + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TextLength/DESCipherWrapper.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; + +/** + * Wrapper class to test a given DES algorithm. + */ +public class DESCipherWrapper { + + private final Cipher ci; + private final byte[] iv; + private final SecretKey key; + private final String algo; + private final String mode; + private final String pad; + private final int keyStrength; + private byte[] resultText = null; + + public DESCipherWrapper(String algo, String mode, String pad) + throws NoSuchAlgorithmException, NoSuchPaddingException { + ci = Cipher.getInstance(algo + "/" + mode + "/" + pad); + + iv = new byte[8]; + for (int i = 0; i < 8; i++) { + iv[i] = (byte) (i & 0xff); + } + + KeyGenerator kg = KeyGenerator.getInstance(algo); + key = kg.generateKey(); + keyStrength = algo.equalsIgnoreCase("DESede") ? 112 + : key.getEncoded().length * 8; + + this.algo = algo; + this.mode = mode; + this.pad = pad; + } + + public byte[] getResult() { + return resultText.clone(); + } + + public void execute(int edMode, byte[] inputText) + throws InvalidKeyException, InvalidAlgorithmParameterException, + IllegalBlockSizeException, BadPaddingException, + ShortBufferException, NoSuchAlgorithmException { + AlgorithmParameterSpec aps = null; + + try { + if (!mode.equalsIgnoreCase("ECB")) { + aps = new IvParameterSpec(iv); + } + ci.init(edMode, key, aps); + + // Generate a resultText using a single-part enc/dec + resultText = ci.doFinal(inputText); + + // Generate outputText for each multi-part en/de-cryption + /* Combination #1: + update(byte[], int, int) + doFinal(byte[], int, int) + */ + byte[] part11 = ci.update(inputText, 0, inputText.length); + byte[] part12 = ci.doFinal(); + byte[] outputText1 = new byte[part11.length + part12.length]; + System.arraycopy(part11, 0, outputText1, 0, part11.length); + System.arraycopy(part12, 0, outputText1, part11.length, + part12.length); + + List<byte[]> outputTexts = new ArrayList<>(4); + outputTexts.add(outputText1); + + /* Combination #2: + update(byte[], int, int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part21 = ci.update(inputText, 0, inputText.length - 5); + byte[] part22 = new byte[ci.getOutputSize(inputText.length)]; + int len2 = ci + .doFinal(inputText, inputText.length - 5, 5, part22, 0); + byte[] outputText2 = new byte[part21.length + len2]; + System.arraycopy(part21, 0, outputText2, 0, part21.length); + System.arraycopy(part22, 0, outputText2, part21.length, len2); + + outputTexts.add(outputText2); + + /* Combination #3: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int) + */ + byte[] part31 = new byte[ci.getOutputSize(inputText.length)]; + int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0); + byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8); + byte[] outputText3 = new byte[len3 + part32.length]; + System.arraycopy(part31, 0, outputText3, 0, len3); + System.arraycopy(part32, 0, outputText3, len3, part32.length); + + outputTexts.add(outputText3); + + /* Combination #4: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part41 = new byte[ci.getOutputSize(inputText.length)]; + int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0); + int rest4 = ci.doFinal(inputText, inputText.length - 8, 8, part41, + len4); + byte[] outputText4 = new byte[len4 + rest4]; + System.arraycopy(part41, 0, outputText4, 0, outputText4.length); + + outputTexts.add(outputText4); + + // Compare results + for (int k = 0; k < outputTexts.size(); k++) { + if (!Arrays.equals(resultText, outputTexts.get(k))) { + out.println(" Testing: " + algo + "/" + mode + "/" + pad); + throw new RuntimeException( + "Compare value of resultText and combination " + k + + " are not same. Test failed."); + } + } + if (keyStrength > Cipher.getMaxAllowedKeyLength(algo)) { + throw new RuntimeException( + "Expected exception uncaught, keyStrength " + + keyStrength); + } + } catch (InvalidKeyException ex) { + if (keyStrength <= Cipher.getMaxAllowedKeyLength(algo)) { + out.println("Unexpected exception in " + algo + "/" + mode + + "/" + pad + " , KeySize " + keyStrength); + throw ex; + } + out.println("Caught InvalidKeyException as expected"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.InvalidParameterSpecException; +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * PBECipherWrapper is the abstract class for all concrete PBE Cipher wrappers. + */ +public abstract class PBECipherWrapper { + + public static final int ITERATION_COUNT = 1000; + private final String algorithm; + private final byte[] salt; + protected SecretKey key; + protected Cipher ci; + protected String baseAlgo; + protected byte[] resultText = null; + protected AlgorithmParameterSpec aps = null; + + public PBECipherWrapper(String algorithm, int saltSize) { + this.algorithm = algorithm; + baseAlgo = algorithm.split("/")[0].toUpperCase(); + salt = generateSalt(saltSize); + } + + protected abstract void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException; + + public void execute(int edMode, byte[] inputText) + throws InvalidAlgorithmParameterException, + InvalidParameterSpecException, IllegalBlockSizeException, + BadPaddingException, ShortBufferException, InvalidKeyException { + // Initialize + initCipher(edMode); + + // Generate a resultText using a single-part enc/dec + resultText = ci.doFinal(inputText); + + // Generate outputText for each multi-part en/de-cryption + /* Combination #1: + update(byte[], int, int) + doFinal(byte[], int, int) + */ + byte[] part11 = ci.update(inputText, 0, inputText.length); + byte[] part12 = ci.doFinal(); + byte[] outputText1 = new byte[part11.length + part12.length]; + System.arraycopy(part11, 0, outputText1, 0, part11.length); + System.arraycopy(part12, 0, outputText1, part11.length, part12.length); + + List<byte[]> outputTexts = new ArrayList<>(4); + outputTexts.add(outputText1); + + /* Combination #2: + update(byte[], int, int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part21 = ci.update(inputText, 0, inputText.length - 5); + byte[] part22 = new byte[ci.getOutputSize(inputText.length)]; + int len2 = ci.doFinal(inputText, inputText.length - 5, 5, part22, 0); + byte[] outputText2 = new byte[part21.length + len2]; + System.arraycopy(part21, 0, outputText2, 0, part21.length); + System.arraycopy(part22, 0, outputText2, part21.length, len2); + + outputTexts.add(outputText2); + + /* Combination #3: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int) + */ + byte[] part31 = new byte[ci.getOutputSize(inputText.length)]; + int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0); + byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8); + byte[] outputText3 = new byte[len3 + part32.length]; + System.arraycopy(part31, 0, outputText3, 0, len3); + System.arraycopy(part32, 0, outputText3, len3, part32.length); + + outputTexts.add(outputText3); + + /* Combination #4: + update(byte[], int, int, byte[], int) + doFinal(byte[], int, int, byte[], int) + */ + byte[] part41 = new byte[ci.getOutputSize(inputText.length)]; + int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0); + int rest4 = ci + .doFinal(inputText, inputText.length - 8, 8, part41, len4); + byte[] outputText4 = new byte[len4 + rest4]; + System.arraycopy(part41, 0, outputText4, 0, outputText4.length); + + outputTexts.add(outputText4); + + // Compare results + for (int k = 0; k < outputTexts.size(); k++) { + if (!Arrays.equals(resultText, outputTexts.get(k))) { + throw new RuntimeException( + "Compare value of resultText and combination " + k + + " are not same. Test failed."); + } + } + + } + + public final byte[] generateSalt(int numberOfBytes) { + byte[] aSalt = new byte[numberOfBytes]; + for (int i = 0; i < numberOfBytes; i++) { + aSalt[i] = (byte) (i & 0xff); + } + return aSalt; + } + + public byte[] getResult() { + return resultText; + } + + public String getAlgorithm() { + return algorithm; + } + + public byte[] getSalt() { + return salt; + } + + /** + * Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm. + */ + public static class PBKDF2 extends PBECipherWrapper { + + private static final int PBKDF2_SALT_SIZE = 64; + private static final int CIPHER_KEY_SIZE = 128; + private static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"; + private static final String KEY_ALGORITHM = "AES"; + private byte[] iv = null; + + public PBKDF2(String algo, String passwd) + throws InvalidKeySpecException, NoSuchAlgorithmException, + NoSuchPaddingException { + super(algo, PBKDF2_SALT_SIZE); + + ci = Cipher.getInstance(CIPHER_TRANSFORMATION); + + PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray(), getSalt(), + ITERATION_COUNT, CIPHER_KEY_SIZE); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo); + key = keyFactory.generateSecret(pbeKeySpec); + } + + @Override + protected void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException { + if (Cipher.ENCRYPT_MODE == mode) { + ci.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncoded(), + KEY_ALGORITHM)); + iv = ci.getParameters().getParameterSpec(IvParameterSpec.class) + .getIV(); + } else { + ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getEncoded(), + KEY_ALGORITHM), new IvParameterSpec(iv)); + } + } + } + + /** + * Wrapper class to test a given AES-based PBE algorithm. + */ + public static class AES extends PBECipherWrapper { + + private AlgorithmParameters pbeParams; + + public AES(String algo, String passwd) + throws NoSuchAlgorithmException, NoSuchPaddingException, + InvalidKeySpecException { + super(algo, 0); + + ci = Cipher.getInstance(algo); + + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo); + key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray())); + } + + @Override + protected void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException { + if (Cipher.ENCRYPT_MODE == mode) { + ci.init(Cipher.ENCRYPT_MODE, key); + pbeParams = ci.getParameters(); + } else { + ci.init(Cipher.DECRYPT_MODE, key, pbeParams); + } + } + } + + /** + * Wrapper class to test a given PBE algorithm. + */ + public static class Legacy extends PBECipherWrapper { + + private static final int PBE_SALT_SIZE = 8; + + public Legacy(String algo, String passwd) + throws NoSuchAlgorithmException, NoSuchPaddingException, + InvalidKeySpecException { + super(algo, PBE_SALT_SIZE); + + SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]); + key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray())); + + aps = new PBEParameterSpec(getSalt(), ITERATION_COUNT); + + ci = Cipher.getInstance(algo); + } + + @Override + protected void initCipher(int mode) throws InvalidKeyException, + InvalidAlgorithmParameterException, InvalidParameterSpecException { + ci.init(mode, key, aps); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +/* + * @test + * @bug 8048601 + * @summary Performs multiple-part encryption/decryption depending on the + * specified encryption mode and check if the results obtained by + * different ways are the same. + */ +public class TestCipherTextLength { + + /* Algorithms tested by DESCipherWrapper */ + private static final String[] DES_ALGORITHMS = {"DES", "DESede", + "Blowfish"}; + private static final String[] DES_MODES = {"ECB", "CBC", "PCBC"}; + private static final String[] DES_PADDING = {"PKCS5Padding"}; + + /* Algorithms tested by PBECipherWrapper */ + private static final String[] PBE_ALGORITHMS = {"PBEWithMD5AndDES", + "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5ANDTripleDES", + "PBEWithMD5AndTripleDES/CBC/PKCS5Padding", "PBEwithSHA1AndDESede", + "PBEwithSHA1AndDESede/CBC/PKCS5Padding", "PBEwithSHA1AndRC2_40", + "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", "PBEWithSHA1AndRC2_128", + "PBEWithSHA1andRC2_128/CBC/PKCS5Padding", "PBEWithSHA1AndRC4_40", + "PBEWithsha1AndRC4_40/ECB/NoPadding", "PBEWithSHA1AndRC4_128", + "PBEWithSHA1AndRC4_128/ECB/NoPadding", "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256", "PBKDF2WithHmacSHA1", + "PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256", + "PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512"}; + private static final String PBE_PASSWORD = "Hush, it's a secret!!"; + + // Algorithm tested by PBKDF2Wrappter + private static final String PBKDF2 = "PBKDF2"; + + // Algorithm tested by AESPBEWrapper + private static final String AES = "AES"; + + public static void main(String[] args) throws Exception { + byte[] plainText = new byte[64]; + for (int i = 0; i < 64; i++) { + plainText[i] = (byte) (i & 0xff); + } + + new TestCipherTextLength().runAll(plainText); + } + + public void runAll(byte[] plainText) throws Exception { + + // Testing DES/Blowfish Cipher + for (String algorithm : DES_ALGORITHMS) { + for (String desMode : DES_MODES) { + for (String padding : DES_PADDING) { + out.println("=>Testing: " + algorithm + "/" + desMode + + "/" + padding); + DESCipherWrapper desCi = new DESCipherWrapper(algorithm, + desMode, padding); + desCi.execute(Cipher.ENCRYPT_MODE, plainText); + desCi.execute(Cipher.DECRYPT_MODE, desCi.getResult()); + if (!Arrays.equals(plainText, desCi.getResult())) { + throw new RuntimeException( + "Plain and recovered texts are not same for:" + + algorithm + "/" + desMode + "/" + + padding); + } + } + } + } + + // Testing PBE Cipher + for (String algorithm : PBE_ALGORITHMS) { + int maxKeyLen = Cipher.getMaxAllowedKeyLength(algorithm); + boolean isUnlimited = maxKeyLen == Integer.MAX_VALUE; + if (!isUnlimited + && (algorithm.contains("TripleDES") || algorithm + .contains("AES_256"))) { + out.println("Test " + algorithm + " will be ignored"); + continue; + } + + out.println("=>Testing: " + algorithm); + PBECipherWrapper pbeCi = createWrapper(algorithm, PBE_PASSWORD); + pbeCi.execute(Cipher.ENCRYPT_MODE, plainText); + pbeCi.execute(Cipher.DECRYPT_MODE, pbeCi.getResult()); + if (!Arrays.equals(plainText, pbeCi.getResult())) { + throw new RuntimeException( + "Plain and recovered texts are not same for:" + + algorithm); + } + } + } + + private PBECipherWrapper createWrapper(String algo, String passwd) + throws InvalidKeySpecException, NoSuchAlgorithmException, + NoSuchPaddingException { + if (algo.contains(PBKDF2)) { + return new PBECipherWrapper.PBKDF2(algo, passwd); + } else if (algo.contains(AES)) { + return new PBECipherWrapper.AES(algo, passwd); + } else { + return new PBECipherWrapper.Legacy(algo, passwd); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/jndi/ldap/SimpleClientIdHashCode.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8158802 + * @summary com.sun.jndi.ldap.SimpleClientId produces wrong hash code + * @modules java.naming/com.sun.jndi.ldap + */ + +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import javax.naming.ldap.Control; + + +public class SimpleClientIdHashCode { + public static void main(String[] args) throws Throwable { + Class<?> simpleClientIdClass + = Class.forName("com.sun.jndi.ldap.SimpleClientId"); + Constructor<?> init = simpleClientIdClass.getDeclaredConstructor( + int.class, String.class, int.class, String.class, + Control[].class, OutputStream.class, String.class, + String.class, Object.class); + init.setAccessible(true); + + Object p1 = new byte[]{66,77}; + Object p2 = new char[]{'w','d'}; + Object p3 = "word"; + + test(init, new byte[]{65}, new byte[]{65}); + test(init, new char[]{'p'}, new char[]{'p'}); + test(init, "pass", "pass"); + test(init, p1, p1); + test(init, p2, p2); + test(init, p3, p3); + test(init, null, null); + } + + private static void test(Constructor<?> init, Object pass1, Object pass2) + throws Throwable { + + Object o1 = init.newInstance(1, "host", 3, "", null, System.out, + null, null, pass1); + Object o2 = init.newInstance(1, "host", 3, "", null, System.out, + null, null, pass2); + + if (!o1.equals(o2)) + throw new RuntimeException("Objects not equal"); + + if (o1.hashCode() != o2.hashCode()) + throw new RuntimeException("Inconsistent hash codes"); + } +}
--- a/test/demo/jvmti/hprof/CpuOldTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/CpuOldTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with cpu=old */ - hprof = new DemoRun("hprof", "cpu=old"); + hprof = new DemoRun("hprof", "cpu=old,file=cpuold.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/CpuSamplesTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/CpuSamplesTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with cpu=samples */ - hprof = new DemoRun("hprof", "cpu=samples"); + hprof = new DemoRun("hprof", "cpu=samples,file=cpusamples.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with cpu=times */ - hprof = new DemoRun("hprof", "cpu=times"); + hprof = new DemoRun("hprof", "cpu=times,file=cputimedefineclass.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/CpuTimesTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/CpuTimesTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with cpu=times */ - hprof = new DemoRun("hprof", "cpu=times"); + hprof = new DemoRun("hprof", "cpu=times,file=cputimes.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapAllTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/HeapAllTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with heap=all */ - hprof = new DemoRun("hprof", "heap=all"); + hprof = new DemoRun("hprof", "heap=all,file=heapall.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapBinaryFormatTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/HeapBinaryFormatTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent to get binary format dump */ - hprof = new DemoRun("hprof", "heap=dump,format=b,logflags=4"); + hprof = new DemoRun("hprof", "heap=dump,format=b,logflags=4,file=heapbinaryformat.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapDumpTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/HeapDumpTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with heap=dump */ - hprof = new DemoRun("hprof", "heap=dump"); + hprof = new DemoRun("hprof", "heap=dump,file=heapdump.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapSitesTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/HeapSitesTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with heap=sites */ - hprof = new DemoRun("hprof", "heap=sites"); + hprof = new DemoRun("hprof", "heap=sites,file=heapsites.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/MonitorTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/MonitorTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ DemoRun hprof; /* Run JVMTI hprof agent with monitor=y */ - hprof = new DemoRun("hprof", "monitor=y"); + hprof = new DemoRun("hprof", "monitor=y,file=monitor.txt"); hprof.runit(args[0]); /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/OptionsTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/OptionsTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,10 @@ DemoRun hprof; List<String> options = new LinkedList<String>(); - options.add("cpu=samples,depth=0"); - options.add("cpu=times,depth=0"); - options.add("cpu=old,depth=0"); - options.add("depth=0"); + options.add("cpu=samples,depth=0,file=options0.txt"); + options.add("cpu=times,depth=0,file=options1.txt"); + options.add("cpu=old,depth=0,file=options2.txt"); + options.add("depth=0,file=options3.txt"); for(String option: options) { /* Run JVMTI hprof agent with various options */
--- a/test/demo/jvmti/hprof/StackMapTableTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/demo/jvmti/hprof/StackMapTableTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -40,10 +40,10 @@ DemoRun hprof; List<String> options = new LinkedList<String>(); - options.add("cpu=samples"); - options.add("cpu=times"); - options.add("heap=sites"); - options.add(""); + options.add("cpu=samples,file=stackmaptable0.txt"); + options.add("cpu=times,file=stackmaptable1.txt"); + options.add("heap=sites,file=stackmaptable2.txt"); + options.add("file=stackmaptable3.txt"); for(String option: options) { /* Run JVMTI hprof agent with various options */
--- a/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -94,6 +94,15 @@ int screenX = (int) splashBounds.getCenterX(); int screenY = (int) splashBounds.getCenterY(); + if(splashBounds.width != IMAGE_WIDTH){ + throw new RuntimeException( + "SplashScreen#getBounds has wrong width"); + } + if(splashBounds.height != IMAGE_HEIGHT){ + throw new RuntimeException( + "SplashScreen#getBounds has wrong height"); + } + Robot robot = new Robot(); Color splashScreenColor = robot.getPixelColor(screenX, screenY);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Window/WindowJumpingTest/WindowJumpingTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8080729 + * @summary Dialogs on multiscreen jump to parent frame on focus gain + * @author Dmitry Markov + * @library ../../regtesthelpers + * @build Util + * @run main WindowJumpingTest + */ +import java.awt.*; + +import test.java.awt.regtesthelpers.Util; + +public class WindowJumpingTest { + public static void main(String[] args) throws AWTException { + Robot r = Util.createRobot(); + + GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] graphicsDevices = graphicsEnvironment.getScreenDevices(); + if (graphicsDevices.length < 2) { + System.out.println("This is multi-screen test... Skipping!"); + return; + } + + Frame frame = new Frame("Frame", graphicsDevices[0].getDefaultConfiguration()); + frame.setSize(400, 300); + frame.setVisible(true); + Util.waitForIdle(r); + + Dialog dialog = new Dialog(frame, "Dialog", false, graphicsDevices[1].getDefaultConfiguration()); + dialog.setSize(400, 300); + dialog.setVisible(true); + Util.waitForIdle(r); + + checkGraphicsDevice(frame, graphicsDevices[0]); + checkGraphicsDevice(dialog, graphicsDevices[1]); + + Util.clickOnComp(frame, r); + Util.waitForIdle(r); + + checkGraphicsDevice(frame, graphicsDevices[0]); + checkGraphicsDevice(dialog, graphicsDevices[1]); + + Util.clickOnComp(dialog, r); + Util.waitForIdle(r); + + checkGraphicsDevice(frame, graphicsDevices[0]); + checkGraphicsDevice(dialog, graphicsDevices[1]); + + dialog.dispose(); + frame.dispose(); + } + + private static void checkGraphicsDevice(Window window, GraphicsDevice graphicsDevice) { + GraphicsDevice actualGraphicsDevice = window.getGraphicsConfiguration().getDevice(); + + if (!actualGraphicsDevice.equals(graphicsDevice)) { + System.err.println("Expected screen: " + graphicsDevice); + System.err.println("Actual screen: "+ actualGraphicsDevice); + throw new RuntimeException("Test FAILED: " + window + " is displayed on wrong screen"); + } + } +} +
--- a/test/java/awt/Window/WindowsLeak/WindowsLeak.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/awt/Window/WindowsLeak/WindowsLeak.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,41 +23,40 @@ /* * @test - * @bug 8013563 + * @bug 8013563 8028486 * @summary Tests that windows are removed from windows list + * @library /javax/swing/regtesthelpers + * @build Util * @run main/othervm -Xms32M -Xmx32M WindowsLeak */ -import java.awt.*; -import sun.awt.AppContext; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.Window; +import java.lang.ref.WeakReference; +import java.util.Vector; -import java.lang.ref.WeakReference; - -import java.util.Vector; +import sun.awt.AppContext; +import sun.java2d.Disposer; public class WindowsLeak { - public static void main(String[] args) { - for (int i = 0; i < 100; i++) - { + private static volatile boolean disposerPhantomComplete; + + public static void main(String[] args) throws Exception { + Robot r = new Robot(); + for (int i = 0; i < 100; i++) { Frame f = new Frame(); f.pack(); f.dispose(); } + r.waitForIdle(); - Vector garbage = new Vector(); - while (true) - { - try - { - garbage.add(new byte[1000]); - } - catch (OutOfMemoryError e) - { - break; - } + Disposer.addRecord(new Object(), () -> disposerPhantomComplete = true); + + while (!disposerPhantomComplete) { + Util.generateOOME(); } - garbage = null; Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>) AppContext.getAppContext().get(Window.class);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/im/8148984/bug8148984.html Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,38 @@ +<!-- + Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. +--> + +<html> +<body> +Verify that Chinese comma can be entered in JTextField with Pinyin input method (IM). + +This test is for OS X only. For other platforms please simply press "Pass". + +1. Go to "System Preferences -> Keyboard -> Input Sources" and add "Pinyin – Traditional" or "Pinyin – Simplified" IM from Chinese language group. +2. Set current IM to "Pinyin". +3. Set focus to the text field of the test and press "comma" character on the keyboard. +4. Set current IM to the IM used before "Pinyin" was set. +5. If "," character is displayed in the text area, press "Pass", if "," character is displayed, press "Fail". + +<applet code="bug8148984.class" width=400 height=400></applet> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/im/8148984/bug8148984.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8148984 + * @summary Chinese Comma cannot be entered using Pinyin Input Method on OS X + * @author Dmitry Markov + * @run applet/manual=yesno bug8148984.html + */ + +import javax.swing.*; + +public class bug8148984 extends JApplet { + @Override + public void init() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JPanel panel = new JPanel(); + panel.add(new JLabel("Text field:")); + panel.add(new JTextField(20)); + add(panel); + } + }); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/im/8154816/bug8154816.html Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,39 @@ +<!-- + Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. +--> + +<html> +<body> +Verify that Caps Lock key works properly with Pinyin input method, (i.e. if +Caps Lock is pressed, input should be swithced to lowercase latin letters). + +This test is for OS X only. For other platforms please simply press "Pass". + +1. Go to "System Preferences -> Keyboard -> Input Sources" and add "Pinyin – Traditional" or "Pinyin – Simplified" IM from Chinese language group. +2. Set current IM to "Pinyin". +3. Set focus to the text field of the test and press Caps Lock key on the keyboard. +4. Press "a" character on the keyboard +5. If "a" character is displayed in the text field, press "Pass", if "A" character is displayed, press "Fail". + +<applet code="bug8154816.class" width=400 height=400></applet> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/im/8154816/bug8154816.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8154816 + * @summary Caps Lock doesn't work as expected when using Pinyin Simplified input method + * @author Dmitry Markov + * @run applet/manual=yesno bug8154816.html + */ + +import javax.swing.*; + +public class bug8154816 extends JApplet { + @Override + public void init() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JPanel panel = new JPanel(); + panel.add(new JLabel("Text field:")); + panel.add(new JTextField(20)); + add(panel); + } + }); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/annotation/AnnotationWithLambda.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8147585 + * @summary Check Annotation with Lambda, with or without parameter + * @run testng AnnotationWithLambda + */ + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Method; +import java.util.function.Consumer; + +import org.testng.annotations.*; +import static org.testng.Assert.*; + +public class AnnotationWithLambda { + + @Test + void testAnnotationWithLambda() { + Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods(); + for (Method method : methods) { + assertTrue((method.isAnnotationPresent(LambdaWithParameter.class)) && + (method.isAnnotationPresent(LambdaWithoutParameter.class))); + + } + } + + static class MethodsWithAnnotations { + + @LambdaWithParameter + @LambdaWithoutParameter + public void testAnnotationLambda() { + } + } +} + +@Target(value = ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@interface LambdaWithParameter { + Consumer<Integer> f1 = a -> { + System.out.println("lambda has parameter"); + }; +} + +@Target(value = ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@interface LambdaWithoutParameter { + Runnable r = () -> System.out.println("lambda without parameter"); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ArrayConstructorTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8155106 + * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayConstructorTest + */ +package test.java.lang.invoke; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +import static java.lang.invoke.MethodType.methodType; + +import static org.testng.AssertJUnit.*; + +import org.testng.annotations.*; + + +public class ArrayConstructorTest { + + static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); + + @Test + public static void testFindConstructorArray() { + boolean caught = false; + try { + MethodHandle h = LOOKUP.findConstructor(Object[].class, methodType(void.class)); + } catch (NoSuchMethodException nsme) { + assertEquals("no constructor for array class: [Ljava.lang.Object;", nsme.getMessage()); + caught = true; + } catch (Exception e) { + throw new AssertionError("unexpected exception: " + e); + } + assertTrue(caught); + } + +} +
--- a/test/java/lang/invoke/CustomizedLambdaFormTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/lang/invoke/CustomizedLambdaFormTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -26,7 +26,7 @@ /* @test * @summary Assertion in LambdaFormEditor.bindArgumentType is too strong * - * @run main/bootclasspath -esa java.lang.invoke.CustomizedLambdaFormTest + * @run main/othervm/bootclasspath -esa java.lang.invoke.CustomizedLambdaFormTest */ public class CustomizedLambdaFormTest {
--- a/test/java/lang/invoke/PermuteArgsTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/lang/invoke/PermuteArgsTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* @test * @summary unit tests for method handles which permute their arguments + * @library /lib/testlibrary/jsr292 /lib/testlibrary * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest */ /* Examples of manual runs: @@ -36,6 +37,8 @@ import org.testng.*; import org.testng.annotations.*; +import com.oracle.testlibrary.jsr292.CodeCacheOverflowProcessor; + import java.util.*; import java.lang.reflect.*; @@ -122,9 +125,15 @@ } new PermuteArgsTest().test(); } + static int testCases; + @Test public void test() throws Throwable { + CodeCacheOverflowProcessor.runMHTest(this::test0); + } + + public void test0() throws Throwable { testCases = 0; Lookup lookup = lookup(); for (Method m : lookup.lookupClass().getDeclaredMethods()) {
--- a/test/java/lang/invoke/VarargsArrayTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/lang/invoke/VarargsArrayTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -32,13 +32,12 @@ * @summary unit tests for varargs array methods: MethodHandleInfo.varargsArray(int), * MethodHandleInfo.varargsArray(Class,int) & MethodHandleInfo.varargsList(int) * @library /lib/testlibrary /lib/testlibrary/jsr292 - * @run main/bootclasspath java.lang.invoke.VarargsArrayTest - * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250 - * java.lang.invoke.VarargsArrayTest + * @run main/othervm/bootclasspath java.lang.invoke.VarargsArrayTest + * @run main/othervm/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250 java.lang.invoke.VarargsArrayTest */ /* This might take a while and burn lots of metadata: - * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.EXHAUSTIVE=true java.lang.invoke.VarargsArrayTest + * @run main/othervm/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.EXHAUSTIVE=true java.lang.invoke.VarargsArrayTest */ public class VarargsArrayTest { private static final Class<?> CLASS = VarargsArrayTest.class;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/KeyStore/TestKeyStoreBasic.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; + +/* + * @test + * @bug 8048621 8133090 + * @summary Test basic operations with keystores (jks, jceks, pkcs12) + * @author Yu-Ching Valerie PENG + */ +public class TestKeyStoreBasic { + + private static final String PRIVATE_KEY_PKCS8_BASE64 = "" + + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCpyz97liuWPDYcLH9TX8BiT78o" + + "lCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgKmLhuczF3M9VIcWr+" + + "JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz7leikne7KmclHvTfvFd0WDI7Gb9v" + + "o4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXRv5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfF" + + "e1DDsMg/KpKGiILYZ+g2qtVMZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e" + + "+sO6H24w2F19AgMBAAECggEBAId/12187dO6wUPCjumuJA1QrrBnbKdKONyai36uoc1Od4s5QFj7" + + "+hEIeS7rbGNYQuBvnkgusAbzkW0FIpxpHce3EJez/emux6pEOKoP77BwMt9gy+txyu0+BHi91FQg" + + "AGvrnQDO5EYVY4Cz/WjOsJzKu8zVLg+DS0Toa2qRFwmUe9mVAXPNOCZ3Oae/Q6tCDsaINNw0fmjj" + + "jn6uohPbS+n6xENG3FkQXB36getXy310xTGED2J27cmAQH6gLR6Kl2iROzNPbbpBqbuemI9kbcld" + + "EwBS1jRfZWeaPstYA1niVrE9UgUBzemnoh4TDkG076sYthHMr5QFGjPswnwtJ4ECgYEA0sURQ5+v" + + "baH4tdaemI3qpnknXTlzSpuZZmAoyvY0Id0mlduwKwmZ3Y5989wHfnnhFfyNO4IkTKjI2Wp97qP5" + + "4eqUNpA7FtNU7KUzMcFDTtwtNZuRYMrKlqo2lLbA+gVrAYpYZFL4b7tcwtX4DnYorDsmude6W8sG" + + "4Mx2VdFJC9UCgYEAzjsdXCYH5doWUHb0dvn9ID7IikffEMRM720MRjrnnnVbpzx6ACntkPDNZg7p" + + "TRE/mx7iBz81ZaUWE+V0wd0JvCHEdpAz3mksyvDFhU4Bgs6xzf2pSul5muhsx3hHcvvPezz5Bnxs" + + "faJlzkxfwotyGmvWN15GA/pyfsZjsbbTpwkCgYAO6NnbysQCIV8SnegCKqfatt9N/O5m7LLhRxQb" + + "p2bwrlA4cZ34rWkw/w9x3LK7A6wkfgUPnJkswxPSLXJTG05l6M4rPfCwIKr1Qopojp9QSMr569NQ" + + "4YeLOOc7heIIzbFQHpU6I5Rncv2Q2sn9W+ZsqJKIuvX34FjQNiZ406EzMQKBgHSxOGS61D84DuZK" + + "2Ps1awhC3kB4eHzJRms3vflDPWoJJ+pSKwpKrzUTPHXiPBqyhtYkPGszVeiE6CAr9sv3YZnFVaBs" + + "6hyQUJsob+uE/w/gGvXe8VsFDx0bJOodYfhrCbTHBHWqE81nBcocpxayxsayfAzqWB3KKd0YLrMR" + + "K2PZAoGAcZa8915R2m0KZ6HVJUt/JDR85jCbN71kcVDFY2XSFkOJvOdFoHNfRckfLzjq9Y2MSSTV" + + "+QDWbDo2doUQCejJUTaN8nP79tfyir24X5uVPvQaeVoGTKYb+LfUqK0F60lStmjuddIGSZH55y3v" + + "+9XjmxbVERtd1lqgQg3VlmKlEXY="; + + /* + * Certificate: + * Data: + * Version: 3 (0x2) + * Serial Number: 7 (0x7) + * Signature Algorithm: sha512WithRSAEncryption + * Issuer: CN=Root + * Validity + * Not Before: Sep 1 18:03:59 2015 GMT + * Not After : Jan 17 18:03:59 2043 GMT + * Subject: CN=EE + */ + private static final String CERTIFICATE = "" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIDHTCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQ0FADAPMQ0wCwYDVQQDDARSb290\n" + + "MB4XDTE1MDkwMTE4MDM1OVoXDTQzMDExNzE4MDM1OVowDTELMAkGA1UEAwwCRUUw\n" + + "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpyz97liuWPDYcLH9TX8Bi\n" + + "T78olCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgK\n" + + "mLhuczF3M9VIcWr+JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz\n" + + "7leikne7KmclHvTfvFd0WDI7Gb9vo4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXR\n" + + "v5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfFe1DDsMg/KpKGiILYZ+g2qtVM\n" + + "ZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e+sO6H24w2F19\n" + + "AgMBAAGjgYUwgYIwNAYDVR0fBC0wKzApoCegJYYjbGRhcDovL2xkYXAuaG9zdC5m\n" + + "b3IuY3JsZHAvbWFpbi5jcmwwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzAChi5s\n" + + "ZGFwOi8vbGRhcC5ob3N0LmZvci5haWEvZGM9Um9vdD9jQUNlcnRpZmljYXRlMA0G\n" + + "CSqGSIb3DQEBDQUAA4IBAQBWDfZHpuUx0yn5d3+BuztFqoks1MkGdk+USlH0TB1/\n" + + "gWWBd+4S4PCKlpSur0gj2rMW4fP5HQfNlHci8JV8/bG4KuKRAXW56dg1818Hl3pc\n" + + "iIrUSRn8uUjH3p9qb+Rb/u3mmVQRyJjN2t/zceNsO8/+Dd808OB9aEwGs8lMT0nn\n" + + "ZYaaAqYz1GIY/Ecyx1vfEZEQ1ljo6i/r70C3igbypBUShxSiGsleiVTLOGNA+MN1\n" + + "/a/Qh0bkaQyTGqK3bwvzzMeQVqWu2EWTBD/PmND5ExkpRICdv8LBVXfLnpoBr4lL\n" + + "hnxn9+e0Ah+t8dS5EKfn44w5bI5PCu2bqxs6RCTxNjcY\n" + + "-----END CERTIFICATE-----\n"; + + private static final char[] PASSWD2 = new char[] { + 'b', 'o', 'r', 'e', 'd' + }; + private static final char[] PASSWDK = "cannot be null" + .toCharArray(); + private static final String[] KS_Type = { + "jks", "jceks", "pkcs12", "PKCS11KeyStore" + }; + private static final String[] PROVIDERS = { + "SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris" + }; + private static final String ALIAS_HEAD = "test"; + + public static void main(String args[]) throws Exception { + TestKeyStoreBasic jstest = new TestKeyStoreBasic(); + jstest.run(); + } + + public void run() throws Exception { + for (String provider : PROVIDERS) { + try { + runTest(provider); + System.out.println("Test with provider " + provider + "passed"); + } catch (java.security.KeyStoreException e) { + if (provider.equals("SunPKCS11-Solaris")) { + System.out.println("KeyStoreException is expected: " + + "PKCS11KeyStore is invalid keystore type: " + e); + } else { + throw e; + } + } catch (NoSuchProviderException e) { + String osName = System.getProperty("os.name"); + if (provider.equals("SunPKCS11-Solaris") + && !osName.equals("SunOS")) { + System.out.println("Skip SunPKCS11-Solaris provider on " + + osName); + } else { + throw e; + } + } + } + } + + public void runTest(String provider) throws Exception { + + // load private key + // all keystore types should support private keys + KeySpec spec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder().decode(PRIVATE_KEY_PKCS8_BASE64)); + PrivateKey privateKey = KeyFactory.getInstance("RSA") + .generatePrivate(spec); + + // load x509 certificate + Certificate cert; + try (InputStream is = new BufferedInputStream( + new ByteArrayInputStream(CERTIFICATE.getBytes()))) { + cert = CertificateFactory.getInstance("X.509") + .generateCertificate(is); + } + + int numEntries = 5; + String type = null; + for (int i = 0; i < PROVIDERS.length; i++) { + if (provider.compareTo(PROVIDERS[i]) == 0) { + type = KS_Type[i]; + break; + } + } + + System.out.printf("Test %s provider and %s keystore%n", provider, type); + KeyStore ks = KeyStore.getInstance(type, provider); + KeyStore ks2 = KeyStore.getInstance(type, ks.getProvider().getName()); + + // create an empty key store + ks.load(null, null); + + // store the secret keys + for (int j = 0; j < numEntries; j++) { + ks.setKeyEntry(ALIAS_HEAD + j, privateKey, PASSWDK, + new Certificate[] { cert }); + } + + // initialize the 2nd key store object with the 1st one + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ks.store(baos, PASSWDK); + byte[] bArr = baos.toByteArray(); + ByteArrayInputStream bais = new ByteArrayInputStream(bArr); + ks2.load(bais, null); + + // check 2nd key store type + checkType(ks2, type); + // check the existing aliases for the 2nd key store + checkAlias(ks2, numEntries); + + // compare the creation date of the 2 key stores for all aliases + compareCreationDate(ks, ks2, numEntries); + // remove the last entry from the 2nd key store + numEntries--; + ks2.deleteEntry(ALIAS_HEAD + numEntries); + + // re-initialize the 1st key store with the 2nd key store + baos.reset(); + ks2.store(baos, PASSWD2); + bais = new ByteArrayInputStream(baos.toByteArray()); + try { + // expect an exception since the password is incorrect + ks.load(bais, PASSWDK); + throw new RuntimeException( + "ERROR: passed the loading with incorrect password"); + } catch (IOException ex) { + System.out.println("Expected exception: " + ex); + if (!causedBy(ex, UnrecoverableKeyException.class)) { + ex.printStackTrace(System.out); + throw new RuntimeException("Unexpected cause"); + } + System.out.println("Expected cause: " + + UnrecoverableKeyException.class.getName()); + + bais.reset(); + ks.load(bais, PASSWD2); + bais.reset(); + ks.load(bais, null); + } + + // check key store type + checkType(ks, type); + + // check the existing aliases + checkAlias(ks, numEntries); + + // compare the creation date of the 2 key stores for all aliases + compareCreationDate(ks, ks2, numEntries); + + } + + // check key store type + private void checkType(KeyStore obj, String type) { + if (!obj.getType().equals(type)) { + throw new RuntimeException("ERROR: wrong key store type"); + } + } + + // check the existing aliases + private void checkAlias(KeyStore obj, int range) throws KeyStoreException { + for (int k = 0; k < range; k++) { + if (!obj.containsAlias(ALIAS_HEAD + k)) { + throw new RuntimeException("ERROR: alias (" + k + + ") should exist"); + } + } + } + + // compare the creation dates - true if all the same + private void compareCreationDate(KeyStore o1, KeyStore o2, int range) + throws KeyStoreException { + String alias; + for (int k = 0; k < range; k++) { + alias = ALIAS_HEAD + k; + if (!o1.getCreationDate(alias).equals(o2.getCreationDate(alias))) { + throw new RuntimeException("ERROR: entry creation time (" + k + + ") differs"); + } + } + } + + // checks if an exception was caused by specified exception class + private static boolean causedBy(Exception e, Class klass) { + Throwable cause = e; + while ((cause = cause.getCause()) != null) { + if (cause.getClass().equals(klass)) { + return true; + } + } + return false; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/KeyStore/TestKeyStoreEntry.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.security.Key; +import java.security.KeyStore; +import java.security.Provider; +import java.security.Security; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; + +/* + * @test + * @bug 8048621 + * @summary Test the basic operations of KeyStore entry, provided by SunJCE + * (jceks), and SunPKCS11-Solaris(PKCS11KeyStore) + * @author Yu-Ching Valerie PENG + */ + +public class TestKeyStoreEntry { + private static final char[] PASSWDK = new char[] { + 't', 'e', 'r', 'c', 'e', 's' + }; + private static final char[] PASSWDF = new String("guardian Angel") + .toCharArray(); + private static final String[] KS_ALGOS = { + "DES", "DESede", "Blowfish" + }; + private static final int NUM_ALGOS = KS_ALGOS.length; + + private static final String[] KS_TYPE = { + "jks", "jceks", "pkcs12", "PKCS11KeyStore" + }; + private static final String[] PRO_TYPE = { + "SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris" + }; + + private final SecretKey[] sks = new SecretKey[NUM_ALGOS]; + + TestKeyStoreEntry() throws Exception { + // generate secret keys which are to be stored in the jce + // key store object + KeyGenerator[] kgs = new KeyGenerator[NUM_ALGOS]; + for (int i = 0; i < NUM_ALGOS; i++) { + kgs[i] = KeyGenerator.getInstance(KS_ALGOS[i], "SunJCE"); + sks[i] = kgs[i].generateKey(); + } + + } + + public static void main(String args[]) throws Exception { + TestKeyStoreEntry jstest = new TestKeyStoreEntry(); + jstest.run(); + } + + public void run() throws Exception { + + Provider[] providers = Security.getProviders(); + for (Provider p: providers) { + String prvName = p.getName(); + if (prvName.startsWith("SunJCE") + || prvName.startsWith("SunPKCS11-Solaris")) { + try { + runTest(p); + out.println("Test with provider " + p.getName() + "" + + " passed"); + + } catch (java.security.KeyStoreException e) { + if (prvName.startsWith("SunPKCS11-Solaris")) { + out.println("KeyStoreException is expected because " + + "PKCS11KeyStore is invalid keystore type."); + e.printStackTrace(); + } else { + throw e; + } + } + } + } + } + + public void runTest(Provider p) throws Exception { + try (FileOutputStream fos = new FileOutputStream("jceks"); + FileInputStream fis = new FileInputStream("jceks");) { + + KeyStore ks = KeyStore.getInstance("jceks", p); + // create an empty key store + ks.load(null, null); + + // store the secret keys + String aliasHead = new String("secretKey"); + for (int j = 0; j < NUM_ALGOS; j++) { + ks.setKeyEntry(aliasHead + j, sks[j], PASSWDK, null); + } + + // write the key store out to a file + ks.store(fos, PASSWDF); + // wipe clean the existing key store + for (int k = 0; k < NUM_ALGOS; k++) { + ks.deleteEntry(aliasHead + k); + } + if (ks.size() != 0) { + throw new RuntimeException("ERROR: re-initialization failed"); + } + + // reload the key store with the file + ks.load(fis, PASSWDF); + + // check the integrity/validaty of the key store + Key temp = null; + String alias = null; + if (ks.size() != NUM_ALGOS) { + throw new RuntimeException("ERROR: wrong number of key" + + " entries"); + } + + for (int m = 0; m < ks.size(); m++) { + alias = aliasHead + m; + temp = ks.getKey(alias, PASSWDK); + // compare the keys + if (!temp.equals(sks[m])) { + throw new RuntimeException("ERROR: key comparison (" + m + + ") failed"); + } + // check the type of key + if (ks.isCertificateEntry(alias) || !ks.isKeyEntry(alias)) { + throw new RuntimeException("ERROR: type identification (" + + m + ") failed"); + } + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import TVJar.TVPermission; +import java.security.AccessController; + +/** + * @test @bug 8050402 + * @summary Check policy is extensible with user defined permissions + * @run main/othervm/policy=ExtensiblePolicyTest1.policy + * ExtensiblePolicyTest false + * @run main/othervm/policy=ExtensiblePolicyTest2.policy + * ExtensiblePolicyTest true + * @run main/othervm/policy=ExtensiblePolicyTest3.policy + * ExtensiblePolicyTest true + */ +public class ExtensiblePolicyTest { + + public static void main(String args[]) throws Throwable { + // ExtensiblePolicyTest1.policy: policy file grants permission to + // watch TVChannel 3-6 + // ExtensiblePolicyTest2.policy: policy file grants permission to + // watch TVChanel 4 + // ExtensiblePolicyTest3.policy: policy file grants permission signed + // by duke2 to watch TVChanel 5 + + TVPermission perm = new TVPermission("channel:5", "watch"); + boolean getException = false; + String exceptionMessage = null; + boolean expectException = Boolean.parseBoolean(args[0]); + try { + AccessController.checkPermission(perm); + } catch (SecurityException se) { + getException = true; + exceptionMessage = se.getMessage(); + } + + if (expectException ^ getException) { + throw new RuntimeException("Test Failed: expectException = " + + expectException + " getException = " + getException + + "\n" + exceptionMessage); + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,4 @@ +grant { + permission TVJar.TVPermission "channel:3-6", "watch"; +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,3 @@ +grant { + permission TVJar.TVPermission "channel:4", "watch"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,5 @@ +keystore "file:${user.dir}/epkeystore"; + +grant { + permission TVJar.TVPermission "channel:5", "watch", SignedBy "duke2"; +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import TVJar.TVPermission; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.AccessController; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8050402 + * @summary Check policy is extensible with user defined permissions + * @library /lib/testlibrary + * @compile TVJar/TVPermission.java + * @run main ExtensiblePolicyWithJarTest + */ +public class ExtensiblePolicyWithJarTest { + + public static void main(String args[]) throws Throwable { + final String FS = File.separator; + final String PS = File.pathSeparator; + final String POL = "ExtensiblePolicyTest3.policy"; + final String JAVA_HOME = System.getProperty("test.jdk"); + final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool"; + final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner"; + final String KEYSTORE = "epkeystore"; + final String PASSWORD = "password"; + final String ALIAS = "duke2"; + final String CLASSPATH = System.getProperty("test.class.path", ""); + final String TESTCLASSES = System.getProperty("test.classes", ""); + final String TVPERMJAR = "tvPerm.jar"; + final String PATHTOJAR = System.getProperty("user.dir", "") + + FS + TVPERMJAR; + + // create jar file for TVpermission + new File("TVJar").mkdir(); + Files.copy(Paths.get(TESTCLASSES + FS + "TVJar", "TVPermission.class"), + Paths.get("TVJar", "TVPermission.class")); + Files.copy(Paths.get(TESTCLASSES + FS + "TVJar", + "TVPermissionCollection.class"), + Paths.get("TVJar", "TVPermissionCollection.class")); + JarUtils.createJar(TVPERMJAR, "TVJar/TVPermission.class", + "TVJar/TVPermissionCollection.class"); + + // create key pair for jar signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", ALIAS, + "-keystore", KEYSTORE, + "-storetype", "JKS", + "-keypass", PASSWORD, + "-dname", "cn=Blah", + "-storepass", PASSWORD + ).shouldHaveExitValue(0); + // sign jar + ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + TVPERMJAR, + ALIAS).shouldHaveExitValue(0); + // add jar file to classpath + String cp = PATHTOJAR + PS + CLASSPATH; + + // policy file grants permission signed by duke2 to watch TVChanel 5 + try { + String[] cmd = { + "-classpath", cp, + "-Djava.security.manager", + "-Djava.security.policy=" + POL, + "ExtensiblePolicyTest_orig$TestMain"}; + ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0); + } catch (Exception ex) { + System.out.println("ExtensiblePolicyWithJarTest Failed"); + } + + } + + public static class TestMain { + public static void main(String args[]) { + TVPermission perm = new TVPermission("channel:5", "watch"); + try { + AccessController.checkPermission(perm); + } catch (SecurityException se) { + throw new RuntimeException(se); + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,358 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package TVJar; + +import java.security.Permission; +import java.security.PermissionCollection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.StringJoiner; +import java.util.StringTokenizer; + +public class TVPermission extends Permission { + + /** + * Watch + */ + private final static int WATCH = 0x1; + + /** + * Preview + */ + private final static int PREVIEW = 0x2; + + /** + * No actions + */ + private final static int NONE = 0x0; + + /** + * All actions + */ + private final static int ALL = WATCH | PREVIEW; + + // the actions mask + private int mask; + + // the actions string + private String actions; + + // the canonical name of the channel + private String cname; + + // true if the channelname is a wildcard + private boolean wildcard; + + // num range on channel + private int[] numrange; + + // various num constants + private final static int NUM_MIN = 1; + private final static int NUM_MAX = 128; + + public TVPermission(String channel, String action) { + this(channel, getMask(action)); + } + + TVPermission(String channel, int mask) { + super(channel); + init(channel, mask); + } + + private synchronized int[] parseNum(String num) + throws Exception { + + if (num == null || num.equals("") || num.equals("*")) { + wildcard = true; + return new int[]{NUM_MIN, NUM_MAX}; + } + + int dash = num.indexOf('-'); + + if (dash == -1) { + int p = 0; + try { + p = Integer.parseInt(num); + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException("invalid input" + num); + } + return new int[]{p, p}; + } else { + String low = num.substring(0, dash); + String high = num.substring(dash + 1); + int l, h; + + if (low.equals("")) { + l = NUM_MIN; + } else { + try { + l = Integer.parseInt(low); + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException("invalid input" + num); + } + } + + if (high.equals("")) { + h = NUM_MAX; + } else { + try { + h = Integer.parseInt(high); + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException("invalid input" + num); + } + } + if (h < l || l < NUM_MIN || h > NUM_MAX) { + throw new IllegalArgumentException("invalid num range"); + } + + return new int[]{l, h}; + } + } + + /** + * Initialize the TVPermission object. + */ + private synchronized void init(String channel, int mask) { + + // Parse the channel name. + int sep = channel.indexOf(':'); + + if (sep != -1) { + String num = channel.substring(sep + 1); + cname = channel.substring(0, sep); + try { + numrange = parseNum(num); + } catch (Exception e) { + throw new IllegalArgumentException("invalid num range: " + num); + } + } else { + numrange = new int[]{NUM_MIN, NUM_MAX}; + } + } + + /** + * Convert an action string to an integer actions mask. + * + * @param action the action string + * @return the action mask + */ + private synchronized static int getMask(String action) { + int mask = NONE; + + if (action == null) { + return mask; + } + + StringTokenizer st = new StringTokenizer(action.toLowerCase(), ","); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (token.equals("watch")) { + mask |= WATCH; + } else if (token.equals("preview")) { + mask |= PREVIEW; + } else { + throw new IllegalArgumentException("invalid TV permission: " + token); + } + } + return mask; + } + + @Override + public boolean implies(Permission p) { + if (!(p instanceof TVPermission)) { + return false; + } + + if (this.wildcard) { + return true; + } + + TVPermission that = (TVPermission) p; + + if ((this.mask & that.mask) != that.mask) { + System.out.println("Masks are not ok this = " + + this.mask + "THat = " + that.mask); + return false; + } + + if ((this.numrange[0] > that.numrange[0]) + || (this.numrange[1] < that.numrange[1])) { + + System.out.println("This 0= " + this.numrange[0] + + " 1 = " + this.numrange[1]); + System.out.println("That 0= " + that.numrange[0] + + " 1 = " + that.numrange[1]); + return false; + } + return true; + } + + /** + * Checks two TVPermission objects for equality. + * <p> + * @param obj the object we are testing for equality. + * @return true if obj is a TVPermission, and has the same channelname and + * action mask as this TVPermission object. + */ + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof TVPermission)) { + return false; + } + + TVPermission that = (TVPermission) obj; + + // check the mask first + if (this.mask != that.mask) { + return false; + } + + // now check the num range... + if ((this.numrange[0] != that.numrange[0]) + || (this.numrange[1] != that.numrange[1])) { + return false; + } + + return this.getName().equals(that.getName()); + } + + /** + * Returns the hash code value for this object. + * + * @return a hash code value for this object. + */ + @Override + public int hashCode() { + return this.getName().hashCode(); + } + + /** + * Return the canonical string representation of the actions. Always returns + * actions in the following order: watch,preview. + * + * @param mask a specific integer action mask to translate into a string + * @return the canonical string representation of the actions + */ + private synchronized static String getActions(int mask) { + StringJoiner sj = new StringJoiner(","); + if ((mask & WATCH) == WATCH) { + sj.add("watch"); + } + if ((mask & PREVIEW) == PREVIEW) { + sj.add("preview"); + } + return sj.toString(); + } + + /** + * Return the canonical string representation of the actions. Always returns + * actions in the following order: watch,preview. + * + * @return the canonical string representation of the actions. + */ + @Override + public String getActions() { + if (actions == null) { + actions = getActions(this.mask); + } + + return actions; + } + + @Override + public String toString() { + return super.toString() + "\n" + + "cname = " + cname + "\n" + + "wildcard = " + wildcard + "\n" + + "numrange = " + numrange[0] + "," + numrange[1] + "\n"; + + } + + @Override + public PermissionCollection newPermissionCollection() { + return new TVPermissionCollection(); + } +} + +final class TVPermissionCollection extends PermissionCollection { + + /** + * The TVPermissions for this set. + */ + private final ArrayList<TVPermission> permissions = new ArrayList<>(); + + /** + * Adds a permission to the TVPermissions. The key for the hash is the name + * in the case of wildcards, or all the IP addresses. + * + * @param permission the Permission object to add. + */ + @Override + public void add(Permission permission) { + if (!(permission instanceof TVPermission)) { + throw new IllegalArgumentException("invalid permission: " + permission); + } + permissions.add((TVPermission) permission); + } + + /** + * Check and see if this collection of permissions implies the permissions + * expressed in "permission". + * + * @param p the Permission object to compare + * + * @return true if "permission" is a proper subset of a permission in the + * collection, false if not. + */ + @Override + public boolean implies(Permission p) { + if (!(p instanceof TVPermission)) { + return false; + } + + Iterator<TVPermission> i = permissions.iterator(); + while (i.hasNext()) { + if (((TVPermission) i.next()).implies(p)) { + return true; + } + } + return false; + } + + /** + * Returns an enumeration of all the TVPermission objects in the container. + * + * @return an enumeration of all the TVPermission objects. + */ + @Override + public Enumeration elements() { + return Collections.enumeration(permissions); + } + +}
--- a/test/java/security/SecureRandom/DefaultProvider.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/SecureRandom/DefaultProvider.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,12 +43,7 @@ out.println("TEST: Default provider with constructor"); SecureRandom secureRandom = new SecureRandom(); String provider = secureRandom.getProvider().getName(); - if (OS_NAME.startsWith(SUNOS)) { - if (!provider.startsWith("SunPKCS11-")) { - throw new RuntimeException("Unexpected provider name: " - + provider); - } - } else if (!provider.equals("SUN")) { + if (!provider.equals("SUN")) { throw new RuntimeException("Unexpected provider name: " + provider); } @@ -77,16 +72,6 @@ instance = SecureRandom.getInstance(algorithm); assertInstance(instance, algorithm, provider); out.println("Passed."); - - if (OS_NAME.startsWith(SUNOS)) { - out.println( - "TEST: PKCS11 is supported on Solaris by SunPKCS11 provider"); - algorithm = "PKCS11"; - provider = "SunPKCS11-Solaris"; - instance = SecureRandom.getInstance(algorithm); - assertInstance(instance, algorithm, provider); - out.println("Passed."); - } } private static void assertInstance(SecureRandom instance,
--- a/test/java/security/Security/AddProvider.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/Security/AddProvider.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8001319 + * @bug 8001319 8154009 * @summary check that SecurityPermission insertProvider permission is enforced * correctly * @run main/othervm/policy=AddProvider.policy.1 AddProvider 1
--- a/test/java/security/Security/AddProvider.policy.1 Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/Security/AddProvider.policy.1 Thu Jan 12 06:59:38 2017 +0000 @@ -1,7 +1,3 @@ -grant codeBase "file:${{java.ext.dirs}}/*" { - permission java.security.AllPermission; -}; - grant { permission java.security.SecurityPermission "insertProvider"; };
--- a/test/java/security/Security/AddProvider.policy.2 Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/Security/AddProvider.policy.2 Thu Jan 12 06:59:38 2017 +0000 @@ -1,7 +1,3 @@ -grant codeBase "file:${{java.ext.dirs}}/*" { - permission java.security.AllPermission; -}; - grant { permission java.security.SecurityPermission "insertProvider.Test1"; permission java.security.SecurityPermission "insertProvider.Test2";
--- a/test/java/security/Security/AddProvider.policy.3 Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/Security/AddProvider.policy.3 Thu Jan 12 06:59:38 2017 +0000 @@ -1,7 +1,3 @@ -grant codeBase "file:${{java.ext.dirs}}/*" { - permission java.security.AllPermission; -}; - grant { permission java.security.SecurityPermission "insertProvider.*"; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Security/EmptyPolicy.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,2 @@ +// empty policy file for testing +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Security/GetProviders.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8154009 + * @summary make sure getProviders() doesn't require additional permissions + * @run main/othervm/policy=EmptyPolicy.policy GetProviders + */ + +import java.security.Provider; +import java.security.Security; +import java.util.HashMap; +import java.util.Map; + +public class GetProviders { + + private static final String serviceAlgFilter = "Signature.SHA1withRSA"; + private static final String emptyServAlgFilter = "wrongSig.wrongAlg"; + + public static void main(String[] args) throws Exception { + try { + Provider[] providers1 = Security.getProviders(); + System.out.println("Amount of providers1: " + providers1.length); + + Provider[] providers2 = Security.getProviders(serviceAlgFilter); + System.out.println("Amount of providers2: " + providers2.length); + + Map<String, String> filter = new HashMap<String, String>(); + filter.put(serviceAlgFilter, ""); + Provider[] providers3 = Security.getProviders(filter); + System.out.println("Amount of providers3: " + providers3.length); + + Provider[] emptyProv1 = Security.getProviders(emptyServAlgFilter); + if (emptyProv1 != null) { + throw new RuntimeException("Empty Filter returned: " + + emptyProv1.length + " providers"); + } + System.out.println("emptyProv1 is empty as expected"); + + Map<String, String> emptyFilter = new HashMap<String, String>(); + emptyFilter.put(emptyServAlgFilter, ""); + Provider[] emptyProv2 = Security.getProviders(emptyFilter); + if (emptyProv2 != null) { + throw new RuntimeException("Empty Filter returned: " + + emptyProv2.length + " providers"); + } + System.out.println("emptyProv2 is empty as expected"); + + } catch(ExceptionInInitializerError e) { + e.printStackTrace(System.out); + throw new RuntimeException("Provider initialization error due to " + + e.getCause()); + } + System.out.println("Test passed"); + } + +}
--- a/test/java/security/Security/removing/RemoveStaticProvider.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/Security/removing/RemoveStaticProvider.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4420687 + * @bug 4420687 8154009 * @summary Make sure that a removed provider won't be acceessable. * @run main/othervm/policy=RemoveStaticProvider.policy RemoveStaticProvider */
--- a/test/java/security/Security/removing/RemoveStaticProvider.policy Tue Nov 08 05:26:12 2016 +0000 +++ b/test/java/security/Security/removing/RemoveStaticProvider.policy Thu Jan 12 06:59:38 2017 +0000 @@ -3,8 +3,3 @@ permission java.security.SecurityPermission "insertProvider.SunJCE"; }; -// Standard extensions get all permissions -grant codeBase "file:${java.home}/lib/ext/*" { - permission java.security.AllPermission; -}; -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/MBeanServer/ExceptionFactory.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import javax.management.AttributeNotFoundException; +import javax.management.BadAttributeValueExpException; +import javax.management.BadBinaryOpValueExpException; +import javax.management.BadStringOperationException; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.IntrospectionException; +import javax.management.InvalidApplicationException; +import javax.management.InvalidAttributeValueException; +import javax.management.JMException; +import javax.management.JMRuntimeException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanRegistrationException; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.OperationsException; +import javax.management.ReflectionException; +import javax.management.RuntimeErrorException; +import javax.management.RuntimeMBeanException; +import javax.management.RuntimeOperationsException; +import javax.management.ServiceNotFoundException; +import javax.management.StringValueExp; +import javax.management.modelmbean.InvalidTargetObjectTypeException; +import javax.management.modelmbean.XMLParseException; +import javax.management.monitor.MonitorSettingException; +import javax.management.openmbean.InvalidKeyException; +import javax.management.openmbean.InvalidOpenTypeException; +import javax.management.openmbean.KeyAlreadyExistsException; +import javax.management.openmbean.OpenDataException; +import javax.management.relation.InvalidRelationIdException; +import javax.management.relation.InvalidRelationServiceException; +import javax.management.relation.InvalidRelationTypeException; +import javax.management.relation.InvalidRoleInfoException; +import javax.management.relation.InvalidRoleValueException; +import javax.management.relation.RelationException; +import javax.management.relation.RelationNotFoundException; +import javax.management.relation.RelationServiceNotRegisteredException; +import javax.management.relation.RelationTypeNotFoundException; +import javax.management.relation.RoleInfoNotFoundException; +import javax.management.relation.RoleNotFoundException; +import javax.management.remote.JMXProviderException; +import javax.management.remote.JMXServerErrorException; + +/** + * |----- Original Description Coming From Tonga Original Source Code -------| + * | | + * | That class creates an ArrayList and fill it with an instance of each of | + * | the Exception class of the JMX API. | + * | It's dedicated to use by ExceptionTest. | + * |-------------------------------------------------------------------------| + */ +public class ExceptionFactory { + + public static final ArrayList<Exception> exceptions = + new ArrayList<Exception>(); + + static { + String mes = "SQE"; + exceptions.add(new AttributeNotFoundException()); + exceptions.add(new BadAttributeValueExpException(mes)); + exceptions.add(new BadBinaryOpValueExpException(new StringValueExp(mes))); + exceptions.add(new BadStringOperationException(mes)); + exceptions.add(new InstanceAlreadyExistsException()); + exceptions.add(new InstanceNotFoundException()); + exceptions.add(new IntrospectionException()); + exceptions.add(new InvalidApplicationException(mes)); + exceptions.add(new InvalidAttributeValueException()); + exceptions.add(new JMException()); + exceptions.add(new JMRuntimeException()); + exceptions.add(new ListenerNotFoundException()); + exceptions.add(new MalformedObjectNameException()); + exceptions.add(new MBeanException(new Exception(mes), mes)); + exceptions.add(new MBeanRegistrationException(new Exception(mes), mes)); + exceptions.add(new NotCompliantMBeanException()); + exceptions.add(new OperationsException()); + exceptions.add(new ReflectionException(new Exception(mes), mes)); + exceptions.add(new RuntimeErrorException(new Error(mes), mes)); + exceptions.add(new RuntimeMBeanException(new RuntimeException(mes), mes)); + exceptions.add(new RuntimeOperationsException(new RuntimeException(mes), mes)); + exceptions.add(new ServiceNotFoundException()); + exceptions.add(new InvalidTargetObjectTypeException()); + exceptions.add(new XMLParseException()); + exceptions.add(new MonitorSettingException()); + exceptions.add(new InvalidKeyException()); + exceptions.add(new InvalidOpenTypeException()); + exceptions.add(new KeyAlreadyExistsException()); + exceptions.add(new OpenDataException()); + exceptions.add(new InvalidRelationIdException()); + exceptions.add(new InvalidRelationServiceException()); + exceptions.add(new InvalidRelationTypeException()); + exceptions.add(new InvalidRoleInfoException()); + exceptions.add(new InvalidRoleValueException()); + exceptions.add(new RelationException()); + exceptions.add(new RelationNotFoundException()); + exceptions.add(new RelationServiceNotRegisteredException()); + exceptions.add(new RelationTypeNotFoundException()); + exceptions.add(new RoleInfoNotFoundException()); + exceptions.add(new RoleNotFoundException()); + exceptions.add(new JMXProviderException()); + exceptions.add(new JMXServerErrorException(mes, new Error(mes))); + ExceptionTest.Utils.debug(ExceptionTest.Utils.DEBUG_STANDARD, + "DataFactory::updateMap: Initialized" + + " an ArrayList with the " + + exceptions.size() + " exceptions of the JMX API"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/MBeanServer/ExceptionTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks that exceptions are correctly wired (compared to reference). + * @author Olivier Lagneau + * @modules java.management + * @run main/othervm/timeout=300 -DDEBUG_STANDARD ExceptionTest + */ + +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import java.lang.reflect.Method; + +import java.lang.management.ManagementFactory; +import javax.management.ObjectName; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + + +public class ExceptionTest { + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + ExceptionTest test = new ExceptionTest(); + test.run(map); + + } + + public void run(Map<String, Object> args) { + + System.out.println("ExceptionTest::run: Start"); + int errorCount = 0; + + JMXConnectorServer cs = null; + JMXConnector cc = null; + + try { + // JMX MbeanServer used inside single VM as if remote. + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + JMXServiceURL addr = cs.getAddress(); + cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + // ---- + ObjectName objName = + new ObjectName(ExceptionThrower.EXCEPTION_THROWER_NAME); + System.out.println("ExceptionTest::run: Create and register MBean " + objName); + mbsc.createMBean("ExceptionThrower", objName); + System.out.println("---- OK\n"); + + // ---- + System.out.println("ExceptionTest::run: Ask for exception(s)"); + Object[] throwExceptionParam = new Object[1]; + String[] throwExceptionSig = new String[]{"int"}; + + for (int i = 0; i < ExceptionFactory.exceptions.size(); i++) { + throwExceptionParam[0] = new Integer(i); + + Exception ex = + (Exception)mbsc.invoke(objName, + "throwException", throwExceptionParam, throwExceptionSig); + + if ( ! matches(ex, ExceptionFactory.exceptions.get(i)) ) { + errorCount++; + System.out.println("ExceptionTest::run: (ERROR) Received \n[" + + ex + "]\nin place of\n[" + + ExceptionFactory.exceptions.get(i) + "]"); + } else { + System.out.println("OK [" + ex + "]"); + } + } + + System.out.println("---- DONE\n"); + + } catch (Exception e) { + Utils.printThrowable(e, true); + throw new RuntimeException(); + } finally { + try { + // Close JMX Connector Client + cc.close(); + // Stop connertor server + cs.stop(); + + } catch (Exception e) { + Utils.printThrowable(e, true); + throw new RuntimeException( + "Unable to either close connector client or stop connector server"); + } + } + + if (errorCount == 0) { + System.out.println("ExceptionTest::run: Done without any error"); + } else { + System.out.println("ExceptionTest::run: Done with " + errorCount + + " error(s)"); + throw new RuntimeException("errorCount = " + errorCount); + } + + System.out.println("ExceptionTest::run: Done"); + } + + // Check both Exception are identical. + // That means: + // - none is null. + // - they are of the same Class. + // - if their respective messages aren't null they're equal. + // - if the message of one is null the message of the other is null too. + private boolean matches(Exception ex, Exception refex) { + if ( ex == null || refex == null ) { + System.out.println("(ERROR) Called with one or more null parameter; check " + + ex + " against " + refex); + return false; + } + + String exClass = ex.getClass().getName(); + String refexClass = refex.getClass().getName(); + + if ( ! exClass.equals(refexClass) ) { + System.out.println("(ERROR) Class names don't match; check [" + + exClass + "] against [" + refexClass + "]"); + return false; + } + + String exMes = ex.getMessage(); + String refexMes = refex.getMessage(); + + if ( exMes != null && refexMes != null ) { + if ( ! exMes.equals(refexMes) ) { + System.out.println("(ERROR) Non null messages don't match; check [" + + exMes + "] against [" + refexMes + "]"); + return false; + } + } else if ( (exMes == null && refexMes != null) + || (exMes != null && refexMes == null) ) { + System.out.println("(ERROR) Messages don't match; check [" + exMes + + "] against [" + refexMes + "]"); + } + + return true; + } + + // Utility inner class coming from JMX Tonga test suite. + // Also used by ExceptionFactory. + static class Utils { + + // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property + static final String DEBUG_HEADER = "[debug] "; + + // DEBUG levels + static int selectedDebugLevel = 0; + static final int DEBUG_STANDARD = 1; + static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests + static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE; + + static void parseDebugProperties() { + int level = 0; + Properties p = System.getProperties(); + + // get selected levels + if (p.getProperty("DEBUG_STANDARD") != null) { + level |= DEBUG_STANDARD; + } + + if (p.getProperty("DEBUG_VERBOSE") != null) { + level |= DEBUG_VERBOSE; + } + + if (p.getProperty("DEBUG_ALL") != null) { + level |= DEBUG_ALL; + } + + selectedDebugLevel = level; + } + + /** + * Reproduces the original parsing and collection of test parameters + * from the DTonga JMX test suite. + * + * Collects passed args and returns them in a map(argname, value) structure, + * which will be then propagated as necessary to various called methods. + */ + static Map<String, Object> parseParameters(String args[]) + throws Exception { + debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start"); + HashMap<String, Object> map = new HashMap<>(); + + for ( int i = 0; i < args.length; i++ ) { + if ( args[i].trim().startsWith("-") ) { + if ((i+1) < args.length && !args[i+1].startsWith("-") ) { + debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with value " + + args[i+1]) ; + map.put(args[i].trim(), args[i+1].trim()) ; + } else if ((i+1) < args.length && args[i+1].startsWith("-") || + (i+1) == args.length ) { + debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with null value") ; + map.put(args[i].trim(), null) ; + } else { + System.out.println( + "TestRoot::parseParameters: (WARNING) not added in map = " + + args[i]) ; + } + } + } + + debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ; + return map ; + } + + /** + * This method is to be used in all tests to print anything + * that is temporary. + * Printing is done only when debug is activated by the property DEBUG. + * Printing depends also on the DEBUG_LEVEL property. + * Here it encapsulates a System.out.println. + */ + static void debug(int level, String line) { + if ((selectedDebugLevel & level) != 0) { + System.out.println(DEBUG_HEADER + line); + } + } + + /** + * Do print stack trace when withStack is true. + * Does try to call getTargetException() and getTargetError() then + * print embedded stacks in the case of an Exception wrapping + * another Exception or an Error. Recurse until no more wrapping + * is found. + */ + static void printThrowable(Throwable theThro, boolean withStack) { + try { + if (withStack) { + theThro.printStackTrace(System.out); + } + if (theThro instanceof Exception) { + Exception t = (Exception) theThro; + Method target = null; + String blank = " "; + try { + target = t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not + } + System.out.println(blank + t.getClass() + "==>" + t.getMessage()); + while (target != null) { + try { + t = (Exception) target.invoke(t, + (java.lang.Object[]) null); + } catch (Exception ee) { + t = null; + } + try { + if (t != null) { + blank = blank + " "; + System.out.println(blank + t.getClass() + "==>" + + t.getMessage()); + try { + target = + t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not } + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + + // We may have exceptions wrapping an Error then it is + // getTargetError that is likely to be called + try { + target = ((Exception) theThro).getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + Throwable err = theThro; + while (target != null) { + try { + err = (Error) target.invoke(err, + (java.lang.Object[]) null); + } catch (Exception ee) { + err = null; + } + try { + if (err != null) { + blank = blank + " "; + System.out.println(blank + err.getClass() + "==>" + + err.getMessage()); + if (withStack) { + err.printStackTrace(System.out); + } + try { + target = err.getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + } else { + System.out.println("Throwable is : " + theThro); + } + } catch (Throwable x) { + System.out.println("Exception : raised in printException : " + x); + } + } + } + +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/MBeanServer/ExceptionThrower.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * This class defines a simple standard MBean. + */ +public class ExceptionThrower implements ExceptionThrowerMBean { + + public static final String EXCEPTION_THROWER_NAME + = "sqe:type=ExceptionThrower"; + + public Exception throwException(int exceptionIndex) { + return ExceptionFactory.exceptions.get(exceptionIndex); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/MBeanServer/ExceptionThrowerMBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * This interface defines a simple standard MBean. + */ +public interface ExceptionThrowerMBean { + public Exception throwException(int exceptionIndex); +}
--- a/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -27,6 +27,7 @@ * @summary Test that no locks are held when a monitor attribute is sampled * or notif delivered. * @author Eamonn McManus + * @library /lib/testlibrary * @run clean GaugeMonitorDeadlockTest * @run build GaugeMonitorDeadlockTest * @run main GaugeMonitorDeadlockTest 1 @@ -47,6 +48,8 @@ import javax.management.monitor.GaugeMonitor; import javax.management.monitor.GaugeMonitorMBean; +import jdk.testlibrary.Utils; + public class GaugeMonitorDeadlockTest { private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY}; private static long checkingTime; @@ -54,8 +57,7 @@ public static void main(String[] args) throws Exception { if (args.length != 1) throw new Exception("Arg should be test number"); - double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0")); - checkingTime = (long)factor*1000; + checkingTime = Utils.adjustTimeout(1000); // default 1s timeout System.out.println("=== checkingTime = " + checkingTime + "ms"); int testNo = Integer.parseInt(args[0]) - 1; @@ -101,11 +103,12 @@ monitorProxy.setGranularityPeriod(10L); // 10 ms monitorProxy.setNotifyHigh(true); monitorProxy.setNotifyLow(true); - monitorProxy.start(); System.out.println("=== Waiting observedProxy.getGetCount() to be " + "changed, presumable deadlock if timeout?"); final int initGetCount = observedProxy.getGetCount(); + monitorProxy.start(); + long checkedTime = System.currentTimeMillis(); long nowTime; ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
--- a/test/javax/management/monitor/StringMonitorDeadlockTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/javax/management/monitor/StringMonitorDeadlockTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -37,7 +37,6 @@ import java.lang.management.ManagementFactory; import java.util.concurrent.atomic.AtomicInteger; -import javax.management.Attribute; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.Notification; @@ -95,9 +94,10 @@ monitorProxy.setStringToCompare("old"); monitorProxy.setGranularityPeriod(10L); // 10 ms monitorProxy.setNotifyDiffer(true); + + final int initGetCount = observedProxy.getGetCount(); monitorProxy.start(); - final int initGetCount = observedProxy.getGetCount(); int getCount = initGetCount; for (int i = 0; i < 500; i++) { // 500 * 10 = 5 seconds getCount = observedProxy.getGetCount();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/Basic.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import javax.management.Descriptor; +import javax.management.ImmutableDescriptor; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; + +/** + * Class Basic + * Basic Description + */ +public class Basic implements BasicMXBean, NotificationEmitter, + MBeanRegistration { + + public static final String EXCEPTION_MESSAGE = "from Basic"; + public static final String NOTIFICATION_MESSAGE = "from Basic"; + /** Attribute : IntAtt */ + private int intAtt = 0; + /** Attribute : IntegerAtt */ + private Integer integerAtt = 0; + /** Attribute : BoolAtt */ + private boolean boolAtt = false; + /** Attribute : BooleanAtt */ + private Boolean booleanAtt = false; + /** Attribute : StringAtt */ + private String stringAtt = null; + /** Attribute : DateAtt */ + private Date dateAtt = null; + /** Attribute : ObjectNameAtt */ + private ObjectName objectNameAtt = null; + /** Attribute : NotifDescriptorAsMapAtt */ + private Map<String, String> notifDescriptorAsMapAtt = null; + /** Attribute : NotifDescriptorAtt */ + private Descriptor notifDescriptorAtt = null; + /** Attribute : SqeParameter */ + private SqeParameter sqeParameterAtt = null; + + /* Creates a new instance of Basic */ + @SqeDescriptorKey("CONSTRUCTOR Basic") + public Basic() { + } + + /* Creates a new instance of Basic */ + @SqeDescriptorKey("CONSTRUCTOR Basic") + public Basic( + @SqeDescriptorKey("CONSTRUCTOR PARAMETER SqeParameter") SqeParameter param) { + } + + /** + * Get int attribute + */ + public int getIntAtt() { + return intAtt; + } + + /** + * Set int attribute + */ + public void setIntAtt(int value) { + intAtt = value; + } + + /** + * Get Integer attribute + */ + public Integer getIntegerAtt() { + return integerAtt; + } + + /** + * Set Integer attribute + */ + public void setIntegerAtt(Integer value) { + integerAtt = value; + } + + /** + * Get boolean attribute + */ + public boolean getBoolAtt() { + return boolAtt; + } + + /** + * Set boolean attribute + */ + public void setBoolAtt(boolean value) { + boolAtt = value; + } + + /** + * Get Boolean attribute + */ + public Boolean getBooleanAtt() { + return booleanAtt; + } + + /** + * Set Boolean attribute + */ + public void setBooleanAtt(Boolean value) { + booleanAtt = value; + } + + /** + * Get String attribute + */ + public String getStringAtt() { + return stringAtt; + } + + /** + * Set String attribute + */ + public void setStringAtt(String value) { + stringAtt = value; + } + + /** + * Get Date attribute + */ + public Date getDateAtt() { + return dateAtt; + } + + /** + * Set Date attribute + */ + public void setDateAtt(Date value) { + dateAtt = value; + } + + /** + * Get ObjectName attribute + */ + public ObjectName getObjectNameAtt() { + return objectNameAtt; + } + + /** + * Set ObjectName attribute + */ + public void setObjectNameAtt(ObjectName value) { + objectNameAtt = value; + } + + /** + * Get SqeParameter attribute + */ + public SqeParameter getSqeParameterAtt() throws Exception { + if (sqeParameterAtt == null) { + sqeParameterAtt = new SqeParameter(); + sqeParameterAtt.setGlop("INITIALIZED"); + } + + return sqeParameterAtt; + } + + /** + * Set SqeParameter attribute + */ + public void setSqeParameterAtt(SqeParameter value) { + sqeParameterAtt = value; + } + + /** + * Get the Descriptor used to build the NotificationInfo + * of emitted notifications. + */ + public Map<String, String> getNotifDescriptorAsMapAtt() { + if (notifDescriptorAsMapAtt == null) { + initNotifDescriptorAtt(); + } + + return notifDescriptorAsMapAtt; + } + + /** + * Set the Descriptor used to build the NotificationInfo + * of emitted notifications. + * <br>A Map<String, Object> would better fit Descriptor needs but then + * it is not convertible according the MXBean specification so the MBean + * registration fails. + * As we plan to test our custom Descriptor finds its way into + * the metadata of emitted notifications, String is good enough. + */ + public void setNotifDescriptorAsMapAtt(Map<String, String> value) { + notifDescriptorAsMapAtt = new HashMap<String, String>(value); + notifDescriptorAtt = new ImmutableDescriptor(value); + } + + /** + * Do nothing + */ + public void doNothing() { + // I said NOTHING ! + } + + /** + * Do take SqeParameter as a parameter + */ + public void doWeird(SqeParameter param) { + } + + /** + * Throw an Exception + */ + public void throwException() throws Exception { + throw new Exception(EXCEPTION_MESSAGE); + } + + /** + * Throw an Error + */ + public void throwError() { + throw new InternalError(EXCEPTION_MESSAGE); + } + + /** + * Reset all attributes + */ + public void reset() { + intAtt = 0; + integerAtt = 0; + boolAtt = false; + booleanAtt = Boolean.FALSE; + stringAtt = null; + dateAtt = null; + objectNameAtt = null; + } + + /** + * Returns the weather for the coming days + * @param verbose <code>boolean</code> verbosity + * @throws java.lang.Exception <code>storm</code> + * @return <code>ObjectName</code> + */ + public Weather getWeather(boolean verbose) + throws java.lang.Exception { + return Weather.SUNNY; + } + + // Starting here are the 4 methods of MBeanRegistration interface. + // We use that to grab the ObjectName the MBean is registered with. + // + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + // Grab a reference on the MBeanServer we're registered in. + mbs = server; + // Compute the name we're registered with. + if (name != null) { + mbeanName = name; + return name; + } else { + mbeanName = + new ObjectName("sqe:type=" + Basic.class.getName()); + return mbeanName; + } + } + + public void postRegister(Boolean registrationDone) { + // Do nothing + } + + public void preDeregister() throws Exception { + // Do nothing + } + + public void postDeregister() { + // Do nothing + } + + /** + * Send one Notification of the provided notifType type. + */ + public void sendNotification(String notifType) { + Notification notification = null; + + if (notifType.equals(NOTIF_TYPE_0)) { + notification = new Notification(NOTIF_TYPE_0, + mbeanName, + seqNumber, + NOTIFICATION_MESSAGE); + } else if (notifType.equals(NOTIF_TYPE_1)) { + notification = new SqeNotification(NOTIF_TYPE_1, + mbeanName, + seqNumber, + NOTIFICATION_MESSAGE); + } + + seqNumber++; + broadcaster.sendNotification(notification); + } + + /** + * That method starts a set of threads, each thread sends a given number of + * notifications. + * The number of threads can be set via the attribute numOfNotificationSenders. + * The number of notification sent by each thread can be set via + * the attribute numOfNotificationSenderLoops. + * Depending on the parameter customNotification we send either custom + * notification(s) or MBeanServer registration and unregistration notification(s). + * When customNotification=true the total number of notification(s) sent is + * (numOfNotificationSenders * numOfNotificationSenderLoops). They are + * sequentially of type NOTIF_TYPE_0 then NOTIF_TYPE_1 and so on. + * + * When customNotification=false the total number of notification(s) sent is + * (numOfNotificationSenders * numOfNotificationSenderLoops) registration + * notification(s) + * + + * (numOfNotificationSenders * numOfNotificationSenderLoops) unregistration + * notification(s) + * + * @throws java.lang.Exception + */ + public void sendNotificationWave(boolean customNotification) throws + Exception { + // Build the set of notification sender. + Collection<Callable<Integer>> tasks = + new HashSet<Callable<Integer>>(numOfNotificationSenders); + + for (int i = 1; i <= numOfNotificationSenders; i++) { + tasks.add(new NotifSender(numOfNotificationSenderLoops, + customNotification, i)); + } + + // Start all notification sender in parallel. + ExecutorService execServ = null; + try { + execServ = Executors.newFixedThreadPool(numOfNotificationSenders); + List<Future<Integer>> taskHandlers = execServ.invokeAll(tasks); + checkNotifSenderThreadStatus(taskHandlers); + } finally { + if (!execServ.isShutdown()) { + execServ.shutdown(); + } + } + } + + public void setNumOfNotificationSenders(int value) { + numOfNotificationSenders = value; + } + + public void setNumOfNotificationSenderLoops(int value) { + numOfNotificationSenderLoops = value; + } + + /** + * MBean Notification support + * You shouldn't update these methods + */ + // <editor-fold defaultstate="collapsed" desc=" Generated Code "> + public void addNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object handback) + throws IllegalArgumentException { + broadcaster.addNotificationListener(listener, filter, handback); + } + + public MBeanNotificationInfo[] getNotificationInfo() { + if (notifDescriptorAtt == null) { + initNotifDescriptorAtt(); + } + + return new MBeanNotificationInfo[]{ + new MBeanNotificationInfo(new String[]{ + NOTIF_TYPE_0 + }, + javax.management.Notification.class.getName(), + "Standard JMX Notification", + notifDescriptorAtt), + new MBeanNotificationInfo(new String[]{ + NOTIF_TYPE_1 + }, + SqeNotification.class.getName(), + "SQE Notification", + notifDescriptorAtt) + }; + } + + public void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException { + broadcaster.removeNotificationListener(listener); + } + + public void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object handback) + throws ListenerNotFoundException { + broadcaster.removeNotificationListener(listener, filter, handback); + } + // </editor-fold> + private synchronized long getNextSeqNumber() { + return seqNumber++; + } + + private void initNotifDescriptorAtt() { + String key = "CRABE"; + String value = "TAMBOUR"; + notifDescriptorAtt = + new ImmutableDescriptor(new String[]{key + "=" + value}); + notifDescriptorAsMapAtt = + new HashMap<String, String>(); + notifDescriptorAsMapAtt.put(key, value); + } + + private void checkNotifSenderThreadStatus( + List<Future<Integer>> taskHandlers) + throws Exception { + String msgTag = "Basic::checkNotifSenderThreadStatus: "; + // Grab back status of each notification sender. + for (Future<Integer> f : taskHandlers) { + if (f.isCancelled()) { + String message = msgTag + + "---- ERROR : One thread has been cancelled"; + System.out.println(message); + throw new RuntimeException(message); + } else { + Integer effectiveNumOfLoops = f.get(); + + if (effectiveNumOfLoops != numOfNotificationSenderLoops) { + String message = msgTag + "---- ERROR : One thread did " + + effectiveNumOfLoops + " loops in place of " + + numOfNotificationSenderLoops; + System.out.println(message); + throw new RuntimeException(message); + } + } + } + } + // + private int numOfNotificationSenderLoops = 2; + private int numOfNotificationSenders = 13; + + private class NotifSender implements Callable<Integer> { + + private int cycles; + private boolean customNotification; + private int senderID; + + public NotifSender(int cycles, boolean customNotification, int id) { + this.cycles = cycles; + this.customNotification = customNotification; + this.senderID = id; + } + + public Integer call() throws Exception { + int callsDone = 0; + + try { + for (int i = 1; i <= cycles; i++) { + if (customNotification) { + if (i % 2 == 0) { + sendNotification(NOTIF_TYPE_0); + } else { + sendNotification(NOTIF_TYPE_1); + } + } else { + ObjectName mbeanName = new ObjectName("SQE:type=" + + mbeanClassName + ",senderID=" + senderID); + mbs.createMBean(mbeanClassName, mbeanName); + mbs.unregisterMBean(mbeanName); + } + callsDone++; + } + } catch (Exception e) { + System.out.println("NotifSender::call: (ERROR) Thread [" + senderID + + "] failed after " + callsDone + " cycles"); + throw e; + } + + return Integer.valueOf(callsDone); + } + } + + // + private long seqNumber; + private final NotificationBroadcasterSupport broadcaster = + new NotificationBroadcasterSupport(); + private ObjectName mbeanName; + private MBeanServer mbs; + private String mbeanClassName = "Simple"; + + /** + * Notification types definitions. To use when creating JMX Notifications. + */ + public static final String NOTIF_TYPE_0 = + "sqe.notification.a.type"; + public static final String NOTIF_TYPE_1 = + "sqe.notification.b.type"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/BasicMXBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Date; +import java.util.Map; + +import javax.management.ObjectName; + +/** + * Interface BasicMBean + * Basic Description + */ +@SqeDescriptorKey("INTERFACE BasicMXBean") +public interface BasicMXBean +{ + /** + * Get int attribute + */ + @SqeDescriptorKey("ATTRIBUTE intAtt") + public int getIntAtt(); + + /** + * Set int attribute + */ + @SqeDescriptorKey("ATTRIBUTE intAtt") + public void setIntAtt(int value); + + /** + * Get Integer attribute + */ + @SqeDescriptorKey("ATTRIBUTE integerAtt") + public Integer getIntegerAtt(); + + /** + * Set Integer attribute + */ + @SqeDescriptorKey("ATTRIBUTE integerAtt") + public void setIntegerAtt(Integer value); + + /** + * Get boolean attribute + */ + @SqeDescriptorKey("ATTRIBUTE boolAtt") + public boolean getBoolAtt(); + + /** + * Set boolean attribute + */ + @SqeDescriptorKey("ATTRIBUTE boolAtt") + public void setBoolAtt(boolean value); + + /** + * Get Boolean attribute + */ + @SqeDescriptorKey("ATTRIBUTE booleanAtt") + public Boolean getBooleanAtt(); + + /** + * Set Boolean attribute + */ + @SqeDescriptorKey("ATTRIBUTE booleanAtt") + public void setBooleanAtt(Boolean value); + + /** + * Get String attribute + */ + @SqeDescriptorKey("ATTRIBUTE stringAtt") + public String getStringAtt(); + + /** + * Set String attribute + */ + @SqeDescriptorKey("ATTRIBUTE stringAtt") + public void setStringAtt(String value); + + /** + * Get Date attribute + */ + @SqeDescriptorKey("ATTRIBUTE dateAtt") + public Date getDateAtt(); + + /** + * Set Date attribute + */ + @SqeDescriptorKey("ATTRIBUTE dateAtt") + public void setDateAtt(Date value); + + /** + * Get ObjectName attribute + */ + @SqeDescriptorKey("ATTRIBUTE objectNameAtt") + public ObjectName getObjectNameAtt(); + + /** + * Set ObjectName attribute + */ + @SqeDescriptorKey("ATTRIBUTE objectNameAtt") + public void setObjectNameAtt(ObjectName value); + + /** + * Get SqeParameter attribute + */ + @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt") + public SqeParameter getSqeParameterAtt() throws Exception; + + /** + * Set SqeParameter attribute + */ + @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt") + public void setSqeParameterAtt(SqeParameter value); + + /** + * Set NumOfNotificationSenders attribute + */ + @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenders") + public void setNumOfNotificationSenders(int value); + + /** + * Set NumOfNotificationSenderLoops attribute + */ + @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenderLoops") + public void setNumOfNotificationSenderLoops(int value); + + /** + * do nothing + * + */ + @SqeDescriptorKey("OPERATION doNothing") + public void doNothing(); + + /** + * Do take SqeParameter as a parameter + */ + @SqeDescriptorKey("OPERATION doWeird") + public void doWeird(@SqeDescriptorKey("METHOD PARAMETER")SqeParameter param); + + /** + * throw an Exception + * + */ + @SqeDescriptorKey("OPERATION throwException") + public void throwException() throws Exception; + + /** + * throw an Error + * + */ + @SqeDescriptorKey("OPERATION throwError") + public void throwError(); + + /** + * reset all attributes + * + */ + @SqeDescriptorKey("OPERATION reset") + public void reset(); + + /** + * returns the weather for the coming days + * + * @param verbose <code>boolean</code> verbosity + * @return <code>ObjectName</code> + */ + @SqeDescriptorKey("OPERATION getWeather") + public Weather getWeather(@SqeDescriptorKey("METHOD PARAMETER")boolean verbose) + throws java.lang.Exception; + + public enum Weather { + CLOUDY, SUNNY + } + + @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt") + public Map<String, String> getNotifDescriptorAsMapAtt(); + + @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt") + public void setNotifDescriptorAsMapAtt(Map<String, String> value); + + @SqeDescriptorKey("OPERATION sendNotification") + public void sendNotification(@SqeDescriptorKey("METHOD PARAMETER")String notifType); + + @SqeDescriptorKey("OPERATION sendNotificationWave") + public void sendNotificationWave(boolean customNotification) throws Exception; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks correct exception and error events from NotificationListener + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @compile Basic.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3 + */ + + +import java.util.Map; +import java.util.HashMap; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import java.lang.management.ManagementFactory; +import javax.management.MBeanServer; +import javax.management.MBeanException; +import javax.management.MBeanServerDelegate; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.RuntimeErrorException; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +public class MXBeanExceptionHandlingTest implements NotificationListener { + + private static String BASIC_MXBEAN_CLASS_NAME = "Basic"; + + private long timeForNotificationInSeconds = 3L; + private int numOfNotifications = 2; + private BlockingQueue<Notification> notifList = null; + + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + MXBeanExceptionHandlingTest test = new MXBeanExceptionHandlingTest(); + test.run(map); + + } + + protected void parseArgs(Map<String, Object> args) throws Exception { + + String arg = null; + + // Init timeForNotificationInSeconds + // It is the maximum time in seconds we wait for a notification. + arg = (String)args.get("-timeForNotificationInSeconds") ; + if (arg != null) { + timeForNotificationInSeconds = (new Long(arg)).longValue(); + } + + } + + public void run(Map<String, Object> args) { + + System.out.println("MXBeanExceptionHandlingTest::run: Start") ; + int errorCount = 0 ; + + try { + parseArgs(args); + notifList = new ArrayBlockingQueue<Notification>(numOfNotifications); + + // JMX MbeanServer used inside single VM as if remote. + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + JMXConnectorServer cs = + JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + JMXServiceURL addr = cs.getAddress(); + JMXConnector cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + // ---- + System.out.println("Add me as notification listener"); + mbsc.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, + this, null, null); + System.out.println("---- OK\n") ; + + // ---- + System.out.println("Create and register the MBean"); + ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ; + mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName); + System.out.println("---- OK\n") ; + + // ---- + System.out.println("Call method throwException on our MXBean"); + + try { + mbsc.invoke(objName, "throwException", null, null); + errorCount++; + System.out.println("(ERROR) Did not get awaited MBeanException") ; + } catch (MBeanException mbe) { + System.out.println("(OK) Got awaited MBeanException") ; + Throwable cause = mbe.getCause(); + + if ( cause instanceof java.lang.Exception ) { + System.out.println("(OK) Cause is of the right class") ; + String mess = cause.getMessage(); + + if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) { + System.out.println("(OK) Cause message is fine") ; + } else { + errorCount++; + System.out.println("(ERROR) Cause has message " + + cause.getMessage() + + " as we expect " + + Basic.EXCEPTION_MESSAGE) ; + } + } else { + errorCount++; + System.out.println("(ERROR) Cause is of class " + + cause.getClass().getName() + + " as we expect java.lang.Exception") ; + } + } catch (Exception e) { + errorCount++; + System.out.println("(ERROR) Did not get awaited MBeanException but " + + e) ; + Utils.printThrowable(e, true); + } + System.out.println("---- DONE\n") ; + + // ---- + System.out.println("Call method throwError on our MXBean"); + + try { + mbsc.invoke(objName, "throwError", null, null); + errorCount++; + System.out.println("(ERROR) Did not get awaited RuntimeErrorException") ; + } catch (RuntimeErrorException ree) { + System.out.println("(OK) Got awaited RuntimeErrorException") ; + Throwable cause = ree.getCause(); + + if ( cause instanceof java.lang.InternalError ) { + System.out.println("(OK) Cause is of the right class") ; + String mess = cause.getMessage(); + + if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) { + System.out.println("(OK) Cause message is fine") ; + } else { + errorCount++; + System.out.println("(ERROR) Cause has message " + + cause.getMessage() + + " as we expect " + + Basic.EXCEPTION_MESSAGE) ; + } + } else { + errorCount++; + System.out.println("(ERROR) Cause is of class " + + cause.getClass().getName() + + " as we expect java.lang.InternalError") ; + } + } catch (Exception e) { + errorCount++; + System.out.println("(ERROR) Did not get awaited RuntimeErrorException but " + + e) ; + Utils.printThrowable(e, true); + } + System.out.println("---- DONE\n") ; + + // ---- + System.out.println("Unregister the MBean"); + mbsc.unregisterMBean(objName); + System.out.println("---- OK\n") ; + + Thread.sleep(timeForNotificationInSeconds * 1000); + int numOfReceivedNotif = notifList.size(); + + if ( numOfReceivedNotif == numOfNotifications ) { + System.out.println("(OK) We received " + + numOfNotifications + + " Notifications") ; + } else { + errorCount++; + System.out.println("(ERROR) We received " + + numOfReceivedNotif + + " Notifications in place of " + + numOfNotifications) ; + } + } catch(Exception e) { + Utils.printThrowable(e, true) ; + throw new RuntimeException(e); + } + + if ( errorCount == 0 ) { + System.out.println("MXBeanExceptionHandlingTest::run: Done without any error") ; + } else { + System.out.println("MXBeanExceptionHandlingTest::run: Done with " + + errorCount + + " error(s)") ; + throw new RuntimeException("errorCount = " + errorCount); + } + } + + public void handleNotification(Notification notification, Object handback) { + System.out.println("MXBeanExceptionHandlingTest::handleNotification: Received " + + notification); + notifList.add(notification); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/MXBeanInteropTest1.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Test all MXBeans available by default on the platform + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest1 + */ + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import java.lang.management.ClassLoadingMXBean; +import java.lang.management.CompilationMXBean; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryManagerMXBean; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.OperatingSystemMXBean; +import java.lang.management.RuntimeMXBean; +import java.lang.management.ThreadMXBean; + +import javax.management.JMX; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +public class MXBeanInteropTest1 { + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + MXBeanInteropTest1 test = new MXBeanInteropTest1(); + test.run(map); + + } + + public void run(Map<String, Object> args) { + + System.out.println("MXBeanInteropTest1::run: Start") ; + int errorCount = 0 ; + + try { + // JMX MbeanServer used inside single VM as if remote. + // MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + JMXConnectorServer cs = + JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + JMXServiceURL addr = cs.getAddress(); + JMXConnector cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + // Print out registered java.lang.management MXBeans found + // in the remote jvm. + printMBeans(mbsc) ; + + // For each possible kind of JDK 5 defined MXBean, we retrieve its + // MBeanInfo and print it and we call all getters and print + // their output. + errorCount += doClassLoadingMXBeanTest(mbsc) ; + errorCount += doMemoryMXBeanTest(mbsc) ; + errorCount += doThreadMXBeanTest(mbsc) ; + errorCount += doRuntimeMXBeanTest(mbsc) ; + errorCount += doOperatingSystemMXBeanTest(mbsc) ; + errorCount += doCompilationMXBeanTest(mbsc) ; + errorCount += doGarbageCollectorMXBeanTest(mbsc) ; + errorCount += doMemoryManagerMXBeanTest(mbsc) ; + errorCount += doMemoryPoolMXBeanTest(mbsc) ; + + // Terminate the JMX Client + cc.close(); + + } catch(Exception e) { + Utils.printThrowable(e, true) ; + throw new RuntimeException(e); + } + + if ( errorCount == 0 ) { + System.out.println("MXBeanInteropTest1::run: Done without any error") ; + } else { + System.out.println("MXBeanInteropTest1::run: Done with " + + errorCount + + " error(s)") ; + throw new RuntimeException("errorCount = " + errorCount); + } + } + + /** + * Prints all MBeans of domain java.lang. + * They are MBeans related to the JSR 174 that defines + * package java.lang.management. + */ + private static void printMBeans(MBeanServerConnection mbsc) throws Exception { + ObjectName filterName = new ObjectName("java.lang:*"); + Set<ObjectName> set = mbsc.queryNames(filterName, null); + + if ( set.size() == 0 ) { + throw new RuntimeException("(ERROR) No MBean found with filter " + + filterName); + } + + System.out.println("---- MBeans found in domain java.lang :"); + + for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) { + System.out.println(iter.next().toString()); + } + + System.out.println("\n") ; + } + + + private final int doClassLoadingMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- ClassLoadingMXBean") ; + + try { + ObjectName classLoadingName = + new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(classLoadingName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + + mbInfo); + ClassLoadingMXBean classLoading = null; + + classLoading = JMX.newMXBeanProxy(mbsc, + classLoadingName, + ClassLoadingMXBean.class) ; + System.out.println("getLoadedClassCount\t\t" + + classLoading.getLoadedClassCount()); + System.out.println("getTotalLoadedClassCount\t\t" + + classLoading.getTotalLoadedClassCount()); + System.out.println("getUnloadedClassCount\t\t" + + classLoading.getUnloadedClassCount()); + System.out.println("isVerbose\t\t" + + classLoading.isVerbose()); + + System.out.println("---- OK\n") ; + + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doMemoryMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- MemoryMXBean") ; + + try { + ObjectName memoryName = + new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + + mbInfo); + MemoryMXBean memory = null ; + + memory = + JMX.newMXBeanProxy(mbsc, + memoryName, + MemoryMXBean.class, + true) ; + System.out.println("getMemoryHeapUsage\t\t" + + memory.getHeapMemoryUsage()); + System.out.println("getNonHeapMemoryHeapUsage\t\t" + + memory.getNonHeapMemoryUsage()); + System.out.println("getObjectPendingFinalizationCount\t\t" + + memory.getObjectPendingFinalizationCount()); + System.out.println("isVerbose\t\t" + + memory.isVerbose()); + + System.out.println("---- OK\n") ; + + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doThreadMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- ThreadMXBean") ; + + try { + ObjectName threadName = + new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(threadName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + mbInfo); + ThreadMXBean thread = null ; + + thread = + JMX.newMXBeanProxy(mbsc, + threadName, + ThreadMXBean.class) ; + System.out.println("findMonitorDeadlockedThreads\t\t" + + thread.findMonitorDeadlockedThreads()); + long[] threadIDs = thread.getAllThreadIds() ; + System.out.println("getAllThreadIds\t\t" + + threadIDs); + + for ( long threadID : threadIDs ) { + System.out.println("getThreadInfo long\t\t" + + thread.getThreadInfo(threadID)); + System.out.println("getThreadInfo long, int\t\t" + + thread.getThreadInfo(threadID, 2)); + } + + System.out.println("getThreadInfo long[]\t\t" + + thread.getThreadInfo(threadIDs)); + System.out.println("getThreadInfo long[], int\t\t" + + thread.getThreadInfo(threadIDs, 2)); + System.out.println("getDaemonThreadCount\t\t" + + thread.getDaemonThreadCount()); + System.out.println("getPeakThreadCount\t\t" + + thread.getPeakThreadCount()); + System.out.println("getThreadCount\t\t" + + thread.getThreadCount()); + System.out.println("getTotalStartedThreadCount\t\t" + + thread.getTotalStartedThreadCount()); + boolean supported = thread.isThreadContentionMonitoringSupported() ; + System.out.println("isThreadContentionMonitoringSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("isThreadContentionMonitoringEnabled\t\t" + + thread.isThreadContentionMonitoringEnabled()); + } + + supported = thread.isThreadCpuTimeSupported() ; + System.out.println("isThreadCpuTimeSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("isThreadCpuTimeEnabled\t\t" + + thread.isThreadCpuTimeEnabled()); + + for (long id : threadIDs) { + System.out.println("getThreadCpuTime(" + id + ")\t\t" + + thread.getThreadCpuTime(id)); + System.out.println("getThreadUserTime(" + id + ")\t\t" + + thread.getThreadUserTime(id)); + } + } + + supported = thread.isCurrentThreadCpuTimeSupported() ; + System.out.println("isCurrentThreadCpuTimeSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("getCurrentThreadCpuTime\t\t" + + thread.getCurrentThreadCpuTime()); + System.out.println("getCurrentThreadUserTime\t\t" + + thread.getCurrentThreadUserTime()); + } + + thread.resetPeakThreadCount() ; + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doRuntimeMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- RuntimeMXBean") ; + + try { + ObjectName runtimeName = + new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(runtimeName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + mbInfo); + RuntimeMXBean runtime = null; + + runtime = + JMX.newMXBeanProxy(mbsc, + runtimeName, + RuntimeMXBean.class) ; + System.out.println("getClassPath\t\t" + + runtime.getClassPath()); + System.out.println("getInputArguments\t\t" + + runtime.getInputArguments()); + System.out.println("getLibraryPath\t\t" + + runtime.getLibraryPath()); + System.out.println("getManagementSpecVersion\t\t" + + runtime.getManagementSpecVersion()); + System.out.println("getName\t\t" + + runtime.getName()); + System.out.println("getSpecName\t\t" + + runtime.getSpecName()); + System.out.println("getSpecVendor\t\t" + + runtime.getSpecVendor()); + System.out.println("getSpecVersion\t\t" + + runtime.getSpecVersion()); + System.out.println("getStartTime\t\t" + + runtime.getStartTime()); + System.out.println("getSystemProperties\t\t" + + runtime.getSystemProperties()); + System.out.println("getUptime\t\t" + + runtime.getUptime()); + System.out.println("getVmName\t\t" + + runtime.getVmName()); + System.out.println("getVmVendor\t\t" + + runtime.getVmVendor()); + System.out.println("getVmVersion\t\t" + + runtime.getVmVersion()); + boolean supported = runtime.isBootClassPathSupported() ; + System.out.println("isBootClassPathSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("getBootClassPath\t\t" + + runtime.getBootClassPath()); + } + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doOperatingSystemMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- OperatingSystemMXBean") ; + + try { + ObjectName operationName = + new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(operationName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + mbInfo); + OperatingSystemMXBean operation = null ; + + operation = + JMX.newMXBeanProxy(mbsc, + operationName, + OperatingSystemMXBean.class) ; + System.out.println("getArch\t\t" + + operation.getArch()); + System.out.println("getAvailableProcessors\t\t" + + operation.getAvailableProcessors()); + System.out.println("getName\t\t" + + operation.getName()); + System.out.println("getVersion\t\t" + + operation.getVersion()); + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doCompilationMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- CompilationMXBean") ; + + try { + ObjectName compilationName = + new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME); + + if ( mbsc.isRegistered(compilationName) ) { + MBeanInfo mbInfo = mbsc.getMBeanInfo(compilationName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + mbInfo); + CompilationMXBean compilation = null ; + + compilation = + JMX.newMXBeanProxy(mbsc, + compilationName, + CompilationMXBean.class) ; + System.out.println("getName\t\t" + + compilation.getName()); + boolean supported = + compilation.isCompilationTimeMonitoringSupported() ; + System.out.println("isCompilationTimeMonitoringSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("getTotalCompilationTime\t\t" + + compilation.getTotalCompilationTime()); + } + } + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doGarbageCollectorMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- GarbageCollectorMXBean") ; + + try { + ObjectName filterName = + new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + + ",*"); + Set<ObjectName> onSet = mbsc.queryNames(filterName, null); + + for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) { + ObjectName garbageName = iter.next() ; + System.out.println("-------- " + garbageName) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(garbageName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + mbInfo); + GarbageCollectorMXBean garbage = null ; + + garbage = + JMX.newMXBeanProxy(mbsc, + garbageName, + GarbageCollectorMXBean.class) ; + System.out.println("getCollectionCount\t\t" + + garbage.getCollectionCount()); + System.out.println("getCollectionTime\t\t" + + garbage.getCollectionTime()); + } + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doMemoryManagerMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- MemoryManagerMXBean") ; + + try { + ObjectName filterName = + new ObjectName(ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + + ",*"); + Set<ObjectName> onSet = mbsc.queryNames(filterName, null); + + for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) { + ObjectName memoryManagerName = iter.next() ; + System.out.println("-------- " + memoryManagerName) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryManagerName); + System.out.println("getMBeanInfo\t\t" + mbInfo); + errorCount += checkNonEmpty(mbInfo); + MemoryManagerMXBean memoryManager = null; + + memoryManager = + JMX.newMXBeanProxy(mbsc, + memoryManagerName, + MemoryManagerMXBean.class) ; + System.out.println("getMemoryPoolNames\t\t" + + Arrays.deepToString(memoryManager.getMemoryPoolNames())); + System.out.println("getName\t\t" + + memoryManager.getName()); + System.out.println("isValid\t\t" + + memoryManager.isValid()); + } + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private final int doMemoryPoolMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- MemoryPoolMXBean") ; + + try { + ObjectName filterName = + new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + + ",*"); + Set<ObjectName> onSet = mbsc.queryNames(filterName, null); + + for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) { + ObjectName memoryPoolName = iter.next() ; + System.out.println("-------- " + memoryPoolName) ; + MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryPoolName); + errorCount += checkNonEmpty(mbInfo); + System.out.println("getMBeanInfo\t\t" + mbInfo); + MemoryPoolMXBean memoryPool = null; + + memoryPool = + JMX.newMXBeanProxy(mbsc, + memoryPoolName, + MemoryPoolMXBean.class, + true) ; + System.out.println("getCollectionUsage\t\t" + + memoryPool.getCollectionUsage()); + System.out.println("getMemoryManagerNames\t\t" + + Arrays.deepToString(memoryPool.getMemoryManagerNames())); + System.out.println("getName\t\t" + + memoryPool.getName()); + System.out.println("getPeakUsage\t\t" + + memoryPool.getPeakUsage()); + System.out.println("getType\t\t" + + memoryPool.getType()); + System.out.println("getUsage\t\t" + + memoryPool.getUsage()); + System.out.println("isValid\t\t" + + memoryPool.isValid()); + boolean supported = memoryPool.isUsageThresholdSupported() ; + System.out.println("isUsageThresholdSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("getUsageThreshold\t\t" + + memoryPool.getUsageThreshold()); + System.out.println("isUsageThresholdExceeded\t\t" + + memoryPool.isUsageThresholdExceeded()); + System.out.println("getUsageThresholdCount\t\t" + + memoryPool.getUsageThresholdCount()); + } + + supported = memoryPool.isCollectionUsageThresholdSupported() ; + System.out.println("isCollectionUsageThresholdSupported\t\t" + + supported); + + if ( supported ) { + System.out.println("getCollectionUsageThreshold\t\t" + + memoryPool.getCollectionUsageThreshold()); + System.out.println("getCollectionUsageThresholdCount\t\t" + + memoryPool.getCollectionUsageThresholdCount()); + System.out.println("isCollectionUsageThresholdExceeded\t\t" + + memoryPool.isCollectionUsageThresholdExceeded()); + } + + memoryPool.resetPeakUsage(); + } + + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + + private int checkNonEmpty(MBeanInfo mbi) { + if ( mbi.toString().length() == 0 ) { + System.out.println("(ERROR) MBeanInfo is empty !"); + return 1; + } else { + return 0; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/MXBeanInteropTest2.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks access to test MXBean + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @compile Basic.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest2 + */ + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.JMX; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanServer; +import java.lang.management.ManagementFactory; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +public class MXBeanInteropTest2 { + + private static String BASIC_MXBEAN_CLASS_NAME = "Basic"; + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + MXBeanInteropTest2 test = new MXBeanInteropTest2(); + test.run(map); + + } + + public void run(Map<String, Object> args) { + + System.out.println("MXBeanInteropTest2::run: Start") ; + int errorCount = 0 ; + + try { + // JMX MbeanServer used inside single VM as if remote. + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + JMXConnectorServer cs = + JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + JMXServiceURL addr = cs.getAddress(); + JMXConnector cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + // Prints all MBeans whatever the domain is. + printMBeans(mbsc) ; + + // Call test body + errorCount += doBasicMXBeanTest(mbsc) ; + + // Terminate the JMX Client + cc.close(); + + } catch(Exception e) { + Utils.printThrowable(e, true) ; + throw new RuntimeException(e); + } + + if ( errorCount == 0 ) { + System.out.println("MXBeanInteropTest2::run: Done without any error") ; + } else { + System.out.println("MXBeanInteropTest2::run: Done with " + + errorCount + + " error(s)") ; + throw new RuntimeException("errorCount = " + errorCount); + } + } + + + /** + * Prints all MBeans whatever the domain is. + */ + private static void printMBeans(MBeanServerConnection mbsc) throws Exception { + Set<ObjectName> set = mbsc.queryNames(null, null); + System.out.println("---- MBeans found :"); + + for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) { + System.out.println(iter.next().toString()); + } + + System.out.println("\n") ; + } + + + private final int doBasicMXBeanTest(MBeanServerConnection mbsc) { + int errorCount = 0 ; + System.out.println("---- doBasicMXBeanTest") ; + + try { + ObjectName objName = + new ObjectName("sqe:type=BasicMXBean") ; + mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName); + MBeanInfo mbInfo = mbsc.getMBeanInfo(objName); + printMBeanInfo(mbInfo); + System.out.println("---- OK\n") ; + System.out.println("getMBeanInfo\t\t" + + mbInfo); + System.out.println("---- OK\n") ; + + System.out.println("Check mxbean field in the MBeanInfo"); + String mxbeanField = + (String)mbInfo.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD); + + if ( mxbeanField == null || ! mxbeanField.equals("true")) { + System.out.println("---- ERROR : Improper mxbean field value " + + mxbeanField); + errorCount++; + } + System.out.println("---- OK\n") ; + + System.out.println("Set attribute ObjectNameAtt"); + Attribute att = new Attribute("ObjectNameAtt", objName); + mbsc.setAttribute(objName, att); + ObjectName value = + (ObjectName)mbsc.getAttribute(objName, "ObjectNameAtt"); + + if ( ! value.equals(objName) ) { + errorCount++; + System.out.println("---- ERROR : setAttribute failed, got " + + value + + " while expecting " + + objName); + } + System.out.println("---- OK\n") ; + + System.out.println("Call operation doNothing"); + mbsc.invoke(objName, "doNothing", null, null); + System.out.println("---- OK\n") ; + + System.out.println("Call operation getWeather"); + Object weather = mbsc.invoke(objName, + "getWeather", + new Object[]{Boolean.TRUE}, + new String[]{"boolean"}); + System.out.println("Weather is " + weather); + System.out.println("---- OK\n") ; + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++ ; + System.out.println("---- ERROR\n") ; + } + + return errorCount ; + } + + private void printMBeanInfo(MBeanInfo mbInfo) { + System.out.println("Description " + mbInfo.getDescription()); + + for (MBeanConstructorInfo ctor : mbInfo.getConstructors()) { + System.out.println("Constructor " + ctor.getName()); + } + + for (MBeanAttributeInfo att : mbInfo.getAttributes()) { + System.out.println("Attribute " + att.getName() + + " [" + att.getType() + "]"); + } + + for (MBeanOperationInfo oper : mbInfo.getOperations()) { + System.out.println("Operation " + oper.getName()); + } + + for (MBeanNotificationInfo notif : mbInfo.getNotifications()) { + System.out.println("Notification " + notif.getName()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/MXBeanLoadingTest1.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks correct collection of MXBean's class after unregistration + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @run main/othervm/timeout=300 MXBeanLoadingTest1 + */ + +import java.lang.ref.WeakReference; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.Map; +import javax.management.Attribute; +import javax.management.JMX; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.MXBean; +import javax.management.ObjectName; +import javax.management.loading.PrivateMLet; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; + +public class MXBeanLoadingTest1 { + + public static void main(String[] args) throws Exception { + MXBeanLoadingTest1 test = new MXBeanLoadingTest1(); + test.run((Map<String, Object>)null); + } + + + public void run(Map<String, Object> args) { + + System.out.println("MXBeanLoadingTest1::run: Start") ; + + try { + System.out.println("We ensure no reference is retained on MXBean class" + + " after it is unregistered. We take time to perform" + + " some little extra check of Descriptors, MBean*Info."); + + ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader(); + + if (!(myClassLoader instanceof URLClassLoader)) { + String message = "(ERROR) Test's class loader is not " + + "a URLClassLoader"; + System.out.println(message); + throw new RuntimeException(message); + } + + URLClassLoader myURLClassLoader = (URLClassLoader) myClassLoader; + URL[] urls = myURLClassLoader.getURLs(); + PrivateMLet mlet = new PrivateMLet(urls, null, false); + Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName()); + + if (shadowClass == TestMXBean.class) { + String message = "(ERROR) MLet got original TestMXBean, not shadow"; + System.out.println(message); + throw new RuntimeException(message); + } + shadowClass = null; + + MBeanServer mbs = MBeanServerFactory.createMBeanServer(); + ObjectName mletName = new ObjectName("x:type=mlet"); + mbs.registerMBean(mlet, mletName); + + ObjectName testName = new ObjectName("x:type=test"); + mbs.createMBean(Test.class.getName(), testName, mletName); + + // That test fails because the MXBean instance is accessed via + // a delegate OpenMBean which has + ClassLoader testLoader = mbs.getClassLoaderFor(testName); + + if (testLoader != mlet) { + System.out.println("MLet " + mlet); + String message = "(ERROR) MXBean's class loader is not MLet: " + + testLoader; + System.out.println(message); + throw new RuntimeException(message); + } + testLoader = null; + + + // Cycle get/set/get of the attribute of type Luis. + // We check the set is effective. + CompositeData cd_B = (CompositeData)mbs.getAttribute(testName, "B"); + CompositeType compType_B = cd_B.getCompositeType(); + + CompositeDataSupport cds_B = + new CompositeDataSupport(compType_B, + new String[]{"something"}, + new Object[]{Integer.valueOf(13)}); + Attribute myAtt = new Attribute("B", cds_B); + mbs.setAttribute(testName, myAtt); + + CompositeData cd_B2 = (CompositeData)mbs.getAttribute(testName, "B"); + + if ( ((Integer)cd_B2.get("something")).intValue() != 13 ) { + String message = "(ERROR) The setAttribute of att B did not work;" + + " expect Luis.something = 13 but got " + + cd_B2.get("something"); + System.out.println(message); + throw new RuntimeException(message); + } + + MBeanInfo info = mbs.getMBeanInfo(testName); + String mxbeanField = + (String)info.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD); + + if ( mxbeanField == null || ! mxbeanField.equals("true")) { + String message = "(ERROR) Improper mxbean field value " + + mxbeanField; + System.out.println(message); + throw new RuntimeException(message); + } + + // Check the 2 attributes. + MBeanAttributeInfo[] attrs = info.getAttributes(); + + if ( attrs.length == 2 ) { + for (MBeanAttributeInfo mbai : attrs) { + String originalTypeFieldValue = + (String)mbai.getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD); + OpenType<?> openTypeFieldValue = + (OpenType<?>)mbai.getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD); + + if ( mbai.getName().equals("A") ) { + if ( !mbai.isReadable() || !mbai.isWritable() + || mbai.isIs() + || !mbai.getType().equals("int") ) { + String message = "(ERROR) Unexpected MBeanAttributeInfo for A " + + mbai; + System.out.println(message); + throw new RuntimeException(message); + } + + if ( ! originalTypeFieldValue.equals("int") ) { + String message = "(ERROR) Unexpected originalType in Descriptor for A " + + originalTypeFieldValue; + System.out.println(message); + throw new RuntimeException(message); + } + + if ( ! openTypeFieldValue.equals(SimpleType.INTEGER) ) { + String message = "(ERROR) Unexpected openType in Descriptor for A " + + originalTypeFieldValue; + System.out.println(message); + throw new RuntimeException(message); + } + } else if ( mbai.getName().equals("B") ) { + if ( !mbai.isReadable() || !mbai.isWritable() + || mbai.isIs() + || !mbai.getType().equals("javax.management.openmbean.CompositeData") ) { + String message = "(ERROR) Unexpected MBeanAttributeInfo for B " + + mbai; + System.out.println(message); + throw new RuntimeException(message); + } + + if ( ! originalTypeFieldValue.equals(Luis.class.getName()) ) { + String message = "(ERROR) Unexpected originalType in Descriptor for B " + + originalTypeFieldValue; + System.out.println(message); + throw new RuntimeException(message); + } + + if ( ! openTypeFieldValue.equals(compType_B) ) { + String message = "(ERROR) Unexpected openType in Descriptor for B " + + compType_B; + System.out.println(message); + throw new RuntimeException(message); + } + } else { + String message = "(ERROR) Unknown attribute name"; + System.out.println(message); + throw new RuntimeException(message); + } + } + } else { + String message = "(ERROR) Unexpected MBeanAttributeInfo array" + + Arrays.deepToString(attrs); + System.out.println(message); + throw new RuntimeException(message); + } + + // Check the MXBean operation. + MBeanOperationInfo[] ops = info.getOperations(); + // The impact is ACTION_INFO as for a standard MBean it is UNKNOWN, + // logged 6320104. + if (ops.length != 1 || !ops[0].getName().equals("bogus") + || ops[0].getSignature().length > 0 + || !ops[0].getReturnType().equals("void")) { + String message = "(ERROR) Unexpected MBeanOperationInfo array " + + Arrays.deepToString(ops); + System.out.println(message); + throw new RuntimeException(message); + } + + String originalTypeFieldValue = + (String)ops[0].getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD); + OpenType<?> openTypeFieldValue = + (OpenType<?>)ops[0].getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD); + + if ( ! originalTypeFieldValue.equals("void") ) { + String message = "(ERROR) Unexpected originalType in Descriptor for bogus " + + originalTypeFieldValue; + System.out.println(message); + throw new RuntimeException(message); + } + + if ( ! openTypeFieldValue.equals(SimpleType.VOID) ) { + String message = "(ERROR) Unexpected openType in Descriptor for bogus " + + originalTypeFieldValue; + System.out.println(message); + throw new RuntimeException(message); + } + + // Check there is 2 constructors. + if (info.getConstructors().length != 2) { + String message = "(ERROR) Wrong number of constructors " + + "in introspected bean: " + + Arrays.asList(info.getConstructors()); + System.out.println(message); + throw new RuntimeException(message); + } + + // Check MXBean class name. + if (!info.getClassName().endsWith("Test")) { + String message = "(ERROR) Wrong info class name: " + + info.getClassName(); + System.out.println(message); + throw new RuntimeException(message); + } + + mbs.unregisterMBean(testName); + mbs.unregisterMBean(mletName); + + WeakReference<PrivateMLet> mletRef = + new WeakReference<PrivateMLet>(mlet); + mlet = null; + + System.out.println("MXBean registered and unregistered, waiting for " + + "garbage collector to collect class loader"); + + for (int i = 0; i < 10000 && mletRef.get() != null; i++) { + System.gc(); + Thread.sleep(1); + } + + if (mletRef.get() == null) + System.out.println("(OK) class loader was GC'd"); + else { + String message = "(ERROR) Class loader was not GC'd"; + System.out.println(message); + throw new RuntimeException(message); + } + } catch(Exception e) { + Utils.printThrowable(e, true) ; + throw new RuntimeException(e); + } + + System.out.println("MXBeanLoadingTest1::run: Done without any error") ; + } + + + // I agree the use of the MXBean annotation and the MXBean suffix for the + // interface name are redundant but however harmless. + // + @MXBean(true) + public static interface TestMXBean { + public void bogus(); + public int getA(); + public void setA(int a); + public Luis getB(); + public void setB(Luis mi); + } + + + public static class Test implements TestMXBean { + private Luis luis = new Luis() ; + public Test() {} + public Test(int x) {} + + public void bogus() {} + public int getA() {return 0;} + public void setA(int a) {} + public Luis getB() {return this.luis;} + public void setB(Luis luis) {this.luis = luis;} + } + + + public static class Luis { + private int something = 0; + public Luis() {} + public int getSomething() {return something;} + public void setSomething(int v) {something = v;} + public void doNothing() {} + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/MXBeanNotifTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks MXBean proper registration both as its implementation class and interface + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @compile Basic.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanNotifTest -numOfNotifications 239 -timeForNotificationInSeconds 4 + */ + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +import java.lang.management.ManagementFactory; + +import javax.management.Attribute; +import javax.management.Descriptor; +import javax.management.ImmutableDescriptor; +import javax.management.MBeanServer; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; + +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; + +public class MXBeanNotifTest implements NotificationListener { + + private static String BASIC_MXBEAN_CLASS_NAME = "Basic"; + private static String BASIC_MXBEAN_INTERFACE_NAME = "BasicMXBean"; + + private long timeForNotificationInSeconds = 3L; + private int numOfNotifications = 1; + private BlockingQueue<Notification> notifList = null; + private int numOfNotifDescriptorElements = 13; + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + MXBeanNotifTest test = new MXBeanNotifTest(); + test.run(map); + + } + + protected void parseArgs(Map<String, Object> args) throws Exception { + + String arg = null; + + // Init numOfNotifications + // It is the number of notifications we should trigger and check. + arg = (String)args.get("-numOfNotifications") ; + if (arg != null) { + numOfNotifications = (new Integer(arg)).intValue(); + } + + // Init timeForNotificationInSeconds + // It is the maximum time in seconds we wait for each notification. + arg = (String)args.get("-timeForEachNotificationInSeconds") ; + if (arg != null) { + timeForNotificationInSeconds = (new Long(arg)).longValue(); + } + + } + + public void run(Map<String, Object> args) { + + System.out.println("MXBeanNotifTest::run: Start") ; + int errorCount = 0 ; + + try { + parseArgs(args); + notifList = new ArrayBlockingQueue<Notification>(numOfNotifications); + + // JMX MbeanServer used inside single VM as if remote. + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + JMXConnectorServer cs = + JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + JMXServiceURL addr = cs.getAddress(); + JMXConnector cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + // ---- + System.out.println("MXBeanNotifTest::run: Create and register the MBean"); + ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ; + mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName); + System.out.println("---- OK\n") ; + + // ---- + System.out.println("MXBeanNotifTest::run: Add me as notification listener"); + mbsc.addNotificationListener(objName, this, null, null); + + // ---- + System.out.println("MXBeanNotifTest::run: Retrieve the Descriptor" + + " that should be in MBeanNotificationInfo"); + TabularData tabData = + (TabularData)mbsc.getAttribute(objName, "NotifDescriptorAsMapAtt"); + Map<String, String> descrMap = new HashMap<>(); + + for (Iterator<?> it = tabData.values().iterator(); it.hasNext(); ) { + CompositeData compData = (CompositeData)it.next(); + descrMap.put((String)compData.get("key"), + (String)compData.get("value")); + } + + Descriptor refNotifDescriptor = new ImmutableDescriptor(descrMap); + System.out.println("---- OK\n") ; + + // ---- + // Because the MBean holding the targeted attribute is MXBean, we + // should use for the setAttribute a converted form for the + // attribute value as described by the MXBean mapping rules. + // This explains all that lovely stuff for creating a + // TabularDataSupport. + // + // WARNING : the MBeanInfo of the MXBean used on opposite side + // is computed when the MBean is registered. + // It means the Descriptor considered for the MBeanNotificationInfo + // is not the one we set in the lines below, it is too late. + // However, we check that set is harmless when we check + // the MBeanNotificationInfo. + // + System.out.println("MXBeanNotifTest::run: Set a Map<String, String>" + + " attribute"); + String typeName = + "java.util.Map<java.lang.String,java.lang.String>"; + String[] keyValue = new String[] {"key", "value"}; + OpenType<?>[] openTypes = + new OpenType<?>[] {SimpleType.STRING, SimpleType.STRING}; + CompositeType rowType = new CompositeType(typeName, typeName, + keyValue, keyValue, openTypes); + TabularType tabType = new TabularType(typeName, typeName, + rowType, new String[]{"key"}); + TabularDataSupport convertedDescrMap = + new TabularDataSupport(tabType); + + for (int i = 0; i < numOfNotifDescriptorElements; i++) { + Object[] descrValue = {"field" + i, "value" + i}; + CompositeData data = + new CompositeDataSupport(rowType, keyValue, descrValue); + convertedDescrMap.put(data); + } + + Attribute descrAtt = + new Attribute("NotifDescriptorAsMapAtt", convertedDescrMap); + mbsc.setAttribute(objName, descrAtt); + System.out.println("---- OK\n") ; + + // ---- + System.out.println("MXBeanNotifTest::run: Compare the Descriptor from" + + " the MBeanNotificationInfo against a reference"); + MBeanInfo mbInfo = mbsc.getMBeanInfo(objName); + errorCount += checkMBeanInfo(mbInfo, refNotifDescriptor); + System.out.println("---- DONE\n") ; + + // ---- + System.out.println("Check isInstanceOf(Basic)"); + + if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_CLASS_NAME) ) { + errorCount++; + System.out.println("---- ERROR isInstanceOf returned false\n") ; + } else { + System.out.println("---- OK\n") ; + } + + // ---- + System.out.println("Check isInstanceOf(BasicMXBean)"); + + if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_INTERFACE_NAME) ) { + errorCount++; + System.out.println("---- ERROR isInstanceOf returned false\n") ; + } else { + System.out.println("---- OK\n") ; + } + + // ---- + System.out.println("MXBeanNotifTest::run: Ask for " + + numOfNotifications + " notification(s)"); + Object[] sendNotifParam = new Object[1]; + String[] sendNotifSig = new String[]{"java.lang.String"}; + + for (int i = 0; i < numOfNotifications; i++) { + // Select which type of notification we ask for + if ( i % 2 == 0 ) { + sendNotifParam[0] = Basic.NOTIF_TYPE_0; + } else { + sendNotifParam[0] = Basic.NOTIF_TYPE_1; + } + + // Trigger notification emission + mbsc.invoke(objName, + "sendNotification", + sendNotifParam, + sendNotifSig); + + // Wait for it then check it when it comes early enough + Notification notif = + notifList.poll(timeForNotificationInSeconds, + TimeUnit.SECONDS) ; + // The very first notification is likely to come in slower than + // all the others. Because that test isn't targeting the speed + // notifications are delivered with, we prefer to secure it. + if (i == 0 && notif == null) { + System.out.println("MXBeanNotifTest::run: Wait extra " + + timeForNotificationInSeconds + " second(s) the " + + " very first notification"); + notif = notifList.poll(timeForNotificationInSeconds, + TimeUnit.SECONDS); + } + + if ( notif == null ) { + errorCount++; + System.out.println("---- ERROR No notification received" + + " within allocated " + timeForNotificationInSeconds + + " second(s) !"); + } else { + errorCount += + checkNotification(notif, + (String)sendNotifParam[0], + Basic.NOTIFICATION_MESSAGE, + objName); + } + } + + int toc = 0; + while ( notifList.size() < 2 && toc < 10 ) { + Thread.sleep(499); + toc++; + } + System.out.println("---- DONE\n") ; + } catch(Exception e) { + Utils.printThrowable(e, true) ; + throw new RuntimeException(e); + } + + if ( errorCount == 0 ) { + System.out.println("MXBeanNotifTest::run: Done without any error") ; + } else { + System.out.println("MXBeanNotifTest::run: Done with " + + errorCount + + " error(s)") ; + throw new RuntimeException("errorCount = " + errorCount); + } + } + + + private int checkMBeanInfo(MBeanInfo mbi, Descriptor refDescr) { + MBeanNotificationInfo[] notifsInfo = mbi.getNotifications(); + int res = 0; + + for (MBeanNotificationInfo mbni : notifsInfo) { + if ( mbni.getDescriptor().equals(refDescr) ) { + System.out.println("(OK)"); + } else { + System.out.println("(ERROR) Descriptor of the notification is " + + mbni.getDescriptor() + + " as we expect " + + refDescr); + res++; + } + } + + return res; + } + + + private int checkNotification(Notification notif, + String refType, + String refMessage, + ObjectName refSource) { + int res = 0; + + Utils.debug(Utils.DEBUG_VERBOSE, + "\t getSource " + notif.getSource()); + Utils.debug(Utils.DEBUG_VERBOSE, + "\t getMessage " + notif.getMessage()); + Utils.debug(Utils.DEBUG_VERBOSE, + "\t getSequenceNumber " + notif.getSequenceNumber()); + Utils.debug(Utils.DEBUG_VERBOSE, + "\t getTimeStamp " + notif.getTimeStamp()); + Utils.debug(Utils.DEBUG_VERBOSE, + "\t getType " + notif.getType()); + Utils.debug(Utils.DEBUG_VERBOSE, + "\t getUserData " + notif.getUserData()); + + if ( ! notif.getType().equals(refType) ) { + res++; + System.out.println("(ERROR) Type is not " + + refType + " in notification\n" + notif); + } else { + if ( notif.getType().equals(Basic.NOTIF_TYPE_0) + && ! (notif instanceof javax.management.Notification) ) { + res++; + System.out.println("(ERROR) Notification is not instance of " + + " javax.management.Notification but rather " + + notif.getClass().getName()); + } else if ( notif.getType().equals(Basic.NOTIF_TYPE_1) + && ! (notif instanceof SqeNotification) ) { + res++; + System.out.println("(ERROR) Notification is not instance of " + + " javasoft.sqe.jmx.share.SqeNotification but rather " + + notif.getClass().getName()); + } + } + + if ( ! notif.getMessage().equals(refMessage) ) { + res++; + System.out.println("(ERROR) Message is not " + + refMessage + " in notification\n" + notif); + } + + if ( ! notif.getSource().equals(refSource) ) { + res++; + System.out.println("(ERROR) Source is not " + + refSource + " in notification\n" + notif); + } + + return res; + } + + public void handleNotification(Notification notification, Object handback) { + Utils.debug(Utils.DEBUG_VERBOSE, + "MXBeanNotifTest::handleNotification: Received " + + notification); + notifList.add(notification); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/MXBeanWeirdParamTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks that a serialized instance is not transmitted from an MXBean. + * All the communication should be done via Open Types + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @compile Basic.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest + */ + +import java.util.Map; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +import java.lang.Process; +import java.lang.management.ManagementFactory; + +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +import javax.management.ObjectName; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; + +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JDKToolFinder; + +public class MXBeanWeirdParamTest { + + private static String BASIC_MXBEAN_CLASS_NAME = "Basic"; + + private static final String CLIENT_CLASS_MAIN = + "MXBeanWeirdParamTest$ClientSide"; + + private JMXConnectorServer cs; + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + MXBeanWeirdParamTest test = new MXBeanWeirdParamTest(); + test.run(map); + + } + + /* + * Create the MBeansServe side of the test and returns its address + */ + private JMXServiceURL createServerSide() throws Exception { + final int NINETY_SECONDS = 90; + + // We will use the platform mbean server + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + Utils.waitReady(cs, NINETY_SECONDS); + + JMXServiceURL addr = cs.getAddress(); + return addr; + } + + + /* + * Creating command-line for running subprocess JVM: + * + * JVM command line is like: + * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main + * + * {defaultopts} are the default java options set by the framework. + * + */ + private List<String> buildCommandLine() { + List<String> opts = new ArrayList<>(); + opts.add(JDKToolFinder.getJDKTool("java")); + opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts())); + // We need to set WEIRD_PARAM propertty on the client-side + opts.add("-DWEIRD_PARAM"); + opts.add("-cp"); + opts.add(System.getProperty("test.class.path", "test.class.path")); + opts.add(CLIENT_CLASS_MAIN); + + return opts; + } + + /** + * Runs MXBeanWeirdParamTest$ClientSide with the passed options and redirects + * subprocess standard I/O to the current (parent) process. This provides a + * trace of what happens in the subprocess while it is runnning (and before + * it terminates). + * + * @param serviceUrlStr string representing the JMX service Url to connect to. + */ + private int runClientSide(String serviceUrlStr) throws Exception { + + // Building command-line + List<String> opts = buildCommandLine(); + opts.add(serviceUrlStr); + + // Launch separate JVM subprocess + int exitCode = 0; + String[] optsArray = opts.toArray(new String[0]); + ProcessBuilder pb = new ProcessBuilder(optsArray); + Process p = ProcessTools.startProcess("MXBeanWeirdParamTest$ClientSide", pb); + + // Handling end of subprocess + try { + exitCode = p.waitFor(); + if (exitCode != 0) { + System.out.println( + "Subprocess unexpected exit value of [" + exitCode + + "]. Expected 0.\n"); + } + } catch (InterruptedException e) { + System.out.println("Parent process interrupted with exception : \n " + e + " :" ); + + // Parent thread unknown state, killing subprocess. + p.destroyForcibly(); + + throw new RuntimeException( + "Parent process interrupted with exception : \n " + e + " :" ); + } finally { + return exitCode; + } + + } + + public void run(Map<String, Object> args) throws Exception { + + System.out.println("MXBeanWeirdParamTest::run: Start") ; + int errorCount = 0; + + try { + // Initialise the server side + JMXServiceURL urlToUse = createServerSide(); + + // Run client side + errorCount = runClientSide(urlToUse.toString()); + + if ( errorCount == 0 ) { + System.out.println("MXBeanWeirdParamTest::run: Done without any error") ; + } else { + System.out.println("MXBeanWeirdParamTest::run: Done with " + + errorCount + + " error(s)") ; + throw new RuntimeException("errorCount = " + errorCount); + } + + cs.stop(); + + } catch(Exception e) { + throw new RuntimeException(e); + } + + } + + private static class ClientSide { + public static void main(String args[]) throws Exception { + + int errorCount = 0 ; + String msgTag = "ClientSide::main: "; + + try { + + // Get a connection to remote mbean server + JMXServiceURL addr = new JMXServiceURL(args[0]); + JMXConnector cc = JMXConnectorFactory.connect(addr); + MBeanServerConnection mbsc = cc.getMBeanServerConnection(); + + // ---- + System.out.println(msgTag + "Create and register the MBean"); + ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ; + mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName); + System.out.println(msgTag +"---- OK\n") ; + + // ---- + System.out.println(msgTag +"Get attribute SqeParameterAtt on our MXBean"); + Object result = mbsc.getAttribute(objName, "SqeParameterAtt"); + System.out.println(msgTag +"(OK) Got result of class " + + result.getClass().getName()); + System.out.println(msgTag +"Received CompositeData is " + result); + System.out.println(msgTag +"---- OK\n") ; + + // ---- + // We use the value returned by getAttribute to perform the invoke. + System.out.println(msgTag +"Call operation doWeird on our MXBean [1]"); + mbsc.invoke(objName, "doWeird", + new Object[]{result}, + new String[]{"javax.management.openmbean.CompositeData"}); + System.out.println(msgTag +"---- OK\n") ; + + // ---- + // We build the CompositeData ourselves that time. + System.out.println(msgTag +"Call operation doWeird on our MXBean [2]"); + String typeName = "SqeParameter"; + String[] itemNames = new String[] {"glop"}; + OpenType<?>[] openTypes = new OpenType<?>[] {SimpleType.STRING}; + CompositeType rowType = new CompositeType(typeName, typeName, + itemNames, itemNames, openTypes); + Object[] itemValues = {"HECTOR"}; + CompositeData data = + new CompositeDataSupport(rowType, itemNames, itemValues); + TabularType tabType = new TabularType(typeName, typeName, + rowType, new String[]{"glop"}); + TabularDataSupport tds = new TabularDataSupport(tabType); + tds.put(data); + System.out.println(msgTag +"Source CompositeData is " + data); + mbsc.invoke(objName, "doWeird", + new Object[]{data}, + new String[]{"javax.management.openmbean.CompositeData"}); + System.out.println(msgTag +"---- OK\n") ; + + // ---- + System.out.println(msgTag +"Unregister the MBean"); + mbsc.unregisterMBean(objName); + System.out.println(msgTag +"---- OK\n") ; + + // Terminate the JMX Client + cc.close(); + + } catch(Exception e) { + Utils.printThrowable(e, true) ; + errorCount++; + throw new RuntimeException(e); + } finally { + System.exit(errorCount); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/SqeDescriptorKey.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import javax.management.DescriptorKey; + +/** + * That annotation is usable everywhere DescriptorKey is (and even more). + * It is for use to test that you can retrieve the SqeDescriptorKey into the + * appropriate Descriptor instances as built by the JMX runtime. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface SqeDescriptorKey { + @DescriptorKey("sqeDescriptorKey") + String value(); + + // List descriptor fields that may be added or may be updated + // when retrieving an MBeanInfo using a JMXWS connection compared to the + // MBeanInfo returned by a local MBeanServer. + // The annotation format is : + // <descriptorFieldName>=<descriptorFieldValue> + // The values actually handled by the test suite are : + // openType=SimpleType.VOID + @DescriptorKey("descriptorFields") + String[] descriptorFields() default {}; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/SqeNotification.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.Notification; + +/** + * Could hold someday a specific semantic. + * For now it is used to have a Notification which of another class, no more. + */ +public class SqeNotification extends Notification { + + /** Creates a new instance of SqeNotification */ + public SqeNotification(String type, Object source, long sequenceNumber) { + super(type, source, sequenceNumber); + } + + /** Creates a new instance of SqeNotification */ + public SqeNotification(String type, Object source, long sequenceNumber, + long timeStamp) { + super(type, source, sequenceNumber, timeStamp); + } + + /** Creates a new instance of SqeNotification */ + public SqeNotification(String type, Object source, long sequenceNumber, + long timeStamp, String message) { + super(type, source, sequenceNumber, timeStamp, message); + } + + /** Creates a new instance of SqeNotification */ + public SqeNotification(String type, Object source, long sequenceNumber, + String message) { + super(type, source, sequenceNumber, message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/SqeParameter.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.Serializable; + +/** + * That class is to use as an MBean operation parameter or returned value. + * The property Glop with its public getter + setter is only there to be + * reconstructible following MXBean specification, so that SqeParameter can be + * used for what it is designed to. + */ +public class SqeParameter implements Serializable { + + private static boolean weird; + private String glop; + + static { + if ( System.getProperty("WEIRD_PARAM") != null ) { + weird = true; + } + } + + /** + * Creates a new instance of SqeParameter. + * <br>When the Java property WEIRD_PARAM is set, that constructor + * throws an exception. + * <br>That can be used to ensure the class is instantiated on server side + * but never on client side. + */ + public SqeParameter() throws Exception { + if ( weird ) { + throw new Exception(); + } + } + + public String getGlop() { + return glop; + } + + public void setGlop(String value) { + glop = value; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/mxbean/Utils.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import java.lang.reflect.Method; +import javax.management.remote.JMXConnectorServerMBean; + +// utility class for MXBean* tests coming from JMX Tonga test suite +class Utils { + + // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property + private static final String DEBUG_HEADER = "[debug] "; + + // DEBUG levels + private static int selectedDebugLevel = 0; + static final int DEBUG_STANDARD = 1; + static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests + static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE; + + static void parseDebugProperties() { + int level = 0; + Properties p = System.getProperties(); + + // get selected levels + if (p.getProperty("DEBUG_STANDARD") != null) { + level |= DEBUG_STANDARD; + } + + if (p.getProperty("DEBUG_VERBOSE") != null) { + level |= DEBUG_VERBOSE; + } + + if (p.getProperty("DEBUG_ALL") != null) { + level |= DEBUG_ALL; + } + + selectedDebugLevel = level; + } + + /** + * Reproduces the original parsing and collection of test parameters + * from the DTonga JMX test suite. + * + * Collects passed args and returns them in a map(argname, value) structure, + * which will be then propagated as necessary to various called methods. + */ + static Map<String, Object> parseParameters(String args[]) + throws Exception { + Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start"); + HashMap<String, Object> map = new HashMap<>(); + + for ( int i = 0; i < args.length; i++ ) { + if ( args[i].trim().startsWith("-") ) { + if ((i+1) < args.length && !args[i+1].startsWith("-") ) { + Utils.debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with value " + + args[i+1]) ; + map.put(args[i].trim(), args[i+1].trim()) ; + } else if ((i+1) < args.length && args[i+1].startsWith("-") || + (i+1) == args.length ) { + Utils.debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with null value") ; + map.put(args[i].trim(), null) ; + } else { + System.out.println( + "TestRoot::parseParameters: (WARNING) not added in map = " + + args[i]) ; + } + } + } + + Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ; + return map ; + } + + /** + * This method is to be used in all tests to print anything + * that is temporary. + * Printing is done only when debug is activated by the property DEBUG. + * Printing depends also on the DEBUG_LEVEL property. + * Here it encapsulates a System.out.println. + */ + public static void debug(int level, String line) { + if ((selectedDebugLevel & level) != 0) { + System.out.println(DEBUG_HEADER + line); + } + } + + /** + * Do print stack trace when withStack is true. + * Does try to call getTargetException() and getTargetError() then + * print embedded stacks in the case of an Exception wrapping + * another Exception or an Error. Recurse until no more wrapping + * is found. + */ + public static void printThrowable(Throwable theThro, boolean withStack) { + try { + if (withStack) { + theThro.printStackTrace(System.out); + } + if (theThro instanceof Exception) { + Exception t = (Exception) theThro; + Method target = null; + String blank = " "; + try { + target = t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not + } + System.out.println(blank + t.getClass() + "==>" + t.getMessage()); + while (target != null) { + try { + t = (Exception) target.invoke(t, + (java.lang.Object[]) null); + } catch (Exception ee) { + t = null; + } + try { + if (t != null) { + blank = blank + " "; + System.out.println(blank + t.getClass() + "==>" + + t.getMessage()); + try { + target = + t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not } + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + + // We may have exceptions wrapping an Error then it is + // getTargetError that is likely to be called + try { + target = ((Exception) theThro).getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + Throwable err = theThro; + while (target != null) { + try { + err = (Error) target.invoke(err, + (java.lang.Object[]) null); + } catch (Exception ee) { + err = null; + } + try { + if (err != null) { + blank = blank + " "; + System.out.println(blank + err.getClass() + "==>" + + err.getMessage()); + if (withStack) { + err.printStackTrace(System.out); + } + try { + target = err.getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + } else { + System.out.println("Throwable is : " + theThro); + } + } catch (Throwable x) { + System.out.println("Exception : raised in printException : " + x); + } + } + + /** + * Wait up to maxTimeInSeconds second(s) the given JMX connector server + * comes up (which means isActive returns true). + * If it fails to do so we throw a RunTime exception. + */ + public static void waitReady(JMXConnectorServerMBean server, + int maxTimeInSeconds) throws Exception { + int elapsed = 0; + + while (!server.isActive() && elapsed < maxTimeInSeconds) { + Thread.sleep(1000); + elapsed++; + } + + if (server.isActive()) { + String message = "Utils::waitReady: JMX connector server came up"; + if ( elapsed == 0) { + message += " immediately"; + } else { + message += " after " + elapsed + " seconds"; + } + message += " [" + server.getAddress() + "]"; + Utils.debug(DEBUG_STANDARD, message); + } else { + String message = "Utils::waitReady: (ERROR) JMX connector" + + " server didn't come up after " + elapsed + " seconds [" + + server.getAddress() + "]"; + System.out.println(message); + throw new RuntimeException(message); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/QueryData.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public abstract class QueryData { + protected int intValue = 9; + protected long longValue = 9L; + protected Integer integerValue = Integer.valueOf(9); + protected boolean booleanValue = true; + protected double doubleValue = 9D; + protected float floatValue = 9.0F; + protected String stringValue = "9"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/QueryFactory.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; + +import javax.management.Query; +import javax.management.QueryExp; +import javax.management.ValueExp; + +/** + * Class used for building QueryExp instances of all every possible type + * in terms of JMX API members; note that several JMX classes are private + * and appears in the JDK API only by their serial form. + * Comments in each case of the big switch in method getQuery() details which + * API member we cover with a given query. + */ +public class QueryFactory extends QueryData { + + private String mbeanClassName = ""; + private String primitiveIntAttName = "IntAtt"; + private String primitiveLongAttName = "LongAtt"; + private String integerAttName = "IntegerAtt"; + private String primitiveBooleanAttName = "BooleanAtt"; + private String primitiveDoubleAttName = "DoubleAtt"; + private String primitiveFloatAttName = "FloatAtt"; + private String stringAttName = "StringAtt"; + private ArrayList<QueryExp> queries = new ArrayList<QueryExp>(); + + /** + * Creates a new instance of QueryFactory. + * The name is the fully qualified class name of an MBean. + * There is severe constraints on that MBean that must: + * <ul> + * <li>extend QueryData in order to inherit attribute values. + * <li>define a RW attribute IntAtt of type int + * initialized to QueryData.longValue + * <li>define a RW attribute LongAtt of type long + * initialized to QueryData.intValue + * <li>define a RW attribute IntegerAtt of type Integer + * initialized to QueryData.integerValue + * <li>define a RW attribute BooleanAtt of type boolean + * initialized to QueryData.booleanValue + * <li>define a RW attribute DoubleAtt of type double + * initialized to QueryData.doubleValue + * <li>define a RW attribute FloatAtt of type float + * initialized to QueryData.floatValue + * <li>define a RW attribute StringAtt of type String + * initialized to QueryData.stringValue + * </ul> + */ + public QueryFactory(String name) { + this.mbeanClassName = name; + } + + /** + * Returns the highest index value the method getQuery supports. + * WARNING : returns 0 if buildQueries haven't been called first ! + */ + public int getSize() { + return queries.size(); + } + + /** + * Populates an ArrayList of QueryExp. + * Lowest index is 1. + * Highest index is returned by getSize(). + * <br>The queries numbered 1 to 23 allow to cover all the underlying + * Java classes of the JMX API used to build queries. + */ + public void buildQueries() { + if ( queries.size() == 0 ) { + int smallerIntValue = intValue - 1; + int biggerIntValue = intValue + 1; + + // case 1: + // True if the MBean is of class mbeanClassName + // We cover javax.management.InstanceOfQueryExp + queries.add(Query.isInstanceOf(Query.value(mbeanClassName))); + + // case 2: + // True if the MBean is of class mbeanClassName + // We cover javax.management.MatchQueryExp and + // javax.management.ClassAttributeValueExp + queries.add(Query.match(Query.classattr(), + Query.value(mbeanClassName))); + + // case 3: + // True if an attribute named primitiveIntAttName of type int has + // the value intValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.NumericValueExp + queries.add(Query.eq(Query.attr(primitiveIntAttName), + Query.value(intValue))); + + // case 4: + // True if an attribute named primitiveLongAttName of type long has + // the value longValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.NumericValueExp + queries.add(Query.eq(Query.attr(primitiveLongAttName), + Query.value(longValue))); + + // case 5: + // True if an attribute named primitiveDoubleAttName of type double + // has the value doubleValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.NumericValueExp + queries.add(Query.eq(Query.attr(primitiveDoubleAttName), + Query.value(doubleValue))); + + // case 6: + // True if an attribute named primitiveFloatAttName of type float + // has the value floatValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.NumericValueExp + queries.add(Query.eq(Query.attr(primitiveFloatAttName), + Query.value(floatValue))); + + // case 7: + // True if an attribute named primitiveIntAttName of type int is + // hold by an MBean of class mbeanClassName and has + // the value intValue + // We cover javax.management.QualifiedAttributeValueExp + queries.add(Query.eq(Query.attr(mbeanClassName, primitiveIntAttName), + Query.value(intValue))); + + // case 8: + // True if an attribute named stringAttName of type String has + // the value stringValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.StringValueExp + queries.add(Query.eq(Query.attr(stringAttName), + Query.value(stringValue))); + + // case 9: + // True if an attribute named integerAttName of type Integer has + // the value integerValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.NumericValueExp + queries.add(Query.eq(Query.attr(integerAttName), + Query.value(integerValue))); + + // case 10: + // True if an attribute named primitiveBooleanAttName of type boolean + // has the value booleanValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to EQ and javax.management.BooleanValueExp + queries.add(Query.eq(Query.attr(primitiveBooleanAttName), + Query.value(booleanValue))); + + // case 11: + // True if an attribute named primitiveIntAttName of type int has + // not the value smallerIntValue + // We cover javax.management.NotQueryExp + queries.add(Query.not(Query.eq(Query.attr(primitiveIntAttName), + Query.value(smallerIntValue)))); + + // case 12: + // True if either + // an attribute named primitiveIntAttName of type int has + // the value intValue + // or + // an attribute named primitiveLongAttName of type long has + // the value longValue + // We cover javax.management.OrQueryExp + queries.add(Query.or( + Query.eq(Query.attr(primitiveIntAttName), + Query.value(intValue)), + Query.eq(Query.attr(primitiveLongAttName), + Query.value(longValue)))); + + // case 13: + // True if + // an attribute named primitiveIntAttName of type int has + // the value intValue + // and + // an attribute named primitiveLongAttName of type long has + // the value longValue + // We cover javax.management.AndQueryExp + queries.add(Query.and( + Query.eq(Query.attr(primitiveIntAttName), + Query.value(intValue)), + Query.eq(Query.attr(primitiveLongAttName), + Query.value(longValue)))); + + // case 14: + // True if an attribute named primitiveIntAttName of type int has + // the value intValue + // We cover javax.management.InQueryExp + ValueExp[] inArray = {Query.value(intValue)}; + queries.add(Query.in(Query.attr(primitiveIntAttName), inArray)); + + // case 15: + // True if an attribute named primitiveIntAttName of type int has + // its value in between smallerIntValue and biggerIntValue + // We cover javax.management.BetweenRelQueryExp + queries.add(Query.between(Query.attr(primitiveIntAttName), + Query.value(smallerIntValue), + Query.value(biggerIntValue))); + + // case 16: + // True if an attribute named primitiveIntAttName of type int has + // a value greater than smallerIntValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to GT + queries.add(Query.gt(Query.attr(primitiveIntAttName), + Query.value(smallerIntValue))); + + // case 17: + // True if an attribute named primitiveIntAttName of type int has + // a value greater or equal to smallerIntValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to GE + queries.add(Query.geq(Query.attr(primitiveIntAttName), + Query.value(smallerIntValue))); + + // case 18: + // True if an attribute named primitiveIntAttName of type int has + // a value smaller than biggerIntValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to LT + queries.add(Query.lt(Query.attr(primitiveIntAttName), + Query.value(biggerIntValue))); + + // case 19: + // True if an attribute named primitiveIntAttName of type int has + // a value smaller or equal to biggerIntValue + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to LE + queries.add(Query.leq(Query.attr(primitiveIntAttName), + Query.value(biggerIntValue))); + + // case 20: + // True if an attribute named primitiveIntAttName of type int has + // a value equal to intValue minus zero + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to MINUS + queries.add(Query.eq(Query.attr(primitiveIntAttName), + Query.minus(Query.value(intValue), Query.value(0)))); + + // case 21: + // True if an attribute named primitiveIntAttName of type int has + // a value equal to intValue plus zero + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to PLUS + queries.add(Query.eq(Query.attr(primitiveIntAttName), + Query.plus(Query.value(intValue), Query.value(0)))); + + // case 22: + // True if an attribute named primitiveIntAttName of type int has + // a value equal to intValue divided by one + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to DIV + queries.add(Query.eq(Query.attr(primitiveIntAttName), + Query.div(Query.value(intValue), Query.value(1)))); + + // case 23: + // True if an attribute named primitiveIntAttName of type int has + // a value equal to intValue multiplicated by one + // We cover javax.management.BinaryRelQueryExp with + // a relOp equal to TIMES + queries.add(Query.eq(Query.attr(primitiveIntAttName), + Query.times(Query.value(intValue), Query.value(1)))); + + // case 24: + // That query is a complex one that combines within a big AND + // queries with index 2 to 23 inclusive. But because a List is + // zero based, we must decrement all indexes by 1 when retrieving + // any previously stored query. + QueryExp q2_3 = Query.and(queries.get(2-1), queries.get(3-1)); + QueryExp q4_5 = Query.and(queries.get(4-1), queries.get(5-1)); + QueryExp q6_7 = Query.and(queries.get(6-1), queries.get(7-1)); + QueryExp q8_9 = Query.and(queries.get(8-1), queries.get(9-1)); + QueryExp q10_11 = Query.and(queries.get(10-1), queries.get(11-1)); + QueryExp q12_13 = Query.and(queries.get(12-1), queries.get(13-1)); + QueryExp q14_15 = Query.and(queries.get(14-1), queries.get(15-1)); + QueryExp q16_17 = Query.and(queries.get(16-1), queries.get(17-1)); + QueryExp q18_19 = Query.and(queries.get(18-1), queries.get(19-1)); + QueryExp q20_21 = Query.and(queries.get(20-1), queries.get(21-1)); + QueryExp q22_23 = Query.and(queries.get(22-1), queries.get(23-1)); + QueryExp q2_5 = Query.and(q2_3, q4_5); + QueryExp q6_9 = Query.and(q6_7, q8_9); + QueryExp q10_13 = Query.and(q10_11, q12_13); + QueryExp q14_17 = Query.and(q14_15, q16_17); + QueryExp q18_21 = Query.and(q18_19, q20_21); + QueryExp q2_9 = Query.and(q2_5, q6_9); + QueryExp q10_17 = Query.and(q10_13, q14_17); + QueryExp q18_23 = Query.and(q18_21, q22_23); + QueryExp q2_17 = Query.and(q2_9, q10_17); + queries.add(Query.and(q2_17, q18_23)); + + // case 25: + // Complex query mixing AND and OR. + queries.add(Query.or(q6_9, q18_23)); + } + } + + /** + * Returns a QueryExp taken is the ArrayList populated by buildQueries(). + * Lowest index is 1. + * Highest index is returned by getSize(). + * <br>The queries numbered 1 to 23 allow to cover all the underlying + * Java classes of the JMX API used to build queries. + */ + public QueryExp getQuery(int index) { + return queries.get(index - 1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/ServerDelegate.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import javax.management.remote.JMXServiceURL ; +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.StandardMBean; + +/** + * This class defines an MBean that can be registered and used on client side + * to handle informations or properties of the remote server. + * + * For example, this MBean can store IOR addresses + * of RMI/IIOP connector(s) used in a test. + * + * That MBean might not be used for testing purpose itself. + */ +public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration { + + private MBeanServer mbeanServer = null; + private List<JMXServiceURL> addresses = null; + private String port; + private static String javaVersion = System.getProperty("java.version"); + private int sqeJmxwsCredentialsProviderCallCount = 0; + private String jmxwsCredentialsProviderUrl = null; + private int testJMXAuthenticatorCallCount = 0; + private Principal testJMXAuthenticatorPrincipal = null; + + @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate") + public ServerDelegate() { + addresses = new ArrayList<JMXServiceURL>(); + } + + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + // Initialize MBeanServer attribute + mbeanServer = server; + return name; + } + public void postRegister(Boolean registrationDone) { + } + public void preDeregister() throws Exception { + } + public void postDeregister() { + } + + public void addAddress(JMXServiceURL url) { + addresses.add(url) ; + } + + public List<JMXServiceURL> getAddresses() { + return addresses ; + } + + public void setPort(String p) { + port = p ; + } + + public String getPort() { + return port ; + } + + public String getJavaVersion() { + return javaVersion; + } + + public void sqeJmxwsCredentialsProviderCalled() { + sqeJmxwsCredentialsProviderCallCount++; + } + + public int getSqeJmxwsCredentialsProviderCallCount() { + return sqeJmxwsCredentialsProviderCallCount; + } + + public void setJmxwsCredentialsProviderUrl(String url) { + jmxwsCredentialsProviderUrl = url; + } + + public String getJmxwsCredentialsProviderUrl() { + return jmxwsCredentialsProviderUrl; + } + + public void testJMXAuthenticatorCalled() { + testJMXAuthenticatorCallCount++; + } + + public int getTestJMXAuthenticatorCallCount() { + return testJMXAuthenticatorCallCount; + } + + public void setTestJMXAuthenticatorPrincipal(Principal principal) { + testJMXAuthenticatorPrincipal = principal; + } + + public String getTestJMXAuthenticatorPrincipalString() { + if ( testJMXAuthenticatorPrincipal != null ) { + return testJMXAuthenticatorPrincipal.toString(); + } + + return null; + } + + /** + * Instantiates and registers a StandardMBean in the MBean server. + * + * @param implementationClassName + * The implementation class name of the MBean. + * @param interfaceClassName + * The management interface class name of the MBean. + * @param isMXBean + * If true, the resultant MBean is an MXBean. + * @param name + * The object name of the StandardMBean. + */ + @SuppressWarnings("unchecked") + public void createStandardMBean( + String implementationClassName, + String interfaceClassName, + boolean isMXBean, + ObjectName name) + throws Exception { + + Object implementation = + Class.forName(implementationClassName).newInstance(); + Class<Object> interfaceClass = interfaceClassName == null ? null : + (Class<Object>)Class.forName(interfaceClassName); + + // Create the StandardMBean + StandardMBean standardMBean = new StandardMBean( + implementation, + interfaceClass, + isMXBean); + + // Register the StandardMBean + mbeanServer.registerMBean(standardMBean, name); + } + + /** + * Instantiates and registers a StandardMBean in the MBean server. + * The object will use standard JMX design pattern to determine + * the management interface associated with the given implementation. + */ + @SuppressWarnings("unchecked") + public void createStandardMBean( + String implementationClassName, + boolean isMXBean, + ObjectName name) + throws Exception { + + createStandardMBean(implementationClassName, null, isMXBean, name); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/ServerDelegateMBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Principal; +import java.util.List; + +import javax.management.remote.JMXServiceURL ; +import javax.management.ObjectName; + +@SqeDescriptorKey("INTERFACE ServerDelegateMBean") +public interface ServerDelegateMBean { + @SqeDescriptorKey("ATTRIBUTE Address") + public void addAddress(JMXServiceURL url); + + @SqeDescriptorKey("ATTRIBUTE Address") + public List<JMXServiceURL> getAddresses(); + + public String getPort(); + public void setPort(String p); + + public String getJavaVersion(); + + public void sqeJmxwsCredentialsProviderCalled(); + public int getSqeJmxwsCredentialsProviderCallCount(); + + public void setJmxwsCredentialsProviderUrl(String url); + public String getJmxwsCredentialsProviderUrl(); + + public void testJMXAuthenticatorCalled(); + public int getTestJMXAuthenticatorCallCount(); + + public void setTestJMXAuthenticatorPrincipal(Principal principal); + public String getTestJMXAuthenticatorPrincipalString(); + + public void createStandardMBean( + String implementationClassName, + String interfaceClassName, + boolean isMXBean, + ObjectName name) + throws Exception; + + public void createStandardMBean( + String implementationClassName, + boolean isMXBean, + ObjectName name) + throws Exception; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/SqeDescriptorKey.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import javax.management.DescriptorKey; + +/** + * That annotation is usable everywhere DescriptorKey is (and even more). + * It is for use to test that you can retrieve the SqeDescriptorKey into the + * appropriate Descriptor instances as built by the JMX runtime. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface SqeDescriptorKey { + @DescriptorKey("sqeDescriptorKey") + String value(); + + // List descriptor fields that may be added or may be updated + // when retrieving an MBeanInfo using a JMXWS connection compared to the + // MBeanInfo returned by a local MBeanServer. + // The annotation format is : + // <descriptorFieldName>=<descriptorFieldValue> + // The values actually handled by the test suite are : + // openType=SimpleType.VOID + @DescriptorKey("descriptorFields") + String[] descriptorFields() default {}; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/SupportedQueryTypesTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Tests most of the existing query types. + * @author Olivier Lagneau + * @modules java.management + * @compile TestQuery.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SupportedQueryTypesTest -mbeanClassName TestQuery + */ + +import java.util.Map ; +import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; +import java.lang.reflect.Method; + +import java.lang.management.ManagementFactory; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.MBeanServerConnection; +import javax.management.ObjectInstance; +import javax.management.ObjectName ; +import javax.management.QueryExp; + +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +public class SupportedQueryTypesTest { + + protected String mbeanClassName = null; + + private MBeanServerConnection mbsc = null; + + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + Map<String, Object> map = Utils.parseParameters(args) ; + + // Run test + SupportedQueryTypesTest test = new SupportedQueryTypesTest(); + test.run(map); + + } + + public void run(Map<String, Object> args) { + int errorCount = 0; + + ObjectName on = null; + ObjectName serverDelegateObjectName = null; + + JMXConnectorServer cs = null; + JMXConnector cc = null; + + System.out.println("SupportedQueryTypesTest::run: Start") ; + try { + // JMX MbeanServer used inside single VM as if remote. + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); + cs.start(); + + JMXServiceURL addr = cs.getAddress(); + cc = JMXConnectorFactory.connect(addr); + mbsc = cc.getMBeanServerConnection(); + + + // Create and register the ServerDelegate MBean on the remote MBeanServer + String serverDelegateClassName = ServerDelegate.class.getName(); + serverDelegateObjectName = + new ObjectName("defaultDomain:class=" + serverDelegateClassName); + mbsc.createMBean(serverDelegateClassName, serverDelegateObjectName); + + // Retrieve the MBean class name + mbeanClassName = (String) args.get("-mbeanClassName") ; + on = new ObjectName("defaultDomain:class=" + mbeanClassName); + + // Create and register the MBean on the remote MBeanServer + System.out.println("SupportedQueryTypesTest::run: CREATE " + + mbeanClassName + " on the remote MBeanServer with name " + + on); + mbsc.createMBean(mbeanClassName, on); + + // Create a QueryFactory and setup which query we'll use. + QueryFactory queries = new QueryFactory(mbeanClassName); + queries.buildQueries(); + int maxIndex = queries.getSize(); + int minIndex = 1; + + // Create a reference Set<ObjectName> to check later on + // the queryNames() results + Set<ObjectName> referenceNameSet = new HashSet<ObjectName>(); + referenceNameSet.add(on); + + // Create a reference Set<ObjectInstance> to check later on + // the queryMBeans() results + ObjectInstance oi = new ObjectInstance(on, mbeanClassName); + Set<ObjectInstance> referenceInstanceSet = + new HashSet<ObjectInstance>(); + referenceInstanceSet.add(oi); + + // Perform the queryNames and queryMBeans requests + for (int i = minIndex; i <= maxIndex; i++ ) { + QueryExp query = queries.getQuery(i); + System.out.println("----"); + System.out.println("SupportedQueryTypesTest::run: Query # " + i); + System.out.println("query " + query); + errorCount += + doQueryNames(query, referenceNameSet); + errorCount += + doQueryMBeans(query, referenceInstanceSet); + } + + } catch(Exception e) { + Utils.printThrowable(e, true); + errorCount++; + + } finally { + // Do unregister the MBean + try { + if (mbsc.isRegistered(on)) { + mbsc.unregisterMBean(on); + } + if (mbsc.isRegistered(serverDelegateObjectName)) { + mbsc.unregisterMBean(serverDelegateObjectName); + } + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++; + } + + try { + // Close JMX Connector Client + cc.close(); + // Stop connertor server + cs.stop(); + + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++; + } + } + + System.out.println(""); + System.out.println("SupportedQueryTypesTest::run: Done") ; + + // Handle result + if (errorCount == 0) { + System.out.println("SupportedQueryTypesTest::run: (OK)"); + } else { + String message = "SupportedQueryTypesTest::run: (ERROR) Got " + + + errorCount + " error(s)"; + System.out.println(message); + throw new RuntimeException(message); + } + } + + + private int doQueryNames(QueryExp query, Set<ObjectName> referenceSet) { + int errorCount = 0; + System.out.println(" <*> Perform queryNames call "); + + try { + // Call queryNames on the remote MBeanServer + Set<ObjectName> remoteSet = mbsc.queryNames(null, query); + + // Compare the 2 Set<ObjectName> + errorCount += checkSet(remoteSet, referenceSet); + + // Cleaning + remoteSet.clear(); + + } catch (Exception e) { + Utils.printThrowable(e, true); + errorCount++; + } + + if ( errorCount == 0 ) { + System.out.println("\t(OK)"); + } else { + System.out.println("\t(ERROR) Query failed"); + } + + return errorCount; + } + + + private int doQueryMBeans(QueryExp query, Set<ObjectInstance> referenceSet) { + int errorCount = 0; + System.out.println(" <*> Perform queryMBeans call "); + + try { + // Call queryMBeans on the remote MBeanServer + Set<ObjectInstance> remoteSet = mbsc.queryMBeans(null, query); + + // Compare the 2 Set<ObjectInstance> + errorCount += checkSet(remoteSet, referenceSet); + + // Cleaning + remoteSet.clear(); + + } catch (Exception e) { + Utils.printThrowable(e, true); + errorCount++; + } + + if ( errorCount == 0 ) { + System.out.println("\t(OK)"); + } else { + System.out.println("\t(ERROR) Query failed"); + } + + return errorCount; + } + + /** + * Pretty print of a Set content. + * When the Set isn't empty, toString() is called on each element. + * <br>The variable's name used to hold that Set is given via the setName + * parameter and used in the output. + */ + private static void printSet(Set<?> printableSet, String setName) { + if ( printableSet.size() == 0 ) { + System.out.println("The Set " + setName + " is empty"); + } else { + System.out.println("The Set " + setName + " contains :"); + + for (Iterator<?> it = printableSet.iterator(); it.hasNext();) { + Object elem = it.next(); + System.out.println("\t" + elem.toString()); + } + } + } + + + /** + * This method check the Set remoteSet is equal to + * the reference Set referenceSet, + * which means same size and content (order doesn't matter). + * <br>It returns 0 when the check is fine, otherwise 1. + */ + private int checkSet(Set<?> remoteSet, Set<?> referenceSet) { + if ( ! remoteSet.equals(referenceSet) ) { + System.out.println("SupportedQueryTypesTest::checkSet:" + + " (ERROR) Set aren't as expected"); + printSet(remoteSet, "remoteSet"); + printSet(referenceSet, "referenceSet"); + return 1; + } else { + return 0; + } + } + + // Utility inner class coming from JMX Tonga test suite. + private static class Utils { + + // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property + static final String DEBUG_HEADER = "[debug] "; + + // DEBUG levels + static int selectedDebugLevel = 0; + static final int DEBUG_STANDARD = 1; + static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests + static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE; + + static void parseDebugProperties() { + int level = 0; + Properties p = System.getProperties(); + + // get selected levels + if (p.getProperty("DEBUG_STANDARD") != null) { + level |= DEBUG_STANDARD; + } + + if (p.getProperty("DEBUG_VERBOSE") != null) { + level |= DEBUG_VERBOSE; + } + + if (p.getProperty("DEBUG_ALL") != null) { + level |= DEBUG_ALL; + } + + selectedDebugLevel = level; + } + + /** + * Reproduces the original parsing and collection of test parameters + * from the DTonga JMX test suite. + * + * Collects passed args and returns them in a map(argname, value) structure, + * which will be then propagated as necessary to various called methods. + */ + static Map<String, Object> parseParameters(String args[]) + throws Exception { + debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start"); + HashMap<String, Object> map = new HashMap<>(); + + for ( int i = 0; i < args.length; i++ ) { + if ( args[i].trim().startsWith("-") ) { + if ((i+1) < args.length && !args[i+1].startsWith("-") ) { + debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with value " + + args[i+1]) ; + map.put(args[i].trim(), args[i+1].trim()) ; + } else if ((i+1) < args.length && args[i+1].startsWith("-") || + (i+1) == args.length ) { + debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with null value") ; + map.put(args[i].trim(), null) ; + } else { + System.out.println( + "TestRoot::parseParameters: (WARNING) not added in map = " + + args[i]) ; + } + } + } + + debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ; + return map ; + } + + /** + * This method is to be used in all tests to print anything + * that is temporary. + * Printing is done only when debug is activated by the property DEBUG. + * Printing depends also on the DEBUG_LEVEL property. + * Here it encapsulates a System.out.println. + */ + static void debug(int level, String line) { + if ((selectedDebugLevel & level) != 0) { + System.out.println(DEBUG_HEADER + line); + } + } + + /** + * Do print stack trace when withStack is true. + * Does try to call getTargetException() and getTargetError() then + * print embedded stacks in the case of an Exception wrapping + * another Exception or an Error. Recurse until no more wrapping + * is found. + */ + static void printThrowable(Throwable theThro, boolean withStack) { + try { + if (withStack) { + theThro.printStackTrace(System.out); + } + if (theThro instanceof Exception) { + Exception t = (Exception) theThro; + Method target = null; + String blank = " "; + try { + target = t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not + } + System.out.println(blank + t.getClass() + "==>" + t.getMessage()); + while (target != null) { + try { + t = (Exception) target.invoke(t, + (java.lang.Object[]) null); + } catch (Exception ee) { + t = null; + } + try { + if (t != null) { + blank = blank + " "; + System.out.println(blank + t.getClass() + "==>" + + t.getMessage()); + try { + target = + t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not } + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + + // We may have exceptions wrapping an Error then it is + // getTargetError that is likely to be called + try { + target = ((Exception) theThro).getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + Throwable err = theThro; + while (target != null) { + try { + err = (Error) target.invoke(err, + (java.lang.Object[]) null); + } catch (Exception ee) { + err = null; + } + try { + if (err != null) { + blank = blank + " "; + System.out.println(blank + err.getClass() + "==>" + + err.getMessage()); + if (withStack) { + err.printStackTrace(System.out); + } + try { + target = err.getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + } else { + System.out.println("Throwable is : " + theThro); + } + } catch (Throwable x) { + System.out.println("Exception : raised in printException : " + x); + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/TestQuery.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Class TestQuery + * MBean used for testing the types wired when using QueryExp. + * It is heavily linked to QueryFactory. + */ +public class TestQuery extends QueryData implements TestQueryMBean { + + /** + * Attribute : BooleanAtt + */ + private boolean booleanAtt = booleanValue; + + /** + * Attribute : DoubleAtt + */ + private double doubleAtt = doubleValue; + + /** + * Attribute : FloatAtt + */ + private float floatAtt = floatValue; + + /** + * Attribute : IntAtt + */ + private int intAtt = intValue; + + /** + * Attribute : IntegerAtt + */ + private Integer integerAtt = integerValue; + + /** + * Attribute : LongAtt + */ + private long longAtt = longValue; + + /** + * Attribute : StringAtt + */ + private String stringAtt = stringValue; + + public TestQuery() { + } + + /** + * Get Att of type boolean + */ + public boolean getBooleanAtt() { + return booleanAtt; + } + + /** + * Set Att of type boolean + */ + public void setBooleanAtt(boolean value) { + booleanAtt = value; + } + + /** + * Get Att of type double + */ + public double getDoubleAtt() { + return doubleAtt; + } + + /** + * Set Att of type double + */ + public void setDoubleAtt(double value) { + doubleAtt = value; + } + + /** + * Get Att of type float + */ + public float getFloatAtt() { + return floatAtt; + } + + /** + * Set Att of type float + */ + public void setFloatAtt(float value) { + floatAtt = value; + } + + /** + * Get Att of type int + */ + public int getIntAtt() { + return intAtt; + } + + /** + * Set Att of type int + */ + public void setIntAtt(int value) { + intAtt = value; + } + + /** + * Get Att of type Integer + */ + public Integer getIntegerAtt() { + return integerAtt; + } + + /** + * Set Att of type Integer + */ + public void setIntegerAtt(Integer value) { + integerAtt = value; + } + + /** + * Get Att of type long + */ + public long getLongAtt() { + return longAtt; + } + + /** + * Set Att of type long + */ + public void setLongAtt(long value) { + longAtt = value; + } + + /** + * Get Att of type String + */ + public String getStringAtt() { + return stringAtt; + } + + /** + * Set Att of type String + */ + public void setStringAtt(String value) { + stringAtt = value; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/TestQueryMBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Interface TestQueryMBean + * MBean used for testing the types wired when using QueryExp. + * It is heavily linked to QueryFactory. + */ +public interface TestQueryMBean +{ + /** + * Get Att of type boolean + */ + public boolean getBooleanAtt(); + + /** + * Set Att of type boolean + */ + public void setBooleanAtt(boolean value); + + /** + * Get Att of type double + */ + public double getDoubleAtt(); + + /** + * Set Att of type double + */ + public void setDoubleAtt(double value); + + /** + * Get Att of type float + */ + public float getFloatAtt(); + + /** + * Set Att of type float + */ + public void setFloatAtt(float value); + + /** + * Get Att of type int + */ + public int getIntAtt(); + + /** + * Set Att of type int + */ + public void setIntAtt(int value); + + /** + * Get Att of type Integer + */ + public Integer getIntegerAtt(); + + /** + * Set Att of type Integer + */ + public void setIntegerAtt(Integer value); + + /** + * Get Att of type long + */ + public long getLongAtt(); + + /** + * Set Att of type long + */ + public void setLongAtt(long value); + + /** + * Get Att of type String + */ + public String getStringAtt(); + + /** + * Set Att of type String + */ + public void setStringAtt(String value); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/AuthorizationTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks various authentication behavior from remote jmx client + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @compile Simple.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username4 -Dpassword=password4 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedGetException -expectedSetException + * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + */ + +import java.io.File; +import java.util.Map ; +import java.util.HashMap ; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +import java.lang.management.ManagementFactory; + +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory ; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +import javax.management.Attribute ; +import javax.management.ObjectName ; + +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JDKToolFinder; + +public class AuthorizationTest { + + static final String SERVER_CLASS_NAME = "AuthorizationTest"; + static final String CLIENT_CLASS_NAME = "AuthorizationTest$ClientSide"; + static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME; + + static final String USERNAME_PROPERTY = "username"; + static final String PASSWORD_PROPERTY = "password"; + + private JMXConnectorServer cs; + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + + // Supported parameters list format is : + // "MainClass [-server <param-spec> ...] [-client <param-spec> ...] + // with <param-spec> either "-parami valuei" or "-parami" + HashMap<String, Object> serverMap = new HashMap<>() ; + int clientArgsIndex = + Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap); + + // Extract and records client params + String[] clientParams = null; + if (clientArgsIndex < args.length) { + int clientParamsSize = args.length - clientArgsIndex; + clientParams = new String[clientParamsSize]; + System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize); + } else { + clientParams = new String[0]; + } + + // Run test + AuthorizationTest test = new AuthorizationTest(); + test.run(serverMap, clientParams); + + } + + /* + * Create the MBeansServer side of the test and returns its address + */ + private JMXServiceURL createServerSide(Map<String, Object> serverMap) + throws Exception { + final int NINETY_SECONDS = 90; + + System.out.println("AuthorizationTest::createServerSide: Start") ; + + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + + // Creates connection environment from server side params + HashMap<String, Object> env = new HashMap<>(); + String value = null; + + if ((value = (String)serverMap.get("-mapType")) != null) { + if (value.contains("x.access.file")) { + String accessFileStr = System.getProperty("test.src") + + File.separator + "access.properties"; + env.put("jmx.remote.x.access.file", accessFileStr); + System.out.println("Added " + accessFileStr + " file as jmx.remote.x.access.file"); + } + if (value.contains("x.password.file")) { + String passwordFileStr = System.getProperty("test.src") + + File.separator + "password.properties"; + env.put("jmx.remote.x.password.file", passwordFileStr); + System.out.println("Added " + passwordFileStr + " file as jmx.remote.x.password.file"); + } + } + + if (serverMap.containsKey("-populate")) { + String populateClassName = "Simple"; + ObjectName on = + new ObjectName("defaultDomain:class=Simple"); + + Utils.debug(Utils.DEBUG_STANDARD, "create and register Simple MBean") ; + mbs.createMBean(populateClassName, on); + } + + cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); + cs.start(); + + Utils.waitReady(cs, NINETY_SECONDS); + + JMXServiceURL addr = cs.getAddress(); + + System.out.println("AuthorizationTest::createServerSide: Done.") ; + + return addr; + } + + /* + * Creating command-line for running subprocess JVM: + * + * JVM command line is like: + * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main + * + * {defaultopts} are the default java options set by the framework. + * + */ + private List<String> buildCommandLine(String args[]) { + List<String> opts = new ArrayList<>(); + opts.add(JDKToolFinder.getJDKTool("java")); + opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts())); + + String usernameValue = System.getProperty(USERNAME_PROPERTY); + if (usernameValue != null) { + opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue); + } + String passwordValue = System.getProperty(PASSWORD_PROPERTY); + if (passwordValue != null) { + opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue); + } + + opts.add("-cp"); + opts.add(System.getProperty("test.class.path", "test.class.path")); + opts.add(CLIENT_CLASS_MAIN); + opts.addAll(Arrays.asList(args)); + return opts; + } + + /** + * Runs AuthorizationTest$ClientSide with the passed options and redirects + * subprocess standard I/O to the current (parent) process. This provides a + * trace of what happens in the subprocess while it is runnning (and before + * it terminates). + * + * @param serviceUrlStr string representing the JMX service Url to connect to. + */ + private int runClientSide(String args[], String serviceUrlStr) throws Exception { + + // Building command-line + List<String> opts = buildCommandLine(args); + opts.add("-serviceUrl"); + opts.add(serviceUrlStr); + + // Launch separate JVM subprocess + int exitCode = 0; + String[] optsArray = opts.toArray(new String[0]); + ProcessBuilder pb = new ProcessBuilder(optsArray); + Process p = ProcessTools.startProcess("AuthorizationTest$ClientSide", pb); + + // Handling end of subprocess + try { + exitCode = p.waitFor(); + if (exitCode != 0) { + System.out.println( + "Subprocess unexpected exit value of [" + exitCode + + "]. Expected 0.\n"); + } + } catch (InterruptedException e) { + System.out.println("Parent process interrupted with exception : \n " + e + " :" ); + + // Parent thread unknown state, killing subprocess. + p.destroyForcibly(); + + throw new RuntimeException( + "Parent process interrupted with exception : \n " + e + " :" ); + + } finally { + if (p.isAlive()) { + p.destroyForcibly(); + } + return exitCode; + } + + } + + public void run(Map<String, Object> serverArgs, String clientArgs[]) { + + System.out.println("AuthorizationTest::run: Start") ; + int errorCount = 0; + + try { + // Initialise the server side + JMXServiceURL urlToUse = createServerSide(serverArgs); + + // Run client side + errorCount = runClientSide(clientArgs, urlToUse.toString()); + + if ( errorCount == 0 ) { + System.out.println("AuthorizationTest::run: Done without any error") ; + } else { + System.out.println("AuthorizationTest::run: Done with " + + errorCount + + " error(s)") ; + throw new RuntimeException("errorCount = " + errorCount); + } + + cs.stop(); + + } catch(Exception e) { + throw new RuntimeException(e); + } + + } + + private static class ClientSide { + + private JMXConnector cc = null; + private MBeanServerConnection mbsc = null; + + public static void main(String args[]) throws Exception { + + // Parses parameters + Utils.parseDebugProperties(); + + // Supported parameters list format is : "MainClass [-client <param-spec> ...] + // with <param-spec> either "-parami valuei" or "-parami" + HashMap<String, Object> clientMap = new HashMap<>() ; + Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap); + + // Run test + ClientSide test = new ClientSide(); + test.run(clientMap); + + } + + public void run(Map<String, Object> args) { + + int errorCount = 0 ; + + try { + boolean expectedCreateException = + (args.containsKey("-expectedCreateException")) ? true : false ; + boolean expectedGetException = + (args.containsKey("-expectedGetException")) ? true : false ; + boolean expectedSetException = + (args.containsKey("-expectedSetException")) ? true : false ; + boolean expectedInvokeException = + (args.containsKey("-expectedInvokeException")) ? true : false ; + // JSR262 (see bug 6440374) + // There is no special JSR262 protocol operation for connect. + // The first request sent initiate the connection. + // In the JSR262 current implementation, getDefaultDomain is sent to + // the server in order to get the server part of the connection ID. + // => the connection may fail if no access permission on get requests. + boolean expectedConnectException = + (args.containsKey("-expectedConnectException")) ? true : false ; + // Before connection, + // remove the element of the Map with null values (not supported by RMI) + // See bug 4982668 + args.remove("-expectedCreateException"); + args.remove("-expectedGetException"); + args.remove("-expectedSetException"); + args.remove("-expectedInvokeException"); + args.remove("-expectedConnectException"); + + + // Here do connect to the JMX Server + String username = System.getProperty("username"); + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::run: CONNECT on behalf of \"" + username + "\""); + doConnect(args, expectedConnectException); + + // If the connection did not fail, perform some requests. + // At this stage the mbeanserver connection is up and running + if (mbsc != null) { + ObjectName on = new ObjectName("defaultDomain:class=Simple"); + + // Create request + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::run: CREATE on behalf of \"" + + username + "\""); + errorCount += doCreateRequest(mbsc, + new ObjectName("defaultDomain:class=Simple,user=" + username), + expectedCreateException); + + // Get request + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::run: GET on behalf of \"" + + username + "\""); + errorCount += doGetRequest(mbsc, on, expectedGetException); + + // Set request + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::run: SET on behalf of \"" + + username + "\""); + errorCount += doSetRequest(mbsc, on, expectedSetException); + + // Invoke request + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::run: INVOKE on behalf of \"" + + username + "\""); + errorCount += doInvokeRequest(mbsc, on, expectedInvokeException); + } + + } catch(Exception e) { + Utils.printThrowable(e, true) ; + errorCount++; + } finally { + // Terminate the JMX Client + try { + cc.close(); + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++; + } + } + + System.out.println("ClientSide::run: Done") ; + + // Handle result + if (errorCount == 0) { + System.out.println("ClientSide::run: (OK) authorization test succeeded."); + } else { + String message = "AuthorizationTest$ClientSide::run: (ERROR) " + + " authorization test failed with " + + errorCount + " error(s)"; + System.out.println(message); + throw new RuntimeException(message); + } + } + + protected void doConnect(Map<String, Object> args, + boolean expectedException) { + + String msgTag = "ClientSide::doConnect"; + boolean throwRuntimeException = false; + String message = ""; + + try { + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doConnect: Connect the client"); + + // Collect connection environment + HashMap<String, Object> env = new HashMap<>(); + + Object value = args.get("-mapType"); + if (value != null) { + String username = System.getProperty("username"); + String password = System.getProperty("password"); + Utils.debug(Utils.DEBUG_STANDARD, + msgTag + "add \"jmx.remote.credentials\" = \"" + + username + "\", \"" + password + "\""); + env.put("jmx.remote.credentials", + new String[] { username , password }); + } + + // Get a connection to remote mbean server + JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl")); + cc = JMXConnectorFactory.connect(addr,env); + mbsc = cc.getMBeanServerConnection(); + + if (expectedException) { + message = "ClientSide::doConnect: (ERROR) " + + "Connect did not fail with expected SecurityException"; + System.out.println(message); + throwRuntimeException = true; + } else { + System.out.println("ClientSide::doConnect: (OK) Connect succeed"); + } + } catch(Exception e) { + Utils.printThrowable(e, true); + if (expectedException) { + if (e instanceof java.lang.SecurityException) { + System.out.println("ClientSide::doConnect: (OK) " + + "Connect failed with expected SecurityException"); + } else { + message = "ClientSide::doConnect: (ERROR) " + + "Create failed with " + e.getClass() + + " instead of expected SecurityException"; + System.out.println(message); + throwRuntimeException = true; + } + } else { + message = "ClientSide::doConnect: (ERROR) " + + "Connect failed"; + System.out.println(message); + throwRuntimeException = true; + } + } + + // If the connection failed, or if the connection succeeded but should not, + // no need to go further => throw RuntimeException and exit the test + if (throwRuntimeException) { + throw new RuntimeException(message); + } + } + + protected int doCreateRequest(MBeanServerConnection mbsc, + ObjectName on, + boolean expectedException) { + int errorCount = 0; + + try { + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doCreateRequest: Create and register the MBean") ; + + mbsc.createMBean("Simple", on) ; + + if (expectedException) { + System.out.println("ClientSide::doCreateRequest: " + + "(ERROR) Create did not fail with expected SecurityException"); + errorCount++; + } else { + System.out.println("ClientSide::doCreateRequest: (OK) Create succeed") ; + } + } catch(Exception e) { + Utils.printThrowable(e, true) ; + if (expectedException) { + if (e instanceof java.lang.SecurityException) { + System.out.println("ClientSide::doCreateRequest: " + + "(OK) Create failed with expected SecurityException") ; + } else { + System.out.println("ClientSide::doCreateRequest: " + + "(ERROR) Create failed with " + + e.getClass() + " instead of expected SecurityException"); + errorCount++; + } + } else { + System.out.println("ClientSide::doCreateRequest: " + + "(ERROR) Create failed"); + errorCount++; + } + } + return errorCount; + } + + protected int doGetRequest(MBeanServerConnection mbsc, + ObjectName on, + boolean expectedException) { + int errorCount = 0; + + try { + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doGetRequest: Get attributes of the MBean") ; + + mbsc.getAttribute(on, "Attribute"); + + if (expectedException) { + System.out.println("ClientSide::doGetRequest: " + + "(ERROR) Get did not fail with expected SecurityException"); + errorCount++; + } else { + System.out.println("ClientSide::doGetRequest: (OK) Get succeed") ; + } + } catch(Exception e) { + Utils.printThrowable(e, true) ; + if (expectedException) { + if (e instanceof java.lang.SecurityException) { + System.out.println("ClientSide::doGetRequest: " + + "(OK) Get failed with expected SecurityException") ; + } else { + System.out.println("ClientSide::doGetRequest: " + + "(ERROR) Get failed with " + + e.getClass() + " instead of expected SecurityException"); + errorCount++; + } + } else { + System.out.println("ClientSide::doGetRequest: (ERROR) Get failed"); + errorCount++; + } + } + + return errorCount; + } + + protected int doSetRequest(MBeanServerConnection mbsc, + ObjectName on, + boolean expectedException) { + int errorCount = 0; + + try { + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doSetRequest: Set attributes of the MBean") ; + + Attribute attribute = new Attribute("Attribute", "My value") ; + mbsc.setAttribute(on, attribute) ; + + if (expectedException) { + System.out.println("ClientSide::doSetRequest: " + + "(ERROR) Set did not fail with expected SecurityException"); + errorCount++; + } else { + System.out.println("ClientSide::doSetRequest: (OK) Set succeed") ; + } + } catch(Exception e) { + Utils.printThrowable(e, true) ; + if (expectedException) { + if (e instanceof java.lang.SecurityException) { + System.out.println("ClientSide::doSetRequest: " + + "(OK) Set failed with expected SecurityException") ; + } else { + System.out.println("ClientSide::doSetRequest: " + + "(ERROR) Set failed with " + + e.getClass() + " instead of expected SecurityException"); + errorCount++; + } + } else { + System.out.println("ClientSide::doSetRequest: (ERROR) Set failed"); + errorCount++; + } + } + return errorCount; + } + + protected int doInvokeRequest(MBeanServerConnection mbsc, + ObjectName on, + boolean expectedException) { + int errorCount = 0; + + try { + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doInvokeRequest: Invoke operations on the MBean") ; + + mbsc.invoke(on, "operation", null, null) ; + + if (expectedException) { + System.out.println("ClientSide::doInvokeRequest: " + + "(ERROR) Invoke did not fail with expected SecurityException"); + errorCount++; + } else { + System.out.println("ClientSide::doInvokeRequest: (OK) Invoke succeed") ; + } + } catch(Exception e) { + Utils.printThrowable(e, true) ; + if (expectedException) { + if (e instanceof java.lang.SecurityException) { + System.out.println("ClientSide::doInvokeRequest: " + + "(OK) Invoke failed with expected SecurityException") ; + } else { + System.out.println("ClientSide::doInvokeRequest: " + + " (ERROR) Invoke failed with " + + e.getClass() + " instead of expected SecurityException"); + errorCount++; + } + } else { + System.out.println("ClientSide::doInvokeRequest: " + + "(ERROR) Invoke failed"); + errorCount++; + } + } + return errorCount; + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/MBS_Light.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.AccessControlContext; +import java.security.AccessController; +import javax.security.auth.Subject; +import java.security.Principal; +import java.util.Iterator; +import java.util.Set; + +import javax.management.MBeanRegistration ; +import javax.management.MBeanServer ; +import javax.management.ObjectName ; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationListener; +import javax.management.Notification; + +public class MBS_Light extends NotificationBroadcasterSupport + implements MBS_LightMBean, MBeanRegistration, NotificationListener +{ + private RjmxMBeanParameter param = null ; + private String aString = "notset" ; + private int anInt = 0 ; + private MBeanServer mbs = null ; + private ObjectName objname = null ; + private Exception anException = null ; + private Error anError = null ; + private int count = 0; + private SimpleListener listener = new SimpleListener(); + + @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR MBS_Light") + public MBS_Light() { + } + + @SqeDescriptorKey("ONE RjmxMBeanParameter PARAMETER CONSTRUCTOR MBS_Light") + public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param") + RjmxMBeanParameter param) { + this.param = param ; + } + + @SqeDescriptorKey("ONE String PARAMETER CONSTRUCTOR MBS_Light") + public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")String param) { + this.aString = param ; + } + + // Getter for property param + public RjmxMBeanParameter getParam() { + return this.param ; + } + + // Setter for property param + public void setParam(RjmxMBeanParameter param) { + this.param = param ; + } + + // Getter for property aString + public String getAstring() { + return this.aString ; + } + + // Setter for property aString + public void setAstring(String aString) { + this.aString = aString ; + } + + // Getter for property anInt + public int getAnInt() { + return this.anInt ; + } + + // Setter for property anInt + public void setAnInt(int anInt) { + this.anInt = anInt ; + } + + // Getter for property anException + public Exception getAnException() { + return this.anException ; + } + + // Setter for property anException + public void setAnException(Exception anException) { + this.anException = anException ; + } + + // Getter for property anError + public Error getAnError() { + return this.anError ; + } + + // Setter for property anError + public void setAnError(Error anError) { + this.anError = anError ; + } + + // An operation + public RjmxMBeanParameter operate1(String name) { + return new RjmxMBeanParameter(name) ; + } + + // An operation + public String operate2(RjmxMBeanParameter param) { + return param.name ; + } + + // An operation + public void throwError() { + throw new Error("JSR-160-ERROR"); + } + + // An operation + public void throwException() throws Exception { + throw new Exception("JSR-160-EXCEPTION"); + } + + // MBeanRegistration method + public void postDeregister() { + } + + // MBeanRegistration method + public void postRegister(Boolean registrationDone) { + } + + // MBeanRegistration method + public void preDeregister() + throws Exception + { + } + + // MBeanRegistration method + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception + { + this.mbs = server ; + if ( name == null ) { + this.objname = new ObjectName("protocol:class=MBS_Light") ; + } + else { + this.objname = name ; + } + return this.objname ; + } + + public synchronized void handleNotification(Notification notification, + Object handback) { + Utils.debug(Utils.DEBUG_STANDARD, + "MBS_Light::handleNotification: " + notification); + listener.handleNotification(notification, handback); + } + + // Send a notification + public void sendNotification() { + Notification notification = + new Notification("JSR160-TCK-NOTIFICATION", this, count++); + sendNotification(notification); + } + + public Object waitForNotificationHB() { + return listener.waitForNotificationHB(); + } + + // Receive multi notifications and send back handbacks + public synchronized Object[] waitForMultiNotifications(String nb) { + return listener.waitForMultiNotifications(Integer.valueOf(nb).intValue()); + } + + // Receive a notification + public synchronized String waitForNotification() { + return listener.waitForNotification(); + } + + // Is the notification received + public synchronized Boolean notificationReceived() { + return Boolean.valueOf(listener.isNotificationReceived()); + } + + // The authorization Id + public String getAuthorizationId() { + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + Set<Principal> principals = subject.getPrincipals(); + Iterator<Principal> i = principals.iterator(); + StringBuffer buffer = new StringBuffer(); + while(i.hasNext()) { + Principal p = i.next(); + buffer.append(p.getName()); + if(i.hasNext()) + buffer.append(" "); + } + + return buffer.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/MBS_LightMBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +@SqeDescriptorKey("INTERFACE MBS_LightMBean") +public interface MBS_LightMBean { + // Getter for property param + @SqeDescriptorKey("ATTRIBUTE Param") + public RjmxMBeanParameter getParam() ; + + // Setter for property param + @SqeDescriptorKey("ATTRIBUTE Param") + public void setParam(RjmxMBeanParameter param) ; + + // Getter for property aString + @SqeDescriptorKey("ATTRIBUTE Astring") + public String getAstring() ; + + // Setter for property aString + @SqeDescriptorKey("ATTRIBUTE Astring") + public void setAstring(String aString) ; + + // Getter for property anInt + @SqeDescriptorKey("ATTRIBUTE AnInt") + public int getAnInt() ; + + // Setter for property anInt + @SqeDescriptorKey("ATTRIBUTE AnInt") + public void setAnInt(int anInt) ; + + // Getter for property anException + @SqeDescriptorKey("ATTRIBUTE AnException") + public Exception getAnException() ; + + // Setter for property anException + @SqeDescriptorKey("ATTRIBUTE AnException") + public void setAnException(Exception anException) ; + + // Getter for property anError + @SqeDescriptorKey("ATTRIBUTE AnError") + public Error getAnError() ; + + // Setter for property anError + @SqeDescriptorKey("ATTRIBUTE AnError") + public void setAnError(Error anError) ; + + // An operation + @SqeDescriptorKey("OPERATION operate1") + public RjmxMBeanParameter operate1( + @SqeDescriptorKey("OPERATION PARAMETER name")String name) ; + + // An operation + @SqeDescriptorKey("OPERATION operate2") + public String operate2( + @SqeDescriptorKey("OPERATION PARAMETER param")RjmxMBeanParameter param) ; + + // Throws an error + @SqeDescriptorKey("OPERATION throwError") + public void throwError(); + + // Throws an exception + @SqeDescriptorKey("OPERATION throwException") + public void throwException() throws Exception; + + // Send a notification + @SqeDescriptorKey("OPERATION sendNotification") + public void sendNotification(); + + // Receive a notification and return the type + @SqeDescriptorKey("OPERATION waitForNotification") + public String waitForNotification(); + + // Receive a notification and return the HandBack + @SqeDescriptorKey("OPERATION waitForNotificationHB") + public Object waitForNotificationHB(); + + // Receive multi notifications and return the HandBacks + @SqeDescriptorKey("OPERATION waitForMultiNotifications") + public Object[] waitForMultiNotifications( + @SqeDescriptorKey("OPERATION PARAMETER nb")String nb); + + // Is the notification received + @SqeDescriptorKey("OPERATION notificationReceived") + public Boolean notificationReceived(); + + // Return the current authorization Id + @SqeDescriptorKey("OPERATION getAuthorizationId") + public String getAuthorizationId(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/RjmxMBeanParameter.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.Serializable ; + +/** + * That class is used to modelize a parameter to be used as MBean property + * value or MBean operation parameter or returned value. + */ +public class RjmxMBeanParameter implements Serializable { + public String name = "unset" ; + + public RjmxMBeanParameter() { + } + + public RjmxMBeanParameter(String name) { + this.name = name ; + } + + public boolean equals(Object obj) { + if ( this.name.equals(((RjmxMBeanParameter)obj).name) ) { + return true ; + } else { + return false ; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/SecurityTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,800 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8058865 + * @summary Checks various secure ways of connecting from remote jmx client + * @author Olivier Lagneau + * @modules java.management + * @library /lib/testlibrary + * @compile MBS_Light.java ServerDelegate.java TestSampleLoginModule.java + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=UNKNOWN_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=WRONG_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=TestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=AnotherTestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials -expectedThrowable java.lang.SecurityException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentials + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config.UNKNOWN -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentialss -expectedThrowable java.lang.SecurityException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.UnknownAuthentication -client -mapType credentials -expectedThrowable java.lang.SecurityException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=usernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=AnotherUsernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials -expectedThrowable java.lang.SecurityException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword WRONG_password -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword WRONG_password -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.sha -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=TLSv1 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.tlsv1 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException + */ + +import java.io.File; +import java.util.Map ; +import java.util.HashMap ; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory ; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +import javax.management.Attribute ; +import javax.management.ObjectName ; + +import javax.rmi.ssl.SslRMIClientSocketFactory; +import javax.rmi.ssl.SslRMIServerSocketFactory; + +import java.security.Security; + +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JDKToolFinder; + +public class SecurityTest { + + static final String SERVER_CLASS_NAME = "SecurityTest"; + static final String CLIENT_CLASS_NAME = "SecurityTest$ClientSide"; + static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME; + + static final String USERNAME_PROPERTY = "username"; + static final String PASSWORD_PROPERTY = "password"; + + static final String SERVER_DELEGATE_MBEAN_NAME = + "defaultDomain:class=ServerDelegate"; + + static final String RMI_SERVER_SOCKET_FACTORY_SSL = "rmi.server.socket.factory.ssl"; + static final String RMI_CLIENT_SOCKET_FACTORY_SSL = "rmi.client.socket.factory.ssl"; + static final String KEYSTORE_PROPNAME = "javax.net.ssl.keyStore"; + static final String KEYSTORE_PWD_PROPNAME = "javax.net.ssl.keyStorePassword"; + static final String TRUSTSTORE_PROPNAME = "javax.net.ssl.trustStore"; + static final String TRUSTSTORE_PWD_PROPNAME = "javax.net.ssl.trustStorePassword"; + + static final String RMI_SSL_CLIENT_ENABLEDCIPHERSUITES = + "javax.rmi.ssl.client.enabledCipherSuites"; + static final String RMI_SSL_CLIENT_ENABLEDPROTOCOLS = + "javax.rmi.ssl.client.enabledProtocols"; + + private JMXConnectorServer cs; + + // Construct and set keyStore properties from given map + static void setKeyStoreProperties(Map<String, Object> map) { + + String keyStore = (String) map.get("-keystore"); + keyStore = buildSourcePath(keyStore); + System.setProperty(KEYSTORE_PROPNAME, keyStore); + System.out.println("keyStore location = \"" + keyStore + "\""); + + String password = (String) map.get("-keystorepassword"); + System.setProperty(KEYSTORE_PWD_PROPNAME, password); + System.out.println("keyStore password = " + password); + + } + + // Construct and set trustStore properties from given map + static void setTrustStoreProperties(Map<String, Object> map) { + + String trustStore = (String) map.get("-truststore"); + trustStore = buildSourcePath(trustStore); + System.setProperty(TRUSTSTORE_PROPNAME, trustStore); + System.out.println("trustStore location = \"" + trustStore + "\""); + + String password = (String) map.get("-truststorepassword"); + System.setProperty(TRUSTSTORE_PWD_PROPNAME, password); + System.out.println("trustStore password = " + password); + + } + + /* + * First Debug properties and arguments are collect in expected + * map (argName, value) format, then calls original test's run method. + */ + public static void main(String args[]) throws Exception { + + System.out.println("================================================="); + + // Parses parameters + Utils.parseDebugProperties(); + + // Supported parameters list format is : + // "MainClass [-server <param-spec> ...] [-client <param-spec> ...] + // with <param-spec> either "-parami valuei" or "-parami" + HashMap<String, Object> serverMap = new HashMap<>() ; + int clientArgsIndex = + Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap); + + // Extract and records client params + String[] clientParams = null; + if (clientArgsIndex < args.length) { + int clientParamsSize = args.length - clientArgsIndex; + clientParams = new String[clientParamsSize]; + System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize); + } else { + clientParams = new String[0]; + } + + // Run test + SecurityTest test = new SecurityTest(); + test.run(serverMap, clientParams); + + } + + // Return full path of filename in the test sopurce directory + private static String buildSourcePath(String filename) { + return System.getProperty("test.src") + File.separator + filename; + } + + /* + * Collects security run params for server side. + */ + private HashMap<String, Object> setServerSecurityEnv(Map<String, Object> map) + throws Exception { + + // Creates Authentication environment from server side params + HashMap<String, Object> env = new HashMap<>(); + + // Retrieve and set keystore and truststore config if any + if (map.containsKey("-keystore") && + map.get("-keystore") != null) { + setKeyStoreProperties(map); + } + System.out.println("Done keystore properties"); + + if (map.containsKey("-truststore") && + map.get("-truststore") != null) { + setTrustStoreProperties(map); + } + System.out.println("Done truststore properties"); + + String value = null; + if ((value = (String)map.get("-mapType")) != null) { + + // Case of remote password file with all authorized credentials + if (value.contains("x.password.file")) { + String passwordFileStr = buildSourcePath("password.properties"); + env.put("jmx.remote.x.password.file", passwordFileStr); + System.out.println("Added " + passwordFileStr + + " file as jmx.remote.x.password.file"); + } + + // Case of dedicated authenticator class : TestJMXAuthenticator + if (value.contains("x.authenticator")) { + env.put("jmx.remote.authenticator", new TestJMXAuthenticator()) ; + System.out.println( + "Added \"jmx.remote.authenticator\" = TestJMXAuthenticator"); + } + + // Case of security config file with standard Authentication + if (value.contains("x.login.config.PasswordFileAuthentication")) { + String loginConfig = System.getProperty("login.config.file"); + + // Override the default JAAS configuration + System.setProperty("java.security.auth.login.config", + "file:" + loginConfig); + System.out.println("Overrided default JAAS configuration with " + + "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ; + + env.put("jmx.remote.x.login.config", "PasswordFileAuthentication") ; + System.out.println( + "Added \"jmx.remote.x.login.config\" = " + + "\"PasswordFileAuthentication\"") ; + + // redirects "password.file" property to file in ${test.src} + String passwordFileStr = + buildSourcePath(System.getProperty("password.file")); + System.setProperty("password.file", passwordFileStr); + System.out.println( + "Redirected \"password.file\" property value to = " + + passwordFileStr) ; + } + + // Case of security config file with unexisting athentication config + if (value.contains("x.login.config.UnknownAuthentication")) { + String loginConfig = System.getProperty("login.config.file"); + + // Override the default JAAS configuration + System.setProperty("java.security.auth.login.config", + "file:" + loginConfig); + System.out.println("Overrided default JAAS configuration with " + + "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ; + + env.put("jmx.remote.x.login.config", "UnknownAuthentication") ; + System.out.println( + "Added \"jmx.remote.x.login.config\" = " + + "\"UnknownAuthentication\"") ; + + // redirects "password.file" property to file in ${test.src} + String passwordFileStr = + buildSourcePath(System.getProperty("password.file")); + System.setProperty("password.file", passwordFileStr); + System.out.println( + "Redirected \"password.file\" property value to = " + + passwordFileStr) ; + } + + // Case of security config file with dedicated login module + if (value.contains("x.login.config.SampleLoginModule")) { + String loginConfig = System.getProperty("login.config.file"); + + // Override the default JAAS configuration + System.setProperty("java.security.auth.login.config", + "file:" + loginConfig); + System.out.println("Overrided default JAAS configuration with " + + "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ; + + env.put("jmx.remote.x.login.config", "SampleLoginModule") ; + System.out.println( + "Added \"jmx.remote.x.login.config\" = " + + "\"SampleLoginModule\"") ; + } + + // Simple rmi ssl authentication + if (value.contains(RMI_CLIENT_SOCKET_FACTORY_SSL)) { + env.put("jmx.remote.rmi.client.socket.factory", + new SslRMIClientSocketFactory()) ; + System.out.println( + "Added \"jmx.remote.rmi.client.socket.factory\"" + + " = SslRMIClientSocketFactory") ; + } + + if (value.contains(RMI_SERVER_SOCKET_FACTORY_SSL)) { + if (value.contains( + "rmi.server.socket.factory.ssl.need.client.authentication")) { + // rmi ssl authentication with client authentication + env.put("jmx.remote.rmi.server.socket.factory", + new SslRMIServerSocketFactory(null, null, true)) ; + System.out.println( + "Added \"jmx.remote.rmi.server.socket.factory\"" + + " = SslRMIServerSocketFactory with client authentication") ; + + } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.md5")) { + // Allows all ciphering and protocols for testing purpose + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + env.put("jmx.remote.rmi.server.socket.factory", + new SslRMIServerSocketFactory( + new String[] {"SSL_RSA_WITH_RC4_128_MD5"}, null, false)); + System.out.println( + "Added \"jmx.remote.rmi.server.socket.factory\"" + + " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_MD5 cipher suite"); + + } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.sha")) { + // Allows all ciphering and protocols for testing purpose + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + env.put("jmx.remote.rmi.server.socket.factory", + new SslRMIServerSocketFactory( + new String[] { "SSL_RSA_WITH_RC4_128_SHA" }, null, false)) ; + System.out.println( + "Added \"jmx.remote.rmi.server.socket.factory\"" + + " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_SHA cipher suite") ; + + } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.sslv3")) { + // Allows all ciphering and protocols for testing purpose + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + env.put("jmx.remote.rmi.server.socket.factory", + new SslRMIServerSocketFactory(null, new String[] {"SSLv3"}, false)) ; + System.out.println( + "Added \"jmx.remote.rmi.server.socket.factory\"" + + " = SslRMIServerSocketFactory with SSLv3 protocol") ; + + } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.tlsv1")) { + // Allows all ciphering and protocols for testing purpose + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + env.put("jmx.remote.rmi.server.socket.factory", + new SslRMIServerSocketFactory(null, new String[] {"TLSv1"}, false)) ; + System.out.println( + "Added \"jmx.remote.rmi.server.socket.factory\"" + + " = SslRMIServerSocketFactory with TLSv1 protocol") ; + + } else { + env.put("jmx.remote.rmi.server.socket.factory", + new SslRMIServerSocketFactory()); + System.out.println( + "Added \"jmx.remote.rmi.server.socket.factory\"" + + " = SslRMIServerSocketFactory"); + } + } + } + + return env; + } + + /* + * Create the MBeansServer side of the test and returns its address + */ + private JMXServiceURL createServerSide(Map<String, Object> serverMap) + throws Exception { + final int NINETY_SECONDS = 90; + + System.out.println("SecurityTest::createServerSide: Start") ; + + // Prepare server side security env + HashMap<String, Object> env = setServerSecurityEnv(serverMap); + + // Create and start mbean server and connector server + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); + cs.start(); + + // Waits availibility of connector server + Utils.waitReady(cs, NINETY_SECONDS); + + JMXServiceURL addr = cs.getAddress(); + + System.out.println("SecurityTest::createServerSide: Done.") ; + + return addr; + } + + /* + * Creating command-line for running subprocess JVM: + * + * JVM command line is like: + * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main + * + * {defaultopts} are the default java options set by the framework. + * + */ + private List<String> buildCommandLine(String args[]) { + + System.out.println("SecurityTest::buildCommandLine: Start") ; + + List<String> opts = new ArrayList<>(); + opts.add(JDKToolFinder.getJDKTool("java")); + opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts())); + + // We need to forward some properties to the client side + opts.add("-Dtest.src=" + System.getProperty("test.src")); + + String usernameValue = System.getProperty(USERNAME_PROPERTY); + if (usernameValue != null) { + System.out.println("SecurityTest::buildCommandLine: "+ + " forward username property to client side"); + opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue); + } + String passwordValue = System.getProperty(PASSWORD_PROPERTY); + if (passwordValue != null) { + System.out.println("SecurityTest::buildCommandLine: "+ + " forward password property to client side"); + opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue); + } + + String enabledCipherSuites = + System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES); + if (enabledCipherSuites != null) { + System.out.println("SecurityTest::buildCommandLine: "+ + " forward enabledCipherSuites property to client side"); + opts.add("-D" + RMI_SSL_CLIENT_ENABLEDCIPHERSUITES + + "=" + enabledCipherSuites); + } + + String enabledProtocols = + System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS); + if (enabledProtocols != null) { + System.out.println("SecurityTest::buildCommandLine: "+ + " forward enabledProtocols property to client side"); + opts.add("-D" + RMI_SSL_CLIENT_ENABLEDPROTOCOLS + + "=" + enabledProtocols); + } + + opts.add("-cp"); + opts.add(System.getProperty("test.class.path", "test.class.path")); + opts.add(CLIENT_CLASS_MAIN); + opts.addAll(Arrays.asList(args)); + + System.out.println("SecurityTest::buildCommandLine: Done.") ; + + return opts; + } + + /** + * Runs SecurityTest$ClientSide with the passed options and redirects + * subprocess standard I/O to the current (parent) process. This provides a + * trace of what happens in the subprocess while it is runnning (and before + * it terminates). + * + * @param serviceUrlStr string representing the JMX service Url to connect to. + */ + private int runClientSide(String args[], String serviceUrlStr) throws Exception { + + System.out.println("SecurityTest::runClientSide: Start") ; + + // Building command-line + List<String> opts = buildCommandLine(args); + opts.add("-serviceUrl"); + opts.add(serviceUrlStr); + + // Launch separate JVM subprocess + int exitCode = 0; + String[] optsArray = opts.toArray(new String[0]); + ProcessBuilder pb = new ProcessBuilder(optsArray); + Process p = ProcessTools.startProcess("SecurityTest$ClientSide", pb); + + // Handling end of subprocess + try { + exitCode = p.waitFor(); + if (exitCode != 0) { + System.out.println( + "Subprocess unexpected exit value of [" + exitCode + + "]. Expected 0.\n"); + } + } catch (InterruptedException e) { + System.out.println("Parent process interrupted with exception : \n " + e + " :" ); + + // Parent thread unknown state, killing subprocess. + p.destroyForcibly(); + + throw new RuntimeException( + "Parent process interrupted with exception : \n " + e + " :" ); + + } finally { + if (p.isAlive()) { + p.destroyForcibly(); + } + + System.out.println("SecurityTest::runClientSide: Done") ; + + return exitCode; + } + + } + + public void run(Map<String, Object> serverArgs, String clientArgs[]) { + + System.out.println("SecurityTest::run: Start") ; + int errorCount = 0; + + try { + // Initialise the server side + JMXServiceURL urlToUse = createServerSide(serverArgs); + + // Run client side + errorCount = runClientSide(clientArgs, urlToUse.toString()); + + if ( errorCount == 0 ) { + System.out.println("SecurityTest::run: Done without any error") ; + } else { + System.out.println( + "SecurityTest::run: Done with " + errorCount + " error(s)"); + throw new RuntimeException("errorCount = " + errorCount); + } + + cs.stop(); + + } catch(Exception e) { + throw new RuntimeException(e); + } + + } + + private static class ClientSide { + + private JMXConnector cc = null; + private MBeanServerConnection mbsc = null; + + public static void main(String args[]) throws Exception { + + // Parses parameters + Utils.parseDebugProperties(); + + // Supported parameters list format is : "MainClass [-client <param-spec> ...] + // with <param-spec> either "-parami valuei" or "-parami" + HashMap<String, Object> clientMap = new HashMap<>() ; + Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap); + + // Run test + ClientSide test = new ClientSide(); + test.run(clientMap); + } + + public void run(Map<String, Object> args) { + + System.out.println("ClientSide::run: Start"); + int errorCount = 0; + + try { + // Setup client side parameters + HashMap<String, Object> env = new HashMap<>(); + + // If needed allows all ciphering and protocols for testing purpose + if (System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES) != null) { + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + } + + // If needed allows all ciphering and protocols for testing purpose + if (System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS) != null) { + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + } + + // Retrieve and set keystore and truststore config if any + if (args.containsKey("-keystore") && + args.get("-keystore") != null) { + SecurityTest.setKeyStoreProperties(args); + } + if (args.containsKey("-truststore") && + args.get("-truststore") != null) { + SecurityTest.setTrustStoreProperties(args); + } + + Object value = args.get("-mapType"); + if ((value != null) && + value.equals("credentials")) { + String username = System.getProperty("username"); + String password = System.getProperty("password"); + Utils.debug(Utils.DEBUG_STANDARD, + "add \"jmx.remote.credentials\" = \"" + + username + "\", \"" + password + "\""); + env.put("jmx.remote.credentials", + new String[] { username , password }); + } + + String expectedThrowable = (String) args.get("-expectedThrowable"); + + String authCallCountName = "-expectedAuthenticatorCallCount"; + int authCallCountValue = 0; + if (args.containsKey(authCallCountName)) { + authCallCountValue = + (new Integer((String) args.get(authCallCountName))).intValue(); + } + + try { + // Get a connection to remote mbean server + JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl")); + cc = JMXConnectorFactory.connect(addr,env); + mbsc = cc.getMBeanServerConnection(); + + // In case we should have got an exception + if (expectedThrowable != null) { + System.out.println("ClientSide::run: (ERROR) " + + " Connect did not fail with expected " + expectedThrowable); + errorCount++; + } else { + System.out.println("ClientSide::run: (OK) Connect succeed"); + } + } catch (Throwable e) { + Utils.printThrowable(e, true); + if (expectedThrowable != null) { + if (Utils.compareThrowable(e, expectedThrowable)) { + System.out.println("ClientSide::run: (OK) " + + "Connect failed with expected " + expectedThrowable); + } else { + System.out.println("ClientSide::run: (ERROR) Connect failed with " + + e.getClass() + " instead of expected " + + expectedThrowable); + errorCount++; + } + } else { + System.out.println("ClientSide::run: (ERROR) " + + "Connect failed with exception"); + errorCount++; + } + } + + // Depending on the client state, + // perform some requests + if (mbsc != null && errorCount == 0) { + // Perform some little JMX requests + System.out.println("ClientSide::run: Start sending requests"); + + doRequests(); + + // In case authentication has been used we check how it did. + if (authCallCountValue != 0) { + errorCount += checkAuthenticator(mbsc, authCallCountValue); + } + } + } catch (Exception e) { + Utils.printThrowable(e, true); + errorCount++; + } finally { + // Terminate the JMX Client if any + if (cc != null) { + try { + cc.close(); + } catch (Exception e) { + Utils.printThrowable(e, true) ; + errorCount++; + } + } + } + + System.out.println("ClientSide::run: Done"); + + // Handle result + if (errorCount != 0) { + throw new RuntimeException(); + } + } + + private void doRequests() throws Exception { + + // Send some requests to the remote JMX server + ObjectName objName1 = + new ObjectName("TestDomain:class=MBS_Light,rank=1"); + String mbeanClass = "MBS_Light"; + Exception exception = new Exception("MY TEST EXCEPTION"); + Attribute attException = new Attribute("AnException", exception); + Error error = new Error("MY TEST ERROR"); + Attribute attError = new Attribute("AnError", error); + String opParamString = "TOTORO"; + RjmxMBeanParameter opParam = new RjmxMBeanParameter(opParamString); + Object[] params1 = {opParamString}; + String[] sig1 = {"java.lang.String"}; + Object[] params2 = {opParam}; + String[] sig2 = {"RjmxMBeanParameter"}; + + // Create and register the MBean + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doRequests: Create and register the MBean"); + mbsc.createMBean(mbeanClass, objName1); + if (!mbsc.isRegistered(objName1)) { + throw new Exception("Unable to register an MBean"); + } + + // Set attributes of the MBean + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doRequests: Set attributes of the MBean"); + mbsc.setAttribute(objName1, attException); + mbsc.setAttribute(objName1, attError); + + // Get attributes of the MBean + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doRequests: Get attributes of the MBean"); + Exception retException = + (Exception) mbsc.getAttribute(objName1,"AnException"); + if (!retException.getMessage().equals(exception.getMessage())) { + System.out.println("Expected = " + exception); + System.out.println("Got = " + retException); + throw new Exception("Attribute AnException not as expected"); + } + Error retError = (Error) mbsc.getAttribute(objName1, "AnError"); + if (!retError.getMessage().equals(error.getMessage())) { + System.out.println("Expected = " + error); + System.out.println("Got = " + retError); + throw new Exception("Attribute AnError not as expected"); + } + + // Invoke operations on the MBean + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doRequests: Invoke operations on the MBean"); + RjmxMBeanParameter res1 = + (RjmxMBeanParameter) mbsc.invoke(objName1, "operate1", params1, sig1); + if (!res1.equals(opParam)) { + System.out.println("Expected = " + opParam); + System.out.println("Got = " + res1); + throw new Exception("Operation operate1 behaved badly"); + } + String res2 = + (String) mbsc.invoke(objName1, "operate2", params2, sig2); + if (!res2.equals(opParamString)) { + System.out.println("Expected = " + opParamString); + System.out.println("Got = " + res2); + throw new Exception("Operation operate2 behaved badly"); + } + + // Unregister the MBean + Utils.debug(Utils.DEBUG_STANDARD, + "ClientSide::doRequests: Unregister the MBean"); + mbsc.unregisterMBean(objName1); + if (mbsc.isRegistered(objName1)) { + throw new Exception("Unable to unregister an MBean"); + } + } + + /** + * Make some check about the instance of TestJMXAuthenticator. + * The authenticator is supposed to have set some properties on + * a ServerDelegate MBean. + * We compare the number of times it has been called with the expected value. + * We also check the Principal that has been given to the authenticator + * was not null. + * That method is of use to authentication with the JSR 262. + * @param mbs + * @param expectedAuthenticatorCallCount + * @return The number of errors encountered. + * @throws java.lang.Exception + */ + protected int checkAuthenticator(MBeanServerConnection mbs, + int expectedAuthenticatorCallCount) throws Exception { + int errorCount = 0; + + // Ensure the authenticator has been called the right number + // of times. + int callCount = + ((Integer) mbs.getAttribute( + new ObjectName(SERVER_DELEGATE_MBEAN_NAME), + "TestJMXAuthenticatorCallCount")).intValue(); + + if (callCount == expectedAuthenticatorCallCount) { + System.out.println("---- OK Authenticator has been called " + + expectedAuthenticatorCallCount + " time"); + } else { + errorCount++; + System.out.println("---- ERROR Authenticator has been called " + callCount + + " times in place of " + expectedAuthenticatorCallCount); + } + + // Ensure the provider has been called with + // a non null Principal. + String principalString = + (String) mbs.getAttribute( + new ObjectName(SERVER_DELEGATE_MBEAN_NAME), + "TestJMXAuthenticatorPrincipalString"); + + if (principalString == null) { + errorCount++; + System.out.println("---- ERROR Authenticator has been called" + + " with a null Principal"); + } else { + if (principalString.length() > 0) { + System.out.println("---- OK Authenticator has been called" + + " with the Principal " + principalString); + } else { + errorCount++; + System.out.println("---- ERROR Authenticator has been called" + + " with an empty Principal"); + } + } + + return errorCount; + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/ServerDelegate.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import javax.management.remote.JMXServiceURL ; +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.StandardMBean; + +/** + * This class defines an MBean that can be registered and used on client side + * to handle informations or properties of the remote server. + * + * For example, this MBean can store IOR addresses + * of RMI/IIOP connector(s) used in a test. + * + * That MBean might not be used for testing purpose itself. + */ +public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration { + + private MBeanServer mbeanServer = null; + private List<JMXServiceURL> addresses = null; + private String port; + private static String javaVersion = System.getProperty("java.version"); + private int sqeJmxwsCredentialsProviderCallCount = 0; + private String jmxwsCredentialsProviderUrl = null; + private int testJMXAuthenticatorCallCount = 0; + private Principal testJMXAuthenticatorPrincipal = null; + + @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate") + public ServerDelegate() { + addresses = new ArrayList<JMXServiceURL>(); + } + + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + // Initialize MBeanServer attribute + mbeanServer = server; + return name; + } + public void postRegister(Boolean registrationDone) { + } + public void preDeregister() throws Exception { + } + public void postDeregister() { + } + + public void addAddress(JMXServiceURL url) { + addresses.add(url) ; + } + + public List<JMXServiceURL> getAddresses() { + return addresses ; + } + + public void setPort(String p) { + port = p ; + } + + public String getPort() { + return port ; + } + + public String getJavaVersion() { + return javaVersion; + } + + public void sqeJmxwsCredentialsProviderCalled() { + sqeJmxwsCredentialsProviderCallCount++; + } + + public int getSqeJmxwsCredentialsProviderCallCount() { + return sqeJmxwsCredentialsProviderCallCount; + } + + public void setJmxwsCredentialsProviderUrl(String url) { + jmxwsCredentialsProviderUrl = url; + } + + public String getJmxwsCredentialsProviderUrl() { + return jmxwsCredentialsProviderUrl; + } + + public void testJMXAuthenticatorCalled() { + testJMXAuthenticatorCallCount++; + } + + public int getTestJMXAuthenticatorCallCount() { + return testJMXAuthenticatorCallCount; + } + + public void setTestJMXAuthenticatorPrincipal(Principal principal) { + testJMXAuthenticatorPrincipal = principal; + } + + public String getTestJMXAuthenticatorPrincipalString() { + if ( testJMXAuthenticatorPrincipal != null ) { + return testJMXAuthenticatorPrincipal.toString(); + } + + return null; + } + + /** + * Instantiates and registers a StandardMBean in the MBean server. + * + * @param implementationClassName + * The implementation class name of the MBean. + * @param interfaceClassName + * The management interface class name of the MBean. + * @param isMXBean + * If true, the resultant MBean is an MXBean. + * @param name + * The object name of the StandardMBean. + */ + @SuppressWarnings("unchecked") + public void createStandardMBean( + String implementationClassName, + String interfaceClassName, + boolean isMXBean, + ObjectName name) + throws Exception { + + Object implementation = + Class.forName(implementationClassName).newInstance(); + Class<Object> interfaceClass = interfaceClassName == null ? null : + (Class<Object>)Class.forName(interfaceClassName); + + // Create the StandardMBean + StandardMBean standardMBean = new StandardMBean( + implementation, + interfaceClass, + isMXBean); + + // Register the StandardMBean + mbeanServer.registerMBean(standardMBean, name); + } + + /** + * Instantiates and registers a StandardMBean in the MBean server. + * The object will use standard JMX design pattern to determine + * the management interface associated with the given implementation. + */ + @SuppressWarnings("unchecked") + public void createStandardMBean( + String implementationClassName, + boolean isMXBean, + ObjectName name) + throws Exception { + + createStandardMBean(implementationClassName, null, isMXBean, name); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/ServerDelegateMBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Principal; +import java.util.List; + +import javax.management.remote.JMXServiceURL ; +import javax.management.ObjectName; + +@SqeDescriptorKey("INTERFACE ServerDelegateMBean") +public interface ServerDelegateMBean { + @SqeDescriptorKey("ATTRIBUTE Address") + public void addAddress(JMXServiceURL url); + + @SqeDescriptorKey("ATTRIBUTE Address") + public List<JMXServiceURL> getAddresses(); + + public String getPort(); + public void setPort(String p); + + public String getJavaVersion(); + + public void sqeJmxwsCredentialsProviderCalled(); + public int getSqeJmxwsCredentialsProviderCallCount(); + + public void setJmxwsCredentialsProviderUrl(String url); + public String getJmxwsCredentialsProviderUrl(); + + public void testJMXAuthenticatorCalled(); + public int getTestJMXAuthenticatorCallCount(); + + public void setTestJMXAuthenticatorPrincipal(Principal principal); + public String getTestJMXAuthenticatorPrincipalString(); + + public void createStandardMBean( + String implementationClassName, + String interfaceClassName, + boolean isMXBean, + ObjectName name) + throws Exception; + + public void createStandardMBean( + String implementationClassName, + boolean isMXBean, + ObjectName name) + throws Exception; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/Simple.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.beans.ConstructorProperties; + +/** + * This class defines a simple standard MBean. + */ +public class Simple implements SimpleMBean { + + private String attribute = "initial_value"; + private boolean operationInvoked = false; + private boolean operation2Invoked = false; + + @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR Simple") + public Simple() { + } + + @SqeDescriptorKey("TWO PARAMETERS CONSTRUCTOR Simple") + @ConstructorProperties({"unused1", "unused2"}) + public Simple(@SqeDescriptorKey("CONSTRUCTOR PARAMETER unused1")int unused1, + @SqeDescriptorKey("CONSTRUCTOR PARAMETER unused2")int unused2) { + } + + public String getAttribute() { + return attribute; + } + public void setAttribute(String s) { + attribute = s; + } + public boolean getOperationInvoked() { + return operationInvoked; + } + public boolean getOperation2Invoked() { + return operation2Invoked; + } + + public void operation() { + operationInvoked = true; + return; + } + + public String operation2(int i) { + operation2Invoked = true; + return String.valueOf(i); + } + + public void reset() { + attribute = "initial_value"; + operationInvoked = false; + operation2Invoked = false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/SimpleListener.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// JDK +import java.util.Vector; + +// JMX +import javax.management.NotificationListener; +import javax.management.Notification; + +public class SimpleListener implements NotificationListener { + private boolean received = false; + private String type = null; + private Object handback = null; + private Vector<Object> handbacks = new Vector<Object>(); + private int nbrec = 0; + + public synchronized void handleNotification(Notification notification, + Object handback) { + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::handleNotification :" + notification); + try { + received = true; + type = notification.getType(); + this.handback = handback; + handbacks.add(handback); + nbrec++; + notify(); + } catch(Exception e) { + System.out.println("(ERROR) SimpleListener::handleNotification :" + + " Caught exception " + + e) ; + } + } + + public synchronized boolean isNotificationReceived() { + boolean ret = received; + reset(); + return ret; + } + + public synchronized Object[] waitForMultiNotifications(int nb) { + while(true) { + if(nbrec < nb) { + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::waitForMultiNotifications wait"); + try { + wait(); + } catch(InterruptedException ie) { + // OK : we wait for being interrupted + } + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::waitForMultiNotifications wait over"); + } + else + break; + } + Object[] ret = handbacks.toArray(); + reset(); + return ret; + } + + private void reset() { + received = false; + handback = null; + handbacks.removeAllElements(); + type = null; + } + + public synchronized Object waitForNotificationHB() { + while(true) { + if(!received) { + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::waitForNotificationHB wait"); + try { + wait(); + } catch(InterruptedException ie) { + // OK : we wait for being interrupted + } + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::waitForNotificationHB received"); + } + else + break; + } + Object ret = handback; + reset(); + return ret; + } + + public synchronized String waitForNotification() { + while(true) { + if(!received) { + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::waitForNotification wait"); + try { + wait(); + } catch(InterruptedException ie) { + // OK : we wait for being interrupted + } + Utils.debug(Utils.DEBUG_STANDARD, + "SimpleListener::waitForNotification received"); + } + else + break; + } + String ret = type; + reset(); + return ret; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/SimpleMBean.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * This interface defines a simple standard MBean. + */ +@SqeDescriptorKey("INTERFACE SimpleMBean") +public interface SimpleMBean { + + @SqeDescriptorKey("ATTRIBUTE Attribute") + public String getAttribute(); + + @SqeDescriptorKey("ATTRIBUTE Attribute") + public void setAttribute(String s); + + @SqeDescriptorKey("ATTRIBUTE OperationInvoked") + public boolean getOperationInvoked(); + + @SqeDescriptorKey("ATTRIBUTE Operation2Invoked") + public boolean getOperation2Invoked(); + + // Void operation + // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo + // => openType is added to the descriptor + @SqeDescriptorKey(value = "OPERATION operation", + descriptorFields = {"openType=SimpleType.VOID"}) + public void operation(); + + @SqeDescriptorKey("OPERATION operation2") + public String operation2(int i); + + // Void operation + // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo + // => openType is added to the descriptor + @SqeDescriptorKey(value = "OPERATION reset", + descriptorFields = {"openType=SimpleType.VOID"}) + public void reset(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/SqeDescriptorKey.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import javax.management.DescriptorKey; + +/** + * That annotation is usable everywhere DescriptorKey is (and even more). + * It is for use to test that you can retrieve the SqeDescriptorKey into the + * appropriate Descriptor instances as built by the JMX runtime. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface SqeDescriptorKey { + @DescriptorKey("sqeDescriptorKey") + String value(); + + // List descriptor fields that may be added or may be updated + // when retrieving an MBeanInfo using a JMXWS connection compared to the + // MBeanInfo returned by a local MBeanServer. + // The annotation format is : + // <descriptorFieldName>=<descriptorFieldValue> + // The values actually handled by the test suite are : + // openType=SimpleType.VOID + @DescriptorKey("descriptorFields") + String[] descriptorFields() default {}; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/TestJMXAuthenticator.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Principal; + +import javax.management.Attribute; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.remote.JMXAuthenticator; +import javax.management.remote.JMXPrincipal; +import javax.security.auth.Subject; + +public final class TestJMXAuthenticator implements JMXAuthenticator { + + private String protocol = ""; + private MBeanServer mbs = null; + + public TestJMXAuthenticator() { + } + + public TestJMXAuthenticator(String protocol) { + this.protocol = protocol; + } + + public TestJMXAuthenticator(String protocol, MBeanServer mbs) { + this.protocol = protocol; + this.mbs = mbs; + } + + public Subject authenticate(Object credentials) { + + String credentials_username = ""; + String credentials_password = ""; + Principal aPrincipal = null; + + credentials_username = ((String[]) credentials)[0]; + credentials_password = ((String[]) credentials)[1]; + + String authenticated_username = System.getProperty("susername"); + String authenticated_password = System.getProperty("spassword"); + String principal = System.getProperty("principal"); + + System.out.println("TestJMXAuthenticator::authenticate: Start"); + System.out.println("TestJMXAuthenticator::authenticate: credentials username = " + + credentials_username); + System.out.println("TestJMXAuthenticator::authenticate: credentials password = " + + credentials_password); + System.out.println("TestJMXAuthenticator::authenticate: authenticated username = " + + authenticated_username); + System.out.println("TestJMXAuthenticator::authenticate: authenticated password = " + + authenticated_password); + System.out.println("TestJMXAuthenticator::authenticate: principal used for " + + "authorization = " + principal); + + if (credentials_username.equals(authenticated_username) && + credentials_password.equals(authenticated_password)) { + System.out.println("TestJMXAuthenticator::authenticate: " + + "Authenticator should succeed"); + } else { + System.out.println("TestJMXAuthenticator::authenticate: " + + "Authenticator should reject"); + throw new SecurityException("TestJMXAuthenticator throws EXCEPTION"); + } + + // At this point, authentication has succeeded + // (no SecurityException thrown). + // + // If no authorization is required, the returned subject (empty or not) + // is useless. + // Otherwise, the returned subject must define a principal + // and authorization will be performed against this principal. + // + // Note that this custom JMXAuthenticator is used for test purpose and + // the username used to perform authentication may be different from the + // username used to perform authorization. + // + Subject subject = new Subject(); + + if (principal != null) { + System.out.println("TestJMXAuthenticator::authenticate: " + + "Add " + principal + " principal to the returned subject"); + subject.getPrincipals().add(new JMXPrincipal(principal)); + } + + return subject; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/TestSampleLoginModule.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +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.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + + +public final class TestSampleLoginModule implements LoginModule { + + private Subject subject; + private CallbackHandler callbackHandler; + private Map<String, ?> sharedState; + private Map<String, ?> options; + + public TestSampleLoginModule() { + } + + public void initialize(Subject subject, + CallbackHandler callbackHandler, + Map<String,?> sharedState, + Map<String,?> options) { + + this.subject = subject; + this.callbackHandler = callbackHandler; + this.sharedState = sharedState; + this.options = options; + } + + /* + * Authenticate the user by comparing the values of the java properties + * (username and password) against the values of the credentials. + * */ + public boolean login() throws LoginException { + + String credentials_username = null; + String credentials_password = null; + String authenticated_username = System.getProperty("susername"); + String authenticated_password = System.getProperty("spassword"); + + System.out.println("TestSampleLoginModule::login: Start"); + + // First retreive the credentials {username, password} from + // the callback handler + Callback[] callbacks = new Callback[2]; + callbacks[0] = new NameCallback("username"); + callbacks[1] = new PasswordCallback("password", false); + try { + callbackHandler.handle(callbacks); + credentials_username = ((NameCallback)callbacks[0]).getName(); + credentials_password = new String(((PasswordCallback)callbacks[1]). + getPassword()); + } catch (Exception e) { + throw new LoginException(e.toString()); + } + + System.out.println("TestSampleLoginModule::login: credentials username = " + + credentials_username); + System.out.println("TestSampleLoginModule::login: credentials password = " + + credentials_password); + System.out.println("TestSampleLoginModule::login: authenticated username = " + + authenticated_username); + System.out.println("TestSampleLoginModule::login: authenticated password = " + + authenticated_password); + + if (credentials_username.equals(authenticated_username) && + credentials_password.equals(authenticated_password)) { + System.out.println("TestSampleLoginModule::login: " + + "Authentication should succeed"); + return true; + } else { + System.out.println("TestSampleLoginModule::login: " + + "Authentication should reject"); + throw new LoginException("TestSampleLoginModule throws EXCEPTION"); + } + } + + public boolean commit() throws LoginException { + return true; + } + + public boolean abort() throws LoginException { + return true; + } + + public boolean logout() throws LoginException { + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/Utils.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import java.util.StringTokenizer; +import java.lang.reflect.Method; +import javax.management.remote.JMXConnectorServerMBean; + +// utility class for MXBean* tests coming from JMX Tonga test suite +class Utils { + + private static final String SERVER_SIDE_NAME = "-server"; + private static final String CLIENT_SIDE_NAME = "-client"; + + // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property + private static final String DEBUG_HEADER = "[debug] "; + + // DEBUG levels + private static int selectedDebugLevel = 0; + static final int DEBUG_STANDARD = 1; + static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests + static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE; + + static void parseDebugProperties() { + int level = 0; + Properties p = System.getProperties(); + + // get selected levels + if (p.getProperty("DEBUG_STANDARD") != null) { + level |= DEBUG_STANDARD; + } + + if (p.getProperty("DEBUG_VERBOSE") != null) { + level |= DEBUG_VERBOSE; + } + + if (p.getProperty("DEBUG_ALL") != null) { + level |= DEBUG_ALL; + } + + selectedDebugLevel = level; + } + + /** + * Reproduces the original parsing and collection of test parameters + * from the DTonga JMX test suite. + * + * Collects passed args and returns them in a map(argname, value) structure, + * which will be then propagated as necessary to various called methods. + */ + static Map<String, Object> parseParameters(String args[]) + throws Exception { + Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start"); + HashMap<String, Object> map = new HashMap<>(); + + for ( int i = 0; i < args.length; i++ ) { + if ( args[i].trim().startsWith("-") ) { + if ((i+1) < args.length && !args[i+1].startsWith("-") ) { + Utils.debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with value " + + args[i+1]) ; + map.put(args[i].trim(), args[i+1].trim()) ; + } else if ((i+1) < args.length && args[i+1].startsWith("-") || + (i+1) == args.length ) { + Utils.debug(DEBUG_STANDARD, + "TestRoot::parseParameters: added in map = " + + args[i] + + " with null value") ; + map.put(args[i].trim(), null) ; + } else { + System.out.println( + "TestRoot::parseParameters: (WARNING) not added in map = " + + args[i]) ; + } + } + } + + Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ; + return map ; + } + + // Parse server parameters and put them in passed serverMap + static int parseServerParameters(String args[], + String serverSideName, + Map<String, Object> serverMap ) + throws Exception { + Utils.debug(Utils.DEBUG_STANDARD, + serverSideName + "::parseServerParameters: Start"); + + int nextIndex = 0; + boolean seenServerFlag = false; + + for ( int i = 0; i < args.length; i++ ) { + // Case of reaching "-server" flag parameter + if (args[i].equals(SERVER_SIDE_NAME)) { + if (!seenServerFlag) { + seenServerFlag = true; + continue; + } else { + // Already parsing server params, invalid params list + Utils.debug(Utils.DEBUG_STANDARD, + serverSideName + "::parseParameters: Invalid " + + args[i] + " parameter detected in " + + SERVER_SIDE_NAME + " parameters list"); + nextIndex = -1; + throw new RuntimeException("Invalid Parameter list"); + } + } + + // Case of reaching "-client" flag parameter + if (args[i].equals(CLIENT_SIDE_NAME)) { + // While parsing server parameters, then parsing is done. + Utils.debug(Utils.DEBUG_STANDARD, + serverSideName + "::parseServerParameters: Parsing of " + + SERVER_SIDE_NAME + " parameters done."); + return i; + } + + i = parseParamAtIndex(args, i, serverMap); + nextIndex = i; + } + + Utils.debug(Utils.DEBUG_STANDARD, + serverSideName + "::parseServerParameters: Parsing of parameters done"); + + return nextIndex; + } + + // Parse client parameters and put them in passed clientMap + static void parseClientParameters(String args[], + String clientSideName, + Map<String, Object> clientMap ) + throws Exception { + + Utils.debug(Utils.DEBUG_STANDARD, + clientSideName + "::parseClientParameters: Start"); + + boolean seenClientFlag = false; + + for ( int i = 0; i < args.length; i++ ) { + // Case of reaching "-client" flag parameter + if (args[i].equals(CLIENT_SIDE_NAME)) { + if (!seenClientFlag) { + seenClientFlag = true; + continue; + } else { + // Already parsing client params, invalid params list + Utils.debug(Utils.DEBUG_STANDARD, + clientSideName + "::parseClientParameters: Invalid " + + CLIENT_SIDE_NAME + " parameter detected in " + + CLIENT_SIDE_NAME + " parameters list."); + throw new RuntimeException("Invalid parameter in " + + clientSideName + " parameter list"); + } + } + + // Case of reaching "-server" flag parameter + if (args[i].equals(SERVER_SIDE_NAME)) { + // While parsing client parameters, invalid parameter list. + Utils.debug(Utils.DEBUG_STANDARD, + clientSideName + "::parseClientParameters: Invalid " + + SERVER_SIDE_NAME + " parameter inside " + + CLIENT_SIDE_NAME + " parameters list."); + throw new RuntimeException("Invalid parameter in " + + clientSideName + " parameter list"); + } + + i = parseParamAtIndex(args, i, clientMap); + } + + Utils.debug(Utils.DEBUG_STANDARD, + clientSideName + "::parseClientParameters: Parsing of parameters done."); + } + + // Add param found at index to passed map + // We only accept either "-param value" or "-param" form. + // The "value" form is invalid but just ignored. + private static int parseParamAtIndex(String args[], + int index, + Map<String, Object> map) { + + if (args[index].trim().startsWith("-") ) { + // Case of a "-param value" form + if ((index+1) < args.length && !args[index+1].startsWith("-") ) { + Utils.debug(Utils.DEBUG_STANDARD, + "TestRoot::parseParamAtIndex: added in map = " + + args[index] + + " with value " + + args[index+1]) ; + // adding ("param", value) to the passed map + map.put(args[index].trim(), args[index+1].trim()) ; + // value should not be parsed a second time + return index+1; + } + // Case of a "-param" form (flag parameter) + else if (((index+1) < args.length && args[index+1].startsWith("-")) || + (index+1) == args.length ) { + Utils.debug(Utils.DEBUG_STANDARD, + "TestRoot::parseParamAtIndex: added in map = " + + args[index] + + " with null value") ; + // adding ("param", null) to passed map + map.put(args[index].trim(), null) ; + } + } else { + // Unsupported "value" alone parameter + Utils.debug(Utils.DEBUG_STANDARD, + "TestRoot::parseParamAtIndex: invalid " + + " value-alone \"" + args[index] + "\" parameter." + + " Parameter ignored."); + } + + return index; + } + + /** + * This method is to be used in all tests to print anything + * that is temporary. + * Printing is done only when debug is activated by the property DEBUG. + * Printing depends also on the DEBUG_LEVEL property. + * Here it encapsulates a System.out.println. + */ + static void debug(int level, String line) { + if ((selectedDebugLevel & level) != 0) { + System.out.println(DEBUG_HEADER + line); + } + } + + /** + * Do print stack trace when withStack is true. + * Does try to call getTargetException() and getTargetError() then + * print embedded stacks in the case of an Exception wrapping + * another Exception or an Error. Recurse until no more wrapping + * is found. + */ + static void printThrowable(Throwable theThro, boolean withStack) { + try { + if (withStack) { + theThro.printStackTrace(System.out); + } + if (theThro instanceof Exception) { + Exception t = (Exception) theThro; + Method target = null; + String blank = " "; + try { + target = t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not + } + System.out.println(blank + t.getClass() + "==>" + t.getMessage()); + while (target != null) { + try { + t = (Exception) target.invoke(t, + (java.lang.Object[]) null); + } catch (Exception ee) { + t = null; + } + try { + if (t != null) { + blank = blank + " "; + System.out.println(blank + t.getClass() + "==>" + + t.getMessage()); + try { + target = + t.getClass().getMethod("getTargetException", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetException method could be there or not } + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + + // We may have exceptions wrapping an Error then it is + // getTargetError that is likely to be called + try { + target = ((Exception) theThro).getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + Throwable err = theThro; + while (target != null) { + try { + err = (Error) target.invoke(err, + (java.lang.Object[]) null); + } catch (Exception ee) { + err = null; + } + try { + if (err != null) { + blank = blank + " "; + System.out.println(blank + err.getClass() + "==>" + + err.getMessage()); + if (withStack) { + err.printStackTrace(System.out); + } + try { + target = err.getClass().getMethod("getTargetError", + (java.lang.Class<?>[]) null); + } catch (Exception ee) { + // OK: getTargetError method could be there or not + } + } else { + target = null; + } + } catch (Exception ee) { + target = null; + } + } + } else { + System.out.println("Throwable is : " + theThro); + } + } catch (Throwable x) { + System.out.println("Exception : raised in printException : " + x); + } + } + + /** + * Wait up to maxTimeInSeconds second(s) the given JMX connector server + * comes up (which means isActive returns true). + * If it fails to do so we throw a RunTime exception. + */ + static void waitReady(JMXConnectorServerMBean server, + int maxTimeInSeconds) throws Exception { + int elapsed = 0; + + while (!server.isActive() && elapsed < maxTimeInSeconds) { + Thread.sleep(1000); + elapsed++; + } + + if (server.isActive()) { + String message = "Utils::waitReady: JMX connector server came up"; + if ( elapsed == 0) { + message += " immediately"; + } else { + message += " after " + elapsed + " seconds"; + } + message += " [" + server.getAddress() + "]"; + Utils.debug(DEBUG_STANDARD, message); + } else { + String message = "Utils::waitReady: (ERROR) JMX connector" + + " server didn't come up after " + elapsed + " seconds [" + + server.getAddress() + "]"; + System.out.println(message); + throw new RuntimeException(message); + } + } + + /** + * This method is used to compare the specified Throwable and possibly + * the derived causes to the specified String argument. + * The expected String argument format is : + * throwable_1;throwable_2;...;throwable_N + * where throwable_i can be : + * - either a throwable class name + * - or the "*" character meaning several unknown throwable class names + * This character must be followed by a throwable class name + */ + static boolean compareThrowable( + Throwable t, + String expectedThrowable) { + + // First parse the expectedThrowable String + StringTokenizer tokenizer = new StringTokenizer(expectedThrowable, ";"); + String token = null; + + try { + while (tokenizer.hasMoreTokens()) { + token = tokenizer.nextToken(); + if (!token.equals("*")) { + if (!Class.forName(token).isInstance(t)) { + return false; + } + } else { + token = tokenizer.nextToken(); + while (!Class.forName(token).isInstance(t)) { + t = t.getCause(); + if (t == null) { + return false; + } + } + } + t = t.getCause(); + } + } catch (ClassNotFoundException cnfe) { + String msg = "Expected throwable class(es) " + expectedThrowable + + " cannot be located"; + System.out.println(msg); + throw new IllegalArgumentException(msg); + } + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/access.properties Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,11 @@ +# Access control file for SQE tests. + +# Default username +SQE_username readwrite create Simple + +# Functional authorization tests +username1 readwrite create Simple +username2 readonly +username3 readonly +username4 readwrite create Simple +username5 readwrite create Simple
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/java.policy.authorization Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,98 @@ +// Standard extensions get all permissions by default + +grant codeBase "file:${java.home}/lib/ext/*" { + permission java.security.AllPermission; +}; + +// default permissions granted to all domains +grant { + // Allows any thread to stop itself using the java.lang.Thread.stop() + // method that takes no argument. + // Note that this permission is granted by default only to remain + // backwards compatible. + // It is strongly recommended that you either remove this permission + // from this policy file or further restrict it to code sources + // that you specify, because Thread.stop() is potentially unsafe. + // See "http://java.sun.com/notes" for more information. + permission java.lang.RuntimePermission "stopThread"; + + // allows anyone to listen on un-privileged ports + permission java.net.SocketPermission "localhost:1024-", "listen"; + + // "standard" properies that can be read by anyone + + permission java.util.PropertyPermission "java.version", "read"; + permission java.util.PropertyPermission "java.vendor", "read"; + permission java.util.PropertyPermission "java.vendor.url", "read"; + permission java.util.PropertyPermission "java.class.version", "read"; + permission java.util.PropertyPermission "os.name", "read"; + permission java.util.PropertyPermission "os.version", "read"; + permission java.util.PropertyPermission "os.arch", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "line.separator", "read"; + + permission java.util.PropertyPermission "java.specification.version", "read"; + permission java.util.PropertyPermission "java.specification.vendor", "read"; + permission java.util.PropertyPermission "java.specification.name", "read"; + + permission java.util.PropertyPermission "java.vm.specification.version", "read"; + permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; + permission java.util.PropertyPermission "java.vm.specification.name", "read"; + permission java.util.PropertyPermission "java.vm.version", "read"; + permission java.util.PropertyPermission "java.vm.vendor", "read"; + permission java.util.PropertyPermission "java.vm.name", "read"; + + permission java.io.FilePermission "*","read,write"; + +}; + +grant codeBase "file:/-" { + permission java.security.AllPermission; + permission java.io.FilePermission "*","read,write"; +}; + +grant principal javax.management.remote.JMXPrincipal "SQE_username" { + permission javax.management.MBeanServerPermission "*"; + permission javax.management.MBeanPermission "Simple", "instantiate"; + permission javax.management.MBeanPermission "Simple", "registerMBean"; +}; + +grant principal javax.management.remote.JMXPrincipal "username1" { + // + // JMXPrincipals "username1" has all permissions. + // + permission java.security.AllPermission; +}; + +grant principal javax.management.remote.JMXPrincipal "username2" { + // + // JMXPrincipals "username2" has all permissions. + // + permission java.security.AllPermission; +}; + +grant principal javax.management.remote.JMXPrincipal "username3" { + // + // JMXPrincipals "username3" has some permissions. + // + permission javax.management.MBeanPermission "Simple", "instantiate"; + permission javax.management.MBeanPermission "Simple", "registerMBean"; + permission javax.management.MBeanPermission "Simple", "setAttribute"; + permission javax.management.MBeanPermission "Simple", "invoke"; +}; + +grant principal javax.management.remote.JMXPrincipal "username4" { + // + // JMXPrincipals "username4" has all permissions. + // + permission javax.management.MBeanPermission "Simple", "instantiate"; + permission javax.management.MBeanPermission "Simple", "registerMBean"; + permission javax.management.MBeanPermission "Simple", "invoke"; +}; + +grant principal javax.management.remote.JMXPrincipal "username5" { + // + // JMXPrincipals "username5" has no permissions. + // +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/login.config Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,8 @@ +PasswordFileAuthentication { + com.sun.jmx.remote.security.FileLoginModule required + passwordFile="${password.file}"; +}; + +SampleLoginModule { + TestSampleLoginModule required; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/security/password.properties Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,12 @@ +# Password file for default SQE username. +SQE_username SQE_password + +# Functional authorization tests +username1 password1 +username2 password2 +username3 password3 +username4 password4 +username5 password5 +username6 password6 + +usernameFileLoginModule passwordFileLoginModule
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloClient.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.util.ArrayList; + +import javax.naming.InitialContext; +import javax.naming.Context; +import javax.naming.NameNotFoundException; + +import javax.rmi.PortableRemoteObject; + + + +public class HelloClient implements Runnable { + static final int MAX_RETRY = 10; + static final int ONE_SECOND = 1000; + private static boolean responseReceived; + + public static void main(String args[]) throws Exception { + executeRmiClientCall(); + } + + @Override + public void run() { + try { + executeRmiClientCall(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + + public static boolean isResponseReceived () { + return responseReceived; + } + + public static void executeRmiClientCall() throws Exception { + Context ic; + Object objref; + HelloInterface helloSvc; + String response; + Object testResponse; + int retryCount = 0; + + ArrayList<Test> listParam = new ArrayList<Test>(); + listParam.add(null); + System.out.println("HelloClient.main: enter ..."); + while (retryCount < MAX_RETRY) { + try { + ic = new InitialContext(); + System.out.println("HelloClient.main: HelloService lookup ..."); + // STEP 1: Get the Object reference from the Name Service + // using JNDI call. + objref = ic.lookup("HelloService"); + System.out.println("HelloClient: Obtained a ref. to Hello server."); + + // STEP 2: Narrow the object reference to the concrete type and + // invoke the method. + helloSvc = (HelloInterface) PortableRemoteObject.narrow(objref, + HelloInterface.class); + + Test3 test3 = new Test3(listParam); + Test3 test3Response = helloSvc.sayHelloWithTest3(test3); + System.out.println("Server says: Test3 response == " + test3Response); + + Test3 test3WithNullList = new Test3(null); + test3Response = helloSvc.sayHelloWithTest3(test3WithNullList); + System.out.println("Server says: Test3 response == " + + test3Response); + + Test4 test4 = new Test4(listParam); + Test3 test4Response = helloSvc.sayHelloWithTest3(test4); + System.out.println("Server says: Test3 response == " + test4Response); + + responseReceived = true; + break; + } catch (NameNotFoundException nnfEx) { + System.err.println("NameNotFoundException Caught .... try again"); + retryCount++; + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } catch (Exception e) { + System.err.println("Exception " + e + "Caught"); + e.printStackTrace(); + throw new RuntimeException(e); + } + } + System.err.println("HelloClient terminating "); + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloImpl.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.rmi.RemoteException; +import javax.rmi.PortableRemoteObject; + +public class HelloImpl extends PortableRemoteObject implements HelloInterface { + + public HelloImpl() throws java.rmi.RemoteException { + super(); // invoke rmi linking and remote object initialization + } + + @Override + public Test3 sayHelloWithTest3(Test3 test) throws RemoteException { + System.out.println("sayHelloToTest3: ENTER " ); + + return test; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloInterface.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.rmi.Remote; + +public interface HelloInterface extends Remote { + public Test3 sayHelloWithTest3( Test3 test ) throws java.rmi.RemoteException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloServer.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.naming.InitialContext; +import javax.naming.Context; + +public class HelloServer { + + static final int MAX_RETRY = 10; + static final int ONE_SECOND = 1000; + + public static void main(String[] args) { + int retryCount = 0; + while (retryCount < MAX_RETRY) { + try { + //HelloServer.set("SETTING TEST ITL"); + // Step 1: Instantiate the Hello servant + HelloImpl helloRef = new HelloImpl(); + + // Step 2: Publish the reference in the Naming Service + // using JNDI API + Context initialNamingContext = new InitialContext(); + initialNamingContext.rebind("HelloService", helloRef); + + System.out.println("Hello Server: Ready..."); + break; + } catch (Exception e) { + System.out.println("Server initialization problem: " + e); + e.printStackTrace(); + retryCount++; + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8146975 + * @summary test RMI-IIOP with value object return + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @compile Test.java Test2.java Test3.java Test4.java + * HelloInterface.java HelloServer.java HelloClient.java + * HelloImpl.java _HelloImpl_Tie.java _HelloInterface_Stub.java + * RmiIiopReturnValueTest.java + * @run main/othervm -Djava.naming.provider.url=iiop://localhost:5050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory + * RmiIiopReturnValueTest -port 5049 + * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy + * -Djava.naming.provider.url=iiop://localhost:5050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory + * RmiIiopReturnValueTest -port 5049 + */ + + +import java.io.DataInputStream; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.CountDownLatch; +import jdk.testlibrary.JDKToolFinder; +import jdk.testlibrary.JDKToolLauncher; + +public class RmiIiopReturnValueTest { + + static final String ORBD = JDKToolFinder.getTestJDKTool("orbd"); + static final String JAVA = JDKToolFinder.getTestJDKTool("java"); + static final JDKToolLauncher orbdLauncher = JDKToolLauncher.createUsingTestJDK("orbd"); + static final String CLASSPATH = System.getProperty("java.class.path"); + static final int FIVE_SECONDS = 5000; + + private static Throwable clientException; + private static boolean exceptionInClient; + private static Process orbdProcess; + private static Process rmiServerProcess; + + public static void main(String[] args) throws Exception { + startTestComponents(); + stopTestComponents(); + System.err.println("Test completed OK "); + } + + static void startTestComponents () throws Exception { + startOrbd(); + Thread.sleep(FIVE_SECONDS); + startRmiIiopServer(); + Thread.sleep(FIVE_SECONDS); + executeRmiIiopClient(); + } + + private static void stopTestComponents() throws Exception { + stopRmiIiopServer(); + stopOrbd(); + if (exceptionInClient) { + throw new RuntimeException(clientException); + } else if (!isResponseReceived()) { + throw new RuntimeException("Expected Response not received"); + } + } + + static void startOrbd() throws Exception { + System.out.println("\nStarting orbd with NS port 5050 and activation port 5049 "); + + //orbd -ORBInitialHost localhost -ORBInitialPort 5050 -port 5049 + orbdLauncher.addToolArg("-ORBInitialHost").addToolArg("localhost") + .addToolArg("-ORBInitialPort").addToolArg("5050") + .addToolArg("-port").addToolArg("5049"); + + System.out.println("RmiIiopReturnValueTest: Executing: " + Arrays.asList(orbdLauncher.getCommand())); + ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand()); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + orbdProcess = pb.start(); + } + + + static void startRmiIiopServer() throws Exception { + System.out.println("\nStarting RmiIiopServer"); + // java -cp . + // -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory + // -Djava.naming.provider.url=iiop://localhost:5050 HelloServer -port 5049 + List<String> commands = new ArrayList<>(); + commands.add(RmiIiopReturnValueTest.JAVA); + commands.add("-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory"); + commands.add("-Djava.naming.provider.url=iiop://localhost:5050"); + commands.add("-cp"); + commands.add(RmiIiopReturnValueTest.CLASSPATH); + commands.add("HelloServer"); + commands.add("-port"); + commands.add("5049"); + + System.out.println("RmiIiopReturnValueTest: Executing: " + commands); + ProcessBuilder pb = new ProcessBuilder(commands); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + rmiServerProcess = pb.start(); + } + + static boolean isResponseReceived() { + return HelloClient.isResponseReceived(); + } + + static void stopRmiIiopServer() throws Exception { + if (rmiServerProcess != null) { + System.out.println("RmiIiopReturnValueTest.stopRmiIiopServer: destroy rmiServerProcess"); + rmiServerProcess.destroyForcibly(); + rmiServerProcess.waitFor(); + System.out.println("serverProcess exitCode:" + + rmiServerProcess.exitValue()); + } + } + + static void stopOrbd() throws Exception { + System.out.println("RmiIiopReturnValueTest.stopOrbd: destroy orbdProcess "); + orbdProcess.destroyForcibly(); + orbdProcess.waitFor(); + System.out.println("orbd exitCode:" + + orbdProcess.exitValue()); + } + + static void executeRmiIiopClient() throws Exception { + System.out.println("RmiIiopReturnValueTest.executeRmiIiopClient: HelloClient.executeRmiClientCall"); + try { + HelloClient.executeRmiClientCall(); + } catch (Throwable t) { + clientException = t; + exceptionInClient = true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.Serializable; + + +public class Test implements Serializable { + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test2.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.Serializable; + + +public class Test2 implements Serializable { + + private int testValue; + private String name; + private Test aTest; + + public Test2 (String name, int value, Test test) { + this.name = name; + this.aTest = test; + this.testValue = value; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test3.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.Serializable; +import java.util.List; + + +public class Test3 implements Serializable { + + private List<Test> list; + + public Test3(List<Test> list) { + this.list = list; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/Test4.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; + + +public class Test4 extends Test3 { + + private int aNumber = 1; + + public Test4(List<Test> list) { + super(list); + } + + /** + * + */ + private static final long serialVersionUID = 1L; + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloImpl_Tie.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// Tie class generated by rmic, do not edit. +// Contents subject to change without notice. + +import java.io.Serializable; +import java.rmi.Remote; +import java.rmi.RemoteException; +import javax.rmi.CORBA.Tie; +import javax.rmi.CORBA.Util; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.UnknownException; +import org.omg.CORBA_2_3.portable.ObjectImpl; + + +public class _HelloImpl_Tie extends ObjectImpl implements Tie { + + volatile private HelloImpl target = null; + + private static final String[] _type_ids = { + "RMI:HelloInterface:0000000000000000" + }; + + public void setTarget(Remote target) { + this.target = (HelloImpl) target; + } + + public Remote getTarget() { + return target; + } + + public org.omg.CORBA.Object thisObject() { + return this; + } + + public void deactivate() { + _orb().disconnect(this); + _set_delegate(null); + target = null; + } + + public ORB orb() { + return _orb(); + } + + public void orb(ORB orb) { + orb.connect(this); + } + + public String[] _ids() { + return (String[]) _type_ids.clone(); + } + + public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException { + try { + HelloImpl target = this.target; + if (target == null) { + throw new java.io.IOException(); + } + org.omg.CORBA_2_3.portable.InputStream in = + (org.omg.CORBA_2_3.portable.InputStream) _in; + if (method.equals("sayHelloWithTest3")) { + Test3 arg0 = (Test3) in.read_value(Test3.class); + Test3 result = target.sayHelloWithTest3(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,Test3.class); + return out; + } + throw new BAD_OPERATION(); + } catch (SystemException ex) { + throw ex; + } catch (Throwable ex) { + throw new UnknownException(ex); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloInterface_Stub.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// Stub class generated by rmic, do not edit. +// Contents subject to change without notice. + +import java.io.Serializable; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.UnexpectedException; +import javax.rmi.CORBA.Stub; +import javax.rmi.CORBA.Util; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.ServantObject; + + +public class _HelloInterface_Stub extends Stub implements HelloInterface { + + private static final String[] _type_ids = { + "RMI:HelloInterface:0000000000000000" + }; + + public String[] _ids() { + return (String[]) _type_ids.clone(); + } + + public Test3 sayHelloWithTest3(Test3 arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloWithTest3", true); + out.write_value(arg0,Test3.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (Test3) in.read_value(Test3.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloWithTest3(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloWithTest3",HelloInterface.class); + if (so == null) { + return sayHelloWithTest3(arg0); + } + try { + Test3 arg0Copy = (Test3) Util.copyObject(arg0,_orb()); + Test3 result = ((HelloInterface)so.servant).sayHelloWithTest3(arg0Copy); + return (Test3)Util.copyObject(result,_orb()); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/8146975/jtreg.test.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +grant { + permission java.io.FilePermission "*", "read"; + permission java.io.FilePermission "./-", "read,write,execute"; + permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve"; + permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.*"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.security.util"; + permission java.io.SerializablePermission "enableSubclassImplementation"; + permission java.util.PropertyPermission "*", "read, write"; + permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute"; +};
--- a/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -28,7 +28,11 @@ * @library /lib/testlibrary * @build jdk.testlibrary.* * @build Test HelloInterface HelloServer HelloClient HelloImpl _HelloImpl_Tie _HelloInterface_Stub ConcurrentHashMapTest - * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050 -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest + * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest + * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy + * -Djava.naming.provider.url=iiop://localhost:1050 + * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/rmi/PortableRemoteObject/jtreg.test.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +grant { + permission java.io.FilePermission "*", "read"; + permission java.io.FilePermission "./-", "read,write,execute"; + permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve"; + permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.*"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.security.util"; + permission java.io.SerializablePermission "enableSubclassImplementation"; + permission java.util.PropertyPermission "*", "read, write"; + permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.security.auth.NTUserPrincipal; +import com.sun.security.auth.UnixPrincipal; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import javax.security.auth.Subject; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/* + * @test + * @bug 8050409 + * @summary Tests with Subject.getPrivateCredentials to check permission checks with one or more principals. + * @run testng/othervm/policy=MoreThenOnePrincipals.policy MoreThenOnePrincipals + */ +public class MoreThenOnePrincipals { + private static final String[] CRED_VALUES = + new String[]{"testPrivateCredential-1", "testPrivateCredentials-2"}; + private static final HashSet CREDS = new HashSet<>(Arrays.asList(CRED_VALUES)); + + /** + * Policy file grants access to the private Credential,belonging to a + * Subject with at least two associated Principals:"com.sun.security.auth + * .NTUserPrincipal", with the name,"NTUserPrincipal-1", and + * "com.sun.security.auth.UnixPrincipal", with the name, "UnixPrincipals-1". + * + * For test1 and test2, subjects are associated with none or only one of + * principals mentioned above, SecurityException is expected. + * For test 3 and test 4, subjects are associated with two or more + * Principals (above principals are included), no exception is expected. + * + */ + + @Test(dataProvider = "Provider1", expectedExceptions = SecurityException.class) + public void test1(Subject s) { + s.getPrivateCredentials(String.class); + } + + @Test(dataProvider = "Provider1", expectedExceptions = SecurityException.class) + public void test2(Subject s) { + s.getPrivateCredentials().iterator().next(); + } + + @Test(dataProvider = "Provider2") + public void test3(Subject s) { + s.getPrivateCredentials(String.class); + } + + @Test(dataProvider = "Provider2") + public void test4(Subject s) { + s.getPrivateCredentials().iterator().next(); + } + + @DataProvider + public Object[][] Provider1() { + Subject s1 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS); + s1.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-2")); + Subject s2 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS); + s2.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-1")); + return new Object[][]{{s1}, {s2}}; + } + + @DataProvider + public Object[][] Provider2() { + Subject s3 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS); + s3.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-1")); + s3.getPrincipals().add(new UnixPrincipal("UnixPrincipals-1")); + Subject s4 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS); + s4.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-1")); + s4.getPrincipals().add(new UnixPrincipal("UnixPrincipals-1")); + s4.getPrincipals().add(new UnixPrincipal("UnixPrincipals-2")); + return new Object[][]{{s3}, {s4}}; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,10 @@ +grant{ +// permissions for TestNG execution +permission java.io.FilePermission "*","read,write"; +permission java.lang.RuntimePermission "accessDeclaredMembers"; +permission java.util.PropertyPermission "*","read"; +permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; +// permissions for test itself +permission javax.security.auth.AuthPermission "modifyPrincipals"; +permission javax.security.auth.PrivateCredentialPermission "* com.sun.security.auth.NTUserPrincipal \"NTUserPrincipal-1\" com.sun.security.auth.UnixPrincipal \"UnixPrincipals-1\"", "read"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/smartcardio/CommandAPDUTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8049021 + * @summary Test different constructors for CommandAPDU and check CLA,INS,NC,NE, + * P1,and P2 + * @run testng CommandAPDUTest + */ +import java.nio.ByteBuffer; +import javax.smartcardio.CommandAPDU; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class CommandAPDUTest { + + static final byte[] C1 = {(byte) 0x00, (byte) 0xA4, (byte) 0x04, + (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x62, (byte) 0x81, (byte) 0x01, (byte) 0x00}; + static int cla, ins, nc, ne, p1, p2; + static byte[] apdu, data; + static CommandAPDU cm1, cm2, cm3, cm4, cm5, cm6, cm7, cm8, cm9; + + @BeforeClass + public static void setUpClass() throws Exception { + //expected values of apdu, data, headers, nc, ne + CommandAPDU capdu = new CommandAPDU(C1); + apdu = capdu.getBytes(); + data = capdu.getData(); + + cla = capdu.getCLA(); + if (cla != (C1[0] & 0xff)) { + throw new RuntimeException("Failure: cla is not right"); + } + + ins = capdu.getINS(); + if (ins != (C1[1] & 0xff)) { + throw new RuntimeException("Failure: ins is not right"); + } + + p1 = capdu.getP1(); + if (p1 != (C1[2] & 0xff)) { + throw new RuntimeException("Failure: p1 is not right"); + } + + p2 = capdu.getP2(); + if (p2 != (C1[3] & 0xff)) { + throw new RuntimeException("Failure: p2 is not right"); + } + + nc = capdu.getNc(); + ne = capdu.getNe(); + + //Test on following constructors + cm1 = new CommandAPDU(apdu); + cm2 = new CommandAPDU(cla, ins, p1, p2); + cm3 = new CommandAPDU(cla, ins, p1, p2, data); + cm4 = new CommandAPDU(cla, ins, p1, p2, data, ne); + cm5 = new CommandAPDU(cla, ins, p1, p2, ne); + cm6 = new CommandAPDU(ByteBuffer.wrap(apdu)); + cm7 = new CommandAPDU(apdu, 0, apdu.length); + cm8 = new CommandAPDU(cla, ins, p1, p2, data, 0, nc); + cm9 = new CommandAPDU(cla, ins, p1, p2, data, 0, nc, ne); + } + + @Test(dataProvider = "provider1") + public static void testHeaders(CommandAPDU cm) { + assertEquals(cla, cm.getCLA()); + assertEquals(ins, cm.getINS()); + assertEquals(p1, cm.getP1()); + assertEquals(p2, cm.getP2()); + } + + @Test(dataProvider = "provider2") + public static void testAPDU(CommandAPDU cm) { + assertEquals(apdu, cm.getBytes()); + } + + @Test(dataProvider = "provider3") + public static void testData(CommandAPDU cm) { + assertEquals(data, cm.getData()); + } + + @Test(dataProvider = "provider3") + public static void testNC(CommandAPDU cm) { + assertEquals(nc, cm.getNc()); + } + + @Test(dataProvider = "provider4") + public static void testNE(CommandAPDU cm) { + assertEquals(ne, cm.getNe()); + } + + @DataProvider + public Object[][] provider1() { + return new Object[][]{{cm1}, {cm2}, {cm3}, {cm4}, {cm5}, {cm6}, {cm7}, + {cm8}, {cm9}}; + } + + @DataProvider + public Object[][] provider2() { + return new Object[][]{{cm1}, {cm6}, {cm7}}; + } + + @DataProvider + public Object[][] provider3() { + return new Object[][]{{cm1}, {cm3}, {cm4}, {cm6}, {cm7}, {cm8}, {cm9}}; + } + + @DataProvider + public Object[][] provider4() { + return new Object[][]{{cm1}, {cm4}, {cm5}, {cm6}, {cm7}, {cm9}}; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/smartcardio/ResponseAPDUTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8049021 + * @summary Construct ResponseAPDU from byte array and check NR< SW, SW1 and SW2 + * @run testng ResponseAPDUTest + */ +import javax.smartcardio.ResponseAPDU; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class ResponseAPDUTest { + + static final byte[] R1 = {(byte) 0x07, (byte) 0xA0, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x81, (byte) 0x01, + (byte) 0x04, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x24, + (byte) 0x05, (byte) 0x00, (byte) 0x0B, (byte) 0x04, (byte) 0xB0, + (byte) 0x25, (byte) 0x90, (byte) 0x00}; + static final ResponseAPDU RAPDU = new ResponseAPDU(R1); + static byte[] expectedData; + static int expectedNr, expectedSw1, expectedSw2, expectedSw; + + @BeforeClass + public static void setUpClass() throws Exception { + //expected values for data,nr,sw1,sw2 and sw + + int apduLen = R1.length; + expectedData = new byte[apduLen - 2]; + for (int i = 0; i < (apduLen - 2); i++) { + expectedData[i] = R1[i]; + } + + expectedNr = expectedData.length; + expectedSw1 = R1[apduLen - 2] & 0xff; + expectedSw2 = R1[apduLen - 1] & 0xff; + expectedSw = (expectedSw1 << 8) | expectedSw2; + } + + @Test + public static void test() { + assertEquals(RAPDU.getBytes(), R1); + assertEquals(RAPDU.getData(), expectedData); + assertEquals(RAPDU.getNr(), expectedNr); + assertEquals(RAPDU.getSW(), expectedSw); + assertEquals(RAPDU.getSW1(), expectedSw1); + assertEquals(RAPDU.getSW2(), expectedSw2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/smartcardio/TerminalFactorySpiTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8049021 + * @summary Test if we can write new provider for smart card + * @run main/othervm/policy=policy TerminalFactorySpiTest + */ +import java.security.Provider; +import java.security.Security; +import java.util.Arrays; +import javax.smartcardio.CardTerminals; +import javax.smartcardio.TerminalFactory; +import javax.smartcardio.TerminalFactorySpi; + +public class TerminalFactorySpiTest { + + static boolean callMethod = false; + + public static void main(String[] args) throws Exception { + Provider myProvider = new MyProvider(); + Security.addProvider(myProvider); + System.out.println(Arrays.asList(Security.getProviders())); + + TerminalFactory.getInstance("MyType", new Object()).terminals(); + if (!callMethod) { + throw new RuntimeException("Expected engineTerminals() not called"); + } + } + + public static class MyProvider extends Provider { + + MyProvider() { + super("MyProvider", 1.0d, "smart Card Example"); + put("TerminalFactory.MyType", "TerminalFactorySpiTest$MyTerminalFactorySpi"); + } + } + + public static class MyTerminalFactorySpi extends TerminalFactorySpi { + + public MyTerminalFactorySpi(Object ob) { + } + + protected CardTerminals engineTerminals() { + System.out.println("MyTerminalFactory.engineTerminals()"); + callMethod = true; + return null; + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/smartcardio/policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,4 @@ +grant { + permission java.security.SecurityPermission "insertProvider.MyProvider"; + permission java.security.SecurityPermission "putProviderProperty.MyProvider"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/JComboBox/8136998/bug8136998.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.WindowConstants; + +/* @test + * @bug 8136998 + * @summary Checks that JComboBox does not prevent mouse-wheel scrolling JScrollPane. + * @library ../../regtesthelpers + * @build Util + * @run main bug8136998 + * @author Alexey Ivanov + */ +public class bug8136998 { + + private static final String[] ITEMS = new String[] { + "A", "B", "C", "D", "E", "F" + }; + + private final Robot robot; + + private JFrame frame; + private JComboBox comboBox; + private JScrollPane scrollPane; + + public static void main(String[] args) throws Exception { + iterateLookAndFeels(new bug8136998()); + } + + protected static void iterateLookAndFeels(final bug8136998 test) throws Exception { + LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels(); + for (LookAndFeelInfo info : lafInfo) { + try { + UIManager.setLookAndFeel(info.getClassName()); + System.out.println("Look and Feel: " + info.getClassName()); + test.runTest(); + } catch (UnsupportedLookAndFeelException e) { + System.out.println("Skipping unsupported LaF: " + info); + } + } + } + + public bug8136998() throws AWTException { + robot = new Robot(); + robot.setAutoDelay(200); + } + + private void setupUI() { + frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + comboBox = new JComboBox<>(ITEMS); + + JPanel scrollable = new JPanel(); + scrollable.setLayout(new BoxLayout(scrollable, BoxLayout.Y_AXIS)); + + scrollable.add(Box.createVerticalStrut(200)); + scrollable.add(comboBox); + scrollable.add(Box.createVerticalStrut(200)); + + scrollPane = new JScrollPane(scrollable); + + frame.add(scrollPane); + + frame.setSize(100, 200); + frame.setVisible(true); + } + + public void runTest() throws Exception { + try { + SwingUtilities.invokeAndWait(this::setupUI); + + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(() -> + scrollPane.getViewport().scrollRectToVisible(comboBox.getBounds()) + ); + robot.waitForIdle(); + + // Move mouse pointer to the center of the combo box + Point p = comboBox.getLocationOnScreen(); + Dimension d = comboBox.getSize(); + robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2); + + // The currently visible rectangle in scrollPane + Rectangle viewRect0 = Util.invokeOnEDT(scrollPane.getViewport()::getViewRect); + + // Scroll the scrollPane with mouse wheel + robot.mouseWheel(1); + robot.waitForIdle(); + + // The updated rectangle + Rectangle viewRect1 = Util.invokeOnEDT(scrollPane.getViewport()::getViewRect); + + if (viewRect0.y == viewRect1.y) { + throw new RuntimeException("Mouse wheel should have scrolled the JScrollPane"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + + System.out.println("Test passed"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/plaf/basic/BasicComboPopup/8154069/Bug8154069.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8154069 + * @summary Jaws reads wrong values from comboboxes when no element is selected + * @run main Bug8154069 + */ + +import javax.accessibility.Accessible; +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleSelection; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.plaf.nimbus.NimbusLookAndFeel; + +public class Bug8154069 { + + private static JFrame frame; + private static volatile Exception exception = null; + + public static void main(String args[]) throws Exception { + try { + try { + UIManager.setLookAndFeel(new NimbusLookAndFeel()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + String[] petStrings = { "Bird", "Cat" }; + JComboBox<String> cb = new JComboBox<>(petStrings); + cb.setSelectedIndex(1); // select Cat + frame.add(cb); + frame.pack(); + try { + cb.setSelectedIndex(-1); + int i = cb.getSelectedIndex(); + if (i != -1) { + throw new RuntimeException("getSelectedIndex is not -1"); + } + Object o = cb.getSelectedItem(); + if (o != null) { + throw new RuntimeException("getSelectedItem is not null"); + } + AccessibleContext ac = cb.getAccessibleContext(); + AccessibleSelection as = ac.getAccessibleSelection(); + int count = as.getAccessibleSelectionCount(); + if (count != 0) { + throw new RuntimeException("getAccessibleSelection count is not 0"); + } + Accessible a = as.getAccessibleSelection(0); + if (a != null) { + throw new RuntimeException("getAccessibleSelection(0) is not null"); + } + } catch (Exception e) { + exception = e; + } + }); + if (exception != null) { + System.out.println("Test failed: " + exception.getMessage()); + throw exception; + } else { + System.out.println("Test passed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + frame.dispose(); + }); + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/plaf/nimbus/8057791/bug8057791.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8057791 + @summary Selection in JList is drawn with wrong colors in Nimbus L&F + @author Anton Litvinov + @run main bug8057791 + */ + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.plaf.nimbus.NimbusLookAndFeel; + +public class bug8057791 { + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(new NimbusLookAndFeel()); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + final int listWidth = 50; + final int listHeight = 50; + final int selCellIndex = 0; + + JList<String> list = new JList<String>(); + list.setSize(listWidth, listHeight); + DefaultListModel<String> listModel = new DefaultListModel<String>(); + listModel.add(selCellIndex, "E"); + list.setModel(listModel); + list.setSelectedIndex(selCellIndex); + + BufferedImage img = new BufferedImage(listWidth, listHeight, + BufferedImage.TYPE_INT_ARGB); + Graphics g = img.getGraphics(); + list.paint(g); + g.dispose(); + + Rectangle cellRect = list.getCellBounds(selCellIndex, selCellIndex); + HashSet<Color> cellColors = new HashSet<Color>(); + int uniqueColorIndex = 0; + for (int x = cellRect.x; x < (cellRect.x + cellRect.width); x++) { + for (int y = cellRect.y; y < (cellRect.y + cellRect.height); y++) { + Color cellColor = new Color(img.getRGB(x, y), true); + if (cellColors.add(cellColor)) { + System.err.println(String.format("Cell color #%d: %s", + uniqueColorIndex++, cellColor)); + } + } + } + + Color selForegroundColor = list.getSelectionForeground(); + Color selBackgroundColor = list.getSelectionBackground(); + if (!cellColors.contains(new Color(selForegroundColor.getRGB(), true))) { + throw new RuntimeException(String.format( + "Selected cell is drawn without selection foreground color '%s'.", + selForegroundColor)); + } + if (!cellColors.contains(new Color(selBackgroundColor.getRGB(), true))) { + throw new RuntimeException(String.format( + "Selected cell is drawn without selection background color '%s'.", + selBackgroundColor)); + } + } + }); + } catch (UnsupportedLookAndFeelException | InterruptedException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +}
--- a/test/javax/xml/crypto/dsig/GenerationTests.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/javax/xml/crypto/dsig/GenerationTests.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 + * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8074784 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -31,16 +31,23 @@ * @author Sean Mullan */ +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; import java.io.*; import java.math.BigInteger; +import java.net.InetSocketAddress; import java.security.Key; import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; import java.security.cert.X509CRL; import java.security.spec.KeySpec; import java.security.spec.DSAPrivateKeySpec; @@ -48,10 +55,10 @@ import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.*; +import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.xml.XMLConstants; import javax.xml.parsers.*; -import org.w3c.dom.*; import javax.xml.crypto.Data; import javax.xml.crypto.KeySelector; import javax.xml.crypto.OctetStreamData; @@ -69,6 +76,7 @@ import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.w3c.dom.*; /** * Test that recreates merlin-xmldsig-twenty-three test vectors but with @@ -110,6 +118,73 @@ private final static String DSA_SHA256 = "http://www.w3.org/2009/xmldsig11#dsa-sha256"; + private static final String BOGUS = "bogus"; + + private static final String xslt = "" + + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n" + + " xmlns='http://www.w3.org/TR/xhtml1/strict' \n" + + " exclude-result-prefixes='foo' \n" + + " version='1.0'>\n" + + " <xsl:output encoding='UTF-8' \n" + + " indent='no' \n" + + " method='xml' />\n" + + " <xsl:template match='/'>\n" + + " <html>\n" + + " <head>\n" + + " <title>Notaries</title>\n" + + " </head>\n" + + " <body>\n" + + " <table>\n" + + " <xsl:for-each select='Notaries/Notary'>\n" + + " <tr>\n" + + " <th>\n" + + " <xsl:value-of select='@name' />\n" + + " </th>\n" + + " </tr>\n" + + " </xsl:for-each>\n" + + " </table>\n" + + " </body>\n" + + " </html>\n" + + " </xsl:template>\n" + + "</xsl:stylesheet>\n"; + + private static final String[] canonicalizationMethods = new String[] { + CanonicalizationMethod.EXCLUSIVE, + CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, + CanonicalizationMethod.INCLUSIVE, + CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS + }; + + private static final String[] xml_transforms = new String[] { + Transform.XSLT, + Transform.XPATH, + Transform.XPATH2, + CanonicalizationMethod.EXCLUSIVE, + CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, + CanonicalizationMethod.INCLUSIVE, + CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, + }; + + private static final String[] non_xml_transforms = new String[] { + null, Transform.BASE64 + }; + + private static final String[] signatureMethods = new String[] { + SignatureMethod.DSA_SHA1, + SignatureMethod.RSA_SHA1, + SignatureMethod.HMAC_SHA1 + }; + + private static enum Content { + Xml, Text, Base64, NotExisitng + } + + private static enum KeyInfoType { + KeyValue, x509data, KeyName + } + + private static boolean result = true; + public static void main(String args[]) throws Exception { setup(); test_create_signature_enveloped_dsa(1024); @@ -140,6 +215,97 @@ test_create_signature_reference_dependency(); test_create_signature_with_attr_in_no_namespace(); test_create_signature_with_empty_id(); + + // run tests for detached signatures with local http server + try (Http server = Http.startServer()) { + server.start(); + + // tests for XML documents + Arrays.stream(canonicalizationMethods).forEach(c -> + Arrays.stream(signatureMethods).forEach(s -> + Arrays.stream(xml_transforms).forEach(t -> + Arrays.stream(KeyInfoType.values()).forEach(k -> { + test_create_detached_signature(c, s, t, k, + Content.Xml, server.getPort(), false, null); + })))); + + // tests for text data with no transform + Arrays.stream(canonicalizationMethods).forEach(c -> + Arrays.stream(signatureMethods).forEach(s -> + Arrays.stream(KeyInfoType.values()).forEach(k -> { + test_create_detached_signature(c, s, null, k, + Content.Text, server.getPort(), false, null); + }))); + + // tests for base64 data + Arrays.stream(canonicalizationMethods).forEach(c -> + Arrays.stream(signatureMethods).forEach(s -> + Arrays.stream(non_xml_transforms).forEach(t -> + Arrays.stream(KeyInfoType.values()).forEach(k -> { + test_create_detached_signature(c, s, t, k, + Content.Base64, server.getPort(), + false, null); + })))); + + // negative tests + + // unknown CanonicalizationMethod + test_create_detached_signature( + CanonicalizationMethod.EXCLUSIVE + BOGUS, + SignatureMethod.DSA_SHA1, + CanonicalizationMethod.INCLUSIVE, + KeyInfoType.KeyName, + Content.Xml, + server.getPort(), + true, + NoSuchAlgorithmException.class); + + // unknown SignatureMethod + test_create_detached_signature( + CanonicalizationMethod.EXCLUSIVE, + SignatureMethod.DSA_SHA1 + BOGUS, + CanonicalizationMethod.INCLUSIVE, + KeyInfoType.KeyName, Content.Xml, + server.getPort(), + true, + NoSuchAlgorithmException.class); + + // unknown Transform + test_create_detached_signature( + CanonicalizationMethod.EXCLUSIVE, + SignatureMethod.DSA_SHA1, + CanonicalizationMethod.INCLUSIVE + BOGUS, + KeyInfoType.KeyName, Content.Xml, + server.getPort(), + true, + NoSuchAlgorithmException.class); + + // no source document + test_create_detached_signature( + CanonicalizationMethod.EXCLUSIVE, + SignatureMethod.DSA_SHA1, + CanonicalizationMethod.INCLUSIVE, + KeyInfoType.KeyName, + Content.NotExisitng, + server.getPort(), + true, + XMLSignatureException.class); + + // wrong transform for text data + test_create_detached_signature( + CanonicalizationMethod.EXCLUSIVE, + SignatureMethod.DSA_SHA1, + CanonicalizationMethod.INCLUSIVE, + KeyInfoType.KeyName, + Content.Text, + server.getPort(), + true, + XMLSignatureException.class); + } + + if (!result) { + throw new RuntimeException("At least one test case failed"); + } } private static void setup() throws Exception { @@ -716,33 +882,6 @@ // Manifest Reference 3 List<Transform> manTrans = new ArrayList<Transform>(); - String xslt = "" - + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n" - + " xmlns='http://www.w3.org/TR/xhtml1/strict' \n" - + " exclude-result-prefixes='foo' \n" - + " version='1.0'>\n" - + " <xsl:output encoding='UTF-8' \n" - + " indent='no' \n" - + " method='xml' />\n" - + " <xsl:template match='/'>\n" - + " <html>\n" - + " <head>\n" - + " <title>Notaries</title>\n" - + " </head>\n" - + " <body>\n" - + " <table>\n" - + " <xsl:for-each select='Notaries/Notary'>\n" - + " <tr>\n" - + " <th>\n" - + " <xsl:value-of select='@name' />\n" - + " </th>\n" - + " </tr>\n" - + " </xsl:for-each>\n" - + " </table>\n" - + " </body>\n" - + " </html>\n" - + " </xsl:template>\n" - + "</xsl:stylesheet>\n"; Document docxslt = db.parse(new ByteArrayInputStream(xslt.getBytes())); Node xslElem = docxslt.getDocumentElement(); @@ -1121,6 +1260,200 @@ System.out.println(); } + static void test_create_detached_signature(String canonicalizationMethod, + String signatureMethod, String transform, KeyInfoType keyInfo, + Content contentType, int port, boolean expectedFailure, + Class expectedException) { + + final String digestMethod = DigestMethod.SHA1; + System.out.println("Test detached signature:"); + System.out.println(" Canonicalization method: " + + canonicalizationMethod); + System.out.println(" Signature method: " + signatureMethod); + System.out.println(" Transform: " + transform); + System.out.println(" Digest method: " + digestMethod); + System.out.println(" KeyInfoType: " + keyInfo); + System.out.println(" Content type: " + contentType); + System.out.println(" Expected failure: " + + (expectedFailure ? "yes" : "no")); + System.out.println(" Expected exception: " + + (expectedException == null ? + "no" : expectedException.getName())); + + try { + boolean success = test_create_detached_signature( + canonicalizationMethod, + signatureMethod, + digestMethod, + transform, + keyInfo, + contentType, + port); + + if (success && expectedFailure) { + System.out.println("Signature validation unexpectedly passed"); + result = false; + } else if (!success && !expectedFailure) { + System.out.println("Signature validation unexpectedly failed"); + result = false; + } else if (expectedException != null) { + System.out.println("Expected " + expectedException + + " not thrown"); + result = false; + } + } catch (Exception e) { + if (expectedException == null + || !e.getClass().isAssignableFrom(expectedException)) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + result = false; + } else { + System.out.println("Expected exception: " + e); + } + } + + System.out.println("Test case passed"); + } + + static boolean test_create_detached_signature(String canonicalizationMethod, + String signatureMethod, String digestMethod, String transform, + KeyInfoType keyInfo, Content contentType, int port) + throws Exception { + + System.out.print("Sign ..."); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + + // Create SignedInfo + DigestMethod dm = fac.newDigestMethod(digestMethod, null); + + List transformList = null; + if (transform != null) { + TransformParameterSpec params = null; + switch (transform) { + case Transform.XPATH: + params = new XPathFilterParameterSpec("//."); + break; + case Transform.XPATH2: + params = new XPathFilter2ParameterSpec( + Collections.singletonList(new XPathType("//.", + XPathType.Filter.INTERSECT))); + break; + case Transform.XSLT: + Element element = dbf.newDocumentBuilder() + .parse(new ByteArrayInputStream(xslt.getBytes())) + .getDocumentElement(); + DOMStructure stylesheet = new DOMStructure(element); + params = new XSLTTransformParameterSpec(stylesheet); + break; + } + transformList = Collections.singletonList(fac.newTransform( + transform, params)); + } + + String url = String.format("http://localhost:%d/%s", port, contentType); + List refs = Collections.singletonList(fac.newReference(url, dm, + transformList, null, null)); + + CanonicalizationMethod cm = fac.newCanonicalizationMethod( + canonicalizationMethod, (C14NMethodParameterSpec) null); + + SignatureMethod sm = fac.newSignatureMethod(signatureMethod, null); + + Key signingKey; + Key validationKey; + switch (signatureMethod) { + case SignatureMethod.DSA_SHA1: + case SignatureMethod.RSA_SHA1: + KeyPair kp = generateKeyPair(sm); + validationKey = kp.getPublic(); + signingKey = kp.getPrivate(); + break; + case SignatureMethod.HMAC_SHA1: + KeyGenerator kg = KeyGenerator.getInstance("HmacSHA1"); + signingKey = kg.generateKey(); + validationKey = signingKey; + break; + default: + throw new RuntimeException("Unsupported signature algorithm"); + } + + SignedInfo si = fac.newSignedInfo(cm, sm, refs, null); + + // Create KeyInfo + KeyInfoFactory kif = fac.getKeyInfoFactory(); + List list = null; + if (keyInfo == KeyInfoType.KeyValue) { + if (validationKey instanceof PublicKey) { + KeyValue kv = kif.newKeyValue((PublicKey) validationKey); + list = Collections.singletonList(kv); + } + } else if (keyInfo == KeyInfoType.x509data) { + list = Collections.singletonList( + kif.newX509Data(Collections.singletonList("cn=Test"))); + } else if (keyInfo == KeyInfoType.KeyName) { + list = Collections.singletonList(kif.newKeyName("Test")); + } else { + throw new RuntimeException("Unexpected KeyInfo: " + keyInfo); + } + KeyInfo ki = list != null ? kif.newKeyInfo(list) : null; + + // Create an empty doc for detached signature + Document doc = dbf.newDocumentBuilder().newDocument(); + DOMSignContext xsc = new DOMSignContext(signingKey, doc); + + // Generate signature + XMLSignature signature = fac.newXMLSignature(si, ki); + signature.sign(xsc); + + // Save signature + String signatureString; + try (StringWriter writer = new StringWriter()) { + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer trans = tf.newTransformer(); + Node parent = xsc.getParent(); + trans.transform(new DOMSource(parent), new StreamResult(writer)); + signatureString = writer.toString(); + } + + System.out.print("Validate ... "); + try (ByteArrayInputStream bis = new ByteArrayInputStream( + signatureString.getBytes())) { + doc = dbf.newDocumentBuilder().parse(bis); + } + + NodeList nodeLst = doc.getElementsByTagName("Signature"); + Node node = nodeLst.item(0); + if (node == null) { + throw new RuntimeException("Couldn't find Signature element"); + } + if (!(node instanceof Element)) { + throw new RuntimeException("Unexpected node type"); + } + Element sig = (Element) node; + + // Validate signature + DOMValidateContext vc = new DOMValidateContext(validationKey, sig); + vc.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.FALSE); + signature = fac.unmarshalXMLSignature(vc); + + boolean success = signature.validate(vc); + if (!success) { + System.out.println("Core signature validation failed"); + return false; + } + + success = signature.getSignatureValue().validate(vc); + if (!success) { + System.out.println("Cryptographic validation of signature failed"); + return false; + } + + return true; + } + private static final String DSA_Y = "070662842167565771936588335128634396171789331656318483584455493822" + "400811200853331373030669235424928346190274044631949560438023934623" + @@ -1231,6 +1564,25 @@ }; } + static KeyPair generateKeyPair(SignatureMethod sm) + throws NoSuchAlgorithmException { + KeyPairGenerator keygen; + switch (sm.getAlgorithm()) { + case SignatureMethod.DSA_SHA1: + keygen = KeyPairGenerator.getInstance("DSA"); + break; + case SignatureMethod.RSA_SHA1: + keygen = KeyPairGenerator.getInstance("RSA"); + break; + default: + throw new RuntimeException("Unsupported signature algorithm"); + } + + SecureRandom random = new SecureRandom(); + keygen.initialize(1024, random); + return keygen.generateKeyPair(); + } + /** * This URIDereferencer returns locally cached copies of http content to * avoid test failures due to network glitches, etc. @@ -1257,4 +1609,82 @@ return defaultUd.dereference(ref, ctx); } } + + // local http server + static class Http implements HttpHandler, AutoCloseable { + + private final HttpServer server; + + private Http(HttpServer server) { + this.server = server; + } + + static Http startServer() throws IOException { + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + return new Http(server); + } + + void start() { + server.createContext("/", this); + server.start(); + } + + void stop() { + server.stop(0); + } + + int getPort() { + return server.getAddress().getPort(); + } + + @Override + public void handle(HttpExchange t) throws IOException { + try { + String type; + String path = t.getRequestURI().getPath(); + if (path.startsWith("/")) { + type = path.substring(1); + } else { + type = path; + } + + String contentTypeHeader = ""; + byte[] output = new byte[] {}; + int code = 200; + Content testContentType = Content.valueOf(type); + switch (testContentType) { + case Base64: + contentTypeHeader = "application/octet-stream"; + output = "VGVzdA==".getBytes(); + break; + case Text: + contentTypeHeader = "text/plain"; + output = "Text".getBytes(); + break; + case Xml: + contentTypeHeader = "application/xml"; + output = "<tag>test</tag>".getBytes(); + break; + case NotExisitng: + code = 404; + break; + default: + throw new IOException("Unknown test content type"); + } + + t.getResponseHeaders().set("Content-Type", contentTypeHeader); + t.sendResponseHeaders(code, output.length); + t.getResponseBody().write(output); + } catch (IOException e) { + System.out.println("Exception: " + e); + t.sendResponseHeaders(500, 0); + } + t.close(); + } + + @Override + public void close() { + stop(); + } + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/stream/8153781/SkipDTDTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; +import java.io.StringReader; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.XMLEvent; +import org.testng.Assert; +import org.testng.annotations.Test; + +/* + * @test + * @bug 8153781 + * @run testng/othervm SkipDTDTest + * @summary Test if method skipDTD of class XMLDTDScannerImpl will correctly skip the DTD section, + * even if a call to XMLEntityScanner.scanData for skipping to the closing ']' returns true. + */ +public class SkipDTDTest { + public static int DOCTYPE_SECTION_LENGTH = XMLEntityManager.DEFAULT_BUFFER_SIZE * 2; + public static int DOCUMENT_LENGTH = DOCTYPE_SECTION_LENGTH + 4096; + + public String createXMLDocument(int doctypeoffset) { + StringBuilder xmlcontentbuilder = new StringBuilder(DOCUMENT_LENGTH); + xmlcontentbuilder.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"); + xmlcontentbuilder.append("<!DOCTYPE dummy [\r\n"); + xmlcontentbuilder.append(" <!ELEMENT dummy EMPTY>\r\n"); + xmlcontentbuilder.append(" <!--\r\n"); + int doctypelines = DOCTYPE_SECTION_LENGTH / 3; + for (int i = 0; i < doctypeoffset; i++) + xmlcontentbuilder.append('a'); + for (int i = 0; i < doctypelines; i++) + xmlcontentbuilder.append("a\r\n"); + xmlcontentbuilder.append(" -->\r\n"); + xmlcontentbuilder.append(" ]\r\n"); + xmlcontentbuilder.append(">\r\n"); + xmlcontentbuilder.append("<dummy>\r\n"); + xmlcontentbuilder.append("</dummy>\r\n"); + System.out.println("Document length:" + xmlcontentbuilder.length()); + return xmlcontentbuilder.toString(); + } + + public void runReader(XMLInputFactory factory, int offset) throws XMLStreamException { + StringReader stringReader = new StringReader(createXMLDocument(offset)); + XMLEventReader reader = factory.createXMLEventReader(stringReader); + + while (reader.hasNext()) { + XMLEvent event = reader.nextEvent(); + System.out.println("Event Type: " + event.getEventType()); + } + } + + @Test + public void test() { + try { + XMLInputFactory factory = XMLInputFactory.newInstance(); + factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); + for (int i = 0; i < 3; i++) { + runReader(factory, i); + } + } catch (XMLStreamException xe) { + xe.printStackTrace(); + Assert.fail(xe.getMessage()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/java2d/ClassCastExceptionForInvalidSurface.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; + +/** + * @test + * @bug 8158072 7172749 + */ +public final class ClassCastExceptionForInvalidSurface { + + static GraphicsEnvironment ge + = GraphicsEnvironment.getLocalGraphicsEnvironment(); + + static GraphicsConfiguration gc + = ge.getDefaultScreenDevice().getDefaultConfiguration(); + + static volatile VolatileImage vi = gc.createCompatibleVolatileImage(10, 10); + + static volatile Throwable failed; + + static BlockingQueue<VolatileImage> list = new ArrayBlockingQueue<>(50); + + // Will run the test no more than 15 seconds + static long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(15); + + public static void main(final String[] args) throws InterruptedException { + + // Catch all uncaught exceptions and treat them as test failure + Thread.setDefaultUncaughtExceptionHandler((t, e) -> failed = e); + + // Data for rendering + BufferedImage bi = new BufferedImage(10, 10, TYPE_INT_ARGB); + FontRenderContext frc = new FontRenderContext(null, false, false); + Font font = new Font("Serif", Font.PLAIN, 12); + GlyphVector gv = font.createGlyphVector(frc, new char[]{'a', '1'}); + + Thread t1 = new Thread(() -> { + while (!isComplete()) { + vi = gc.createCompatibleVolatileImage(10, 10); + if (!list.offer(vi)) { + vi.flush(); + } + } + list.forEach(Image::flush); + }); + Thread t2 = new Thread(() -> { + while (!isComplete()) { + VolatileImage vi = list.poll(); + if (vi != null) { + vi.flush(); + } + } + }); + + Thread t3 = new Thread(() -> { + while (!isComplete()) { + vi.createGraphics().drawImage(bi, 1, 1, null); + } + }); + Thread t4 = new Thread(() -> { + while (!isComplete()) { + vi.createGraphics().drawGlyphVector(gv, 0, 0); + vi.createGraphics().drawOval(0, 0, 10, 10); + vi.createGraphics().drawLine(0, 0, 10, 10); + vi.createGraphics().drawString("123", 1, 1); + vi.createGraphics().draw(new Rectangle(0, 0, 10, 10)); + vi.createGraphics().fillOval(0, 0, 10, 10); + final Graphics2D graphics = vi.createGraphics(); + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + graphics.fillPolygon(new int[] {0, 10, 10, 0}, + new int [] {0, 0, 10, 10}, 4); + } + }); + t1.start(); + t2.start(); + t3.start(); + t4.start(); + t1.join(); + t2.join(); + t3.join(); + t4.join(); + + if (failed != null) { + System.err.println("Test failed"); + failed.printStackTrace(); + } + } + + private static boolean isComplete() { + return endtime - System.nanoTime() < 0 || failed != null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/BogusKDC.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 4515853 8075297 + * @summary Checks that Kerberos client tries slave KDC + * if master KDC is not responding + * @run main/othervm BogusKDC + */ +public class BogusKDC { + + static final String TEST_SRC = System.getProperty("test.src", "."); + static final String HOST = "localhost"; + static final String NOT_EXISTING_HOST = "not.existing.host"; + static final String REALM = "TEST.REALM"; + static final String USER = "USER"; + static final String USER_PRINCIPAL = USER + "@" + REALM; + static final String USER_PASSWORD = "password"; + static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + static final String KRB5_CONF = "krb5.conf"; + static final int WRONG_KDC_PORT = 21; + + static final String KRB5_CONF_TEMPLATE = "" + + "[libdefaults]\n" + + "default_realm = TEST.REALM\n" + + "max_retries = 1\n" + + "\n" + + "[realms]\n" + + "TEST.REALM = {\n" + + " kdc = %s\n" + + " kdc = localhost:%d\n" + + "}"; + + public static void main(String[] args) throws LoginException, IOException { + Map<String, String> principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, USER_PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF); + + // start a local KDC + KDC kdc = KDC.startKDC(HOST, KRB5_CONF, REALM, principals, null, null); + + System.setProperty("java.security.auth.login.config", + TEST_SRC + File.separator + "refreshKrb5Config.jaas"); + + CallbackHandler handler = new Helper.UserPasswordHandler( + USER, USER_PASSWORD); + + // create a krb5 config with non-existing host for master KDC, + // and wrong port for slave KDC + try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) { + w.write(String.format(KRB5_CONF_TEMPLATE, + KDC.KDCNameService.NOT_EXISTING_HOST, WRONG_KDC_PORT)); + w.flush(); + } + + // login with not-refreshable config + try { + new LoginContext("NotRefreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // create a krb5 config with non-existing host for master KDC, + // but correct port for slave KDC + try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) { + w.write(String.format(KRB5_CONF_TEMPLATE, + KDC.KDCNameService.NOT_EXISTING_HOST, kdc.getPort())); + w.flush(); + } + + // login with not-refreshable config + try { + new LoginContext("NotRefreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // login with refreshable config + new LoginContext("Refreshable", handler).login(); + + System.out.println("Test passed"); + } +}
--- a/test/sun/security/krb5/auto/Context.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/krb5/auto/Context.java Thu Jan 12 06:59:38 2017 +0000 @@ -23,6 +23,7 @@ import com.sun.security.auth.module.Krb5LoginModule; import java.security.Key; +import java.lang.reflect.InvocationTargetException; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Arrays; @@ -581,7 +582,12 @@ out.name = name + " as " + out.cred.getName().toString(); return out; } catch (PrivilegedActionException pae) { - throw pae.getException(); + Exception e = pae.getException(); + if (e instanceof InvocationTargetException) { + throw (Exception)((InvocationTargetException) e).getTargetException(); + } else { + throw e; + } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/ForwardableCheck.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8022582 + * @summary Relax response flags checking in sun.security.krb5.KrbKdcRep.check. + * @compile -XDignore.symbol.file ForwardableCheck.java + * @run main/othervm ForwardableCheck + */ + +import org.ietf.jgss.GSSException; +import sun.security.jgss.GSSUtil; + +import java.util.Arrays; + +public class ForwardableCheck { + + public static void main(String[] args) throws Exception { + OneKDC kdc = new OneKDC(null); + kdc.writeJAASConf(); + + // USER can impersonate someone else + kdc.setOption(KDC.Option.ALLOW_S4U2SELF, + Arrays.asList(OneKDC.USER + "@" + OneKDC.REALM)); + // USER2 is sensitive + kdc.setOption(KDC.Option.SENSITIVE_ACCOUNTS, + Arrays.asList(OneKDC.USER2 + "@" + OneKDC.REALM)); + + Context c; + + // USER2 is sensitive but it's still able to get a normal ticket + c = Context.fromUserPass(OneKDC.USER2, OneKDC.PASS2, false); + + // ... and connect to another account + c.startAsClient(OneKDC.USER, GSSUtil.GSS_KRB5_MECH_OID); + c.x().requestCredDeleg(true); + c.x().requestMutualAuth(false); + + c.take(new byte[0]); + + if (!c.x().isEstablished()) { + throw new Exception("Context should have been established"); + } + + // ... but will not be able to delegate itself + if (c.x().getCredDelegState()) { + throw new Exception("Impossible"); + } + + // Although USER is allowed to impersonate other people, + // it cannot impersonate USER2 coz it's sensitive. + c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + try { + c.impersonate(OneKDC.USER2); + throw new Exception("Should fail"); + } catch (GSSException e) { + e.printStackTrace(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/Helper.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +public class Helper { + + static class UserPasswordHandler implements CallbackHandler { + + private final String name; + private final String password; + + UserPasswordHandler(String name, String password) { + this.name = name; + this.password = password; + } + + @Override + public void handle(Callback[] callbacks) + throws UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof PasswordCallback) { + ((PasswordCallback) callback).setPassword( + password.toCharArray()); + } else if (callback instanceof NameCallback) { + ((NameCallback)callback).setName(name); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + } +}
--- a/test/sun/security/krb5/auto/KDC.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/krb5/auto/KDC.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.security.SecureRandom; import java.util.*; import java.util.concurrent.*; + import sun.net.spi.nameservice.NameService; import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.*; @@ -145,9 +146,14 @@ private List<String> conf = new ArrayList<>(); private Thread thread1, thread2, thread3; + private volatile boolean udpConsumerReady = false; + private volatile boolean tcpConsumerReady = false; + private volatile boolean dispatcherReady = false; DatagramSocket u1 = null; ServerSocket t1 = null; + public static enum KtabMode { APPEND, EXISTING }; + /** * Option names, to be expanded forever. */ @@ -194,6 +200,10 @@ * Krb5.KDC_ERR_POLICY will be send for S4U2proxy request. */ ALLOW_S4U2PROXY, + /** + * Sensitive accounts can never be delegated. + */ + SENSITIVE_ACCOUNTS, }; static { @@ -638,7 +648,7 @@ try { System.out.println(realm + "> " + tgsReq.reqBody.cname + " sends TGS-REQ for " + - service); + service + ", " + tgsReq.reqBody.kdcOptions); KDCReqBody body = tgsReq.reqBody; int[] eTypes = KDCReqBodyDotEType(body); int e2 = eTypes[0]; // etype for outgoing session key @@ -714,7 +724,13 @@ boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1]; if (body.kdcOptions.get(KDCOptions.FORWARDABLE) && allowForwardable) { - bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true; + List<String> sensitives = (List<String>) + options.get(Option.SENSITIVE_ACCOUNTS); + if (sensitives != null && sensitives.contains(cname.toString())) { + // Cannot make FORWARDABLE + } else { + bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true; + } } if (body.kdcOptions.get(KDCOptions.FORWARDED) || etp.flags.get(Krb5.TKT_OPTS_FORWARDED)) { @@ -819,7 +835,8 @@ t, edata); System.out.println(" Return " + tgsRep.cname - + " ticket for " + tgsRep.ticket.sname); + + " ticket for " + tgsRep.ticket.sname + ", flags " + + tFlags); DerOutputStream out = new DerOutputStream(); out.write(DerValue.createTag(DerValue.TAG_APPLICATION, @@ -865,7 +882,7 @@ try { System.out.println(realm + "> " + asReq.reqBody.cname + " sends AS-REQ for " + - service); + service + ", " + asReq.reqBody.kdcOptions); KDCReqBody body = asReq.reqBody; @@ -908,7 +925,13 @@ //body.from boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1]; if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) { - bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true; + List<String> sensitives = (List<String>) + options.get(Option.SENSITIVE_ACCOUNTS); + if (sensitives != null && sensitives.contains(body.cname.toString())) { + // Cannot make FORWARDABLE + } else { + bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true; + } } if (body.kdcOptions.get(KDCOptions.RENEWABLE)) { bFlags[Krb5.TKT_OPTS_RENEWABLE] = true; @@ -1084,7 +1107,8 @@ edata); System.out.println(" Return " + asRep.cname - + " ticket for " + asRep.ticket.sname); + + " ticket for " + asRep.ticket.sname + ", flags " + + tFlags); DerOutputStream out = new DerOutputStream(); out.write(DerValue.createTag(DerValue.TAG_APPLICATION, @@ -1192,6 +1216,7 @@ // The UDP consumer thread1 = new Thread() { public void run() { + udpConsumerReady = true; while (true) { try { byte[] inbuf = new byte[8192]; @@ -1212,6 +1237,7 @@ // The TCP consumer thread2 = new Thread() { public void run() { + tcpConsumerReady = true; while (true) { try { Socket socket = tcp.accept(); @@ -1234,6 +1260,7 @@ // The dispatcher thread3 = new Thread() { public void run() { + dispatcherReady = true; while (true) { try { q.take().send(); @@ -1244,6 +1271,19 @@ }; thread3.setDaemon(true); thread3.start(); + + // wait for the KDC is ready + try { + while (!isReady()) { + Thread.sleep(100); + } + } catch(InterruptedException e) { + throw new IOException(e); + } + } + + boolean isReady() { + return udpConsumerReady && tcpConsumerReady && dispatcherReady; } public void terminate() { @@ -1257,6 +1297,72 @@ // OK } } + + public static KDC startKDC(final String host, final String krbConfFileName, + final String realm, final Map<String, String> principals, + final String ktab, final KtabMode mode) { + + KDC kdc; + try { + kdc = KDC.create(realm, host, 0, true); + kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE); + if (krbConfFileName != null) { + KDC.saveConfig(krbConfFileName, kdc); + } + + // Add principals + if (principals != null) { + principals.forEach((name, password) -> { + if (password == null || password.isEmpty()) { + System.out.println(String.format( + "KDC:add a principal '%s' with a random " + + "password", name)); + kdc.addPrincipalRandKey(name); + } else { + System.out.println(String.format( + "KDC:add a principal '%s' with '%s' password", + name, password)); + kdc.addPrincipal(name, password.toCharArray()); + } + }); + } + + // Create or append keys to existing keytab file + if (ktab != null) { + File ktabFile = new File(ktab); + switch(mode) { + case APPEND: + if (ktabFile.exists()) { + System.out.println(String.format( + "KDC:append keys to an exising keytab " + + "file %s", ktab)); + kdc.appendKtab(ktab); + } else { + System.out.println(String.format( + "KDC:create a new keytab file %s", ktab)); + kdc.writeKtab(ktab); + } + break; + case EXISTING: + System.out.println(String.format( + "KDC:use an existing keytab file %s", ktab)); + break; + default: + throw new RuntimeException(String.format( + "KDC:unsupported keytab mode: %s", mode)); + } + } + + System.out.println(String.format( + "KDC: started on %s:%s with '%s' realm", + host, kdc.getPort(), realm)); + } catch (Exception e) { + throw new RuntimeException("KDC: unexpected exception", e); + } + + return kdc; + } + /** * Helper class to encapsulate a job in a KDC. */ @@ -1304,13 +1410,20 @@ } public static class KDCNameService implements NameServiceDescriptor { + + public static String NOT_EXISTING_HOST = "not.existing.host"; + @Override public NameService createNameService() throws Exception { NameService ns = new NameService() { @Override public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - // Everything is localhost + // Everything is localhost except NOT_EXISTING_HOST + if (NOT_EXISTING_HOST.equals(host)) { + throw new UnknownHostException("Unknown host name: " + + NOT_EXISTING_HOST); + } return new InetAddress[]{ InetAddress.getByAddress(host, new byte[]{127,0,0,1}) };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/KrbTicket.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.security.auth.RefreshFailedException; +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosTicket; +import javax.security.auth.login.LoginContext; + +/* + * @test + * @bug 6857795 8075299 + * @summary Checks Kerberos ticket properties + * @run main/othervm KrbTicket + */ +public class KrbTicket { + + private static final String REALM = "TEST.REALM"; + private static final String HOST = "localhost"; + private static final String USER = "TESTER"; + private static final String USER_PRINCIPAL = USER + "@" + REALM; + private static final String PASSWORD = "password"; + private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + private static final String KRB5_CONF_FILENAME = "krb5.conf"; + private static final String JAAS_CONF = "jaas.conf"; + private static final long TICKET_LIFTETIME = 5 * 60 * 1000; // 5 mins + + public static void main(String[] args) throws Exception { + // define principals + Map<String, String> principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + + // start a local KDC instance + KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null); + KDC.saveConfig(KRB5_CONF_FILENAME, kdc, + "forwardable = true", "proxiable = true"); + + // create JAAS config + Files.write(Paths.get(JAAS_CONF), Arrays.asList( + "Client {", + " com.sun.security.auth.module.Krb5LoginModule required;", + "};" + )); + System.setProperty("java.security.auth.login.config", JAAS_CONF); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + long startTime = Instant.now().getEpochSecond() * 1000; + + LoginContext lc = new LoginContext("Client", + new Helper.UserPasswordHandler(USER, PASSWORD)); + lc.login(); + + Subject subject = lc.getSubject(); + System.out.println("subject: " + subject); + + Set creds = subject.getPrivateCredentials( + KerberosTicket.class); + + if (creds.size() > 1) { + throw new RuntimeException("Multiple credintials found"); + } + + Object o = creds.iterator().next(); + if (!(o instanceof KerberosTicket)) { + throw new RuntimeException("Instance of KerberosTicket expected"); + } + KerberosTicket krbTkt = (KerberosTicket) o; + + System.out.println("forwardable = " + krbTkt.isForwardable()); + System.out.println("proxiable = " + krbTkt.isProxiable()); + System.out.println("renewable = " + krbTkt.isRenewable()); + System.out.println("current = " + krbTkt.isCurrent()); + + if (!krbTkt.isForwardable()) { + throw new RuntimeException("Forwardable ticket expected"); + } + + if (!krbTkt.isProxiable()) { + throw new RuntimeException("Proxiable ticket expected"); + } + + if (!krbTkt.isCurrent()) { + throw new RuntimeException("Ticket is not current"); + } + + if (krbTkt.isRenewable()) { + throw new RuntimeException("Not renewable ticket expected"); + } + try { + krbTkt.refresh(); + throw new RuntimeException( + "Expected RefreshFailedException not thrown"); + } catch(RefreshFailedException e) { + System.out.println("Expected exception: " + e); + } + + if (!checkTime(krbTkt, startTime)) { + throw new RuntimeException("Wrong ticket life time"); + } + + krbTkt.destroy(); + if (!krbTkt.isDestroyed()) { + throw new RuntimeException("Ticket not destroyed"); + } + + System.out.println("Test passed"); + } + + private static boolean checkTime(KerberosTicket krbTkt, long startTime) { + long ticketEndTime = krbTkt.getEndTime().getTime(); + long roughLifeTime = ticketEndTime - startTime; + System.out.println("start time = " + startTime); + System.out.println("end time = " + ticketEndTime); + System.out.println("rough life time = " + roughLifeTime); + return roughLifeTime >= TICKET_LIFTETIME; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/RefreshKrb5Config.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 4745056 8075297 + * @summary Checks if refreshKrb5Config is set to true for Krb5LoginModule, + * then configuration will be refreshed before login() method is called + * @run main/othervm RefreshKrb5Config + */ +public class RefreshKrb5Config { + + static final String TEST_SRC = System.getProperty("test.src", "."); + static final String HOST = "localhost"; + static final String NOT_EXISTING_HOST = "not.existing.host"; + static final String REALM = "TEST.REALM"; + static final String USER = "USER"; + static final String USER_PRINCIPAL = USER + "@" + REALM; + static final String USER_PASSWORD = "password"; + static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + static final String KRB5_CONF_FILENAME = "krb5.conf"; + + public static void main(String[] args) throws LoginException, IOException { + Map<String, String> principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, USER_PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + + // start a local KDC, and save krb5 config + KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null); + KDC.saveConfig(KRB5_CONF_FILENAME, kdc, "max_retries = 1"); + + System.setProperty("java.security.auth.login.config", + TEST_SRC + File.separator + "refreshKrb5Config.jaas"); + + CallbackHandler handler = new Helper.UserPasswordHandler( + USER, USER_PASSWORD); + + // set incorrect KDC + System.out.println("java.security.krb5.kdc = " + NOT_EXISTING_HOST); + System.setProperty("java.security.krb5.kdc", NOT_EXISTING_HOST); + System.out.println("java.security.krb5.realm = " + REALM); + System.setProperty("java.security.krb5.realm", REALM); + try { + new LoginContext("Refreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // reset properties + System.out.println("Reset java.security.krb5.kdc"); + System.clearProperty("java.security.krb5.kdc"); + System.out.println("Reset java.security.krb5.realm"); + System.clearProperty("java.security.krb5.realm"); + + // login with not-refreshable config + try { + new LoginContext("NotRefreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // login with refreshable config + new LoginContext("Refreshable", handler).login(); + + System.out.println("Test passed"); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/UnboundSSL.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivilegedActionException; +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 8025123 + * @summary Checks if an unbound server can handle connections + * only for allowed service principals + * @run main/othervm/policy=unbound.ssl.policy UnboundSSL + * unbound.ssl.jaas.conf server_star + * @run main/othervm/policy=unbound.ssl.policy UnboundSSL + * unbound.ssl.jaas.conf server_multiple_principals + */ +public class UnboundSSL { + + public static void main(String[] args) throws IOException, + NoSuchAlgorithmException,LoginException, PrivilegedActionException, + InterruptedException { + UnboundSSL test = new UnboundSSL(); + test.start(args[0], args[1]); + } + + private void start(String jaacConfigFile, String serverJaasConfig) + throws IOException, NoSuchAlgorithmException,LoginException, + PrivilegedActionException, InterruptedException { + + // define principals + String service1host = "service1." + UnboundSSLUtils.HOST; + String service2host = "service2." + UnboundSSLUtils.HOST; + String service3host = "service3." + UnboundSSLUtils.HOST; + String service1Principal = "host/" + service1host + "@" + + UnboundSSLUtils.REALM; + String service2Principal = "host/" + service2host + "@" + + UnboundSSLUtils.REALM; + String service3Principal = "host/" + service3host + "@" + + UnboundSSLUtils.REALM; + + Map<String, String> principals = new HashMap<>(); + principals.put(UnboundSSLUtils.USER_PRINCIPAL, + UnboundSSLUtils.USER_PASSWORD); + principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, null); + principals.put(service1Principal, null); + principals.put(service2Principal, null); + principals.put(service3Principal, null); + + System.setProperty("java.security.krb5.conf", + UnboundSSLUtils.KRB5_CONF_FILENAME); + + // start a local KDC instance + KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME, + UnboundSSLUtils.REALM, principals, + UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND); + + System.setProperty("java.security.auth.login.config", + UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + try (final SSLEchoServer server = SSLEchoServer.init( + UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) { + + // start a server instance + UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig); + + // wait for the server is ready + while (!server.isReady()) { + Thread.sleep(UnboundSSLUtils.DELAY); + } + + int port = server.getPort(); + + // run clients + + // the server should have a permission to handle a request + // with this service principal (there should be an appropriate + // javax.security.auth.kerberos.ServicePermission in policy file) + System.out.println("Connect: SNI hostname = " + service1host + + ", successful connection is expected"); + SSLClient.init(UnboundSSLUtils.HOST, port, + UnboundSSLUtils.TLS_KRB5_FILTER, service1host).connect(); + + // the server should NOT have a permission to handle a request + // with this service principal (there should be an appropriate + // javax.security.auth.kerberos.ServicePermission in policy file) + // handshake failures is expected + System.out.println("Connect: SNI hostname = " + service2host + + ", connection failure is expected"); + try { + SSLClient.init(UnboundSSLUtils.HOST, port, + UnboundSSLUtils.TLS_KRB5_FILTER, service2host) + .connect(); + throw new RuntimeException("Test failed: " + + "expected IOException not thrown"); + } catch (IOException e) { + System.out.println("Expected exception: " + e); + } + + // the server should have a permission to handle a request + // with this service principal (there should be an appropriate + // javax.security.auth.kerberos.ServicePermission in policy file) + System.out.println("Connect: SNI hostname = " + service3host + + ", successful connection is expected"); + SSLClient.init(UnboundSSLUtils.HOST, port, + UnboundSSLUtils.TLS_KRB5_FILTER, service3host).connect(); + } + + System.out.println("Test passed"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivilegedActionException; +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 8025123 + * @summary Checks if an unbound server pick up a correct key from keytab + * @run main/othervm UnboundSSLMultipleKeys + * unbound.ssl.jaas.conf server_star + * @run main/othervm UnboundSSLMultipleKeys + * unbound.ssl.jaas.conf server_multiple_principals + */ +public class UnboundSSLMultipleKeys { + + public static void main(String[] args) + throws IOException, NoSuchAlgorithmException, LoginException, + PrivilegedActionException, InterruptedException { + UnboundSSLMultipleKeys test = new UnboundSSLMultipleKeys(); + test.start(args[0], args[1]); + } + + private void start(String jaacConfigFile, String serverJaasConfig) + throws IOException, NoSuchAlgorithmException, LoginException, + PrivilegedActionException, InterruptedException { + + // define service principals + String service1host = "service1." + UnboundSSLUtils.HOST; + String service2host = "service2." + UnboundSSLUtils.HOST; + String service3host = "service3." + UnboundSSLUtils.HOST; + String service1Principal = "host/" + service1host + "@" + + UnboundSSLUtils.REALM; + String service2Principal = "host/" + service2host + "@" + + UnboundSSLUtils.REALM; + String service3Principal = "host/" + service3host + "@" + + UnboundSSLUtils.REALM; + + Map<String, String> principals = new HashMap<>(); + principals.put(UnboundSSLUtils.USER_PRINCIPAL, + UnboundSSLUtils.USER_PASSWORD); + principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, "pass"); + principals.put(service1Principal, "pass0"); + principals.put(service1Principal, "pass1"); + principals.put(service1Principal, "pass2"); + principals.put(service2Principal, "pass"); + principals.put(service3Principal, "pass"); + + System.setProperty("java.security.krb5.conf", + UnboundSSLUtils.KRB5_CONF_FILENAME); + + /* + * Start a local KDC instance + * + * Keytab file contains 3 keys (with different KVNO) for service1 + * principal, but password for only one key is the same with the record + * for service1 principal in KDC. + */ + KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME, + UnboundSSLUtils.REALM, principals, + UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND); + + System.setProperty("java.security.auth.login.config", + UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + // start an SSL server instance + try (SSLEchoServer server = SSLEchoServer.init( + UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) { + + UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig); + + // wait for the server is ready + while (!server.isReady()) { + Thread.sleep(UnboundSSLUtils.DELAY); + } + + // run a client + System.out.println("Successful connection is expected"); + SSLClient.init(UnboundSSLUtils.HOST, server.getPort(), + UnboundSSLUtils.TLS_KRB5_FILTER, service1host).connect(); + } + + System.out.println("Test passed"); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivilegedActionException; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 8025123 + * @summary Checks if an unbound server uses a service principal + * from sun.security.krb5.principal system property if specified + * @run main/othervm UnboundSSLPrincipalProperty + * unbound.ssl.jaas.conf server_star + * @run main/othervm UnboundSSLPrincipalProperty + * unbound.ssl.jaas.conf server_multiple_principals + */ +public class UnboundSSLPrincipalProperty { + + public static void main(String[] args) throws IOException, + NoSuchAlgorithmException,LoginException, PrivilegedActionException, + InterruptedException { + UnboundSSLPrincipalProperty test = new UnboundSSLPrincipalProperty(); + test.start(args[0], args[1]); + } + + public void start(String jaacConfigFile, String serverJaasConfig) + throws IOException, NoSuchAlgorithmException,LoginException, + PrivilegedActionException, InterruptedException { + + // define principals + String service1host = "service1." + UnboundSSLUtils.HOST; + String service3host = "service3." + UnboundSSLUtils.HOST; + String service1Principal = "host/" + service1host + "@" + + UnboundSSLUtils.REALM; + String service3Principal = "host/" + service3host + + "@" + UnboundSSLUtils.REALM; + + Map<String, String> principals = new HashMap<>(); + principals.put(UnboundSSLUtils.USER_PRINCIPAL, + UnboundSSLUtils.USER_PASSWORD); + principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, null); + principals.put(service1Principal, null); + principals.put(service3Principal, null); + + System.setProperty("java.security.krb5.conf", + UnboundSSLUtils.KRB5_CONF_FILENAME); + + // start a local KDC instance + KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME, + UnboundSSLUtils.REALM, principals, + UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND); + + System.setProperty("java.security.auth.login.config", + UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + // start an SSL server instance + try (final SSLEchoServer server = SSLEchoServer.init( + UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) { + + // specify a service principal for the server + System.setProperty("sun.security.krb5.principal", + service3Principal); + + UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig); + + // wait for the server is ready + while (!server.isReady()) { + Thread.sleep(UnboundSSLUtils.DELAY); + } + + int port = server.getPort(); + + // connetion failure is expected + // since service3 principal was specified to use by the server + System.out.println("Connect: SNI hostname = " + service1host + + ", connection failure is expected"); + try { + SSLClient.init(UnboundSSLUtils.HOST, port, + UnboundSSLUtils.TLS_KRB5_FILTER, service1host) + .connect(); + throw new RuntimeException("Test failed: " + + "expected IOException not thrown"); + } catch (IOException e) { + System.out.println("Expected exception: " + e); + } + + System.out.println("Connect: SNI hostname = " + service3host + + ", successful connection is expected"); + SSLClient.init(UnboundSSLUtils.HOST, port, + UnboundSSLUtils.TLS_KRB5_FILTER, service3host).connect(); + } + + System.out.println("Test passed"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/UnboundSSLUtils.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SNIServerName; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * Helper class for unbound krb5 tests. + */ +class UnboundSSLUtils { + + static final String KTAB_FILENAME = "krb5.keytab.data"; + static final String HOST = "localhost"; + static final String REALM = "TEST.REALM"; + static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + static final String TEST_SRC = System.getProperty("test.src", "."); + static final String TLS_KRB5_FILTER = "TLS_KRB5"; + static final String USER = "USER"; + static final String USER_PASSWORD = "password"; + static final String FS = System.getProperty("file.separator"); + static final String SNI_PATTERN = ".*"; + static final String USER_PRINCIPAL = USER + "@" + REALM; + static final String KRB5_CONF_FILENAME = "krb5.conf"; + static final int DELAY = 1000; + + static String[] filterStringArray(String[] src, String filter) { + return Arrays.stream(src).filter((item) -> item.startsWith(filter)) + .toArray(size -> new String[size]); + } + + /* + * The method does JAAS login, + * and runs an SSL server in the JAAS context. + */ + static void startServerWithJaas(final SSLEchoServer server, + String config) throws LoginException, PrivilegedActionException { + LoginContext context = new LoginContext(config); + context.login(); + System.out.println("Server: successful authentication"); + Subject.doAs(context.getSubject(), + (PrivilegedExceptionAction<Object>) () -> { + SSLEchoServer.startServer(server); + return null; + }); + } + +} + +class SSLClient { + + private final static byte[][] arrays = { + new byte[] {-1, 0, 2}, + new byte[] {} + }; + + private final SSLSocket socket; + + private SSLClient(SSLSocket socket) { + this.socket = socket; + } + + void connect() throws IOException { + System.out.println("Client: connect to server"); + try (BufferedInputStream bis = new BufferedInputStream( + socket.getInputStream()); + BufferedOutputStream bos = new BufferedOutputStream( + socket.getOutputStream())) { + + for (byte[] bytes : arrays) { + System.out.println("Client: send byte array: " + + Arrays.toString(bytes)); + + bos.write(bytes); + bos.flush(); + + byte[] recieved = new byte[bytes.length]; + int read = bis.read(recieved, 0, bytes.length); + if (read < 0) { + throw new IOException("Client: couldn't read a response"); + } + + System.out.println("Client: recieved byte array: " + + Arrays.toString(recieved)); + + if (!Arrays.equals(bytes, recieved)) { + throw new IOException("Client: sent byte array " + + "is not equal with recieved byte array"); + } + } + socket.getSession().invalidate(); + } finally { + if (!socket.isClosed()) { + socket.close(); + } + } + } + + static SSLClient init(String host, int port, String cipherSuiteFilter, + String sniHostName) throws NoSuchAlgorithmException, IOException { + SSLContext sslContext = SSLContext.getDefault(); + SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory(); + SSLSocket socket = (SSLSocket) ssf.createSocket(host, port); + SSLParameters params = new SSLParameters(); + + if (cipherSuiteFilter != null) { + String[] cipherSuites = UnboundSSLUtils.filterStringArray( + ssf.getSupportedCipherSuites(), cipherSuiteFilter); + System.out.println("Client: enabled cipher suites: " + + Arrays.toString(cipherSuites)); + params.setCipherSuites(cipherSuites); + } + + if (sniHostName != null) { + System.out.println("Client: set SNI hostname: " + sniHostName); + SNIHostName serverName = new SNIHostName(sniHostName); + List<SNIServerName> serverNames = new ArrayList<>(); + serverNames.add(serverName); + params.setServerNames(serverNames); + } + + socket.setSSLParameters(params); + + return new SSLClient(socket); + } + +} + +class SSLEchoServer implements Runnable, AutoCloseable { + + private final SSLServerSocket ssocket; + private volatile boolean stopped = false; + private volatile boolean ready = false; + + /* + * Starts the server in a separate thread. + */ + static void startServer(SSLEchoServer server) { + Thread serverThread = new Thread(server, "SSL echo server thread"); + serverThread.setDaemon(true); + serverThread.start(); + } + + private SSLEchoServer(SSLServerSocket ssocket) { + this.ssocket = ssocket; + } + + /* + * Main server loop. + */ + @Override + public void run() { + System.out.println("Server: started"); + while (!stopped) { + ready = true; + try (SSLSocket socket = (SSLSocket) ssocket.accept()) { + System.out.println("Server: client connection accepted"); + try ( + BufferedInputStream bis = new BufferedInputStream( + socket.getInputStream()); + BufferedOutputStream bos = new BufferedOutputStream( + socket.getOutputStream()) + ) { + byte[] buffer = new byte[1024]; + int read; + while ((read = bis.read(buffer)) > 0) { + bos.write(buffer, 0, read); + System.out.println("Server: recieved " + read + + " bytes: " + + Arrays.toString(Arrays.copyOf(buffer, read))); + bos.flush(); + } + } + } catch (IOException e) { + if (stopped) { + // stopped == true means that stop() method was called, + // so just ignore the exception, and finish the loop + break; + } + System.out.println("Server: couldn't accept client connection: " + + e); + } + } + System.out.println("Server: finished"); + } + + boolean isReady() { + return ready; + } + + void stop() { + stopped = true; + ready = false; + + // close the server socket to interupt accept() method + try { + if (!ssocket.isClosed()) { + ssocket.close(); + } + } catch (IOException e) { + throw new RuntimeException("Unexpected exception: " + e); + } + } + + @Override + public void close() { + stop(); + } + + int getPort() { + return ssocket.getLocalPort(); + } + + /* + * Creates server instance. + * + * @param cipherSuiteFilter Filter for enabled cipher suites + * @param sniMatcherPattern Pattern for SNI server hame + */ + static SSLEchoServer init(String cipherSuiteFilter, + String sniPattern) throws NoSuchAlgorithmException, IOException { + SSLContext context = SSLContext.getDefault(); + SSLServerSocketFactory ssf = + (SSLServerSocketFactory) context.getServerSocketFactory(); + SSLServerSocket ssocket = + (SSLServerSocket) ssf.createServerSocket(0); + + // specify enabled cipher suites + if (cipherSuiteFilter != null) { + String[] ciphersuites = UnboundSSLUtils.filterStringArray( + ssf.getSupportedCipherSuites(), cipherSuiteFilter); + System.out.println("Server: enabled cipher suites: " + + Arrays.toString(ciphersuites)); + ssocket.setEnabledCipherSuites(ciphersuites); + } + + // specify SNI matcher pattern + if (sniPattern != null) { + System.out.println("Server: set SNI matcher: " + sniPattern); + SNIMatcher matcher = SNIHostName.createSNIMatcher(sniPattern); + List<SNIMatcher> matchers = new ArrayList<>(); + matchers.add(matcher); + SSLParameters params = ssocket.getSSLParameters(); + params.setSNIMatchers(matchers); + ssocket.setSSLParameters(params); + } + + return new SSLEchoServer(ssocket); + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8075301 + * @library /sun/security/krb5/auto + * @summary New test for sun.security.krb5.principal system property. + * The principal can set using the system property sun.security.krb5.principal. + * This property is checked during login. If this property is not set, + * then the principal name from the configuration is used. + * @run main/othervm/java.security.policy=principalSystemPropTest.policy + * PrincipalSystemPropTest + */ + +import java.io.File; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.security.auth.login.LoginException; +import javax.security.auth.login.LoginContext; +import com.sun.security.auth.callback.TextCallbackHandler; + +public class PrincipalSystemPropTest { + + private static final boolean PASS = Boolean.TRUE; + private static final boolean FAIL = Boolean.FALSE; + private static final String VALID_PRINCIPAL_JAAS_ENTRY = + "ValidPrincipalSystemPropTest"; + private static final String INVALID_PRINCIPAL_JAAS_ENTRY = + "InvalidPrincipalSystemPropTest"; + private static final String NO_PRINCIPAL_JAAS_ENTRY = + "NoPrincipalSystemPropTest"; + private static final String SAME_PRINCIPAL_JAAS_ENTRY = + "SelfPrincipalSystemPropTest"; + private static final String HOST = "localhost"; + private static final String KTAB_FILENAME = "krb5.keytab.data"; + private static final String REALM = "TEST.REALM"; + private static final String TEST_SRC = System.getProperty("test.src", "."); + private static final String USER = "USER"; + private static final String AVAILABLE_USER = "AVAILABLE"; + private static final String USER_PASSWORD = "password"; + private static final String FS = System.getProperty("file.separator"); + private static final String KRB5_CONF_FILENAME = "krb5.conf"; + private static final String JAAS_CONF_FILENAME = "jaas.conf"; + private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + private static final String USER_PRINCIPAL = USER + "@" + REALM; + private static final String AVAILABLE_USER_PRINCIPAL = + AVAILABLE_USER + "@" + REALM; + + public static void main(String[] args) throws Exception { + + setupTest(); + + // Expected result, Jaas Config Entry, Login Principal Expected, + // Principal passed through System property + runTest(PASS, VALID_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + runTest(PASS, VALID_PRINCIPAL_JAAS_ENTRY, + AVAILABLE_USER_PRINCIPAL, null); + runTest(PASS, INVALID_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + runTest(FAIL, INVALID_PRINCIPAL_JAAS_ENTRY, null, null); + runTest(PASS, NO_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + runTest(FAIL, NO_PRINCIPAL_JAAS_ENTRY, null, null); + runTest(PASS, SAME_PRINCIPAL_JAAS_ENTRY, + USER_PRINCIPAL, "USER@TEST.REALM"); + + } + + private static void setupTest() { + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + System.setProperty("java.security.auth.login.config", + TEST_SRC + FS + JAAS_CONF_FILENAME); + + Map<String, String> principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, USER_PASSWORD); + principals.put(AVAILABLE_USER_PRINCIPAL, USER_PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + KDC.startKDC(HOST, KRB5_CONF_FILENAME, REALM, principals, + KTAB_FILENAME, KDC.KtabMode.APPEND); + + } + + private static void runTest(boolean expected, String jaasConfigEntry, + String expectedLoginUser, String loginUserBySysProp) { + + if(loginUserBySysProp != null) { + System.setProperty("sun.security.krb5.principal", + loginUserBySysProp); + } else { + System.clearProperty("sun.security.krb5.principal"); + } + + try { + LoginContext lc = new LoginContext(jaasConfigEntry, + new TextCallbackHandler()); + lc.login(); + System.out.println(String.format( + "Authentication completed with Subject '%s' ", + lc.getSubject())); + + if (!expected) { + throw new RuntimeException( + "TEST FAILED - JAAS login success isn't expected"); + } + if(expectedLoginUser != null && !lc.getSubject().getPrincipals() + .stream().map(p -> p.getName()).filter( + expectedLoginUser :: equals).findFirst() + .isPresent()) { + throw new RuntimeException(String.format( + "TEST FAILED - Login principal is not matched " + + "to expected principal '%s'.", expectedLoginUser)); + } + System.out.println( + "TEST PASSED - JAAS login success is expected."); + } catch (LoginException ie) { + System.out.println(String.format( + "Authentication failed with exception: %s", + ie.getMessage())); + if (expected) { + System.out.println( + "TEST FAILED - JAAS login failure isn't expected"); + throw new RuntimeException(ie); + } + System.out.println( + "TEST PASSED - JAAS login failure is expected."); + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/principalProperty/jaas.conf Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,34 @@ +NoPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; + +InvalidPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + principal="UNAVAILABLE@TEST.REALM" + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; + +ValidPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + principal="AVAILABLE@TEST.REALM" + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +}; + +SelfPrincipalSystemPropTest { + com.sun.security.auth.module.Krb5LoginModule required + principal="USER@TEST.REALM" + useKeyTab = true + keyTab = krb5.keytab.data + doNotPrompt =true + debug=true; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,21 @@ +grant { + permission javax.security.auth.AuthPermission + "createLoginContext.ValidPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission + "createLoginContext.InvalidPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission + "createLoginContext.NoPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission + "createLoginContext.SelfPrincipalSystemPropTest"; + permission javax.security.auth.AuthPermission "doAs"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission javax.security.auth.AuthPermission "getSubject"; + permission java.util.PropertyPermission "*", "read,write"; + permission java.io.FilePermission "*", "read,write,delete"; + permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; + permission java.lang.RuntimePermission "accessClassInPackage.*"; + permission java.net.SocketPermission "*:*", + "listen,resolve,accept,connect"; +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/refreshKrb5Config.jaas Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,11 @@ +Refreshable { + com.sun.security.auth.module.Krb5LoginModule required + useTicketCache=false + refreshKrb5Config=true; +}; + +NotRefreshable { + com.sun.security.auth.module.Krb5LoginModule required + useTicketCache=false + refreshKrb5Config=false; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.net.PortUnreachableException; +import java.util.HashMap; +import java.util.Map; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.OutputAnalyzer; + +/* + * @test + * @bug 6857795 8075299 + * @summary Checks if kinit uses both krb5 conf file and system properties + * @requires os.family == "windows" + * @library /lib/testlibrary + * @library /sun/security/krb5/auto + * @run main/othervm KinitConfPlusProps + */ +public class KinitConfPlusProps { + + private static final String KINIT = System.getProperty("java.home") + + File.separator + "bin" + File.separator + "kinit"; + private static final String KLIST = System.getProperty("java.home") + + File.separator + "bin" + File.separator + "klist"; + private static final String REALM = "REALM"; + private static final String ANOTHER_REALM = "ANOTHER.REALM"; + private static final String HOST = "localhost"; + private static final String CC_FILENAME = "krb5cc_test"; + private static final String USER = "TESTER"; + private static final String USER_PRINCIPAL = USER + "@" + REALM; + private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + private static final String KEYTAB_FILE = "test.keytab"; + private static final String KRB5_CONF_FILENAME = "krb5.conf"; + + public static void main(String[] args) throws Exception { + // define principals + Map<String, String> principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, null); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + + // start a local KDC instance + KDC kdc = KDC.startKDC(HOST, null, REALM, principals, KEYTAB_FILE, + KDC.KtabMode.APPEND); + KDC.saveConfig(KRB5_CONF_FILENAME, kdc, + "forwardable = true", "proxiable = true"); + + boolean success = true; + + /* + * kinit should fail since java.security.krb5.kdc + * and java.security.krb5.realm properties override correct values + * in krb5 conf file + */ + String[] command = {KINIT, "-k", + "-J-Djava.security.krb5.realm=" + REALM, + "-J-Djava.security.krb5.kdc=" + HOST, // without port + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(-1); + out.shouldContain(PortUnreachableException.class.getName()); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + /* + * kinit should succeed + * since realm should be picked up from principal name + */ + command = new String[] {KINIT, "-k", + "-J-Djava.security.krb5.realm=" + ANOTHER_REALM, + "-J-Djava.security.krb5.kdc=" + HOST, + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER_PRINCIPAL + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain(CC_FILENAME); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + success &= checkTicketFlags(); + + /* + * kinit should succeed + * since realm should be picked up from principal name, + * and other data should come from krb5 conf file + */ + command = new String[] {KINIT, "-k", + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER_PRINCIPAL + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain(CC_FILENAME); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + success &= checkTicketFlags(); + + // kinit should succeed even if a principal name doesn't have realm + command = new String[] {KINIT, "-k", + "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME, + "-t", KEYTAB_FILE, + "-c", CC_FILENAME, + USER + }; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain(CC_FILENAME); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + + success &= checkTicketFlags(); + + if (!success) { + throw new RuntimeException("At least one test case failed"); + } + System.out.println("Test passed"); + } + + // check if a ticket has forwardable and proxiable flags + private static boolean checkTicketFlags() { + String[] command = new String[] {KLIST, "-f", "-c", CC_FILENAME}; + + try { + OutputAnalyzer out = ProcessTools.executeCommand(command); + out.shouldHaveExitValue(0); + out.shouldContain("FORWARDABLE"); + out.shouldContain("PROXIABLE"); + } catch(Throwable e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + return false; + } + + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/unbound.ssl.jaas.conf Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,40 @@ +com.sun.net.ssl.client { + com.sun.security.auth.module.Krb5LoginModule required + principal="USER@TEST.REALM" + doNotPrompt=true + useKeyTab=true + keyTab="krb5.keytab.data"; +}; + +server_star { + com.sun.security.auth.module.Krb5LoginModule required + principal="*" + isInitiator=false + useKeyTab=true + keyTab="krb5.keytab.data" + storeKey=true; +}; + +server_multiple_principals { + com.sun.security.auth.module.Krb5LoginModule required + principal="host/service1.localhost@TEST.REALM" + isInitiator=false + useKeyTab=true + keyTab="krb5.keytab.data" + storeKey=true; + + com.sun.security.auth.module.Krb5LoginModule required + principal="host/service2.localhost@TEST.REALM" + isInitiator=false + useKeyTab=true + keyTab="krb5.keytab.data" + storeKey=true; + + com.sun.security.auth.module.Krb5LoginModule required + principal="host/service3.localhost@TEST.REALM" + isInitiator=false + useKeyTab=true + keyTab="krb5.keytab.data" + storeKey=true; +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/unbound.ssl.policy Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,29 @@ +grant { + permission java.util.PropertyPermission "*", "read,write"; + permission java.net.SocketPermission "*:*", "listen,resolve,accept,connect"; + permission java.io.FilePermission "*", "read,write,delete"; + permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; + permission java.lang.RuntimePermission "accessClassInPackage.*"; + permission javax.security.auth.AuthPermission "doAs"; + permission javax.security.auth.AuthPermission "getSubject"; + permission javax.security.auth.AuthPermission + "createLoginContext.server_star"; + permission javax.security.auth.AuthPermission + "createLoginContext.server_multiple_principals"; + permission javax.security.auth.AuthPermission "modifyPrincipals"; + permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab java.security.Principal \"krb5.keytab.data\"", "read"; + + // clients have a permission to use all service principals + permission javax.security.auth.kerberos.ServicePermission "*", "initiate"; + + // server has a service permission + // to accept only service1 and service3 principals + permission javax.security.auth.kerberos.ServicePermission + "host/service1.localhost@TEST.REALM", "accept"; + permission javax.security.auth.kerberos.ServicePermission + "host/service3.localhost@TEST.REALM", "accept"; + + // permission to use SunJCE provider + permission java.security.SecurityPermission "putProviderProperty.SunJCE"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/config/Semicolon.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8160518 + * @summary Semicolon is not recognized as comment starting character + * @run main/othervm Semicolon + */ + +import sun.security.krb5.Config; + +public class Semicolon { + public static void main(String[] args) throws Throwable { + System.setProperty("java.security.krb5.conf", + System.getProperty("test.src", ".") + "/comments.conf"); + Config config = Config.getInstance(); + config.get("section", "value"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/config/comments.conf Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,12 @@ +[section] + +# comment + # comment + # comment + # comment +; comment + ; comment + ; comment + ; comment + +value = true
--- a/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,10 @@ */ import java.io.*; +import java.net.*; +import java.util.*; import java.security.*; +import java.security.cert.*; import javax.net.*; import javax.net.ssl.*; @@ -71,22 +74,34 @@ void doServerSide() throws Exception { // load the key store - KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); - ks.load(null, null); + serverKS = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); + serverKS.load(null, null); System.out.println("Loaded keystore: Windows-MY"); // check key size - checkKeySize(ks); + checkKeySize(serverKS); // initialize the SSLContext KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, null); + kmf.init(serverKS, null); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ks); + tmf.init(serverKS); + TrustManager[] tms = tmf.getTrustManagers(); + if (tms == null || tms.length == 0) { + throw new Exception("unexpected trust manager implementation"); + } else { + if (!(tms[0] instanceof X509TrustManager)) { + throw new Exception("unexpected trust manager" + + " implementation: " + + tms[0].getClass().getCanonicalName()); + } + } + serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]); + tms = new TrustManager[] {serverTM}; SSLContext ctx = SSLContext.getInstance("TLS"); - ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + ctx.init(kmf.getKeyManagers(), tms, null); ServerSocketFactory ssf = ctx.getServerSocketFactory(); SSLServerSocket sslServerSocket = (SSLServerSocket) @@ -228,6 +243,8 @@ Thread clientThread = null; Thread serverThread = null; + KeyStore serverKS; + MyExtendedX509TM serverTM; /* * Primary constructor, used to drive remainder of the test. @@ -348,5 +365,60 @@ } } } + + + class MyExtendedX509TM extends X509ExtendedTrustManager + implements X509TrustManager { + + X509TrustManager tm; + + MyExtendedX509TM(X509TrustManager tm) { + this.tm = tm; + } + + public void checkClientTrusted(X509Certificate chain[], String authType) + throws CertificateException { + tm.checkClientTrusted(chain, authType); + } + + public void checkServerTrusted(X509Certificate chain[], String authType) + throws CertificateException { + tm.checkServerTrusted(chain, authType); + } + + public X509Certificate[] getAcceptedIssuers() { + List<X509Certificate> certs = new ArrayList<>(); + try { + for (X509Certificate c : tm.getAcceptedIssuers()) { + if (serverKS.getCertificateAlias(c).equals(keyAlias)) + certs.add(c); + } + } catch (KeyStoreException kse) { + throw new RuntimeException(kse); + } + return certs.toArray(new X509Certificate[certs.size()]); + } + + public void checkClientTrusted(X509Certificate[] chain, String authType, + Socket socket) throws CertificateException { + tm.checkClientTrusted(chain, authType); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType, + Socket socket) throws CertificateException { + tm.checkServerTrusted(chain, authType); + } + + public void checkClientTrusted(X509Certificate[] chain, String authType, + SSLEngine engine) throws CertificateException { + tm.checkClientTrusted(chain, authType); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType, + SSLEngine engine) throws CertificateException { + tm.checkServerTrusted(chain, authType); + } + } + }
--- a/test/sun/security/pkcs11/PKCS11Test.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/pkcs11/PKCS11Test.java Thu Jan 12 06:59:38 2017 +0000 @@ -34,6 +34,8 @@ public abstract class PKCS11Test { + static final String PKCS11 = "PKCS11"; + // directory of the test source static final String BASE = System.getProperty("test.src", "."); @@ -568,6 +570,14 @@ } } + static byte[] generateData(int length) { + byte data[] = new byte[length]; + for (int i=0; i<data.length; i++) { + data[i] = (byte) (i % 256); + } + return data; + } + <T> T[] concat(T[] a, T[] b) { if ((b == null) || (b.length == 0)) { return a;
--- a/test/sun/security/pkcs11/Secmod/AddPrivateKey.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/pkcs11/Secmod/AddPrivateKey.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,13 @@ // all providers. public class AddPrivateKey extends SecmodTest { + private static final String ALIAS1 = "entry1"; + private static final String ALIAS2 = "entry2"; + private static final String ALIAS3 = "entry3"; + private static final int MAX_LINE = 85; + private static final int DATA_LENGTH = 4096; + private static final byte[] DATA = generateData(DATA_LENGTH); + public static void main(String[] args) throws Exception { if (initSecmod() == false) { return; @@ -56,7 +63,7 @@ System.out.println(); Security.addProvider(p); - KeyStore ks = KeyStore.getInstance("PKCS11", p); + KeyStore ks = KeyStore.getInstance(PKCS11, p); ks.load(null, password); for (String alias : aliases(ks)) { System.out.println("Deleting: " + alias); @@ -64,25 +71,28 @@ } KeyStore jks = KeyStore.getInstance("JKS"); - InputStream in = new FileInputStream(new File(BASE, "keystore.jks")); - char[] jkspass = "passphrase".toCharArray(); - jks.load(in, jkspass); - List<PrivateKeyEntry> entries = new ArrayList<PrivateKeyEntry>(); - for (String alias : Collections.list(jks.aliases())) { - if (jks.entryInstanceOf(alias, PrivateKeyEntry.class)) { - PrivateKeyEntry entry = (PrivateKeyEntry)jks.getEntry(alias, new PasswordProtection(jkspass)); - String algorithm = entry.getPrivateKey().getAlgorithm(); - System.out.println("-Entry " + alias + " (" + algorithm + ")"); - if ((supportsEC == false) && algorithm.equals("EC")) { - System.out.println("EC not supported by provider, skipping"); - continue; - } - if ((supportsEC == false) && algorithm.equals("DSA")) { - System.out.println("Provider does not appear to have CKA_NETSCAPE_DB fix, skipping"); - continue; - } - test(p, entry); - } // else ignore + try (InputStream in = new FileInputStream(BASE + SEP + "keystore.jks")) { + char[] jkspass = "passphrase".toCharArray(); + jks.load(in, jkspass); + for (String alias : Collections.list(jks.aliases())) { + if (jks.entryInstanceOf(alias, PrivateKeyEntry.class)) { + PrivateKeyEntry entry = (PrivateKeyEntry)jks.getEntry(alias, + new PasswordProtection(jkspass)); + String algorithm = entry.getPrivateKey().getAlgorithm(); + System.out.printf("-Entry %s (%s)%n", alias, algorithm); + if ((supportsEC == false) && algorithm.equals("EC")) { + System.out.println("EC not supported by provider, " + + "skipping"); + continue; + } + if ((supportsEC == false) && algorithm.equals("DSA")) { + System.out.println("Provider does not appear to have " + + "CKA_NETSCAPE_DB fix, skipping"); + continue; + } + test(p, entry); + } // else ignore + } } System.out.println("OK"); } @@ -91,10 +101,6 @@ return Collections.list(ks.aliases()); } - private final static String ALIAS1 = "entry1"; - private final static String ALIAS2 = "entry2"; - private final static String ALIAS3 = "entry3"; - private static void test(Provider p, PrivateKeyEntry entry) throws Exception { PrivateKey key = entry.getPrivateKey(); X509Certificate[] chain = (X509Certificate[])entry.getCertificateChain(); @@ -121,11 +127,8 @@ PrivateKey key2 = (PrivateKey)ks.getKey(ALIAS1, null); System.out.println(toString(key2)); - X509Certificate[] chain2 = (X509Certificate[])ks.getCertificateChain(ALIAS1); - // NSS makes token keys always sensitive, skip this check -// if (key.equals(key2) == false) { -// throw new Exception("key mismatch"); -// } + X509Certificate[] chain2 = + (X509Certificate[]) ks.getCertificateChain(ALIAS1); if (Arrays.equals(chain, chain2) == false) { throw new Exception("chain mismatch"); } @@ -153,7 +156,8 @@ PrivateKey key4 = (PrivateKey)ks.getKey(ALIAS2, null); System.out.println(toString(key4)); - X509Certificate[] chain4 = (X509Certificate[])ks.getCertificateChain(ALIAS2); + X509Certificate[] chain4 = (X509Certificate[]) + ks.getCertificateChain(ALIAS2); if (Arrays.equals(chain, chain4) == false) { throw new Exception("chain mismatch"); } @@ -171,7 +175,8 @@ PrivateKey key5 = (PrivateKey)ks.getKey(ALIAS3, null); System.out.println(toString(key5)); - X509Certificate[] chain5 = (X509Certificate[])ks.getCertificateChain(ALIAS3); + X509Certificate[] chain5 = (X509Certificate[]) + ks.getCertificateChain(ALIAS3); if (Arrays.equals(chain, chain5) == false) { throw new Exception("chain mismatch"); } @@ -185,24 +190,22 @@ System.out.println("OK"); } - private final static byte[] DATA = new byte[4096]; - - static { - Random random = new Random(); - random.nextBytes(DATA); - } - - private static void sign(Provider p, PrivateKey privateKey, PublicKey publicKey) throws Exception { + private static void sign(Provider p, PrivateKey privateKey, + PublicKey publicKey) throws Exception { String keyAlg = privateKey.getAlgorithm(); String alg; - if (keyAlg.equals("RSA")) { - alg = "SHA1withRSA"; - } else if (keyAlg.equals("DSA")) { - alg = "SHA1withDSA"; - } else if (keyAlg.equals("EC")) { - alg = "SHA1withECDSA"; - } else { - throw new Exception("Unknown algorithm " + keyAlg); + switch (keyAlg) { + case "RSA": + alg = "SHA1withRSA"; + break; + case "DSA": + alg = "SHA1withDSA"; + break; + case "EC": + alg = "SHA1withECDSA"; + break; + default: + throw new Exception("Unknown algorithm " + keyAlg); } Signature s = Signature.getInstance(alg, p); s.initSign(privateKey); @@ -216,8 +219,6 @@ } } - private final static int MAX_LINE = 85; - private static String toString(Object o) { String s = String.valueOf(o).split("\n")[0]; return (s.length() <= MAX_LINE) ? s : s.substring(0, MAX_LINE);
--- a/test/sun/security/pkcs11/Secmod/AddTrustedCert.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/pkcs11/Secmod/AddTrustedCert.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,29 +44,47 @@ return; } - InputStream in = new FileInputStream(BASE + SEP + "anchor.cer"); - CertificateFactory factory = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate)factory.generateCertificate(in); - in.close(); -// System.out.println(cert); + X509Certificate cert; + try (InputStream in = new FileInputStream(BASE + SEP + "anchor.cer")) { + CertificateFactory factory = + CertificateFactory.getInstance("X.509"); + cert = (X509Certificate)factory.generateCertificate(in); + } String configName = BASE + SEP + "nss.cfg"; Provider p = getSunPKCS11(configName); System.out.println(p); Security.addProvider(p); - KeyStore ks = KeyStore.getInstance("PKCS11", p); + KeyStore ks = KeyStore.getInstance(PKCS11, p); ks.load(null, password); - Collection<String> aliases = new TreeSet<String>(Collections.list(ks.aliases())); + Collection<String> aliases = new TreeSet<>(Collections.list( + ks.aliases())); System.out.println("entries: " + aliases.size()); System.out.println(aliases); int size1 = aliases.size(); String alias = "anchor"; - ks.setCertificateEntry(alias, cert); + if (ks.containsAlias(alias)) { + throw new Exception("Alias exists: " + alias); + } + ks.setCertificateEntry(alias, cert); + KeyStore.Entry first = ks.getEntry(alias, null); + System.out.println("first entry = " + first); + if (!ks.entryInstanceOf(alias, TrustedCertificateEntry.class)) { + throw new Exception("Unexpected first entry type: " + first); + } - aliases = new TreeSet<String>(Collections.list(ks.aliases())); + ks.setCertificateEntry(alias, cert); + KeyStore.Entry second = ks.getEntry(alias, null); + System.out.println("second entry = " + second); + if (!ks.entryInstanceOf(alias, TrustedCertificateEntry.class)) { + throw new Exception("Unexpected second entry type: " + + second); + } + + aliases = new TreeSet<>(Collections.list(ks.aliases())); System.out.println("entries: " + aliases.size()); System.out.println(aliases); int size2 = aliases.size(); @@ -79,8 +97,12 @@ throw new Exception("KeyStore returned incorrect certificate"); } + ks.deleteEntry(alias); + if (ks.containsAlias(alias)) { + throw new Exception("Alias still exists: " + alias); + } + System.out.println("OK"); - } }
--- a/test/sun/security/pkcs11/Secmod/Crypto.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/pkcs11/Secmod/Crypto.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ * @run main/othervm Crypto */ -import java.util.*; - import java.security.*; public class Crypto extends SecmodTest { @@ -50,9 +48,7 @@ System.out.println(kp.getPublic()); System.out.println(kp.getPrivate()); - SecureRandom random = new SecureRandom(); - byte[] data = new byte[2048]; - random.nextBytes(data); + byte[] data = generateData(2048); Signature sig = Signature.getInstance("SHA1withRSA", p); sig.initSign(kp.getPrivate());
--- a/test/sun/security/pkcs11/Secmod/GetPrivateKey.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/pkcs11/Secmod/GetPrivateKey.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,18 +48,17 @@ System.out.println(p); Security.addProvider(p); - KeyStore ks = KeyStore.getInstance("PKCS11", p); + KeyStore ks = KeyStore.getInstance(PKCS11, p); ks.load(null, password); - Collection<String> aliases = new TreeSet<String>(Collections.list(ks.aliases())); + Collection<String> aliases = new TreeSet<>( + Collections.list(ks.aliases())); System.out.println("entries: " + aliases.size()); System.out.println(aliases); PrivateKey privateKey = (PrivateKey)ks.getKey(keyAlias, password); System.out.println(privateKey); - byte[] data = new byte[1024]; - Random random = new Random(); - random.nextBytes(data); + byte[] data = generateData(1024); System.out.println("Signing..."); Signature signature = Signature.getInstance("MD5withRSA"); @@ -67,7 +66,8 @@ signature.update(data); byte[] sig = signature.sign(); - X509Certificate[] chain = (X509Certificate[])ks.getCertificateChain(keyAlias); + X509Certificate[] chain = + (X509Certificate[]) ks.getCertificateChain(keyAlias); signature.initVerify(chain[0].getPublicKey()); signature.update(data); boolean ok = signature.verify(sig);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/pkcs11/Secmod/LoadKeystore.java Thu Jan 12 06:59:38 2017 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Provider; +import java.security.Security; +import java.security.UnrecoverableKeyException; +import java.util.Collections; + +/* + * @test + * @bug 8048622 8134232 + * @summary Checks that PKCS#11 keystore can't be loaded with wrong password + * @library ../ + * @run main/othervm LoadKeystore + */ +public class LoadKeystore extends SecmodTest { + + public static void main(String[] args) throws Exception { + if (!initSecmod()) { + return; + } + + String configName = BASE + SEP + "nss.cfg"; + Provider p = getSunPKCS11(configName); + + System.out.println("Add provider " + p); + System.out.println(); + Security.addProvider(p); + + try { + System.out.println("Load keystore with wrong type"); + KeyStore.getInstance("unknown", p); + throw new RuntimeException("Expected exception not thrown"); + } catch(KeyStoreException e) { + System.out.println("Expected exception: " + e); + } + + KeyStore ks = KeyStore.getInstance("PKCS11", p); + if (!"PKCS11".equals(ks.getType())) { + throw new RuntimeException("Unexpected keystore type: " + + ks.getType()); + } + if (!p.equals(ks.getProvider())) { + throw new RuntimeException("Unexpected keystore provider: " + + ks.getProvider()); + } + + try { + System.out.println("Load keystore with wrong password"); + ks.load(null, "wrong".toCharArray()); + throw new RuntimeException("Expected exception not thrown"); + } catch(IOException e) { + System.out.println("Expected exception: " + e); + Throwable cause = e.getCause(); + if (!(cause instanceof UnrecoverableKeyException)) { + e.printStackTrace(System.out); + throw new RuntimeException("Unexpected cause: " + cause); + } + System.out.println("Expected cause: " + cause); + } + + System.out.println("Load keystore with correct password"); + ks.load(null, password); + for (String alias : Collections.list(ks.aliases())) { + System.out.println("Alias: " + alias); + } + + System.out.println("Test passed"); + } + +}
--- a/test/sun/security/provider/KeyStore/DKSTest.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/provider/KeyStore/DKSTest.java Thu Jan 12 06:59:38 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,8 +60,38 @@ new KeyStore.PasswordProtection("passphrase".toCharArray())); }}; + private static final Map<String, KeyStore.ProtectionParameter> + WRONG_PASSWORDS = new HashMap<String, KeyStore.ProtectionParameter>() {{ + put("policy_keystore", + new KeyStore.PasswordProtection( + "wrong".toCharArray())); + put("pw_keystore", + new KeyStore.PasswordProtection("wrong".toCharArray())); + put("eckeystore1", + new KeyStore.PasswordProtection("wrong".toCharArray())); + put("eckeystore2", + new KeyStore.PasswordProtection("wrong".toCharArray())); + }}; + public static void main(String[] args) throws Exception { /* + * domain keystore: keystores with wrong passwords + */ + try { + URI config = new URI(CONFIG + "#keystores"); + KeyStore ks = KeyStore.getInstance("DKS"); + ks.load(new DomainLoadStoreParameter(config, WRONG_PASSWORDS)); + throw new RuntimeException("Expected exception not thrown"); + } catch (IOException e) { + System.out.println("Expected exception: " + e); + if (!causedBy(e, UnrecoverableKeyException.class)) { + e.printStackTrace(System.out); + throw new RuntimeException("Unexpected cause"); + } + System.out.println("Expected cause: " + e); + } + + /* * domain keystore: system */ URI config = new URI(CONFIG + "#system"); @@ -182,4 +212,15 @@ return factory.generateCertificate(certStream); } } + + // checks if an exception was caused by specified exception class + private static boolean causedBy(Exception e, Class klass) { + Throwable cause = e; + while ((cause = cause.getCause()) != null) { + if (cause.getClass().equals(klass)) { + return true; + } + } + return false; + } }
--- a/test/sun/security/tools/jarsigner/warnings/Test.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/security/tools/jarsigner/warnings/Test.java Thu Jan 12 06:59:38 2017 +0000 @@ -22,11 +22,6 @@ */ import jdk.testlibrary.OutputAnalyzer; -import jdk.testlibrary.ProcessTools; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; /** * Base class. @@ -180,21 +175,4 @@ } analyzer.shouldContain(JAR_SIGNED); } - - protected OutputAnalyzer keytool(String... cmd) throws Throwable { - return tool(KEYTOOL, cmd); - } - - protected OutputAnalyzer jarsigner(String... cmd) throws Throwable { - return tool(JARSIGNER, cmd); - } - - private OutputAnalyzer tool(String tool, String... args) throws Throwable { - List<String> cmd = new ArrayList<>(); - cmd.add(tool); - cmd.add("-J-Duser.language=en"); - cmd.add("-J-Duser.country=US"); - cmd.addAll(Arrays.asList(args)); - return ProcessTools.executeCommand(cmd.toArray(new String[cmd.size()])); - } }
--- a/test/sun/tools/native2ascii/Native2AsciiTests.sh Tue Nov 08 05:26:12 2016 +0000 +++ b/test/sun/tools/native2ascii/Native2AsciiTests.sh Thu Jan 12 06:59:38 2017 +0000 @@ -24,7 +24,7 @@ # # @test -# @bug 4630463 4630971 4636448 4701617 4721296 4710890 6247817 7021987 +# @bug 4630463 4630971 4636448 4701617 4721296 4710890 6247817 7021987 8067964 # @summary Tests miscellaneous native2ascii bugfixes and regressions
--- a/test/tools/launcher/Arrrghs.java Tue Nov 08 05:26:12 2016 +0000 +++ b/test/tools/launcher/Arrrghs.java Thu Jan 12 06:59:38 2017 +0000 @@ -24,7 +24,7 @@ /** * @test * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938 - * 6894719 6968053 7151434 7146424 8007333 8077822 + * 6894719 6968053 7151434 7146424 8007333 8077822 8143640 * @summary Argument parsing validation. * @compile -XDignore.symbol.file Arrrghs.java * @run main/othervm Arrrghs @@ -324,6 +324,8 @@ // more treatment of mixed slashes checkArgumentParsing("f1/ f3\\ f4/", "f1/", "f3\\", "f4/"); checkArgumentParsing("f1/ f2\' ' f3/ f4/", "f1/", "f2\'", "'", "f3/", "f4/"); + + checkArgumentParsing("a\\*\\b", "a\\*\\b"); } private void initEmptyDir(File emptyDir) throws IOException {