printing from the mac sandbox

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

printing from the mac sandbox

Sean Reilly

There is a printing problem using recent JDKs when running within the macOS sandbox as of 10.12.4.

Looking at the jdk8 sources, CUPSfuncs.c seems to ignore the cupsServer by the system CUPS libraries if it returns a reference to a unix domain socket address:

 // Is this a local domain socket?
 if (strncmp(server, "/", 1) == 0) {
   cServer = JNU_NewStringPlatform(env, "localhost");
 } else {
   cServer = JNU_NewStringPlatform(env, server);
 }

This causes the CUPSPrinter.java and CUPSfunc code to connect to localhost via TCP port 631 instead of the advertised unix domain socket.

MacOS Sierra 10.12.4 had some security related changes to the sandbox which explicitly blocks connections from a sandboxed app to TCP localhost:631.  This blockage (or at least a very long delay) applies even if the sandboxed app has network-client, network-server, and print entitlements, which means there's no way around the problem.

I've talked to Apple DTS and they aren't inclined to allow the connection to localhost:631, even if the network-client and print entitlements are enabled.  It seems a bit stubborn of them but to be fair java is ignoring the advertised CUPS server string and assuming that a TCP/localhost:631 interface is available.

As you can imagine, not being able to print from a desktop app is pretty bad for business.

My questions are:
1) Is anyone at Oracle aware of and working on this?

2) Is there a reason not to use the unix domain socket connection? The connection details seem to be encapsulated within the libcups code so I don't see why the java level needs to override the result returned by the call to `cupsServer`

3) Is a patch that uses the unix domain socket likely to be accepted, and if so, where should it be sent?

Thanks,
Sean



signature.asc (817 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: printing from the mac sandbox

Sergey Bylokhov
Hi, Sean.
The correct mailing list for discussion of such issues is: 2d-dev (cc).

----- [hidden email] wrote:

> There seems to be a big printing problem using recent JDKs when
> running within the macOS sandbox as of 10.12.4.
>
> Looking at the jdk8 sources, CUPSfuncs.c seems to ignore the
> connection point provided by the system CUPS libraries if it returns a
> reference to a unix domain socket address:
>
>   // Is this a local domain socket?
>   if (strncmp(server, "/", 1) == 0) {
>     cServer = JNU_NewStringPlatform(env, "localhost");
>   } else {
>     cServer = JNU_NewStringPlatform(env, server);
>   }
>
> This causes the CUPSPrinter.java and CUPSfunc code to connect to
> localhost via TCP port 631 instead of the unix domain socket which
> should be where it connects.
>
> MacOS Sierra 10.12.4 had some security related changes to the sandbox
> which explicitly blocks connections from a sandboxed app to TCP
> localhost:631.  This blockage (or at least a very long delay) applies
> even if network-client, network-server, and print entitlements are set
> for the app, which means there's no way around the problem.
>
> I've talked to Apple DTS and they aren't inclined to allow the
> connection to localhost:631, even if the network-client and print
> entitlements are enabled.
>
> As you can imagine, not being able to print from a desktop app is
> pretty bad for business.
>
> My questions are:
>  1) Is anyone at Oracle aware of and working on this?
>
>  2) Is there a reason not to use the unix domain socket connection?
> The connection details seem to be encapsulated within the libcups code
> so I don't see why the java level needs to override the result
> returned by the call to `cupsServer`
>
>  3) Is a patch that uses the unix domain socket likely to be accepted,
> and if so, where should it be sent?
>
>  4) Is there a better mailing list for this discussion?
>
> Thanks,
> Sean
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: printing from the mac sandbox

Philip Race
In reply to this post by Sean Reilly
see in-line.

On 06/01/2017 08:09 AM, Sean Reilly wrote:

> There is a printing problem using recent JDKs when running within the macOS sandbox as of 10.12.4.
>
> Looking at the jdk8 sources, CUPSfuncs.c seems to ignore the cupsServer by the system CUPS libraries if it returns a reference to a unix domain socket address:
>
>   // Is this a local domain socket?
>   if (strncmp(server, "/", 1) == 0) {
>     cServer = JNU_NewStringPlatform(env, "localhost");
>   } else {
>     cServer = JNU_NewStringPlatform(env, server);
>   }
>
> This causes the CUPSPrinter.java and CUPSfunc code to connect to localhost via TCP port 631 instead of the advertised unix domain socket.
>
> MacOS Sierra 10.12.4 had some security related changes to the sandbox which explicitly blocks connections from a sandboxed app to TCP localhost:631.  This blockage (or at least a very long delay) applies even if the sandboxed app has network-client, network-server, and print entitlements, which means there's no way around the problem.
>
> I've talked to Apple DTS and they aren't inclined to allow the connection to localhost:631, even if the network-client and print entitlements are enabled.  It seems a bit stubborn of them but to be fair java is ignoring the advertised CUPS server string and assuming that a TCP/localhost:631 interface is available.
>
> As you can imagine, not being able to print from a desktop app is pretty bad for business.
>
> My questions are:
> 1) Is anyone at Oracle aware of and working on this?
Not so far as I know.
>
> 2) Is there a reason not to use the unix domain socket connection? The connection details seem to be encapsulated within the libcups code so I don't see why the java level needs to override the result returned by the call to `cupsServer`

I don't follow your comment about encapsulation in libcups code.
The server name is returned to Java code and there a connection is made
over HTTP.
The socket string would not work there .. and Java does not have any
support I know of
for Unix domain sockets anyway. This would seem to require a lot of
re-working of the
code unless I am missing something.

Also I asked someone with 10.12.5 to run the following program and it
worked fine for them.
What is your program doing and how are you running it ?
import javax.print.*;

public class GAP {

   public static void main(String[] args) {
      System.out.println("get printers");
      long t0 = System.currentTimeMillis();
      PrintService[] printers =
          PrintServiceLookup.lookupPrintServices(null, null);
      long t1 = System.currentTimeMillis();
      System.out.println("got printers in " + (t1-t0) + "ms.");
      for (int p=0; p<printers.length; p++) {
         System.out.println(printers[p]);
      }
   }
}

>
> 3) Is a patch that uses the unix domain socket likely to be accepted, and if so, where should it be sent?

This list.

-phil.
>
> Thanks,
> Sean
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: printing from the mac sandbox

Sean Reilly

> On 2017.06.02, at 18:06, Phil Race <[hidden email]> wrote:
>> 2) Is there a reason not to use the unix domain socket connection? The connection details seem to be encapsulated within the libcups code so I don't see why the java level needs to override the result returned by the call to `cupsServer`
>
> I don't follow your comment about encapsulation in libcups code.
> The server name is returned to Java code and there a connection is made over HTTP.
> The socket string would not work there .. and Java does not have any support I know of
> for Unix domain sockets anyway. This would seem to require a lot of re-working of the
> code unless I am missing something.

I'm not sure how much reworking it would require, but IMO a bug preventing printing in any sandboxed (ie mac app store) app is a big deal.

> Also I asked someone with 10.12.5 to run the following program and it worked fine for them.
> What is your program doing and how are you running it ?

The test code you included wouldn't reveal the problem because it wasn't running within the mac sandbox.

I've created a small test case that shows the problem:
 https://infinitekind.com/tmp/javacups/

 SandboxedJavaTestPrint.zip - has a signed sandboxed java app as well as the source and scripts that were used to build it.  I've signed it with my developer key and added a debugging flag (-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005) so that you can trace through the steps while it runs within the sandbox.

 TEST CUPS Sandboxed.zip - contains an objective-c/Xcode project which shows how native connections to localhost port 631 through the CUPS API time out, but how passing the result of a call to cupsServer() (which returns the unix domain socket path) to httpConnect2() results in a successful connection.  This shows that we can still (probably) use a call to httpConnect/httpConnect2, but the java-side code that assumes cupsServer() returns a hostname will need to change.  It's not a trivial change, but it also doesn't look like it gets too hairy... mainly some changes in UnixPrintServiceLocalLookup.java and IPPPrintService.java.

Both test apps have network-client and printing entitlements in the sandbox.

The problem mainly seems to be a delay (often measured in tens of minutes) when attempting to print.  Curiously the print dialog does appear after a very long delay and printing can then proceed.  This makes me think that the problem is related to discovery of printers or print services for which there is a fallback.

I've submitted a DTS incident to Apple and a friend there has followed-up. Their unofficial position is that java should be connecting to the cups interface returned by the cupsServer() function and not changing the interface string to "localhost".  Security changes in 10.12.4 reject the TCP connection which they say confuses network-client access with print access.  They don't seem interested in loosening that change.

You can find Apple's CUPS port in github:  https://github.com/apple/cups
Their github repo seems to be a bit ahead of what is shipped in macOS Sierra.

I'm still digging into this, but would appreciate hearing if Oracle would be interested in helping resolve the issue.

Thanks,
Sean



signature.asc (817 bytes) Download Attachment
Loading...