As a security measure Windows forwards local smartcard readers to the remote machine. The problem is that
- readers you already have handles for become unusable
- it’s not possible to get new readers
If you try to use a terminal or CardTerminals object, you get a PCSCException: SCARD_E_SERVICE_STOPPED.
I have code to demonstrate the issue:
import javax.smartcardio.*;
public class ScRdp {
public static void main( final String[] args ) throws Exception
{
TerminalFactory factory = TerminalFactory.getDefault();
System.out.println( "Factory: " + factory.hashCode() );
final CardTerminals terminals = factory.terminals();
List<CardTerminal> termNames = terminals.list();
BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
in.readLine();
main( args );
}
}
Launch the code on machine A, RDP in using machine B and hit enter. You can even RDP in, immediately disconnect and hit enter on machine A.
In C, I would use SCardReleaseContext and SCardEstablishContext (ref). Is there any way to do this through the Java API?
Followup
AFAICT this is not possible. However see link, link. It should be possible to disable smartcard redirection on the server, circumventing the problem.
On Win7 Pro I found the setting in gpedit.msc: “Computer Configuration/Administrative Templates/Windows Components/Remote Desktop Services/Remote Desktop Session Host/Device and Resource Redirection/Do not allow smart card device redirection”. That said I do not have this working yet. Even unchecking the “forward smartcards” checkbox in the RDP client before connection doesn’t help.
This is only an issue if you RDP in as the same user as the one using the readers. We circumvented it by running the server using JavaService.exe from ObjectWeb to run as “Local System” user.