X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/1d4977afe4282d300f0f34e68974f4ef211ac769..5977791e005446f4cd8b2f04bfb14c8cd265df8a:/sbr/ruserpass.c diff --git a/sbr/ruserpass.c b/sbr/ruserpass.c index bc24f520..1e43571e 100644 --- a/sbr/ruserpass.c +++ b/sbr/ruserpass.c @@ -1,4 +1,5 @@ -/* +/* ruserpass.c -- parse .netrc-format file. + * * Portions of this code are * Copyright (c) 1985 Regents of the University of California. * All rights reserved. @@ -26,6 +27,7 @@ static FILE *cfile; +#define TOK_EOF 0 #define DEFAULT 1 #define LOGIN 2 #define PASSWD 3 @@ -34,7 +36,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; @@ -42,6 +44,7 @@ struct toktab { }; static struct toktab toktabs[] = { + { "", TOK_EOF }, { "default", DEFAULT }, { "login", LOGIN }, { "password", PASSWD }, @@ -59,7 +62,7 @@ static int token(char *); void -ruserpass(char *host, char **aname, char **apass) +ruserpass(const char *host, char **aname, char **apass, int flags) { int t, usedefault = 0; struct stat stb; @@ -78,7 +81,7 @@ ruserpass(char *host, char **aname, char **apass) switch(t) { case DEFAULT: usedefault = 1; - /* FALL THROUGH */ + /* FALLTHRU */ case MACH: if (!usedefault) { @@ -105,8 +108,8 @@ ruserpass(char *host, char **aname, char **apass) (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); + inform("group or other permissions, %#o, " + "forbidden: %s", stb.st_mode, credentials_file); adios(NULL, "Remove password or correct file " "permissions."); } @@ -133,7 +136,7 @@ ruserpass(char *host, char **aname, char **apass) } } - if (!*aname) { + if (!*aname && ! (flags & RUSERPASS_NO_PROMPT_USER)) { char tmp[80]; char *myname; @@ -145,10 +148,10 @@ ruserpass(char *host, char **aname, char **apass) } printf("Name (%s:%s): ", host, myname); - if (fgets(tmp, sizeof(tmp) - 1, stdin) == NULL) { + if (fgets(tmp, sizeof tmp, stdin) == NULL) { advise ("tmp", "fgets"); } - tmp[strlen(tmp) - 1] = '\0'; + trim_suffix_c(tmp, '\n'); if (*tmp != '\0' || myname == NULL) { myname = tmp; } @@ -156,7 +159,7 @@ ruserpass(char *host, char **aname, char **apass) *aname = mh_xstrdup(myname); } - if (!*apass) { + if (!*apass && ! (flags & RUSERPASS_NO_PROMPT_PASSWORD)) { char prompt[256]; char *mypass; @@ -175,46 +178,47 @@ ruserpass(char *host, char **aname, char **apass) 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)) - return (0); - while ((c = getc(cfile)) != EOF && - (c == '\n' || c == '\t' || c == ' ' || c == ',')) - continue; + if (feof(cfile) || ferror(cfile)) + return TOK_EOF; + + stop = normalStop; + while ((c = getc(cfile)) != EOF && c && strchr(stop, c)) + ; if (c == EOF) - return (0); + 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; - if (tokval[0] == 0) - return (0); + *cp = '\0'; + for (t = toktabs; t->tokstr; t++) if (!strcmp(t->tokstr, tokval)) return (t->tval); + return (ID); }