126053Sminshall /* 226053Sminshall * Copyright (c) 1985 Regents of the University of California. 333737Sbostic * All rights reserved. 433737Sbostic * 533737Sbostic * Redistribution and use in source and binary forms are permitted 634901Sbostic * provided that the above copyright notice and this paragraph are 734901Sbostic * duplicated in all such forms and that any documentation, 834901Sbostic * advertising materials, and other materials related to such 934901Sbostic * distribution and use acknowledge that the software was developed 1034901Sbostic * by the University of California, Berkeley. The name of the 1134901Sbostic * University may not be used to endorse or promote products derived 1234901Sbostic * from this software without specific prior written permission. 1334901Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434901Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536935Skarels * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1626053Sminshall */ 1726053Sminshall 1826053Sminshall #ifndef lint 19*36940Skarels static char sccsid[] = "@(#)ruserpass.c 1.8 (Berkeley) 03/01/89"; 2033737Sbostic #endif /* not lint */ 2126053Sminshall 2235631Sbostic #include <sys/types.h> 2326053Sminshall #include <stdio.h> 2426053Sminshall #include <utmp.h> 2526053Sminshall #include <ctype.h> 2626053Sminshall #include <sys/stat.h> 2726053Sminshall #include <errno.h> 28*36940Skarels #include "ftp_var.h" 2926053Sminshall 3026053Sminshall char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 3126498Sminshall char *strcpy(); 3226053Sminshall struct utmp *getutmp(); 3326053Sminshall static FILE *cfile; 3426053Sminshall 3526053Sminshall #define DEFAULT 1 3626053Sminshall #define LOGIN 2 3726053Sminshall #define PASSWD 3 3826053Sminshall #define ACCOUNT 4 3926053Sminshall #define MACDEF 5 4026053Sminshall #define ID 10 41*36940Skarels #define MACH 11 4226053Sminshall 4326053Sminshall static char tokval[100]; 4426053Sminshall 4526053Sminshall static struct toktab { 4626053Sminshall char *tokstr; 4726053Sminshall int tval; 4826053Sminshall } toktab[]= { 4926053Sminshall "default", DEFAULT, 5026053Sminshall "login", LOGIN, 5126053Sminshall "password", PASSWD, 52*36940Skarels "passwd", PASSWD, 5326053Sminshall "account", ACCOUNT, 54*36940Skarels "machine", MACH, 5526053Sminshall "macdef", MACDEF, 5626053Sminshall 0, 0 5726053Sminshall }; 5826053Sminshall 59*36940Skarels ruserpass(host, aname, apass, aacct) 6026053Sminshall char *host, **aname, **apass, **aacct; 6126053Sminshall { 6226498Sminshall char *hdir, buf[BUFSIZ], *tmp; 63*36940Skarels char myname[MAXHOSTNAMELEN], *mydomain; 6436935Skarels int t, i, c, usedefault = 0; 6526053Sminshall struct stat stb; 6626053Sminshall extern int errno; 6726053Sminshall 6826053Sminshall hdir = getenv("HOME"); 6926053Sminshall if (hdir == NULL) 7026053Sminshall hdir = "."; 7126498Sminshall (void) sprintf(buf, "%s/.netrc", hdir); 7226053Sminshall cfile = fopen(buf, "r"); 7326053Sminshall if (cfile == NULL) { 7426053Sminshall if (errno != ENOENT) 7526053Sminshall perror(buf); 7626053Sminshall return(0); 7726053Sminshall } 78*36940Skarels if (gethostname(myname, sizeof(myname)) < 0) 79*36940Skarels myname[0] = '\0'; 80*36940Skarels if ((mydomain = index(myname, '.')) == NULL) 81*36940Skarels mydomain = ""; 8226053Sminshall next: 8326053Sminshall while ((t = token())) switch(t) { 8426053Sminshall 8526053Sminshall case DEFAULT: 8636935Skarels usedefault = 1; 8736935Skarels /* FALL THROUGH */ 8826053Sminshall 89*36940Skarels case MACH: 90*36940Skarels if (!usedefault) { 91*36940Skarels if (token() != ID) 92*36940Skarels continue; 93*36940Skarels /* 94*36940Skarels * Allow match either for user's input host name 95*36940Skarels * or official hostname. Also allow match of 96*36940Skarels * incompletely-specified host in local domain. 97*36940Skarels */ 98*36940Skarels if (strcasecmp(host, tokval) == 0) 99*36940Skarels goto match; 100*36940Skarels if (strcasecmp(hostname, tokval) == 0) 101*36940Skarels goto match; 102*36940Skarels if ((tmp = index(hostname, '.')) != NULL && 103*36940Skarels strcasecmp(tmp, mydomain) == 0 && 104*36940Skarels strncasecmp(hostname, tokval, tmp-hostname) == 0 && 105*36940Skarels tokval[tmp - hostname] == '\0') 106*36940Skarels goto match; 107*36940Skarels if ((tmp = index(host, '.')) != NULL && 108*36940Skarels strcasecmp(tmp, mydomain) == 0 && 109*36940Skarels strncasecmp(host, tokval, tmp - host) == 0 && 110*36940Skarels tokval[tmp - host] == '\0') 111*36940Skarels goto match; 11226053Sminshall continue; 113*36940Skarels } 114*36940Skarels match: 115*36940Skarels while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { 11626053Sminshall 11726053Sminshall case LOGIN: 11826053Sminshall if (token()) 11926053Sminshall if (*aname == 0) { 12026498Sminshall *aname = malloc((unsigned) strlen(tokval) + 1); 12126498Sminshall (void) strcpy(*aname, tokval); 12226053Sminshall } else { 12326053Sminshall if (strcmp(*aname, tokval)) 12426053Sminshall goto next; 12526053Sminshall } 12626053Sminshall break; 12726053Sminshall case PASSWD: 128*36940Skarels if (strcmp(*aname, "anonymous") && 129*36940Skarels fstat(fileno(cfile), &stb) >= 0 && 130*36940Skarels (stb.st_mode & 077) != 0) { 13126054Sminshall fprintf(stderr, "Error - .netrc file not correct mode.\n"); 13226053Sminshall fprintf(stderr, "Remove password or correct mode.\n"); 133*36940Skarels goto bad; 13426053Sminshall } 13526053Sminshall if (token() && *apass == 0) { 13626498Sminshall *apass = malloc((unsigned) strlen(tokval) + 1); 13726498Sminshall (void) strcpy(*apass, tokval); 13826053Sminshall } 13926053Sminshall break; 14026053Sminshall case ACCOUNT: 14126053Sminshall if (fstat(fileno(cfile), &stb) >= 0 14226053Sminshall && (stb.st_mode & 077) != 0) { 14326054Sminshall fprintf(stderr, "Error - .netrc file not correct mode.\n"); 14426053Sminshall fprintf(stderr, "Remove account or correct mode.\n"); 145*36940Skarels goto bad; 14626053Sminshall } 14726053Sminshall if (token() && *aacct == 0) { 14826498Sminshall *aacct = malloc((unsigned) strlen(tokval) + 1); 14926498Sminshall (void) strcpy(*aacct, tokval); 15026053Sminshall } 15126053Sminshall break; 15226053Sminshall case MACDEF: 15326053Sminshall if (proxy) { 154*36940Skarels (void) fclose(cfile); 15526053Sminshall return(0); 15626053Sminshall } 15726053Sminshall while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); 15826053Sminshall if (c == EOF || c == '\n') { 15926053Sminshall printf("Missing macdef name argument.\n"); 160*36940Skarels goto bad; 16126053Sminshall } 16226053Sminshall if (macnum == 16) { 16326053Sminshall printf("Limit of 16 macros have already been defined\n"); 164*36940Skarels goto bad; 16526053Sminshall } 16626053Sminshall tmp = macros[macnum].mac_name; 16726053Sminshall *tmp++ = c; 16826053Sminshall for (i=0; i < 8 && (c=getc(cfile)) != EOF && 16926053Sminshall !isspace(c); ++i) { 17026053Sminshall *tmp++ = c; 17126053Sminshall } 17226053Sminshall if (c == EOF) { 17326053Sminshall printf("Macro definition missing null line terminator.\n"); 174*36940Skarels goto bad; 17526053Sminshall } 17626053Sminshall *tmp = '\0'; 17726053Sminshall if (c != '\n') { 17826053Sminshall while ((c=getc(cfile)) != EOF && c != '\n'); 17926053Sminshall } 18026053Sminshall if (c == EOF) { 18126053Sminshall printf("Macro definition missing null line terminator.\n"); 182*36940Skarels goto bad; 18326053Sminshall } 18426053Sminshall if (macnum == 0) { 18526053Sminshall macros[macnum].mac_start = macbuf; 18626053Sminshall } 18726053Sminshall else { 18826053Sminshall macros[macnum].mac_start = macros[macnum-1].mac_end + 1; 18926053Sminshall } 19026053Sminshall tmp = macros[macnum].mac_start; 19126053Sminshall while (tmp != macbuf + 4096) { 19226053Sminshall if ((c=getc(cfile)) == EOF) { 19326053Sminshall printf("Macro definition missing null line terminator.\n"); 194*36940Skarels goto bad; 19526053Sminshall } 19626053Sminshall *tmp = c; 19726053Sminshall if (*tmp == '\n') { 19826053Sminshall if (*(tmp-1) == '\0') { 19926053Sminshall macros[macnum++].mac_end = tmp - 1; 20026053Sminshall break; 20126053Sminshall } 20226053Sminshall *tmp = '\0'; 20326053Sminshall } 20426053Sminshall tmp++; 20526053Sminshall } 20626053Sminshall if (tmp == macbuf + 4096) { 20726053Sminshall printf("4K macro buffer exceeded\n"); 208*36940Skarels goto bad; 20926053Sminshall } 21026053Sminshall break; 21126053Sminshall default: 21226054Sminshall fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 21326053Sminshall break; 21426053Sminshall } 21526053Sminshall goto done; 21626053Sminshall } 21726053Sminshall done: 21826498Sminshall (void) fclose(cfile); 21926498Sminshall return(0); 220*36940Skarels bad: 221*36940Skarels (void) fclose(cfile); 222*36940Skarels return(-1); 22326053Sminshall } 22426053Sminshall 22526053Sminshall static 22626053Sminshall token() 22726053Sminshall { 22826053Sminshall char *cp; 22926053Sminshall int c; 23026053Sminshall struct toktab *t; 23126053Sminshall 23226053Sminshall if (feof(cfile)) 23326053Sminshall return (0); 23426053Sminshall while ((c = getc(cfile)) != EOF && 23526053Sminshall (c == '\n' || c == '\t' || c == ' ' || c == ',')) 23626053Sminshall continue; 23726053Sminshall if (c == EOF) 23826053Sminshall return (0); 23926053Sminshall cp = tokval; 24026053Sminshall if (c == '"') { 24126053Sminshall while ((c = getc(cfile)) != EOF && c != '"') { 24226053Sminshall if (c == '\\') 24326053Sminshall c = getc(cfile); 24426053Sminshall *cp++ = c; 24526053Sminshall } 24626053Sminshall } else { 24726053Sminshall *cp++ = c; 24826053Sminshall while ((c = getc(cfile)) != EOF 24926053Sminshall && c != '\n' && c != '\t' && c != ' ' && c != ',') { 25026053Sminshall if (c == '\\') 25126053Sminshall c = getc(cfile); 25226053Sminshall *cp++ = c; 25326053Sminshall } 25426053Sminshall } 25526053Sminshall *cp = 0; 25626053Sminshall if (tokval[0] == 0) 25726053Sminshall return (0); 25826053Sminshall for (t = toktab; t->tokstr; t++) 25926053Sminshall if (!strcmp(t->tokstr, tokval)) 26026053Sminshall return (t->tval); 26126053Sminshall return (ID); 26226053Sminshall } 263