1+ using System ;
2+ using System . Diagnostics ;
3+ using System . Linq ;
4+ using System . Windows . Automation ;
5+
6+ namespace AutoSafeNetLogon
7+ {
8+ class Program
9+ {
10+ static void Main ( string [ ] args )
11+ {
12+ // Find and extract the password argument
13+ string passwordArg = args . FirstOrDefault ( a => a . StartsWith ( "/password:" , StringComparison . OrdinalIgnoreCase ) ) ;
14+ string password = "" ;
15+ if ( passwordArg != null )
16+ {
17+ password = passwordArg . Substring ( "/password:" . Length ) ;
18+ }
19+
20+ if ( ! string . IsNullOrWhiteSpace ( password ) )
21+ {
22+ // Add an automation event handler to handle SafeNet token password requests
23+ SatisfyEverySafeNetTokenPasswordRequest ( password ) ;
24+ }
25+ else
26+ {
27+ Console . WriteLine ( "Missing /password:<pwd> argument, if the the certificate is on a SafeNet token, you will be prompted for the password." ) ;
28+ }
29+
30+ // Remove password from args before calling signtool
31+ var remainingArgs = args . Where ( a => ! a . StartsWith ( "/password:" , StringComparison . OrdinalIgnoreCase ) ) . ToArray ( ) ;
32+
33+ // Run signtool with the remaining args<
34+ var startInfo = new ProcessStartInfo
35+ {
36+ FileName = "signtool.exe" ,
37+ Arguments = string . Join ( " " , remainingArgs ) ,
38+ UseShellExecute = false ,
39+ RedirectStandardOutput = true ,
40+ RedirectStandardError = true ,
41+ } ;
42+
43+ try
44+ {
45+ Console . WriteLine ( "Signtool starting with arguments: " + startInfo . Arguments ) ;
46+ var process = Process . Start ( startInfo ) ;
47+ process . OutputDataReceived += ( sender , e ) => Console . WriteLine ( e . Data ) ;
48+ process . ErrorDataReceived += ( sender , e ) => Console . Error . WriteLine ( e . Data ) ;
49+ process . BeginOutputReadLine ( ) ;
50+ process . BeginErrorReadLine ( ) ;
51+ process . WaitForExit ( ) ;
52+ if ( process . ExitCode != 0 )
53+ {
54+ Console . Error . WriteLine ( $ "Signtool exited with code { process . ExitCode } ") ;
55+ Environment . Exit ( process . ExitCode ) ;
56+ }
57+ else
58+ {
59+ Console . WriteLine ( "Signtool completed successfully." ) ;
60+ }
61+ }
62+ catch ( Exception ex )
63+ {
64+ Console . Error . WriteLine ( $ "Failed to start signtool: { ex . Message } ") ;
65+ }
66+ Console . WriteLine ( "ksigntool finished" ) ;
67+ // Clear automation handlers
68+ Automation . RemoveAllEventHandlers ( ) ;
69+ }
70+
71+ static void SatisfyEverySafeNetTokenPasswordRequest ( string password )
72+ {
73+ int count = 0 ;
74+ Automation . AddAutomationEventHandler ( WindowPattern . WindowOpenedEvent , AutomationElement . RootElement , TreeScope . Children , ( sender , e ) =>
75+ {
76+ var element = sender as AutomationElement ;
77+ if ( element . Current . Name == "Token Logon" || element . Current . Name == "Connexion au token" )
78+ {
79+ WindowPattern pattern = ( WindowPattern ) element . GetCurrentPattern ( WindowPattern . Pattern ) ;
80+ pattern . WaitForInputIdle ( 10000 ) ;
81+ var edit = element . FindFirst ( TreeScope . Descendants , new AndCondition (
82+ new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Edit ) ,
83+ new PropertyCondition ( AutomationElement . NameProperty , "Token Password:" ) ) ) ;
84+ if ( edit == null )
85+ {
86+ edit = element . FindFirst ( TreeScope . Descendants , new AndCondition (
87+ new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Edit ) ,
88+ new PropertyCondition ( AutomationElement . NameProperty , "Mot de passe du token:" ) ) ) ;
89+ }
90+
91+ var ok = element . FindFirst ( TreeScope . Descendants , new AndCondition (
92+ new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Button ) ,
93+ new PropertyCondition ( AutomationElement . NameProperty , "OK" ) ) ) ;
94+
95+ if ( edit != null && ok != null )
96+ {
97+ count ++ ;
98+ ValuePattern vp = ( ValuePattern ) edit . GetCurrentPattern ( ValuePattern . Pattern ) ;
99+ vp . SetValue ( password ) ;
100+ Console . WriteLine ( "SafeNet window (count: " + count + " window(s)) detected. Setting password..." ) ;
101+
102+ InvokePattern ip = ( InvokePattern ) ok . GetCurrentPattern ( InvokePattern . Pattern ) ;
103+ ip . Invoke ( ) ;
104+ }
105+ else
106+ {
107+ Console . WriteLine ( "SafeNet window detected but not with edit and button..." ) ;
108+ }
109+ }
110+ } ) ;
111+ }
112+ }
113+ }
0 commit comments