126053Sminshall /* 2*66673Spendry * Copyright (c) 1985, 1993, 1994 362012Sbostic * The Regents of the University of California. All rights reserved. 433737Sbostic * 542666Sbostic * %sccs.include.redist.c% 626053Sminshall */ 726053Sminshall 826053Sminshall #ifndef lint 9*66673Spendry static char sccsid[] = "@(#)ruserpass.c 8.3 (Berkeley) 04/02/94"; 1033737Sbostic #endif /* not lint */ 1126053Sminshall 1235631Sbostic #include <sys/types.h> 1366670Spendry #include <sys/stat.h> 1466670Spendry 1526053Sminshall #include <ctype.h> 1666670Spendry #include <err.h> 1726053Sminshall #include <errno.h> 1866670Spendry #include <stdio.h> 1966670Spendry #include <stdlib.h> 2066670Spendry #include <string.h> 2166670Spendry #include <unistd.h> 2266670Spendry 2336940Skarels #include "ftp_var.h" 2426053Sminshall 2566670Spendry static int token __P((void)); 2626053Sminshall static FILE *cfile; 2726053Sminshall 2826053Sminshall #define DEFAULT 1 2926053Sminshall #define LOGIN 2 3026053Sminshall #define PASSWD 3 3126053Sminshall #define ACCOUNT 4 3226053Sminshall #define MACDEF 5 3326053Sminshall #define ID 10 3436940Skarels #define MACH 11 3526053Sminshall 3626053Sminshall static char tokval[100]; 3726053Sminshall 3826053Sminshall static struct toktab { 3926053Sminshall char *tokstr; 4026053Sminshall int tval; 4126053Sminshall } toktab[]= { 4266670Spendry { "default", DEFAULT }, 4366670Spendry { "login", LOGIN }, 4466670Spendry { "password", PASSWD }, 4566670Spendry { "passwd", PASSWD }, 4666670Spendry { "account", ACCOUNT }, 4766670Spendry { "machine", MACH }, 4866670Spendry { "macdef", MACDEF }, 4966670Spendry { NULL, 0 } 5026053Sminshall }; 5126053Sminshall 5266670Spendry int 5336940Skarels ruserpass(host, aname, apass, aacct) 5426053Sminshall char *host, **aname, **apass, **aacct; 5526053Sminshall { 5626498Sminshall char *hdir, buf[BUFSIZ], *tmp; 5736940Skarels char myname[MAXHOSTNAMELEN], *mydomain; 5836935Skarels int t, i, c, usedefault = 0; 5926053Sminshall struct stat stb; 6026053Sminshall 6126053Sminshall hdir = getenv("HOME"); 6226053Sminshall if (hdir == NULL) 6326053Sminshall hdir = "."; 6426498Sminshall (void) sprintf(buf, "%s/.netrc", hdir); 6526053Sminshall cfile = fopen(buf, "r"); 6626053Sminshall if (cfile == NULL) { 6726053Sminshall if (errno != ENOENT) 6866670Spendry warn("%s", buf); 6966670Spendry return (0); 7026053Sminshall } 7136940Skarels if (gethostname(myname, sizeof(myname)) < 0) 7236940Skarels myname[0] = '\0'; 7366670Spendry if ((mydomain = strchr(myname, '.')) == NULL) 7436940Skarels mydomain = ""; 7526053Sminshall next: 7626053Sminshall while ((t = token())) switch(t) { 7726053Sminshall 7826053Sminshall case DEFAULT: 7936935Skarels usedefault = 1; 8036935Skarels /* FALL THROUGH */ 8126053Sminshall 8236940Skarels case MACH: 8336940Skarels if (!usedefault) { 8436940Skarels if (token() != ID) 8536940Skarels continue; 8636940Skarels /* 8736940Skarels * Allow match either for user's input host name 8836940Skarels * or official hostname. Also allow match of 8936940Skarels * incompletely-specified host in local domain. 9036940Skarels */ 9136940Skarels if (strcasecmp(host, tokval) == 0) 9236940Skarels goto match; 9336940Skarels if (strcasecmp(hostname, tokval) == 0) 9436940Skarels goto match; 9566670Spendry if ((tmp = strchr(hostname, '.')) != NULL && 9636940Skarels strcasecmp(tmp, mydomain) == 0 && 9736940Skarels strncasecmp(hostname, tokval, tmp-hostname) == 0 && 9836940Skarels tokval[tmp - hostname] == '\0') 9936940Skarels goto match; 10066670Spendry if ((tmp = strchr(host, '.')) != NULL && 10136940Skarels strcasecmp(tmp, mydomain) == 0 && 10236940Skarels strncasecmp(host, tokval, tmp - host) == 0 && 10336940Skarels tokval[tmp - host] == '\0') 10436940Skarels goto match; 10526053Sminshall continue; 10636940Skarels } 10736940Skarels match: 10836940Skarels while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { 10926053Sminshall 11026053Sminshall case LOGIN: 11126053Sminshall if (token()) 11226053Sminshall if (*aname == 0) { 11326498Sminshall *aname = malloc((unsigned) strlen(tokval) + 1); 11426498Sminshall (void) strcpy(*aname, tokval); 11526053Sminshall } else { 11626053Sminshall if (strcmp(*aname, tokval)) 11726053Sminshall goto next; 11826053Sminshall } 11926053Sminshall break; 12026053Sminshall case PASSWD: 12136940Skarels if (strcmp(*aname, "anonymous") && 12236940Skarels fstat(fileno(cfile), &stb) >= 0 && 12336940Skarels (stb.st_mode & 077) != 0) { 12466670Spendry warnx("Error: .netrc file is readable by others."); 12566670Spendry warnx("Remove password or make file unreadable by others."); 12636940Skarels goto bad; 12726053Sminshall } 12826053Sminshall if (token() && *apass == 0) { 12926498Sminshall *apass = malloc((unsigned) strlen(tokval) + 1); 13026498Sminshall (void) strcpy(*apass, tokval); 13126053Sminshall } 13226053Sminshall break; 13326053Sminshall case ACCOUNT: 13426053Sminshall if (fstat(fileno(cfile), &stb) >= 0 13526053Sminshall && (stb.st_mode & 077) != 0) { 13666670Spendry warnx("Error: .netrc file is readable by others."); 13766670Spendry warnx("Remove account or make file unreadable by others."); 13836940Skarels goto bad; 13926053Sminshall } 14026053Sminshall if (token() && *aacct == 0) { 14126498Sminshall *aacct = malloc((unsigned) strlen(tokval) + 1); 14226498Sminshall (void) strcpy(*aacct, tokval); 14326053Sminshall } 14426053Sminshall break; 14526053Sminshall case MACDEF: 14626053Sminshall if (proxy) { 14736940Skarels (void) fclose(cfile); 14866670Spendry return (0); 14926053Sminshall } 15026053Sminshall while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); 15126053Sminshall if (c == EOF || c == '\n') { 15226053Sminshall printf("Missing macdef name argument.\n"); 15336940Skarels goto bad; 15426053Sminshall } 15526053Sminshall if (macnum == 16) { 15626053Sminshall printf("Limit of 16 macros have already been defined\n"); 15736940Skarels goto bad; 15826053Sminshall } 15926053Sminshall tmp = macros[macnum].mac_name; 16026053Sminshall *tmp++ = c; 16126053Sminshall for (i=0; i < 8 && (c=getc(cfile)) != EOF && 16226053Sminshall !isspace(c); ++i) { 16326053Sminshall *tmp++ = c; 16426053Sminshall } 16526053Sminshall if (c == EOF) { 16626053Sminshall printf("Macro definition missing null line terminator.\n"); 16736940Skarels goto bad; 16826053Sminshall } 16926053Sminshall *tmp = '\0'; 17026053Sminshall if (c != '\n') { 17126053Sminshall while ((c=getc(cfile)) != EOF && c != '\n'); 17226053Sminshall } 17326053Sminshall if (c == EOF) { 17426053Sminshall printf("Macro definition missing null line terminator.\n"); 17536940Skarels goto bad; 17626053Sminshall } 17726053Sminshall if (macnum == 0) { 17826053Sminshall macros[macnum].mac_start = macbuf; 17926053Sminshall } 18026053Sminshall else { 18126053Sminshall macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 18226053Sminshall } 18326053Sminshall tmp = macros[macnum].mac_start; 18426053Sminshall while (tmp != macbuf + 4096) { 18526053Sminshall if ((c=getc(cfile)) == EOF) { 18626053Sminshall printf("Macro definition missing null line terminator.\n"); 18736940Skarels goto bad; 18826053Sminshall } 18926053Sminshall *tmp = c; 19026053Sminshall if (*tmp == '\n') { 19126053Sminshall if (*(tmp-1) == '\0') { 19226053Sminshall macros[macnum++].mac_end = tmp - 1; 19326053Sminshall break; 19426053Sminshall } 19526053Sminshall *tmp = '\0'; 19626053Sminshall } 19726053Sminshall tmp++; 19826053Sminshall } 19926053Sminshall if (tmp == macbuf + 4096) { 20026053Sminshall printf("4K macro buffer exceeded\n"); 20136940Skarels goto bad; 20226053Sminshall } 20326053Sminshall break; 20426053Sminshall default: 20566670Spendry warnx("Unknown .netrc keyword %s", tokval); 20626053Sminshall break; 20726053Sminshall } 20826053Sminshall goto done; 20926053Sminshall } 21026053Sminshall done: 21126498Sminshall (void) fclose(cfile); 21266670Spendry return (0); 21336940Skarels bad: 21436940Skarels (void) fclose(cfile); 21566670Spendry return (-1); 21626053Sminshall } 21726053Sminshall 21866670Spendry static int 21926053Sminshall token() 22026053Sminshall { 22126053Sminshall char *cp; 22226053Sminshall int c; 22326053Sminshall struct toktab *t; 22426053Sminshall 22554057Sandrew if (feof(cfile) || ferror(cfile)) 22626053Sminshall return (0); 22726053Sminshall while ((c = getc(cfile)) != EOF && 22826053Sminshall (c == '\n' || c == '\t' || c == ' ' || c == ',')) 22926053Sminshall continue; 23026053Sminshall if (c == EOF) 23126053Sminshall return (0); 23226053Sminshall cp = tokval; 23326053Sminshall if (c == '"') { 23426053Sminshall while ((c = getc(cfile)) != EOF && c != '"') { 23526053Sminshall if (c == '\\') 23626053Sminshall c = getc(cfile); 23726053Sminshall *cp++ = c; 23826053Sminshall } 23926053Sminshall } else { 24026053Sminshall *cp++ = c; 24126053Sminshall while ((c = getc(cfile)) != EOF 24226053Sminshall && c != '\n' && c != '\t' && c != ' ' && c != ',') { 24326053Sminshall if (c == '\\') 24426053Sminshall c = getc(cfile); 24526053Sminshall *cp++ = c; 24626053Sminshall } 24726053Sminshall } 24826053Sminshall *cp = 0; 24926053Sminshall if (tokval[0] == 0) 25026053Sminshall return (0); 25126053Sminshall for (t = toktab; t->tokstr; t++) 25226053Sminshall if (!strcmp(t->tokstr, tokval)) 25326053Sminshall return (t->tval); 25426053Sminshall return (ID); 25526053Sminshall } 256