]> diplodocus.org Git - nmh/blobdiff - sbr/ruserpass.c
Fix flex 2.6.1's output regarding signed/unsigned comparisons.
[nmh] / sbr / ruserpass.c
index f7f01792e988b2f01c27356aebfda9137f1b103e..43784d528d02158c3050a90e88dfb836d613162d 100644 (file)
@@ -35,7 +35,7 @@ static FILE *cfile;
 #define        ID      10
 #define        MACH    11
 
-#define MAX_TOKVAL_SIZE 1024
+#define MAX_TOKVAL_SIZE 1024 /* Including terminating NUL. */
 
 struct toktab {
     char *tokstr;
@@ -107,8 +107,8 @@ ruserpass(const char *host, char **aname, char **apass, int flags)
                            (stb.st_mode & 077) != 0) {
                            /* We make this a fatal error to force the
                               user to correct it. */
-                           advise(NULL, "Error - file %s must not be world or "
-                                  "group readable.", credentials_file);
+                            advise(NULL, "group or other permissions, %#o, "
+                                "forbidden: %s", stb.st_mode, credentials_file);
                            adios(NULL, "Remove password or correct file "
                                  "permissions.");
                        }
@@ -177,44 +177,47 @@ ruserpass(const char *host, char **aname, char **apass, int flags)
 static int
 token(char *tokval)
 {
-    char *cp;
     int c;
+    const char normalStop[] = "\t\n ,"; /* Each breaks a word. */
+    const char *stop;
+    char *cp;
     struct toktab *t;
 
-    if (feof(cfile))
+    if (feof(cfile) || ferror(cfile))
        return TOK_EOF;
-    while ((c = getc(cfile)) != EOF &&
-          (c == '\n' || c == '\t' || c == ' ' || c == ','))
-       continue;
+
+    stop = normalStop;
+    while ((c = getc(cfile)) != EOF && c && strchr(stop, c))
+        ;
     if (c == EOF)
        return TOK_EOF;
+
     cp = tokval;
-    if (c == '"') {
-       while ((c = getc(cfile)) != EOF && c != '"') {
-           if (c == '\\')
-               c = getc(cfile);
-           *cp++ = c;
-            if (cp - tokval > MAX_TOKVAL_SIZE-1) {
-                adios(NULL, "credential tokens restricted to length %d",
-                      MAX_TOKVAL_SIZE - 1);
-            }
-       }
-    } else {
-       *cp++ = c;
-       while ((c = getc(cfile)) != EOF
-              && c != '\n' && c != '\t' && c != ' ' && c != ',') {
-           if (c == '\\')
-               c = getc(cfile);
-           *cp++ = c;
-            if (cp - tokval > MAX_TOKVAL_SIZE-1) {
-                adios(NULL, "credential tokens restricted to length %d",
-                      MAX_TOKVAL_SIZE - 1);
-            }
-       }
+    if (c == '"')
+        /* FIXME: Where is the quoted-string syntax of netrc documented?
+         * This code treats «"foo""bar"» as two tokens without further
+         * separators. */
+        stop = "\"";
+    else
+        /* Might be backslash.  Get it again later.  It's handled then. */
+        if (ungetc(c, cfile) == EOF)
+            return TOK_EOF;
+
+    while ((c = getc(cfile)) != EOF && c && !strchr(stop, c)) {
+        if (c == '\\' && (c = getc(cfile)) == EOF)
+            return TOK_EOF; /* Discard whole token. */
+
+        *cp++ = c;
+        if (cp - tokval > MAX_TOKVAL_SIZE-1) {
+            adios(NULL, "credential tokens restricted to length %d",
+                  MAX_TOKVAL_SIZE - 1);
+        }
     }
-    *cp = 0;
+    *cp = '\0';
+
     for (t = toktabs; t->tokstr; t++)
        if (!strcmp(t->tokstr, tokval))
            return (t->tval);
+
     return (ID);
 }