tenseleyflow/gitswitch / 1049f51

Browse files

fix: improve SSH connection test for git hosting services

- Use git@github.com instead of github.com for SSH tests
- Use ssh -T (no TTY) since git hosts don't allow shell commands
- Check for success messages in output instead of exit code
(GitHub returns exit 1 even on successful auth)
- Downgrade SSH test failures to debug level since they're optional
Authored by espadonne
SHA
1049f51f230b0ae54a8e7948ec4d9919de1b0742
Parents
3559e36
Tree
ffc25c0

2 changed files

StatusFile+-
M src/accounts.c 2 2
M src/ssh_manager.c 23 18
src/accounts.cmodified
@@ -118,8 +118,8 @@ int accounts_switch(gitswitch_ctx_t *ctx, const char *identifier) {
118118
                             log_warning("SSH connection test failed for %s", account->ssh_host_alias);
119119
                         }
120120
                     } else {
121
-                        /* Test with default GitHub host */
122
-                        if (ssh_test_connection(account, "github.com") == 0) {
121
+                        /* Test with default GitHub host (git@ is required for GitHub SSH) */
122
+                        if (ssh_test_connection(account, "git@github.com") == 0) {
123123
                             log_info("SSH connection test passed for github.com");
124124
                         } else {
125125
                             log_debug("SSH connection test failed for github.com (this may be normal)");
src/ssh_manager.cmodified
@@ -561,11 +561,13 @@ int ssh_test_connection(const account_t *account, const char *host) {
561561
     
562562
     log_debug("Testing SSH connection to: %s", host);
563563
     
564
-    /* Build SSH test command */
564
+    /* Build SSH test command using -T (no TTY) for git hosting services
565
+     * GitHub/GitLab/Bitbucket don't allow shell commands, they return a
566
+     * greeting message on successful auth (exit code 1 but with success message) */
565567
     if (strlen(account->ssh_host_alias) > 0) {
566568
         /* Use host alias */
567
-        if ((size_t)snprintf(command, sizeof(command), 
568
-                            "ssh -o ConnectTimeout=5 -o BatchMode=yes %s echo 'SSH connection test successful'",
569
+        if ((size_t)snprintf(command, sizeof(command),
570
+                            "ssh -T -o ConnectTimeout=5 -o BatchMode=yes %s 2>&1",
569571
                             account->ssh_host_alias) >= sizeof(command)) {
570572
             set_error(ERR_INVALID_ARGS, "SSH test command too long");
571573
             return -1;
@@ -576,28 +578,31 @@ int ssh_test_connection(const account_t *account, const char *host) {
576578
         if (expand_path(account->ssh_key_path, expanded_key_path, sizeof(expanded_key_path)) != 0) {
577579
             return -1;
578580
         }
579
-        
581
+
580582
         if ((size_t)snprintf(command, sizeof(command),
581
-                            "ssh -o ConnectTimeout=5 -o BatchMode=yes -i '%s' %s echo 'SSH connection test successful'",
583
+                            "ssh -T -o ConnectTimeout=5 -o BatchMode=yes -i '%s' %s 2>&1",
582584
                             expanded_key_path, host) >= sizeof(command)) {
583585
             set_error(ERR_INVALID_ARGS, "SSH test command too long");
584586
             return -1;
585587
         }
586588
     }
587
-    
588
-    /* Execute SSH test */
589
-    if (execute_ssh_command(command, output, sizeof(output)) != 0) {
590
-        set_error(ERR_SSH_CONNECTION_FAILED, "SSH connection test failed to %s: %s", host, output);
591
-        return -1;
592
-    }
593
-    
594
-    if (!strstr(output, "SSH connection test successful")) {
595
-        set_error(ERR_SSH_CONNECTION_FAILED, "SSH connection test did not return expected output");
596
-        return -1;
589
+
590
+    /* Execute SSH test - for git hosts, check output for success indicators
591
+     * Note: GitHub returns exit code 1 even on success (no shell access) */
592
+    (void)execute_ssh_command(command, output, sizeof(output));
593
+
594
+    /* Check for authentication success messages from common git hosting services */
595
+    if (strstr(output, "successfully authenticated") ||  /* GitHub */
596
+        strstr(output, "Welcome to GitLab") ||           /* GitLab */
597
+        strstr(output, "logged in as") ||                /* Bitbucket */
598
+        strstr(output, "Hi ") ||                         /* GitHub greeting */
599
+        strstr(output, "authentication successful")) {   /* Generic */
600
+        log_debug("SSH authentication successful to %s", host);
601
+        return 0;
597602
     }
598
-    
599
-    log_info("SSH connection test successful to: %s", host);
600
-    return 0;
603
+
604
+    log_debug("SSH connection test failed to %s: %s", host, output);
605
+    return -1;
601606
 }
602607
 
603608
 /* Internal helper functions */