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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * University Copyright- Copyright (c) 1982, 1986, 1988 31 * The Regents of the University of California 32 * All Rights Reserved 33 * 34 * University Acknowledgment- Portions of this document are derived from 35 * software developed by the University of California, Berkeley, and its 36 * contributors. 37 */ 38 39 #pragma ident "%Z%%M% %I% %E% SMI" 40 41 #include "ftp_var.h" 42 43 static FILE *cfile; 44 45 static int rnetrc(char *host, char **aname, char **apass, char **aacct); 46 static int token(void); 47 48 int 49 ruserpass(char *host, char **aname, char **apass, char **aacct) 50 { 51 #if 0 52 renv(host, aname, apass, aacct); 53 if (*aname == 0 || *apass == 0) 54 #endif 55 return (rnetrc(host, aname, apass, aacct)); 56 } 57 58 #define DEFAULT 1 59 #define LOGIN 2 60 #define PASSWD 3 61 #define ACCOUNT 4 62 #define MACDEF 5 63 #define SKIPSYST 6 64 #define ID 10 65 #define MACHINE 11 66 67 static char tokval[100]; 68 69 static struct toktab { 70 char *tokstr; 71 int tval; 72 } toktab[] = { 73 "default", DEFAULT, 74 "login", LOGIN, 75 "password", PASSWD, 76 "account", ACCOUNT, 77 "machine", MACHINE, 78 "macdef", MACDEF, 79 "skipsyst", SKIPSYST, 80 0, 0 81 }; 82 83 static int 84 rnetrc(char *host, char **aname, char **apass, char **aacct) 85 { 86 char *hdir, buf[PATH_MAX+1], *tmp; 87 int t, i, c; 88 struct stat stb; 89 extern int errno; 90 91 hdir = getenv("HOME"); 92 if (hdir == NULL) 93 hdir = "."; 94 if (snprintf(buf, sizeof (buf), "%s/.netrc", hdir) >= sizeof (buf)) { 95 fprintf(stderr, ".netrc: %s\n", strerror(ENAMETOOLONG)); 96 exit(1); 97 } 98 99 cfile = fopen(buf, "r"); 100 if (cfile == NULL) { 101 if (errno != ENOENT) 102 perror(buf); 103 return (0); 104 } 105 next: 106 while ((t = token())) 107 switch (t) { 108 109 case MACHINE: 110 if (token() != ID || strcmp(host, tokval)) 111 continue; 112 /* "machine name" matches host */ 113 /* FALLTHROUGH */ 114 115 case DEFAULT: 116 /* "default" matches any host */ 117 while (((t = token()) != 0) && t != MACHINE && t != DEFAULT) 118 switch (t) { 119 120 case LOGIN: 121 if (token()) 122 if (*aname == 0) { 123 *aname = malloc((unsigned) 124 strlen(tokval) + 1); 125 if (*aname == NULL) { 126 fprintf(stderr, 127 "Error - out of VM\n"); 128 exit(1); 129 } 130 (void) strcpy(*aname, tokval); 131 } else { 132 if (strcmp(*aname, tokval)) 133 goto next; 134 } 135 break; 136 case PASSWD: 137 if (fstat(fileno(cfile), &stb) >= 0 && 138 (stb.st_mode & 077) != 0) { 139 fprintf(stderr, "Error - .netrc file not " 140 "correct mode.\n"); 141 fprintf(stderr, "Remove password or correct " 142 "mode.\n"); 143 return (-1); 144 } 145 if (token() && *apass == 0) { 146 *apass = malloc((unsigned)strlen(tokval) + 1); 147 if (*apass == NULL) { 148 fprintf(stderr, "Error - out of VM\n"); 149 exit(1); 150 } 151 (void) strcpy(*apass, tokval); 152 } 153 break; 154 case ACCOUNT: 155 if (fstat(fileno(cfile), &stb) >= 0 && 156 (stb.st_mode & 077) != 0) { 157 fprintf(stderr, "Error - .netrc file not " 158 "correct mode.\n"); 159 fprintf(stderr, "Remove account or correct " 160 "mode.\n"); 161 return (-1); 162 } 163 if (token() && *aacct == 0) { 164 *aacct = malloc((unsigned)strlen(tokval) + 1); 165 if (*aacct == NULL) { 166 fprintf(stderr, "Error - out of VM\n"); 167 exit(1); 168 } 169 (void) strcpy(*aacct, tokval); 170 } 171 break; 172 case MACDEF: 173 if (proxy) { 174 return (0); 175 } 176 while ((c = getc(cfile)) != EOF && c == ' ' || 177 c == '\t'); 178 if (c == EOF || c == '\n') { 179 printf("Missing macdef name argument.\n"); 180 return (-1); 181 } 182 if (macnum == 16) { 183 printf("Limit of 16 macros have already " 184 "been defined\n"); 185 return (-1); 186 } 187 tmp = macros[macnum].mac_name; 188 *tmp++ = c; 189 for (i = 0; i < 8 && (c = getc(cfile)) != EOF && 190 !isspace(c); ++i) { 191 *tmp++ = c; 192 } 193 if (c == EOF) { 194 printf("Macro definition for `%s` missing " 195 "null line terminator.\n", 196 macros[macnum].mac_name); 197 return (-1); 198 } 199 *tmp = '\0'; 200 if (c != '\n') { 201 while ((c = getc(cfile)) != EOF && c != '\n'); 202 } 203 if (c == EOF) { 204 printf("Macro definition for `%s` missing " 205 "null line terminator.\n", 206 macros[macnum].mac_name); 207 return (-1); 208 } 209 if (macnum == 0) { 210 macros[macnum].mac_start = macbuf; 211 } else { 212 macros[macnum].mac_start = 213 macros[macnum-1].mac_end + 1; 214 } 215 tmp = macros[macnum].mac_start; 216 while (tmp != macbuf + 4096) { 217 if ((c = getc(cfile)) == EOF) { 218 printf("Macro definition for `%s` missing " 219 "null line terminator.\n", 220 macros[macnum].mac_name); 221 return (-1); 222 } 223 *tmp = c; 224 if (*tmp == '\n') { 225 if (*(tmp-1) == '\0') { 226 macros[macnum++].mac_end = 227 tmp - 1; 228 break; 229 } 230 *tmp = '\0'; 231 } 232 tmp++; 233 } 234 if (tmp == macbuf + 4096) { 235 printf("4K macro buffer exceeded\n"); 236 return (-1); 237 } 238 if (*macros[macnum - 1].mac_start == '\n') { 239 printf("Macro definition for `%s` is empty, " 240 "macro not stored.\n", 241 macros[--macnum].mac_name); 242 } 243 break; 244 case SKIPSYST: 245 skipsyst = 1; 246 break; 247 default: 248 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 249 break; 250 } 251 goto done; 252 } 253 done: 254 (void) fclose(cfile); 255 return (0); 256 } 257 258 static int 259 token(void) 260 { 261 char *cp; 262 int c; 263 struct toktab *t; 264 int len; 265 266 if (feof(cfile)) 267 return (0); 268 while ((c = fgetwc(cfile)) != EOF && 269 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 270 continue; 271 if (c == EOF) 272 return (0); 273 cp = tokval; 274 if (c == '"') { 275 while ((c = fgetwc(cfile)) != EOF && c != '"') { 276 if (c == '\\') 277 c = fgetwc(cfile); 278 if ((len = wctomb(cp, c)) <= 0) { 279 len = 1; 280 *cp = (unsigned char)c; 281 } 282 cp += len; 283 } 284 } else { 285 if ((len = wctomb(cp, c)) <= 0) { 286 *cp = (unsigned char)c; 287 len = 1; 288 } 289 cp += len; 290 while ((c = fgetwc(cfile)) != EOF && c != '\n' && c != '\t' && 291 c != ' ' && c != ',') { 292 if (c == '\\') 293 c = fgetwc(cfile); 294 if ((len = wctomb(cp, c)) <= 0) { 295 len = 1; 296 *cp = (unsigned char)c; 297 } 298 cp += len; 299 } 300 } 301 *cp = 0; 302 if (tokval[0] == 0) 303 return (0); 304 for (t = toktab; t->tokstr; t++) 305 if (strcmp(t->tokstr, tokval) == 0) 306 return (t->tval); 307 return (ID); 308 } 309