1/* preffw.c 2 * 3 * Copyright (c) 1992-2005 by Mike Gleason. 4 * All rights reserved. 5 * 6 */ 7 8#include "syshdrs.h" 9#ifdef PRAGMA_HDRSTOP 10# pragma hdrstop 11#endif 12 13#include "pref.h" 14#include "util.h" 15 16/* How many times they've run this program. */ 17int gNumProgramRuns = 0; 18 19/* Firewall/proxy configuration parameters. */ 20int gFirewallType; 21char gFirewallHost[64]; 22char gFirewallUser[32]; 23char gFirewallPass[32]; 24char gFirewallExceptionList[256]; 25unsigned int gFirewallPort; 26int gFirewallPrefsLoaded = 0; 27 28/* Active or passive FTP? (PORT or PASV?) Or both? */ 29int gDataPortMode; 30 31/* Hack so the user/admin can set passive in the firewall 32 * prefs file. 33 */ 34int gFwDataPortMode = -1; 35 36/* Need our full hostname with domain, so we can tell if hosts are 37 * in our domain. 38 */ 39char gOurHostName[64]; 40int gGetOurHostNameResult = 100; 41 42extern char gOurDirectoryPath[], gUser[]; 43extern const char gVersion[]; 44 45 46/* Save a sample configuration file for the firewall/proxy setup. */ 47void 48WriteDefaultFirewallPrefs(FILE *fp) 49{ 50 char *cp; 51 time_t now; 52 53 if (gGetOurHostNameResult == 100) 54 gGetOurHostNameResult = GetOurHostName(gOurHostName, sizeof(gOurHostName)); 55 cp = strchr(gOurHostName, '.'); 56 57 (void) fprintf(fp, "%s", "\ 58# NcFTP firewall preferences\n\ 59# ==========================\n\ 60#\n\ 61"); 62 63 (void) fprintf(fp, "%s", "\ 64# If you need to use a proxy for FTP, you can configure it below.\n\ 65# If you do not need one, leave the ``firewall-type'' variable set\n\ 66# to 0. Any line that does not begin with the ``#'' character is\n\ 67# considered a configuration command line.\n\ 68"); 69 (void) fprintf(fp, "%s", "\ 70#\n\ 71# NOTE: NcFTP does NOT support HTTP proxies that do FTP, such as \"squid\"\n\ 72# or Netscape Proxy Server. Why? Because you have to communicate with\n\ 73# them using HTTP, and this is a FTP only program.\n\ 74"); 75 (void) fprintf(fp, "%s", "\ 76#\n\ 77# Types of firewalls:\n\ 78# ------------------\n\ 79#\n\ 80# type 1: Connect to firewall host, but send \"USER user@real.host.name\"\n\ 81#\n\ 82"); 83 (void) fprintf(fp, "%s", "\ 84# type 2: Connect to firewall, login with \"USER fwuser\" and\n\ 85# \"PASS fwpassword\", and then \"USER user@real.host.name\"\n\ 86#\n\ 87# type 3: Connect to and login to firewall, and then use\n\ 88# \"SITE real.host.name\", followed by the regular USER and PASS.\n\ 89#\n\ 90"); 91 (void) fprintf(fp, "%s", "\ 92# type 4: Connect to and login to firewall, and then use\n\ 93# \"OPEN real.host.name\", followed by the regular USER and PASS.\n\ 94#\n\ 95# type 5: Connect to firewall host, but send\n\ 96# \"USER user@fwuser@real.host.name\" and\n\ 97# \"PASS pass@fwpass\" to login.\n\ 98#\n\ 99"); 100 (void) fprintf(fp, "%s", "\ 101# type 6: Connect to firewall host, but send\n\ 102# \"USER fwuser@real.host.name\" and\n\ 103# \"PASS fwpass\" followed by a regular\n\ 104# \"USER user\" and\n\ 105# \"PASS pass\" to complete the login.\n\ 106#\n\ 107"); 108 (void) fprintf(fp, "%s", "\ 109# type 7: Connect to firewall host, but send\n\ 110# \"USER user@real.host.name fwuser\" and\n\ 111# \"PASS pass\" followed by\n\ 112# \"ACCT fwpass\" to complete the login.\n\ 113#\n\ 114"); 115 (void) fprintf(fp, "%s", "\ 116# type 8: Connect to firewall host, but send \"USER user@real.host.name:port\"\n\ 117#\n\ 118# type 9: Connect to firewall host, but send \"USER user@real.host.name port\"\n\ 119#\n\ 120"); 121 (void) fprintf(fp, "%s", "\ 122# type 0: Do NOT use a firewall (most users will choose this).\n\ 123#\n\ 124firewall-type=0\n\ 125#\n\ 126#\n\ 127#\n\ 128"); 129 (void) fprintf(fp, "%s", "\ 130# The ``firewall-host'' variable should be the IP address or hostname of\n\ 131# your firewall server machine.\n\ 132#\n\ 133"); 134 135 if (cp == NULL) { 136 (void) fprintf(fp, "firewall-host=firewall.domain.com\n"); 137 } else { 138 (void) fprintf(fp, "firewall-host=firewall%s\n", cp); 139 } 140 141 (void) fprintf(fp, "%s", "\ 142#\n\ 143#\n\ 144#\n\ 145# The ``firewall-user'' variable tells NcFTP what to use as the user ID\n\ 146# when it logs in to the firewall before connecting to the outside world.\n\ 147#\n\ 148"); 149 (void) fprintf(fp, "firewall-user=%s\n", gUser); 150 (void) fprintf(fp, "%s", "\ 151#\n\ 152#\n\ 153#\n\ 154# The ``firewall-password'' variable is the password associated with\n\ 155# the firewall-user ID. If you set this here, be sure to change the\n\ 156# permissions on this file so that no one (except the superuser) can\n\ 157# see your password. You may also leave this commented out, and then\n\ 158# NcFTP will prompt you each time for the password.\n\ 159"); 160 (void) fprintf(fp, "%s", "\ 161#\n\ 162firewall-password=fwpass\n\ 163#\n\ 164#\n\ 165#\n\ 166# Your firewall may require you to connect to a non-standard port for\n\ 167# outside FTP services, instead of the internet standard port number (21).\n\ 168#\n\ 169firewall-port=21\n\ 170"); 171 (void) fprintf(fp, "%s", "\ 172#\n\ 173#\n\ 174#\n\ 175# You probably do not want to FTP to the firewall for hosts on your own\n\ 176# domain. You can set ``firewall-exception-list'' to a list of domains\n\ 177# or hosts where the firewall should not be used. For example, if your\n\ 178# domain was ``probe.net'' you could set this to ``.probe.net''.\n\ 179#\n\ 180"); 181 (void) fprintf(fp, "%s", "\ 182# If you leave this commented out, the default behavior is to attempt to\n\ 183# lookup the current domain, and exclude hosts for it. Otherwise, set it\n\ 184# to a list of comma-delimited domains or hostnames. The special token\n\ 185# ``localdomain'' is used for unqualified hostnames, so if you want hosts\n\ 186# without explicit domain names to avoid the firewall, be sure to include\n\ 187# that in your list.\n\ 188#\n\ 189"); 190 191 if (cp != NULL) { 192 (void) fprintf(fp, "firewall-exception-list=%s,localhost,localdomain\n", cp); 193 } else { 194 (void) fprintf(fp, "firewall-exception-list=.probe.net,localhost,foo.bar.com,localdomain\n"); 195 } 196 197 (void) fprintf(fp, "%s", "\ 198#\n\ 199#\n\ 200#\n\ 201# You may also specify passive mode here. Normally this is set in the\n\ 202# regular $HOME/.ncftp/prefs file. This must be set to one of\n\ 203# \"on\", \"off\", or \"optional\", which mean always use PASV,\n\ 204# always use PORT, and try PASV then PORT, respectively.\n\ 205#\n\ 206#passive=on\n"); 207 208 time(&now); 209 (void) fprintf(fp, "\ 210#\n\ 211#\n\ 212#\n\ 213# NOTE: This file was created for you on %s\ 214# by NcFTP %.5s. Removing this file will cause the next run of NcFTP\n\ 215# to generate a new one, possibly with more configurable options.\n", 216 ctime(&now), 217 gVersion + 11); 218 (void) fprintf(fp, "\ 219#\n\ 220# ALSO: A %s file, if present, is processed before this file,\n\ 221# and a %s file, if present, is processed after.\n", 222 kGlobalFirewallPrefFileName, 223 kGlobalFixedFirewallPrefFileName 224 ); 225} /* CreateDefaultFirewallPrefs */ 226 227 228 229 230void 231ProcessFirewallPrefFile(FILE *fp) 232{ 233 char line[256]; 234 char *tok1, *tok2; 235 int n; 236 237 /* Opened the firewall preferences file. */ 238 line[sizeof(line) - 1] = '\0'; 239 while (fgets(line, sizeof(line) - 1, fp) != NULL) { 240 tok1 = strtok(line, " =\t\r\n"); 241 if ((tok1 == NULL) || (tok1[0] == '#')) 242 continue; 243 tok2 = strtok(NULL, "\r\n"); 244 if (tok2 == NULL) 245 continue; 246 if (ISTREQ(tok1, "firewall-type")) { 247 n = atoi(tok2); 248 if ((n > 0) && (n <= kFirewallLastType)) 249 gFirewallType = n; 250 } else if (ISTREQ(tok1, "firewall-host")) { 251 (void) STRNCPY(gFirewallHost, tok2); 252 } else if (ISTREQ(tok1, "firewall-port")) { 253 n = atoi(tok2); 254 if (n > 0) 255 gFirewallPort = (unsigned int) n; 256 } else if (ISTREQ(tok1, "firewall-user")) { 257 (void) STRNCPY(gFirewallUser, tok2); 258 } else if (ISTREQ(tok1, "firewall-pass")) { 259 (void) STRNCPY(gFirewallPass, tok2); 260 } else if (ISTREQ(tok1, "firewall-password")) { 261 (void) STRNCPY(gFirewallPass, tok2); 262 } else if (ISTREQ(tok1, "firewall-exception-list")) { 263 (void) STRNCPY(gFirewallExceptionList, tok2); 264 } else if (ISTREQ(tok1, "passive")) { 265 if (ISTREQ(tok2, "optional")) { 266 gDataPortMode = gFwDataPortMode = kFallBackToSendPortMode; 267 } else if (ISTREQ(tok2, "on")) { 268 gDataPortMode = gFwDataPortMode = kPassiveMode; 269 } else if (ISTREQ(tok2, "off")) { 270 gDataPortMode = gFwDataPortMode = kSendPortMode; 271 } else if ((int) isdigit((int) tok2[0])) { 272 gDataPortMode = gFwDataPortMode = atoi(tok2); 273 } 274 } 275 } 276} /* ProcessFirewallPrefFile */ 277 278 279 280 281/* Load those options specific to the firewall/proxy settings. These are 282 * kept in a different file so that other programs can read it and not 283 * have to worry about the other junk in the prefs file. 284 */ 285void 286LoadFirewallPrefs(int forceReload) 287{ 288 FILE *fp, *fp2; 289 char pathName[256]; 290 char *cp; 291 int userFile = 0; 292 int sysFile = 0; 293 294 if ((gFirewallPrefsLoaded != 0) && (forceReload == 0)) 295 return; 296 gFirewallPrefsLoaded = 1; 297 pathName[0] = '\0'; 298 299 /* Set default values. */ 300 gFirewallType = kFirewallNotInUse; 301 gFirewallPort = 0; 302 gFirewallHost[0] = '\0'; 303 gFirewallUser[0] = '\0'; 304 gFirewallPass[0] = '\0'; 305 gFirewallExceptionList[0] = '\0'; 306 307 fp2 = fopen(kGlobalFirewallPrefFileName, FOPEN_READ_TEXT); 308 if (fp2 != NULL) { 309 /* Initialize to system-wide defaults. */ 310 ProcessFirewallPrefFile(fp2); 311 (void) fclose(fp2); 312 sysFile++; 313 } 314 315 if (gOurDirectoryPath[0] != '\0') { 316 (void) OurDirectoryPath(pathName, sizeof(pathName), kFirewallPrefFileName); 317 fp = fopen(pathName, FOPEN_READ_TEXT); 318 if (fp != NULL) { 319 /* Do user's firewall file. */ 320 ProcessFirewallPrefFile(fp); 321 (void) fclose(fp); 322 userFile = 1; 323 } 324 } 325 326 fp2 = fopen(kGlobalFixedFirewallPrefFileName, FOPEN_READ_TEXT); 327 if (fp2 != NULL) { 328 /* Override with system-wide settings. */ 329 ProcessFirewallPrefFile(fp2); 330 (void) fclose(fp2); 331 sysFile++; 332 } 333 334 if ((userFile == 0) && (sysFile == 0) && (pathName[0] != '\0')) { 335 /* Create a blank one, if there were no system-wide files, 336 * and if the user's $HOME is not the root directory. 337 */ 338 fp = fopen(pathName, FOPEN_WRITE_TEXT); 339 if (fp != NULL) { 340 WriteDefaultFirewallPrefs(fp); 341 (void) fclose(fp); 342#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__) 343#else 344 (void) chmod(pathName, 00600); 345#endif 346 gNumProgramRuns = 1; 347 } 348 } 349 350 if (gFirewallExceptionList[0] == '\0') { 351 if (gGetOurHostNameResult == 100) 352 gGetOurHostNameResult = GetOurHostName(gOurHostName, sizeof(gOurHostName)); 353 354 cp = strchr(gOurHostName, '.'); 355 356 if (cp != NULL) { 357 (void) STRNCPY(gFirewallExceptionList, cp); 358 (void) STRNCAT(gFirewallExceptionList, ",localdomain"); 359 } 360 } 361} /* LoadFirewallPrefs */ 362