changeset 179:63fe20298326

2008-10-10 Omair Majid <omajid@redhat.com> * src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java (close): Check for audio permissions. (open): Likewise. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java (open): Removed FIXME for security. (close): Likewise. * src/java/org/classpath/icedtea/pulseaudio/Mixer.java (getLine): Check for permissions before returning a line. (getSourceLines): Check for permissions. (getTargetLines): Likewise. (close): Likewise. (openRemote): Likewise. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java (PulseAudioPort): Dont open the port by default. (open): Removed FIXME. (close): Likewise. * src/java/org/classpath/icedtea/pulseaudio/PulseAUdioSourceDataLine.j.ava (open): Check for permissions. (close): Likewise. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java (open): Likewise. (close): Likewise. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java (open): Likewise. (close): Likewise. * src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java (open): Likewise. (close): Likewise. * unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java (testControls): Open and close the ports. * unittests/org/classpath/icedtea/pulseaudio/PulseAUdioTargetPortTest.java (testControls): Likewise.
author Omair Majid <omajid@redhat.com>
date Fri, 10 Oct 2008 11:10:27 -0400
parents d4676ea1be88
children 095b46980d97
files src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java
diffstat 10 files changed, 131 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Fri Oct 10 11:10:27 2008 -0400
@@ -41,6 +41,7 @@
 
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioPermission;
 import javax.sound.sampled.AudioSystem;
 import javax.sound.sampled.Clip;
 import javax.sound.sampled.LineUnavailableException;
@@ -229,12 +230,15 @@
 
 	@Override
 	public void close() {
+
+		/* check for permission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
+
 		if (!isOpen) {
 			throw new IllegalStateException("line already closed");
 		}
 
-		// FIXME security
-		
 		clipThread.interrupt();
 
 		try {
@@ -358,10 +362,11 @@
 			throw new IllegalStateException("Line not open");
 		}
 
-		if ( count < 0 && count != LOOP_CONTINUOUSLY) {
-			throw new IllegalArgumentException("invalid value for count:" + count);
+		if (count < 0 && count != LOOP_CONTINUOUSLY) {
+			throw new IllegalArgumentException("invalid value for count:"
+					+ count);
 		}
-		
+
 		if (clipThread.isAlive() && count != 0) {
 			// Do nothing; behavior not specified by the Java API
 			return;
@@ -392,8 +397,10 @@
 	public void open(AudioFormat format, byte[] data, int offset, int bufferSize)
 			throws LineUnavailableException {
 
-		// FIXME security
-		
+		/* check for permission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
+
 		super.open(format);
 		this.data = new byte[bufferSize];
 		System.arraycopy(data, offset, this.data, 0, bufferSize);
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Fri Oct 10 11:10:27 2008 -0400
@@ -84,8 +84,6 @@
 		if (isOpen) {
 			throw new IllegalStateException("Line is already open");
 		}
-		
-		// FIXME security
 
 		createStream(format);
 		addStreamListeners();
@@ -290,8 +288,6 @@
 					"Line must be open for close() to work");
 		}
 
-		// FIXME security
-		
 		synchronized (eventLoop.threadLock) {
 			stream.disconnect();
 		}
@@ -310,7 +306,7 @@
 
 		isStarted = false;
 	}
-	
+
 	public void reconnectforSynchronization(Stream masterStream)
 			throws LineUnavailableException {
 		sendEvents = false;
@@ -354,7 +350,6 @@
 
 	}
 
-
 	public synchronized void stop() {
 		if (!isOpen) {
 			throw new IllegalStateException(
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java	Fri Oct 10 11:10:27 2008 -0400
@@ -49,6 +49,7 @@
 
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioPermission;
 import javax.sound.sampled.AudioSystem;
 import javax.sound.sampled.Clip;
 import javax.sound.sampled.Control;
@@ -266,8 +267,6 @@
 	@Override
 	public Line getLine(Line.Info info) throws LineUnavailableException {
 
-		// FIXME security!
-		
 		if (!isLineSupported(info)) {
 			throw new IllegalArgumentException("Line unsupported: " + info);
 		}
@@ -302,16 +301,28 @@
 		}
 
 		if ((info.getLineClass() == SourceDataLine.class)) {
+			/* check for permission to play audio */
+			AudioPermission perm = new AudioPermission("play", null);
+			perm.checkGuard(null);
+
 			return new PulseAudioSourceDataLine(eventLoop, formats,
 					defaultFormat);
 		}
 
 		if ((info.getLineClass() == TargetDataLine.class)) {
+			/* check for permission to play audio */
+			AudioPermission perm = new AudioPermission("record", null);
+			perm.checkGuard(null);
+
 			return new PulseAudioTargetDataLine(eventLoop, formats,
 					defaultFormat);
 		}
 
 		if ((info.getLineClass() == Clip.class)) {
+			/* check for permission to play audio */
+			AudioPermission perm = new AudioPermission("play", null);
+			perm.checkGuard(null);
+
 			return new PulseAudioClip(eventLoop, formats, defaultFormat);
 		}
 
@@ -365,9 +376,11 @@
 
 	@Override
 	public Line[] getSourceLines() {
-		
-		// FIXME security
-		
+
+		/* check for permmission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
+
 		return (Line[]) sourceLines.toArray(new Line[0]);
 
 	}
@@ -392,9 +405,11 @@
 
 	@Override
 	public Line[] getTargetLines() {
-		
-		// FIXME security
-		
+
+		/* check for permission to play audio */
+		AudioPermission perm = new AudioPermission("record", null);
+		perm.checkGuard(null);
+
 		return (Line[]) targetLines.toArray(new TargetDataLine[0]);
 	}
 
@@ -477,12 +492,25 @@
 	@Override
 	synchronized public void close() {
 
+		/*
+		 * only allow the mixer to be controlled if either playback or recording
+		 * is allowed
+		 */
+
+		try {
+			/* check for permission to play audio */
+			AudioPermission perm = new AudioPermission("play", null);
+			perm.checkGuard(null);
+		} catch (SecurityException e) {
+			/* check for permission to record audio */
+			AudioPermission perm = new AudioPermission("record", null);
+			perm.checkGuard(null);
+		}
+
 		if (!this.isOpen) {
 			throw new IllegalStateException("Mixer is not open; cant close");
 		}
 
-		// FIXME security
-		
 		eventLoopThread.interrupt();
 
 		try {
@@ -573,12 +601,25 @@
 	synchronized public void openRemote(String appName, String host,
 			Integer port) throws UnknownHostException, LineUnavailableException {
 
+		/*
+		 * only allow the mixer to be controlled if either playback or recording
+		 * is allowed
+		 */
+
+		try {
+			/* check for permission to play audio */
+			AudioPermission perm = new AudioPermission("play", null);
+			perm.checkGuard(null);
+		} catch (SecurityException e) {
+			/* check for permission to record audio */
+			AudioPermission perm = new AudioPermission("record", null);
+			perm.checkGuard(null);
+		}
+
 		if (isOpen) {
 			throw new IllegalStateException("Mixer is already open");
 		}
 
-		// FIXME security
-		
 		InetAddress addr = InetAddress.getAllByName(host)[0];
 
 		if (port != null) {
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java	Fri Oct 10 11:10:27 2008 -0400
@@ -83,12 +83,8 @@
 		 * 
 		 * close = no sound. open = sound
 		 * 
-		 * so we set it to be open by default
 		 */
-
-		
-		// TODO what to do if a security exception is thrown?
-		open();
+		// FIXME open();
 
 		// System.out.println("Opened Target Port " + name);
 	}
@@ -133,9 +129,7 @@
 
 	@Override
 	public void close() {
-		
-		// FIXME security 
-		
+
 		native_setVolume((float) 0);
 		isOpen = false;
 		fireLineEvent(new LineEvent(this, LineEvent.Type.CLOSE,
@@ -147,9 +141,7 @@
 
 	@Override
 	public void open() {
-		
-		// FIXME security
-		
+
 		native_setVolume(volume);
 		isOpen = true;
 		fireLineEvent(new LineEvent(this, LineEvent.Type.OPEN,
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Fri Oct 10 11:10:27 2008 -0400
@@ -40,6 +40,7 @@
 import java.util.ArrayList;
 
 import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioPermission;
 import javax.sound.sampled.LineListener;
 import javax.sound.sampled.LineUnavailableException;
 import javax.sound.sampled.SourceDataLine;
@@ -67,7 +68,9 @@
 	synchronized public void open(AudioFormat format, int bufferSize)
 			throws LineUnavailableException {
 
-		// FIXME security
+		/* check for permmission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
 
 		super.open(format, bufferSize);
 
@@ -310,12 +313,15 @@
 
 	@Override
 	synchronized public void close() {
+
+		/* check for permmission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
+
 		if (!isOpen) {
 			throw new IllegalStateException("not open so cant close");
 		}
 
-		// FIXME security
-
 		writeInterrupted = true;
 
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java	Fri Oct 10 11:10:27 2008 -0400
@@ -37,6 +37,7 @@
 
 package org.classpath.icedtea.pulseaudio;
 
+import javax.sound.sampled.AudioPermission;
 import javax.sound.sampled.Port;
 
 public class PulseAudioSourcePort extends PulseAudioPort {
@@ -53,7 +54,9 @@
 
 	public void open() {
 		
-		
+		/* check for permission to record audio */
+		AudioPermission perm = new AudioPermission("record", null);
+		perm.checkGuard(null);
 		
 		super.open();
 		
@@ -63,6 +66,14 @@
 	
 	public void close() {
 		
+		/* check for permission to record audio */
+		AudioPermission perm = new AudioPermission("record", null);
+		perm.checkGuard(null);
+		
+		if (!isOpen) {
+			throw new IllegalStateException("Port is not open; so cant close");
+		}
+		
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
 		parent.removeSourceLine(this);
 		
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java	Fri Oct 10 11:10:27 2008 -0400
@@ -38,6 +38,7 @@
 package org.classpath.icedtea.pulseaudio;
 
 import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioPermission;
 import javax.sound.sampled.LineEvent;
 import javax.sound.sampled.LineUnavailableException;
 import javax.sound.sampled.TargetDataLine;
@@ -70,13 +71,15 @@
 
 	@Override
 	synchronized public void close() {
+		/* check for permission to record audio */
+		AudioPermission perm = new AudioPermission("record", null);
+		perm.checkGuard(null);
+
 		if (!isOpen) {
 			throw new IllegalStateException(
 					"Line cant be closed if it isnt open");
 		}
 
-		// FIXME security
-		
 		PulseAudioMixer parentMixer = PulseAudioMixer.getInstance();
 		parentMixer.removeTargetLine(this);
 
@@ -86,12 +89,13 @@
 	@Override
 	synchronized public void open(AudioFormat format, int bufferSize)
 			throws LineUnavailableException {
+		/* check for permission to record audio */
+		AudioPermission perm = new AudioPermission("record", null);
+		perm.checkGuard(null);
+
 		if (isOpen) {
 			throw new IllegalStateException("already open");
 		}
-
-		// FIXME security
-		
 		super.open(format, bufferSize);
 
 		/* initialize all the member variables */
@@ -223,7 +227,7 @@
 
 					/* read a fragment, and drop it from the server */
 					currentFragment = stream.peek();
-					
+
 					stream.drop();
 					if (currentFragment == null) {
 						System.out
--- a/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java	Fri Oct 10 11:10:27 2008 -0400
@@ -37,42 +37,51 @@
 
 package org.classpath.icedtea.pulseaudio;
 
+import javax.sound.sampled.AudioPermission;
 import javax.sound.sampled.Port;
 
 public class PulseAudioTargetPort extends PulseAudioPort {
 
 	/* aka speaker */
-	
+
 	static {
 		System.loadLibrary("pulse-java");
 	}
 
 	public PulseAudioTargetPort(String name, EventLoop eventLoop) {
-		
+
 		super(name, eventLoop);
-		
+
 	}
 
 	public void open() {
-		
-		// FIXME security
-		
+
+		/* check for permission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
+
 		super.open();
-		
+
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
 		parent.addTargetLine(this);
 	}
-	
+
 	public void close() {
+
+		/* check for permission to play audio */
+		AudioPermission perm = new AudioPermission("play", null);
+		perm.checkGuard(null);
 		
-		// FIXME
+		if (!isOpen) {
+			throw new IllegalStateException("not open, so cant close Port");
+		}
 		
 		PulseAudioMixer parent = PulseAudioMixer.getInstance();
 		parent.removeTargetLine(this);
-		
-		super.close();		
+
+		super.close();
 	}
-	
+
 	public native byte[] native_setVolume(float newValue);
 
 	public synchronized native byte[] native_updateVolumeInfo();
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java	Fri Oct 10 11:10:27 2008 -0400
@@ -97,6 +97,9 @@
 			if (info.getLineClass() == Port.class) {
 				System.out.println(info.toString());
 				Port port = (Port) mixer.getLine(info);
+				if (!port.isOpen()) {
+					port.open();
+				}
 				FloatControl volumeControl = (FloatControl) port
 						.getControl(FloatControl.Type.VOLUME);
 				volumeControl.setValue(60000);
@@ -104,6 +107,7 @@
 						.getControl(BooleanControl.Type.MUTE);
 				muteControl.setValue(true);
 				muteControl.setValue(false);
+				port.close();
 			}
 		}
 	}
--- a/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java	Thu Oct 09 17:28:36 2008 -0400
+++ b/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java	Fri Oct 10 11:10:27 2008 -0400
@@ -97,6 +97,9 @@
 			if (info.getLineClass() == Port.class) {
 				System.out.println(info.toString());
 				Port port = (Port) mixer.getLine(info);
+				if (!port.isOpen()) {
+					port.open();
+				}
 				FloatControl volumeControl = (FloatControl) port
 						.getControl(FloatControl.Type.VOLUME);
 				volumeControl.setValue(60000);
@@ -104,6 +107,7 @@
 						.getControl(BooleanControl.Type.MUTE);
 				muteControl.setValue(true);
 				muteControl.setValue(false);
+				port.close();
 			}
 		}
 	}