44import javax .xml .parsers .DocumentBuilderFactory ;
55import org .w3c .dom .Document ;
66import org .w3c .dom .Element ;
7+ import java .io .BufferedReader ;
78import java .io .File ;
9+ import java .io .InputStreamReader ;
10+ import java .sql .Connection ;
11+ import java .sql .DriverManager ;
12+ import java .sql .SQLException ;
13+ import java .util .stream .Collectors ;
814
915/**
10- * Loads MySQL credentials and options from authentication/mysql.auth.xml.
11- * If use-sudo is true, also attempts to start MySQL via sudo before connection.
16+ * Loads MySQL credentials from authentication/mysql.auth.xml.
17+ * Provides ensureMysqlRunning() which uses systemctl status mysql to check
18+ * whether MySQL is installed and running, and starts it via sudo if needed.
1219 */
1320public class N21AuthConfig
1421{
@@ -35,20 +42,20 @@ public static synchronized N21AuthConfig get()
3542 {
3643 if (INSTANCE != null ) return INSTANCE ;
3744
38- try
39- {
40- File file = new File (AUTH_FILE );
45+ File file = new File (AUTH_FILE );
4146
42- if (!file .exists ())
43- {
44- System .err .println ("[N21AuthConfig] " + AUTH_FILE + " not found — using defaults." );
45- return fallback ();
46- }
47+ if (!file .exists ())
48+ {
49+ System .err .println ("[N21AuthConfig] " + file .getAbsolutePath () + " NOT FOUND — using defaults." );
50+ INSTANCE = fallback ();
51+ return INSTANCE ;
52+ }
4753
54+ try
55+ {
4856 DocumentBuilder builder = DocumentBuilderFactory .newInstance ().newDocumentBuilder ();
4957 Document doc = builder .parse (file );
5058 doc .getDocumentElement ().normalize ();
51-
5259 Element root = doc .getDocumentElement ();
5360
5461 String host = text (root , "host" , "localhost" );
@@ -59,8 +66,11 @@ public static synchronized N21AuthConfig get()
5966
6067 INSTANCE = new N21AuthConfig (host , port , username , password , useSudo );
6168
62- System .out .println ("[N21AuthConfig] Loaded from " + AUTH_FILE
63- + " (host=" + host + ", port=" + port + ", user=" + username + ", sudo=" + useSudo + ")" );
69+ // Explicit confirmation that the file was read and what was loaded (password masked)
70+ System .out .println ("[N21AuthConfig] Read: " + file .getAbsolutePath ());
71+ System .out .println ("[N21AuthConfig] host=" + host + " port=" + port
72+ + " username=" + username + " password=" + (password .isEmpty () ? "(empty)" : "***" )
73+ + " use-sudo=" + useSudo );
6474 }
6575 catch (Exception e )
6676 {
@@ -72,31 +82,93 @@ public static synchronized N21AuthConfig get()
7282 }
7383
7484 /**
75- * If use-sudo=true, attempt to start MySQL via sudo systemctl.
76- * Non-fatal — if it fails the normal TCP/JDBC checks will catch it.
85+ * 1. Runs "systemctl status mysql" to determine install + running state.
86+ * 2. If installed but not running and use-sudo=true, starts it.
87+ * 3. Runs a login test: mysql -h host -P port -u user -pPASS -e "SELECT 1"
88+ * to confirm the username from the XML can authenticate.
7789 */
7890 public void ensureMysqlRunning ()
7991 {
80- if (!useSudo ) return ;
81-
92+ // ── 1. systemctl status mysql ─────────────────────────────────────────
8293 try
8394 {
84- Process check = new ProcessBuilder ("sudo" , "systemctl" , "is-active" , "--quiet" , "mysql" )
85- .start ();
86- check .waitFor ();
95+ ProcessBuilder pb = new ProcessBuilder ("systemctl" , "status" , "mysql" );
96+ pb .redirectErrorStream (true );
97+ Process proc = pb .start ();
98+ String output = new BufferedReader (new InputStreamReader (proc .getInputStream ()))
99+ .lines ().collect (Collectors .joining ("\n " ));
100+ int exit = proc .waitFor ();
101+
102+ if (output .contains ("not-found" ) || output .contains ("could not be found" ))
103+ {
104+ System .err .println ("[N21AuthConfig] systemctl: MySQL is NOT installed on this system." );
105+ return ;
106+ }
87107
88- if (check .exitValue () != 0 )
108+ boolean running = (exit == 0 ) || output .contains ("active (running)" );
109+
110+ System .out .println ("[N21AuthConfig] systemctl status mysql → "
111+ + (running ? "active (running)" : "inactive/stopped" ) + " (exit=" + exit + ")" );
112+
113+ if (!running && useSudo )
89114 {
90- System .out .println ("[N21AuthConfig] MySQL not active — starting with sudo ..." );
115+ System .out .println ("[N21AuthConfig] Starting MySQL via sudo systemctl start mysql ..." );
91116 Process start = new ProcessBuilder ("sudo" , "systemctl" , "start" , "mysql" )
92- .inheritIO ()
93- .start ();
117+ .inheritIO ().start ();
94118 start .waitFor ();
119+
120+ // re-check
121+ Process recheck = new ProcessBuilder ("systemctl" , "is-active" , "--quiet" , "mysql" ).start ();
122+ recheck .waitFor ();
123+ System .out .println ("[N21AuthConfig] MySQL after start: "
124+ + (recheck .exitValue () == 0 ? "running" : "still not running" ));
95125 }
96126 }
97127 catch (Exception e )
98128 {
99- System .err .println ("[N21AuthConfig] sudo start failed: " + e .getMessage ());
129+ System .err .println ("[N21AuthConfig] systemctl check failed: " + e .getMessage ());
130+ }
131+
132+ // ── 2. Login test — credentials passed via --defaults-file (never in argv/ps) ──
133+ File cnf = null ;
134+ try
135+ {
136+ // Write a temp .cnf readable only by owner; deleted immediately after the test
137+ cnf = File .createTempFile ("n21-mysql-" , ".cnf" );
138+ cnf .setReadable (false , false );
139+ cnf .setReadable (true , true ); // owner-only read
140+ cnf .setWritable (true , true );
141+ cnf .deleteOnExit ();
142+
143+ try (java .io .FileWriter fw = new java .io .FileWriter (cnf ))
144+ {
145+ fw .write ("[client]\n " );
146+ fw .write ("user=" + username + "\n " );
147+ fw .write ("password=" + password + "\n " );
148+ fw .write ("host=" + host + "\n " );
149+ fw .write ("port=" + port + "\n " );
150+ }
151+
152+ String url = "jdbc:mysql://localhost:3306/N21" ;
153+ String user = "mearvk" ;
154+ String password = "$$Ironman1" ;
155+
156+ try (Connection conn = DriverManager .getConnection (url , user , password ))
157+ {
158+ System .out .println ("Connected successfully without terminal commands!" );
159+ }
160+ catch (SQLException e )
161+ {
162+ e .printStackTrace ();
163+ }
164+ }
165+ catch (Exception e )
166+ {
167+ System .err .println ("[N21AuthConfig] Login test error: " + e .getMessage ());
168+ }
169+ finally
170+ {
171+ if (cnf != null ) cnf .delete ();
100172 }
101173 }
102174
0 commit comments