10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51914Scasper * Common Development and Distribution License (the "License"). 61914Scasper * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*6812Sraf 220Sstevel@tonic-gate /* 23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 280Sstevel@tonic-gate /* All Rights Reserved */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate /* 310Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 320Sstevel@tonic-gate * The Regents of the University of California 330Sstevel@tonic-gate * All Rights Reserved 340Sstevel@tonic-gate * 350Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 360Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 370Sstevel@tonic-gate * contributors. 380Sstevel@tonic-gate */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <stdio.h> 430Sstevel@tonic-gate #include <ctype.h> 440Sstevel@tonic-gate #include <sys/types.h> 450Sstevel@tonic-gate #include <sys/stat.h> 460Sstevel@tonic-gate #include <errno.h> 470Sstevel@tonic-gate #include <unistd.h> 480Sstevel@tonic-gate #include <strings.h> 490Sstevel@tonic-gate #include <stdlib.h> 500Sstevel@tonic-gate #include <libintl.h> 510Sstevel@tonic-gate 520Sstevel@tonic-gate #ifdef SYSV 530Sstevel@tonic-gate #define index strchr 540Sstevel@tonic-gate #endif /* SYSV */ 550Sstevel@tonic-gate 560Sstevel@tonic-gate static void rnetrc(const char *host, char **aname, char **apass); 570Sstevel@tonic-gate static int token(); 580Sstevel@tonic-gate 590Sstevel@tonic-gate #define DEFAULT 1 600Sstevel@tonic-gate #define LOGIN 2 610Sstevel@tonic-gate #define PASSWD 3 620Sstevel@tonic-gate #define NOTIFY 4 630Sstevel@tonic-gate #define WRITE 5 640Sstevel@tonic-gate #define YES 6 650Sstevel@tonic-gate #define NO 7 660Sstevel@tonic-gate #define COMMAND 8 670Sstevel@tonic-gate #define FORCE 9 680Sstevel@tonic-gate #define ID 10 690Sstevel@tonic-gate #define MACHINE 11 700Sstevel@tonic-gate 710Sstevel@tonic-gate #define MAXTOKEN 11 720Sstevel@tonic-gate #define NTOKENS (MAXTOKEN - 1 + 2 + 1) /* two duplicates and null, minus id */ 730Sstevel@tonic-gate 740Sstevel@tonic-gate static struct ruserdata { 750Sstevel@tonic-gate char tokval[100]; 760Sstevel@tonic-gate struct toktab { 770Sstevel@tonic-gate char *tokstr; 780Sstevel@tonic-gate int tval; 790Sstevel@tonic-gate } toktab[NTOKENS]; 800Sstevel@tonic-gate FILE *cfile; 810Sstevel@tonic-gate } *ruserdata, *_ruserdata(); 820Sstevel@tonic-gate 830Sstevel@tonic-gate 840Sstevel@tonic-gate static struct ruserdata * 850Sstevel@tonic-gate _ruserdata() 860Sstevel@tonic-gate { 870Sstevel@tonic-gate struct ruserdata *d = ruserdata; 880Sstevel@tonic-gate struct toktab *t; 890Sstevel@tonic-gate 900Sstevel@tonic-gate if (d == 0) { 910Sstevel@tonic-gate if ((d = (struct ruserdata *) 920Sstevel@tonic-gate calloc(1, sizeof (struct ruserdata))) == NULL) { 930Sstevel@tonic-gate return (NULL); 940Sstevel@tonic-gate } 950Sstevel@tonic-gate ruserdata = d; 960Sstevel@tonic-gate t = d->toktab; 970Sstevel@tonic-gate t->tokstr = "default"; t++->tval = DEFAULT; 980Sstevel@tonic-gate t->tokstr = "login"; t++->tval = LOGIN; 990Sstevel@tonic-gate t->tokstr = "password"; t++->tval = PASSWD; 1000Sstevel@tonic-gate t->tokstr = "notify"; t++->tval = NOTIFY; 1010Sstevel@tonic-gate t->tokstr = "write"; t++->tval = WRITE; 1020Sstevel@tonic-gate t->tokstr = "yes"; t++->tval = YES; 1030Sstevel@tonic-gate t->tokstr = "y"; t++->tval = YES; 1040Sstevel@tonic-gate t->tokstr = "no"; t++->tval = NO; 1050Sstevel@tonic-gate t->tokstr = "n"; t++->tval = NO; 1060Sstevel@tonic-gate t->tokstr = "command"; t++->tval = COMMAND; 1070Sstevel@tonic-gate t->tokstr = "force"; t++->tval = FORCE; 1080Sstevel@tonic-gate t->tokstr = "machine"; t++->tval = MACHINE; 1090Sstevel@tonic-gate t->tokstr = 0; t->tval = 0; 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate return (d); 1120Sstevel@tonic-gate } 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate #define MAXANAME 16 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate void 1180Sstevel@tonic-gate _ruserpass(const char *host, char **aname, char **apass) 1190Sstevel@tonic-gate { 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate if (*aname == 0 || *apass == 0) 1220Sstevel@tonic-gate rnetrc(host, aname, apass); 1230Sstevel@tonic-gate if (*aname == 0) { 1240Sstevel@tonic-gate char myname[L_cuserid]; 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate *aname = malloc(MAXANAME + 1); 1270Sstevel@tonic-gate (void) cuserid(myname); 128*6812Sraf (void) printf(dgettext(TEXT_DOMAIN, "Name (%s:%s): "), 1291914Scasper host, myname); 1300Sstevel@tonic-gate (void) fflush(stdout); 1310Sstevel@tonic-gate if (read(2, *aname, MAXANAME) <= 0) 1320Sstevel@tonic-gate exit(1); 1330Sstevel@tonic-gate aname[0][MAXANAME] = '\0'; 1340Sstevel@tonic-gate if ((*aname)[0] == '\n') 1350Sstevel@tonic-gate (void) strcpy(*aname, myname); 1360Sstevel@tonic-gate else 1370Sstevel@tonic-gate if (index(*aname, '\n')) 1380Sstevel@tonic-gate *index(*aname, '\n') = 0; 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate if (*aname && *apass == 0) { 141*6812Sraf (void) printf(dgettext(TEXT_DOMAIN, "Password (%s:%s): "), 142*6812Sraf host, *aname); 1430Sstevel@tonic-gate (void) fflush(stdout); 1440Sstevel@tonic-gate *apass = getpass(""); 1450Sstevel@tonic-gate } 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate static void 1500Sstevel@tonic-gate rnetrc(const char *host, char **aname, char **apass) 1510Sstevel@tonic-gate { 1520Sstevel@tonic-gate struct ruserdata *d = _ruserdata(); 1530Sstevel@tonic-gate char *hdir, buf[BUFSIZ]; 1540Sstevel@tonic-gate int t; 1550Sstevel@tonic-gate struct stat64 stb; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate if (d == 0) 1580Sstevel@tonic-gate return; 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate hdir = getenv("HOME"); 1610Sstevel@tonic-gate if (hdir == NULL) 1620Sstevel@tonic-gate hdir = "."; 1630Sstevel@tonic-gate (void) sprintf(buf, "%s/.netrc", hdir); 1641914Scasper d->cfile = fopen(buf, "rF"); 1650Sstevel@tonic-gate if (d->cfile == NULL) { 1660Sstevel@tonic-gate if (errno != ENOENT) 1670Sstevel@tonic-gate perror(buf); 1680Sstevel@tonic-gate return; 1690Sstevel@tonic-gate } 1700Sstevel@tonic-gate next: 1710Sstevel@tonic-gate while ((t = token())) 1720Sstevel@tonic-gate switch (t) { 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate case DEFAULT: 1750Sstevel@tonic-gate (void) token(); 1760Sstevel@tonic-gate continue; 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate case MACHINE: 1790Sstevel@tonic-gate if (token() != ID || strcmp(host, d->tokval)) 1800Sstevel@tonic-gate continue; 1810Sstevel@tonic-gate while ((t = token()) != 0 && t != MACHINE) 1820Sstevel@tonic-gate switch (t) { 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate case LOGIN: 1850Sstevel@tonic-gate if (token()) 1860Sstevel@tonic-gate if (*aname == 0) { 1870Sstevel@tonic-gate *aname = malloc(strlen(d->tokval) + 1); 1880Sstevel@tonic-gate (void) strcpy(*aname, d->tokval); 1890Sstevel@tonic-gate } else { 1900Sstevel@tonic-gate if (strcmp(*aname, d->tokval)) 1910Sstevel@tonic-gate goto next; 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate break; 1940Sstevel@tonic-gate case PASSWD: 1950Sstevel@tonic-gate if (fstat64(fileno(d->cfile), &stb) >= 0 && 196*6812Sraf (stb.st_mode & 077) != 0) { 1970Sstevel@tonic-gate (void) fprintf(stderr, 198*6812Sraf dgettext(TEXT_DOMAIN, 1991914Scasper "Error - .netrc file not correct mode.\n")); 2000Sstevel@tonic-gate (void) fprintf(stderr, 201*6812Sraf dgettext(TEXT_DOMAIN, 2021914Scasper "Remove password or correct mode.\n")); 2030Sstevel@tonic-gate exit(1); 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate if (token() && *apass == 0) { 2060Sstevel@tonic-gate *apass = malloc(strlen(d->tokval) + 1); 2070Sstevel@tonic-gate (void) strcpy(*apass, d->tokval); 2080Sstevel@tonic-gate } 2090Sstevel@tonic-gate break; 2100Sstevel@tonic-gate case COMMAND: 2110Sstevel@tonic-gate case NOTIFY: 2120Sstevel@tonic-gate case WRITE: 2130Sstevel@tonic-gate case FORCE: 2140Sstevel@tonic-gate (void) token(); 2150Sstevel@tonic-gate break; 2160Sstevel@tonic-gate default: 217*6812Sraf (void) fprintf(stderr, dgettext(TEXT_DOMAIN, 2181914Scasper "Unknown .netrc option %s\n"), d->tokval); 2190Sstevel@tonic-gate break; 2200Sstevel@tonic-gate } 2210Sstevel@tonic-gate goto done; 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate done: 2240Sstevel@tonic-gate (void) fclose(d->cfile); 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate static int 2280Sstevel@tonic-gate token() 2290Sstevel@tonic-gate { 2300Sstevel@tonic-gate struct ruserdata *d = _ruserdata(); 2310Sstevel@tonic-gate char *cp; 2320Sstevel@tonic-gate int c; 2330Sstevel@tonic-gate struct toktab *t; 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate if (d == 0) 2360Sstevel@tonic-gate return (0); 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate if (feof(d->cfile)) 2390Sstevel@tonic-gate return (0); 2400Sstevel@tonic-gate while ((c = getc(d->cfile)) != EOF && 2410Sstevel@tonic-gate (c == '\n' || c == '\t' || c == ' ' || c == ',')) 2420Sstevel@tonic-gate continue; 2430Sstevel@tonic-gate if (c == EOF) 2440Sstevel@tonic-gate return (0); 2450Sstevel@tonic-gate cp = d->tokval; 2460Sstevel@tonic-gate if (c == '"') { 2470Sstevel@tonic-gate while ((c = getc(d->cfile)) != EOF && c != '"') { 2480Sstevel@tonic-gate if (c == '\\') 2490Sstevel@tonic-gate c = getc(d->cfile); 2500Sstevel@tonic-gate *cp++ = (char)c; 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate } else { 2530Sstevel@tonic-gate *cp++ = (char)c; 2540Sstevel@tonic-gate while ((c = getc(d->cfile)) != EOF && 255*6812Sraf c != '\n' && c != '\t' && c != ' ' && c != ',') { 2560Sstevel@tonic-gate if (c == '\\') 2570Sstevel@tonic-gate c = getc(d->cfile); 2580Sstevel@tonic-gate *cp++ = (char)c; 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate } 2610Sstevel@tonic-gate *cp = 0; 2620Sstevel@tonic-gate if (d->tokval[0] == 0) 2630Sstevel@tonic-gate return (0); 2640Sstevel@tonic-gate for (t = d->toktab; t->tokstr; t++) 2650Sstevel@tonic-gate if ((strcmp(t->tokstr, d->tokval) == 0)) 2660Sstevel@tonic-gate return (t->tval); 2670Sstevel@tonic-gate return (ID); 2680Sstevel@tonic-gate } 269