private void rethrowDeserializationException(IOException ioe) throws ClassNotFoundException, IOException { // specially treating for an UnmarshalException if (ioe instanceof UnmarshalException) { throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs // fetch one by one with UnmarshalException } else if (ioe instanceof MarshalException) { // IIOP will throw MarshalException wrapping a NotSerializableException // when a server fails to serialize a response. MarshalException me = (MarshalException)ioe; if (me.detail instanceof NotSerializableException) { throw (NotSerializableException)me.detail; } } // Not serialization problem, return. }
@Test(dataProvider = "bindData") public void UnicastServerRef(String name, Object obj, int expectedFilterCount) throws RemoteException { try { RemoteImpl impl = RemoteImpl.create(); UnicastServerRef ref = new UnicastServerRef(new LiveRef(0), impl.checker); Echo client = (Echo) ref.exportObject(impl, null, false); int count = client.filterCount(obj); System.out.printf("count: %d, obj: %s%n", count, obj); Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls"); } catch (RemoteException rex) { if (expectedFilterCount == -1 && UnmarshalException.class.equals(rex.getCause().getClass()) && InvalidClassException.class.equals(rex.getCause().getCause().getClass())) { return; // normal expected exception } rex.printStackTrace(); Assert.fail("unexpected remote exception", rex); } catch (Exception ex) { Assert.fail("unexpected exception", ex); } }
/** * Activate the object for this id. * * @param force if true, forces the activator to contact the group * when activating the object (instead of returning a cached reference); * if false, returning a cached value is acceptable. * @return the reference to the active remote object * @exception ActivationException if activation fails * @exception UnknownObjectException if the object is unknown * @exception RemoteException if remote call fails * @since 1.2 */ public Remote activate(boolean force) throws ActivationException, UnknownObjectException, RemoteException { try { MarshalledObject<? extends Remote> mobj = activator.activate(this, force); return AccessController.doPrivileged( new PrivilegedExceptionAction<Remote>() { public Remote run() throws IOException, ClassNotFoundException { return mobj.get(); } }, NOPERMS_ACC); } catch (PrivilegedActionException pae) { Exception ex = pae.getException(); if (ex instanceof RemoteException) { throw (RemoteException) ex; } else { throw new UnmarshalException("activation failed", ex); } } }
/** * Tells the given client vm to exit. Optionally asks it to disconnect * from GemFire before exiting. */ private static void stopClient( ClientVmRecord vm, boolean closeConnection, boolean runShutdownHook) { log().info( "Issuing stop request to " + vm.toInfoString() ); synchronized( vm ) { if ( vm.getPid() == ClientVmRecord.NO_PID ) { log().info( vm.toInfoString() + " is already stopped" ); return; } ClientRecord cr = vm.getRepresentativeClient(); try { cr.getTestModule().shutDownVM( closeConnection, runShutdownHook ); } catch( UnmarshalException ignore ) { // vm is shutting down, don't expect clean reply } catch( RemoteException e ) { String reason = "Unable to reach client " + cr + " in " + vm; throw new HydraRuntimeException( reason, e ); } } log().info( "Issued stop request to " + vm.toInfoString() ); }
private static void runClientShutdownHook( ClientVmRecord vm ) { log().info( "Running client shutdown hook in " + vm.toInfoString() ); ClientRecord cr = null; synchronized( vm ) { if ( vm.getPid() == ClientVmRecord.NO_PID ) { log().info( vm.toInfoString() + " is stopped: can't run client shutdown hook" ); return; } cr = vm.getRepresentativeClient(); } // must run hook outside vm synchronization since it is a fully synchronous // RMI call that could hang, deadlocking master attempt to do stack dumps, // but all is well since the cr test module is never unset and we already // handle an intervening shutdown try { cr.getTestModule().runShutdownHook( ); } catch( UnmarshalException ignore ) { // vm is shutting down, don't expect clean reply } catch( RemoteException e ) { String reason = "Unable to reach client " + cr + " in " + vm; log().severe(reason, e); } log().info( "Ran client shutdown hook in " + vm.toInfoString() ); }
/** * Write the remote object to the output stream. This method first calls * {@link RemoteRef#getRefClass(ObjectOutput)} on the {@link #ref} to get the * class name without package, writes this name and then calls the * ref.writeObject to write the data. The standard packageless class names are * UnicastRef, UnicastRef2, UnicastServerRef, UnicastServerRef2, * ActivatableRef or ActivatableServerRef. The empty string with the * subsequently following serialized ref instance be written if the * ref.getRefClass returns null. * * @param out the stream to write to * @throws IOException if one occurs during writing * @throws ClassNotFoundException never in this implementation (specified as * part of the API standard) * @throws UnmarshalException if the remote reference of this remote object is * null. */ private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException { if (ref == null) { throw new UnmarshalException("no ref to serialize"); } String cname = ref.getRefClass(out); if (cname != null && cname.length() > 0) { out.writeUTF(cname); ref.writeExternal(out); } else { out.writeUTF(""); out.writeObject(ref); } }
/** * @com.intel.drl.spec_ref */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { String refName = null; try { refName = in.readUTF(); if (refName.length() == 0) { // read RemoteRef object ref = (RemoteRef) in.readObject(); return; } // well-known RemoteRef types // TODO: the following line is a temporary solution. Line after // that should be uncommented later. String refClName = "org.apache.harmony.rmi.remoteref." + refName; //$NON-NLS-1$ //String refClName = RemoteRef.packagePrefix + "." + refName; ref = ((RemoteRef) Class.forName(refClName).newInstance()); ref.readExternal(in); } catch (Exception ex) { // rmi.18=Unable to create RemoteRef instance throw new UnmarshalException(Messages.getString("rmi.18"), ex);//$NON-NLS-1$ } }
private Object[] readParams(Method m, RMIObjectInputStream oin) throws RemoteException { Class[] paramTypes = m.getParameterTypes(); Object[] params = new Object[paramTypes.length]; try { for (int i = 0; i < paramTypes.length; ++i) { params[i] = oin.readRMIObject(paramTypes[i]); } } catch (RemoteException re) { // rmi.69=RemoteException occurred while unmarshalling arguments throw new ServerException(Messages.getString("rmi.69"), re); //$NON-NLS-1$ } catch (IOException ioe) { // rmi.6A=IOException occurred while unmarshalling arguments throw new UnmarshalException(Messages.getString("rmi.6A"), ioe); //$NON-NLS-1$ } catch (ClassNotFoundException cnfe) { // rmi.6B=ClassNotFoundException occurred while unmarshalling arguments throw new UnmarshalException(Messages.getString("rmi.6B"), cnfe); //$NON-NLS-1$ } catch (Error er) { // rmi.6C=Error occurred while unmarshalling arguments throw new ServerError(Messages.getString("rmi.6C"), er); //$NON-NLS-1$ } return params; }
/** * Sends the first dirty for a received reference in order to get the * appropiate lease time from the server, and then schedules the dirty call * for lease renewal. If the first dirty message fails, a clean "strong" * message is sent for that remote object. If the first dirty call * succeeded, the reference becomes a "live" reference for the client DGC. * * @param ref * The reference received inside the stub * @return The <code>Endpoint / ObjID</code> pair contained inside the * reference * @throws UnmarshalException * If the first dirty call fails */ private final Pair<Endpoint, ObjID> activateReference(RemoteRef ref) throws UnmarshalException { // Get necessary data previously stored during RemoteRef // deserialization. Pair<Endpoint, ObjID> data = deserializedRemoteRefTable.get(ref); if (data == null) { throw new UnmarshalException( "Impossible to get a stub for this object."); } Lease lease = sendDirty(data.getFirst(), new ObjID[] { data.getSecond() }); if (lease != null) { enqueueDirtyCall(data, lease.getValue()); liveReferences.put(data, new Long(lease.getValue())); return data; } else { sendClean(data.getFirst(), new ObjID[] { data.getSecond() }, true); throw new UnmarshalException( "Impossible to get a stub for this object."); } }
/******************* * Check if the given endpoint can be attacked. * * This check is performed by executing a dummy attack against the * endpoint and observing the resulting exception. * * @param ep An enumerated RMI endpoint. * @return True if we can attack it. ******************/ public boolean canAttackEndpoint(RMIEndpoint ep) { RMIBindExploitProxy proxy = null; Registry reg; //Execute a dummy attack try { //Start a bind exploit proxy proxy = new RMIBindExploitProxy(InetAddress.getByName(ep.getEndpoint().getHost()), ep.getEndpoint().getPort(), this._options, this._dummyPayload); proxy.startProxy(); //Get a proxied RMI registry reference reg = LocateRegistry.getRegistry(proxy.getServerListenAddress().getHostAddress(), proxy.getServerListenPort()); //Bind a dummy object in an attempt to trigger the vulnerability reg.bind(this.generateRandomString(), new BaRMIeBindExploit()); } catch(BaRMIeException | UnknownHostException | RemoteException | AlreadyBoundException ex) { //An up to date RMI registry will, by default, reject the dummy object if(ex instanceof ServerException && ex.getCause() != null && ex.getCause() instanceof UnmarshalException && ex.getCause().getCause() != null && ex.getCause().getCause() instanceof InvalidClassException) { //Check for "filter status: REJECTED" if(ex.getCause().getCause().toString().contains("filter status: REJECTED")) { //Test payload was filtered, likely this attack isn't possible return false; } } } finally { //Stop the proxy if(proxy != null) { proxy.stopProxy(true); } } //In all other cases we should be able to attack the registry return true; }
private NotificationResult fetchNotifs() { try { NotificationResult nr = ClientNotifForwarder.this. fetchNotifs(clientSequenceNumber,maxNotifications, timeout); if (logger.traceOn()) { logger.trace("NotifFetcher-run", "Got notifications from the server: "+nr); } return nr; } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) { logger.trace("NotifFetcher.fetchNotifs", e); return fetchOneNotif(); } catch (IOException ioe) { if (!shouldStop()) { logger.error("NotifFetcher-run", "Failed to fetch notification, " + "stopping thread. Error is: " + ioe, ioe); logger.debug("NotifFetcher-run",ioe); } // no more fetching return null; } }
private static <T> T unwrap(final MarshalledObject<?> mo, final ClassLoader cl, final Class<T> wrappedClass) throws IOException { if (mo == null) { return null; } try { final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl)); try { return wrappedClass.cast(mo.get()); } catch (ClassNotFoundException cnfe) { throw new UnmarshalException(cnfe.toString(), cnfe); } finally { AccessController.doPrivileged(new SetCcl(old)); } } catch (PrivilegedActionException pe) { Exception e = extractException(pe); if (e instanceof IOException) { throw (IOException) e; } if (e instanceof ClassNotFoundException) { throw new UnmarshalException(e.toString(), e); } logger.warning("unwrap", "Failed to unmarshall object: " + e); logger.debug("unwrap", e); } return null; }
private static <T> T unwrap(final MarshalledObject<?> mo, final ClassLoader cl1, final ClassLoader cl2, final Class<T> wrappedClass) throws IOException { if (mo == null) { return null; } try { ClassLoader orderCL = AccessController.doPrivileged( new PrivilegedExceptionAction<ClassLoader>() { public ClassLoader run() throws Exception { return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), new OrderClassLoaders(cl1, cl2)); } } ); return unwrap(mo, orderCL, wrappedClass); } catch (PrivilegedActionException pe) { Exception e = extractException(pe); if (e instanceof IOException) { throw (IOException) e; } if (e instanceof ClassNotFoundException) { throw new UnmarshalException(e.toString(), e); } logger.warning("unwrap", "Failed to unmarshall object: " + e); logger.debug("unwrap", e); } return null; }
private <T> T unwrap(final MarshalledObject<?> mo, final ClassLoader cl1, final ClassLoader cl2, final Class<T> wrappedClass, Subject delegationSubject) throws IOException { if (mo == null) { return null; } try { ClassLoader orderCL = AccessController.doPrivileged( new PrivilegedExceptionAction<ClassLoader>() { public ClassLoader run() throws Exception { return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), new OrderClassLoaders(cl1, cl2)); } } ); return unwrap(mo, orderCL, wrappedClass,delegationSubject); } catch (PrivilegedActionException pe) { Exception e = extractException(pe); if (e instanceof IOException) { throw (IOException) e; } if (e instanceof ClassNotFoundException) { throw new UnmarshalException(e.toString(), e); } logger.warning("unwrap", "Failed to unmarshall object: " + e); logger.debug("unwrap", e); } return null; }
/** * Handle server-side dispatch using the RMI 1.1 stub/skeleton * protocol, given a non-negative operation number that has * already been read from the call stream. * Exceptions are handled by the caller to be sent to the remote client. * * @param obj the target remote object for the call * @param call the "remote call" from which operation and * method arguments can be obtained. * @param op the operation number * @throws Exception if unable to marshal return result or * release input or output streams */ private void oldDispatch(Remote obj, RemoteCall call, int op) throws Exception { long hash; // hash for matching stub with skeleton // read remote call header ObjectInput in; in = call.getInputStream(); try { Class<?> clazz = Class.forName("sun.rmi.transport.DGCImpl_Skel"); if (clazz.isAssignableFrom(skel.getClass())) { ((MarshalInputStream)in).useCodebaseOnly(); } } catch (ClassNotFoundException ignore) { } try { hash = in.readLong(); } catch (Exception ioe) { throw new UnmarshalException("error unmarshalling call header", ioe); } // if calls are being logged, write out object id and operation logCall(obj, skel.getOperations()[op]); unmarshalCustomCallData(in); // dispatch to skeleton for remote object skel.dispatch(obj, call, op, hash); }
private void rethrowDeserializationException(IOException ioe) throws ClassNotFoundException, IOException { // specially treating for an UnmarshalException if (ioe instanceof UnmarshalException) { NotSerializableException nse = new NotSerializableException(); nse.initCause(ioe); throw nse; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs // fetch one by one with UnmarshalException } // Not serialization problem, return. }