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 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 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 "ftp_var.h" 43 44 static FILE *cfile; 45 46 static int rnetrc(char *host, char **aname, char **apass, char **aacct); 47 static int token(void); 48 49 int 50 ruserpass(char *host, char **aname, char **apass, char **aacct) 51 { 52 #if 0 53 renv(host, aname, apass, aacct); 54 if (*aname == 0 || *apass == 0) 55 #endif 56 return (rnetrc(host, aname, apass, aacct)); 57 } 58 59 #define DEFAULT 1 60 #define LOGIN 2 61 #define PASSWD 3 62 #define ACCOUNT 4 63 #define MACDEF 5 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 0, 0 80 }; 81 82 static int 83 rnetrc(char *host, char **aname, char **apass, char **aacct) 84 { 85 char *hdir, buf[PATH_MAX+1], *tmp; 86 int t, i, c; 87 struct stat stb; 88 extern int errno; 89 90 hdir = getenv("HOME"); 91 if (hdir == NULL) 92 hdir = "."; 93 if (snprintf(buf, sizeof (buf), "%s/.netrc", hdir) >= sizeof (buf)) { 94 fprintf(stderr, ".netrc: %s\n", strerror(ENAMETOOLONG)); 95 exit(1); 96 } 97 98 cfile = fopen(buf, "r"); 99 if (cfile == NULL) { 100 if (errno != ENOENT) 101 perror(buf); 102 return (0); 103 } 104 next: 105 while ((t = token())) 106 switch (t) { 107 108 case MACHINE: 109 if (token() != ID || strcmp(host, tokval)) 110 continue; 111 /* "machine name" matches host */ 112 /* FALLTHROUGH */ 113 114 case DEFAULT: 115 /* "default" matches any host */ 116 while (((t = token()) != 0) && t != MACHINE && t != DEFAULT) 117 switch (t) { 118 119 case LOGIN: 120 if (token()) 121 if (*aname == 0) { 122 *aname = malloc((unsigned) 123 strlen(tokval) + 1); 124 if (*aname == NULL) { 125 fprintf(stderr, 126 "Error - out of VM\n"); 127 exit(1); 128 } 129 (void) strcpy(*aname, tokval); 130 } else { 131 if (strcmp(*aname, tokval)) 132 goto next; 133 } 134 break; 135 case PASSWD: 136 if (fstat(fileno(cfile), &stb) >= 0 && 137 (stb.st_mode & 077) != 0) { 138 fprintf(stderr, "Error - .netrc file not " 139 "correct mode.\n"); 140 fprintf(stderr, "Remove password or correct " 141 "mode.\n"); 142 return (-1); 143 } 144 if (token() && *apass == 0) { 145 *apass = malloc((unsigned)strlen(tokval) + 1); 146 if (*apass == NULL) { 147 fprintf(stderr, "Error - out of VM\n"); 148 exit(1); 149 } 150 (void) strcpy(*apass, tokval); 151 } 152 break; 153 case ACCOUNT: 154 if (fstat(fileno(cfile), &stb) >= 0 && 155 (stb.st_mode & 077) != 0) { 156 fprintf(stderr, "Error - .netrc file not " 157 "correct mode.\n"); 158 fprintf(stderr, "Remove account or correct " 159 "mode.\n"); 160 return (-1); 161 } 162 if (token() && *aacct == 0) { 163 *aacct = malloc((unsigned)strlen(tokval) + 1); 164 if (*aacct == NULL) { 165 fprintf(stderr, "Error - out of VM\n"); 166 exit(1); 167 } 168 (void) strcpy(*aacct, tokval); 169 } 170 break; 171 case MACDEF: 172 if (proxy) { 173 return (0); 174 } 175 while ((c = getc(cfile)) != EOF && c == ' ' || 176 c == '\t'); 177 if (c == EOF || c == '\n') { 178 printf("Missing macdef name argument.\n"); 179 return (-1); 180 } 181 if (macnum == 16) { 182 printf("Limit of 16 macros have already " 183 "been defined\n"); 184 return (-1); 185 } 186 tmp = macros[macnum].mac_name; 187 *tmp++ = c; 188 for (i = 0; i < 8 && (c = getc(cfile)) != EOF && 189 !isspace(c); ++i) { 190 *tmp++ = c; 191 } 192 if (c == EOF) { 193 printf("Macro definition for `%s` missing " 194 "null line terminator.\n", 195 macros[macnum].mac_name); 196 return (-1); 197 } 198 *tmp = '\0'; 199 if (c != '\n') { 200 while ((c = getc(cfile)) != EOF && c != '\n'); 201 } 202 if (c == EOF) { 203 printf("Macro definition for `%s` missing " 204 "null line terminator.\n", 205 macros[macnum].mac_name); 206 return (-1); 207 } 208 if (macnum == 0) { 209 macros[macnum].mac_start = macbuf; 210 } else { 211 macros[macnum].mac_start = 212 macros[macnum-1].mac_end + 1; 213 } 214 tmp = macros[macnum].mac_start; 215 while (tmp != macbuf + 4096) { 216 if ((c = getc(cfile)) == EOF) { 217 printf("Macro definition for `%s` missing " 218 "null line terminator.\n", 219 macros[macnum].mac_name); 220 return (-1); 221 } 222 *tmp = c; 223 if (*tmp == '\n') { 224 if (*(tmp-1) == '\0') { 225 macros[macnum++].mac_end = 226 tmp - 1; 227 break; 228 } 229 *tmp = '\0'; 230 } 231 tmp++; 232 } 233 if (tmp == macbuf + 4096) { 234 printf("4K macro buffer exceeded\n"); 235 return (-1); 236 } 237 if (*macros[macnum - 1].mac_start == '\n') { 238 printf("Macro definition for `%s` is empty, " 239 "macro not stored.\n", 240 macros[--macnum].mac_name); 241 } 242 break; 243 default: 244 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); 245 break; 246 } 247 goto done; 248 } 249 done: 250 (void) fclose(cfile); 251 return (0); 252 } 253 254 static int 255 token(void) 256 { 257 char *cp; 258 int c; 259 struct toktab *t; 260 int len; 261 262 if (feof(cfile)) 263 return (0); 264 while ((c = fgetwc(cfile)) != EOF && 265 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 266 continue; 267 if (c == EOF) 268 return (0); 269 cp = tokval; 270 if (c == '"') { 271 while ((c = fgetwc(cfile)) != EOF && c != '"') { 272 if (c == '\\') 273 c = fgetwc(cfile); 274 if ((len = wctomb(cp, c)) <= 0) { 275 len = 1; 276 *cp = (unsigned char)c; 277 } 278 cp += len; 279 } 280 } else { 281 if ((len = wctomb(cp, c)) <= 0) { 282 *cp = (unsigned char)c; 283 len = 1; 284 } 285 cp += len; 286 while ((c = fgetwc(cfile)) != EOF && c != '\n' && c != '\t' && 287 c != ' ' && c != ',') { 288 if (c == '\\') 289 c = fgetwc(cfile); 290 if ((len = wctomb(cp, c)) <= 0) { 291 len = 1; 292 *cp = (unsigned char)c; 293 } 294 cp += len; 295 } 296 } 297 *cp = 0; 298 if (tokval[0] == 0) 299 return (0); 300 for (t = toktab; t->tokstr; t++) 301 if (strcmp(t->tokstr, tokval) == 0) 302 return (t->tval); 303 return (ID); 304 } 305