Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

samtregar (2699)

samtregar
  (email not shown publicly)
http://sam.tregar.com/

Journal of samtregar (2699)

Friday January 17, 2003
06:20 PM

.netrc and SSH

[ #10049 ]
I admit it, I use a .netrc file. If you're not familiar with obsolete UNIX technology, a .netrc file contains machine names, usernames and passwords that programs can use to automate logins. Traditionally ftp has supported .netrc and so does fetchmail. From a security point of view it's pure madness since it means a breakin into one account turns into a breakin on all accounts listed in the .netrc.

I got started using .netrc via Emacs' ange-ftp mode. The ange-ftp mode allows you to edit files via FTP as though they were local. This is all just great, except that every time I open a file with ange-ftp for the first time it prompts for a password. I quickly got tired of that and started looking around for a solution.

Then it hit me that if I was bold enough to store my account passwords in a plaintext on my hard drive, then why shouldn't I get the maximum benefit from the mistake? Why should I type my passwords on those machines at all?

Thus was born my .netrc patch for OpenSSH. I just ported it to OpenSSH 3.5p1 and it occured to me that I might not be the only person that could benefit from it. Just apply it with "patch -p1" inside the 3.5p1 sources, compile it and put a line like this in your ~/.ssh/config:

netrcfile /home/sam/.netrc

Now whenever you ssh to a machine in your .netrc you won't even see a login prompt. Goodbye security and hello slack!

(BTW: I do realize that SSH supports some crazy public key system for automatic logins. I must be too dumb to use it though, because I've tried to set it up a couple times with no success.)

-sam

diff -ru openssh-3.5p1/readconf.c openssh-3.5p1.new/readconf.c
--- openssh-3.5p1/readconf.c    Tue Jul  9 10:06:40 2002
+++ openssh-3.5p1.new/readconf.c    Fri Jan 17 14:57:43 2003
@@ -114,7 +114,7 @@
     oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
     oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
     oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-    oDeprecated
+    oDeprecated, oNetrcFile
} OpCodes;

/* Textual representations of the tokens. */
@@ -186,6 +186,7 @@
     { "smartcarddevice", oSmartcardDevice },
     { "clearallforwardings", oClearAllForwardings },
     { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+        { "netrcfile", oNetrcFile },
     { NULL, oBadOption }
};

@@ -448,6 +449,10 @@
             *charptr = xstrdup(arg);
         break;

+        case oNetrcFile:
+                charptr = &options->netrcfile;
+                goto parse_string;
+
     case oGlobalKnownHostsFile:
         charptr = &options->system_hostfile;
         goto parse_string;
@@ -790,6 +795,7 @@
     options->clear_forwardings = -1;
     options->log_level = SYSLOG_LEVEL_NOT_SET;
     options->preferred_authentications = NULL;
+        options->netrcfile = NULL;
     options->bind_address = NULL;
     options->smartcard_device = NULL;
     options->no_host_authentication_for_localhost = - 1;
diff -ru openssh-3.5p1/readconf.h openssh-3.5p1.new/readconf.h
--- openssh-3.5p1/readconf.h    Sun Jun  9 16:04:03 2002
+++ openssh-3.5p1.new/readconf.h    Fri Jan 17 14:58:29 2003
@@ -100,6 +100,10 @@
     Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
     int    clear_forwardings;
     int    no_host_authentication_for_localhost;
+
+        /* Netrc File */
+        char   *netrcfile;
+
}       Options;

diff -ru openssh-3.5p1/sshconnect1.c openssh-3.5p1.new/sshconnect1.c
--- openssh-3.5p1/sshconnect1.c    Tue Aug 20 14:41:16 2002
+++ openssh-3.5p1.new/sshconnect1.c    Fri Jan 17 15:00:56 2003
@@ -918,18 +918,47 @@
  * Tries to authenticate with plain passwd authentication.
  */
static int
-try_password_authentication(char *prompt)
+try_password_authentication(char *prompt, const char *server_user, const char *host)
{
     int type, i;
-    char *password;
+    char *password = NULL;

+        // try netrc if available
+        if (options.netrcfile) {
+          FILE *file;
+          char line[256];
+          char *machine, *login;
+
+          file = fopen(options.netrcfile, "r");
+          if (!file) error("Unable to open netrc file.");
+
+          // parse through file line-by-line
+          while(!feof(file)) {
+            fgets(line, 254, file);
+            if (!line) break;
+
+            // get line
+            if (sscanf(line, "machine %as login %as password %as", &machine, &login, &password)) {
+              if (!strcmp(host, machine) &&
+                  !strcmp(server_user, login)) {
+                break;
+              } else {
+                password = NULL;
+              }
+            }
+          }
+          fclose(file);
+        }
+
+
     debug("Doing password authentication.");
     if (options.cipher == SSH_CIPHER_NONE)
         log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
     for (i = 0; i < options.number_of_password_prompts; i++) {
         if (i != 0)
             error("Permission denied, please try again.");
-        password = read_passphrase(prompt, 0);
+                if (password == NULL)
+                  password = read_passphrase(prompt, 0);
         packet_start(SSH_CMSG_AUTH_PASSWORD);
         ssh_put_password(password);
         memset(password, 0, strlen(password));
@@ -1263,7 +1292,7 @@

         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
             server_user, host);
-        if (try_password_authentication(prompt))
+        if (try_password_authentication(prompt, server_user, host))
             goto success;
     }
     /* All authentication methods have failed.  Exit with an error message. */
diff -ru openssh-3.5p1/sshconnect2.c openssh-3.5p1.new/sshconnect2.c
--- openssh-3.5p1/sshconnect2.c    Thu Oct  3 01:45:55 2002
+++ openssh-3.5p1.new/sshconnect2.c    Fri Jan 17 15:07:49 2003
@@ -445,7 +445,7 @@
{
     static int attempt = 0;
     char prompt[150];
-    char *password;
+    char *password = NULL;

     if (attempt++ >= options.number_of_password_prompts)
         return 0;
@@ -455,7 +455,40 @@

     snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
         authctxt->server_user, authctxt->host);
-    password = read_passphrase(prompt, 0);
+
+        // try netrc if available
+        if (options.netrcfile) {
+          FILE *file;
+          char line[256];
+          char *machine, *login;
+
+          file = fopen(options.netrcfile, "r");
+          if (!file) error("Unable to open netrc file.");
+
+          // parse through file line-by-line
+          while(!feof(file)) {
+            fgets(line, 254, file);
+            if (!line) break;
+
+            // get line
+            if (sscanf(line, "machine %as login %as password %as", &machine, &login, &password)) {
+              if (!strcmp(authctxt->host, machine) &&
+                  !strcmp(authctxt->server_user, login)) {
+                break;
+              } else {
+                password = NULL;
+              }
+            }
+          }
+          fclose(file);
+        }
+
+        if (password == NULL) {
+          snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
+                   authctxt->server_user, authctxt->host);
+          password = read_passphrase(prompt, 0);
+        }
+
     packet_start(SSH2_MSG_USERAUTH_REQUEST);
     packet_put_cstring(authctxt->server_user);
     packet_put_cstring(authctxt->service);

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.