1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1998 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 #include <stdio.h> 43 #include <ctype.h> 44 #include <sys/types.h> 45 #include <sys/stat.h> 46 #include <errno.h> 47 #include <unistd.h> 48 #include <strings.h> 49 #include <stdlib.h> 50 #include <libintl.h> 51 52 extern char *_dgettext(); 53 54 #ifdef SYSV 55 #define index strchr 56 #endif /* SYSV */ 57 58 static void rnetrc(const char *host, char **aname, char **apass); 59 static int token(); 60 61 #define DEFAULT 1 62 #define LOGIN 2 63 #define PASSWD 3 64 #define NOTIFY 4 65 #define WRITE 5 66 #define YES 6 67 #define NO 7 68 #define COMMAND 8 69 #define FORCE 9 70 #define ID 10 71 #define MACHINE 11 72 73 #define MAXTOKEN 11 74 #define NTOKENS (MAXTOKEN - 1 + 2 + 1) /* two duplicates and null, minus id */ 75 76 static struct ruserdata { 77 char tokval[100]; 78 struct toktab { 79 char *tokstr; 80 int tval; 81 } toktab[NTOKENS]; 82 FILE *cfile; 83 } *ruserdata, *_ruserdata(); 84 85 86 static struct ruserdata * 87 _ruserdata() 88 { 89 struct ruserdata *d = ruserdata; 90 struct toktab *t; 91 92 if (d == 0) { 93 if ((d = (struct ruserdata *) 94 calloc(1, sizeof (struct ruserdata))) == NULL) { 95 return (NULL); 96 } 97 ruserdata = d; 98 t = d->toktab; 99 t->tokstr = "default"; t++->tval = DEFAULT; 100 t->tokstr = "login"; t++->tval = LOGIN; 101 t->tokstr = "password"; t++->tval = PASSWD; 102 t->tokstr = "notify"; t++->tval = NOTIFY; 103 t->tokstr = "write"; t++->tval = WRITE; 104 t->tokstr = "yes"; t++->tval = YES; 105 t->tokstr = "y"; t++->tval = YES; 106 t->tokstr = "no"; t++->tval = NO; 107 t->tokstr = "n"; t++->tval = NO; 108 t->tokstr = "command"; t++->tval = COMMAND; 109 t->tokstr = "force"; t++->tval = FORCE; 110 t->tokstr = "machine"; t++->tval = MACHINE; 111 t->tokstr = 0; t->tval = 0; 112 } 113 return (d); 114 } 115 116 117 #define MAXANAME 16 118 119 void 120 _ruserpass(const char *host, char **aname, char **apass) 121 { 122 123 if (*aname == 0 || *apass == 0) 124 rnetrc(host, aname, apass); 125 if (*aname == 0) { 126 char myname[L_cuserid]; 127 128 *aname = malloc(MAXANAME + 1); 129 (void) cuserid(myname); 130 (void) printf(_dgettext(TEXT_DOMAIN, "Name (%s:%s): "), host, myname); 131 (void) fflush(stdout); 132 if (read(2, *aname, MAXANAME) <= 0) 133 exit(1); 134 aname[0][MAXANAME] = '\0'; 135 if ((*aname)[0] == '\n') 136 (void) strcpy(*aname, myname); 137 else 138 if (index(*aname, '\n')) 139 *index(*aname, '\n') = 0; 140 } 141 if (*aname && *apass == 0) { 142 (void) printf(_dgettext(TEXT_DOMAIN, "Password (%s:%s): "), 143 host, *aname); 144 (void) fflush(stdout); 145 *apass = getpass(""); 146 } 147 } 148 149 150 static void 151 rnetrc(const char *host, char **aname, char **apass) 152 { 153 struct ruserdata *d = _ruserdata(); 154 char *hdir, buf[BUFSIZ]; 155 int t; 156 struct stat64 stb; 157 158 if (d == 0) 159 return; 160 161 hdir = getenv("HOME"); 162 if (hdir == NULL) 163 hdir = "."; 164 (void) sprintf(buf, "%s/.netrc", hdir); 165 d->cfile = fopen(buf, "r"); 166 if (d->cfile == NULL) { 167 if (errno != ENOENT) 168 perror(buf); 169 return; 170 } 171 next: 172 while ((t = token())) 173 switch (t) { 174 175 case DEFAULT: 176 (void) token(); 177 continue; 178 179 case MACHINE: 180 if (token() != ID || strcmp(host, d->tokval)) 181 continue; 182 while ((t = token()) != 0 && t != MACHINE) 183 switch (t) { 184 185 case LOGIN: 186 if (token()) 187 if (*aname == 0) { 188 *aname = malloc(strlen(d->tokval) + 1); 189 (void) strcpy(*aname, d->tokval); 190 } else { 191 if (strcmp(*aname, d->tokval)) 192 goto next; 193 } 194 break; 195 case PASSWD: 196 if (fstat64(fileno(d->cfile), &stb) >= 0 && 197 (stb.st_mode & 077) != 0) { 198 (void) fprintf(stderr, 199 _dgettext(TEXT_DOMAIN, 200 "Error - .netrc file not correct mode.\n")); 201 (void) fprintf(stderr, 202 _dgettext(TEXT_DOMAIN, 203 "Remove password or correct mode.\n")); 204 exit(1); 205 } 206 if (token() && *apass == 0) { 207 *apass = malloc(strlen(d->tokval) + 1); 208 (void) strcpy(*apass, d->tokval); 209 } 210 break; 211 case COMMAND: 212 case NOTIFY: 213 case WRITE: 214 case FORCE: 215 (void) token(); 216 break; 217 default: 218 (void) fprintf(stderr, 219 _dgettext(TEXT_DOMAIN, "Unknown .netrc option %s\n"), 220 d->tokval); 221 break; 222 } 223 goto done; 224 } 225 done: 226 (void) fclose(d->cfile); 227 } 228 229 static int 230 token() 231 { 232 struct ruserdata *d = _ruserdata(); 233 char *cp; 234 int c; 235 struct toktab *t; 236 237 if (d == 0) 238 return (0); 239 240 if (feof(d->cfile)) 241 return (0); 242 while ((c = getc(d->cfile)) != EOF && 243 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 244 continue; 245 if (c == EOF) 246 return (0); 247 cp = d->tokval; 248 if (c == '"') { 249 while ((c = getc(d->cfile)) != EOF && c != '"') { 250 if (c == '\\') 251 c = getc(d->cfile); 252 *cp++ = (char)c; 253 } 254 } else { 255 *cp++ = (char)c; 256 while ((c = getc(d->cfile)) != EOF && 257 c != '\n' && c != '\t' && c != ' ' && c != ',') { 258 if (c == '\\') 259 c = getc(d->cfile); 260 *cp++ = (char)c; 261 } 262 } 263 *cp = 0; 264 if (d->tokval[0] == 0) 265 return (0); 266 for (t = d->toktab; t->tokstr; t++) 267 if ((strcmp(t->tokstr, d->tokval) == 0)) 268 return (t->tval); 269 return (ID); 270 } 271