Exemple #1
0
static int CALLBACK AboutProc(HWND hwnd, UINT msg,
			      WPARAM wParam, LPARAM lParam)
{
    char vbuf[160];
    switch (msg) {
      case WM_INITDIALOG:
	showversion(0, vbuf);
	SetDlgItemText(hwnd, 100, vbuf);
	showversion(1, vbuf);
	SetDlgItemText(hwnd, 101, vbuf);
	showversion(2, vbuf);
	SetDlgItemText(hwnd, 102, vbuf);
	return 1;
      case WM_COMMAND:
	switch (LOWORD(wParam)) {
	  case IDOK:
	    aboutbox = NULL;
	    DestroyWindow(hwnd);
	    return 0;
	  case 112:
	    EnableWindow(hwnd, 0);
	    DialogBox(listener_instance, MAKEINTRESOURCE(301),
		      NULL, LicenceProc);
	    EnableWindow(hwnd, 1);
	    SetActiveWindow(hwnd);
	    return 0;
	}
	return 0;
      case WM_CLOSE:
	aboutbox = NULL;
	DestroyWindow(hwnd);
	return 0;
    }
    return 0;
}
void help(void)
{
    /*
     * Help message is an extended version of the usage message. So
     * start with that, plus a version heading.
     */
    showversion();
    usage();
    fprintf(stderr,
	    "  -t    specify key type when generating (rsa, dsa, rsa1)\n"
	    "  -b    specify number of bits when generating key\n"
	    "  -C    change or specify key comment\n"
	    "  -P    change key passphrase\n"
	    "  -O    specify output type:\n"
	    "           private             output PuTTY private key format\n"
	    "           private-openssh     export OpenSSH private key\n"
	    "           private-sshcom      export ssh.com private key\n"
	    "           public              standard / ssh.com public key\n"
	    "           public-openssh      OpenSSH public key\n"
	    "           fingerprint         output the key fingerprint\n"
	    "  -o    specify output file\n"
	    "  -l    equivalent to `-O fingerprint'\n"
	    "  -L    equivalent to `-O public-openssh'\n"
	    "  -p    equivalent to `-O public'\n"
	    );
}
Exemple #3
0
int parse_arguments(cli_args_t *args, int argc, char **argv) {
	static const struct option options[] = {
		{ "debug",		required_argument,	NULL, 'd' },
		{ "foreground",	no_argument,		NULL, 'f' },
		{ "interface",  required_argument,  NULL, 'i' },
		{ "chrootdir",	required_argument,	NULL, 't' },
		{ "username",	required_argument,	NULL, 'u' },
		{ "version",	no_argument,		NULL, 'v' },
		{ "help",		no_argument,		NULL, 'h' },
		{ NULL, no_argument, NULL, 0 }
	};
	memset(args, 0, sizeof(struct cli_args));
	args->argc = argc;
	args->argv = argv;
	args->exename = strrchr(argv[0], '/');
	args->exename = (args->exename != NULL) ? args->exename+1 : argv[0];
	while (1) {
		int opt_index = 0;
		int opt = getopt_long(argc, argv, get_opt_string(options), options, &opt_index);
		if (opt == -1)
			break;
		switch (opt) {
			case 'd': args->debuglevel = atoi(optarg); break;
			case 'f': args->foreground = true; break;
			case 'i': args->interface_name = optarg; break;
			case 't': args->chrootdir = optarg; break;
			case 'u': args->username = optarg; break;
			case 'v': showversion(); exit(EXIT_SUCCESS);
			case 'h': usage(args); exit(EXIT_SUCCESS);
			case '?': usage(args); exit(EXIT_FAILURE);
		}
	}
	return 0;
}
Exemple #4
0
static int CALLBACK AboutProc(HWND hwnd, UINT msg,
			      WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
      case WM_INITDIALOG:
	showversion(hwnd, 102);
	return 1;
      case WM_COMMAND:
	switch (LOWORD(wParam)) {
	  case IDOK:
	  case IDCANCEL:
	    aboutbox = NULL;
	    DestroyWindow(hwnd);
	    return 0;
	  case 112:
	    EnableWindow(hwnd, 0);
	    DialogBox(winurl_instance, MAKEINTRESOURCE(301),
		      NULL, LicenceProc);
	    EnableWindow(hwnd, 1);
	    SetActiveWindow(hwnd);
	    return 0;
	}
	return 0;
      case WM_CLOSE:
	aboutbox = NULL;
	DestroyWindow(hwnd);
	return 0;
    }
    return 0;
}
Exemple #5
0
int main(int argc, char **argv) {
    int i;
    if (argc<2)
        showusage (1);
    if (!strcmp (argv[1], "-v"))
        showversion ();
    if (!strcmp (argv[1], "-h"))
        showusage (0);
    if (argc == 2)
        return sdb_dump (argv[1]);

#if USE_MMAN
    signal (SIGINT, terminate);
    signal (SIGHUP, syncronize);
#endif

    if (!strcmp (argv[2], "=")) {
        createdb (argv[1]);
    } else if (!strcmp (argv[2], "-")) {
        char line[SDB_VALUESIZE];
        if ((s = sdb_new (argv[1], 0)))
            for (;;) {
                fgets (line, sizeof line, stdin);
                if (feof (stdin))
                    break;
                line[strlen (line)-1] = 0;
                runline (s, line);
            }
    } else if ((s = sdb_new (argv[1], 0)))
        for (i=2; i<argc; i++)
            runline (s, argv[i]);
    terminate (0);
    return 0;
}
Exemple #6
0
int main(int argc, const char **argv) {
	char *line;
	int i;

	if (argc<2) showusage (1);
	if (!strcmp (argv[1], "-d")) {
		if (argc == 4)
			return dbdiff (argv[2], argv[3]);
		showusage(0);
	} else
	if (!strcmp (argv[1], "-v")) showversion ();
	if (!strcmp (argv[1], "-h")) showusage (0);
	if (!strcmp (argv[1], "-j")) {
		if (argc>2)
			return sdb_dump (argv[2], 1);
		printf ("Missing database filename after -j\n");
		return 1;
	}
	if (!strcmp (argv[1], "-")) {
		argv[1] = "";
		if (argc == 2) {
			argv[2] = "-";
			argc++;
		}
	}
	if (argc == 2)
		return sdb_dump (argv[1], 0);
#if USE_MMAN
	signal (SIGINT, terminate);
	signal (SIGHUP, syncronize);
#endif
	if (!strcmp (argv[2], "="))
		return createdb (argv[1]);
	else if (!strcmp (argv[2], "-")) {
		if ((s = sdb_new (NULL, argv[1], 0))) {
			sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP);
			for (;(line = stdin_gets ());) {
				save = sdb_query (s, line);
				free (line);
			}
		}
	} else {
		s = sdb_new (NULL, argv[1], 0);
		if (!s) return 1;
		sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP);
		for (i=2; i<argc; i++)
			save = sdb_query (s, argv[i]);
	}
	terminate (0);
	return 0;
}
Exemple #7
0
bool ParseCommandLine(int argc,wchar* argv[])
{
	int cl=argc-2;
	wchar** arg=argv+1;
	while(cl>=0)
	{
		if (stricmp(*arg,"-help")==0 || stricmp(*arg,"--help")==0)
		{
			showhelp(arg,cl);
			return true;
		}
		if (stricmp(*arg,"-version")==0 || stricmp(*arg,"--version")==0)
		{
			showversion(arg,cl);
			return true;
		}
		else if (stricmp(*arg,"-config")==0 || stricmp(*arg,"--config")==0)
		{
			int as=setconfig(arg,cl);
			cl-=as;
			arg+=as;
		}
		else
		{
			char* extension = strrchr(*arg, '.');

			if (extension
				&& (stricmp(extension, ".cdi") == 0 || stricmp(extension, ".chd") == 0
					|| stricmp(extension, ".gdi") == 0 || stricmp(extension, ".lst") == 0))
			{
				printf("Using '%s' as cd image\n", *arg);
				cfgSetVirtual("config", "image", *arg);
			}
			else if (extension && stricmp(extension, ".elf") == 0)
			{
				printf("Using '%s' as reios elf file\n", *arg);
				cfgSetVirtual("config", "reios.enabled", "1");
				cfgSetVirtual("reios", "ElfFile", *arg);
			}
			else
			{
				printf("wtf %s is supposed to do ?\n",*arg);
			}
		}
		arg++;
		cl--;
	}
	printf("\n");
	return false;
}
Exemple #8
0
void
showhelp()
{
    if (!getenv("MOUNT_FUSEFS_CALL_BY_LIB")) {
        showversion(0);
        fprintf(stderr, "\nThis program is not meant to be called directly. The "
                OSXFUSE_DISPLAY_NAME " library calls it.\n");
    }
    fprintf(stderr,
            "\nAvailable mount options:\n"
            "    -o allow_other         allow access to others besides the user who mounted\n"
            "                           the file system\n"
            "    -o allow_recursion     allow a mount point that itself resides on a " OSXFUSE_DISPLAY_NAME "\n"
            "                           volume (by default, such mounting is disallowed)\n"
            "    -o allow_root          allow access to root (can't be used with allow_other)\n"
            "    -o auto_xattr          handle extended attributes entirely through ._ files\n"
            "    -o blocksize=<size>    specify block size in bytes of \"storage\"\n"
            "    -o daemon_timeout=<s>  timeout in seconds for kernel calls to daemon\n"
            "    -o debug               turn on debug information printing\n"
            "    -o default_permissions let the kernel handle permission checks locally\n"
            "    -o defer_permissions   defer permission checks to file operations themselves\n"
            "    -o direct_io           use alternative (direct) path for kernel-user I/O\n"
            "    -o extended_security   turn on Mac OS X extended security (ACLs)\n"
            "    -o fsid=<fsid>         set the second 32-bit component of the fsid\n"
            "    -o fsname=<name>       set the file system's name\n"
            "    -o fssubtype=<num>     set the file system's fssubtype identifier\n"
            "    -o fstypename=<name>   set the file system's type name\n"
            "    -o iosize=<size>       specify maximum I/O size in bytes\n"
            "    -o jail_symlinks       contain symbolic links within the mount\n"
            "    -o local               mark the volume as \"local\" (default is \"nonlocal\")\n"
            "    -o negative_vncache    enable vnode name caching of non-existent objects\n"
            "    -o sparse              enable support for sparse files\n"
            "    -o volname=<name>      set the file system's volume name\n"
            "\nAvailable negative mount options:\n"
            "    -o noalerts            disable all graphical alerts (if any) in " OSXFUSE_DISPLAY_NAME " Core\n"
            "    -o noappledouble       ignore Apple Double (._) and .DS_Store files entirely\n"
            "    -o noapplexattr        ignore all \"com.apple.*\" extended attributes\n"
            "    -o nobrowse            mark the volume as non-browsable by the Finder\n"
            "    -o nolocalcaches       meta option equivalent to noreadahead,noubc,novncache\n"
            "    -o noreadahead         disable I/O read-ahead behavior for this file system\n"
            "    -o nosynconclose       disable sync-on-close behavior (enabled by default)\n"
            "    -o nosyncwrites        disable synchronous-writes behavior (dangerous)\n"
            "    -o noubc               disable the unified buffer cache for this file system\n"
            "    -o novncache           disable the vnode name cache for this file system\n");
    exit(EX_USAGE);
}
Exemple #9
0
int main(int argc, char **argv) {
	int i;

	if (argc<2)
		showusage (1);
	if (!strcmp (argv[1], "-v"))
		showversion ();
	if (!strcmp (argv[1], "-h"))
		showusage (0);
	if (!strcmp (argv[1], "-")) {
		argv[1] = "";
		if (argc == 2) {
			argv[2] = "-";
			argc++;
		}
	}
	if (argc == 2)
		return sdb_dump (argv[1]);
#if USE_MMAN
	signal (SIGINT, terminate);
	signal (SIGHUP, syncronize);
#endif
	if (!strcmp (argv[2], "=")) {
		createdb (argv[1]);
	} else
	if (!strcmp (argv[2], "-")) {
		char line[SDB_VSZ+SDB_KSZ]; // XXX can overflow stack
		if ((s = sdb_new (argv[1], 0)))
			for (;;) {
				fgets (line, sizeof line, stdin);
				if (feof (stdin))
					break;
				line[strlen (line)-1] = 0;
				save = sdb_query (s, line);
			}
	} else
	if ((s = sdb_new (argv[1], 0))) {
		for (i=2; i<argc; i++)
			save = sdb_query (s, argv[i]);
	}
	terminate (0);
	return 0;
}
Exemple #10
0
static void showusage(char *prog)
{
	showversion();
	printf("Usage: pptpd [options], where options are:\n\n");
#ifdef BCRELAY
	printf(" [-b] [--bcrelay if]       Use broadcast relay for broadcasts comming from.\n");
	printf("                           the specified interface (default is eth1).\n");
#endif
	printf(" [-c] [--conf file]        Specifies the config file to read default\n");
	printf("                           settings from (default is %s).\n", PPTPD_CONFIG_FILE_DEFAULT);
	printf(" [-d] [--debug]            Turns on debugging (to syslog).\n");
	printf(" [-e] [--ppp file]         Use alternate pppd binary, default %s.\n", PPP_BINARY);
	printf(" [-f] [--fg]               Run in foreground.\n");
	printf(" [-h] [--help]             Displays this help message.\n");
	printf(" [-i] [--noipparam]        Suppress the passing of the client's IP address\n");
	printf("                           to PPP, which is done by default otherwise.\n");
	printf(" [-l] [--listen x.x.x.x]   Specifies IP of local interface to listen to.\n");
#if !defined(BSDUSER_PPP)
	printf(" [-o] [--option file]      Specifies the PPP options file to use\n");
	printf("                           (default is /etc/ppp/options).\n");
#endif
	printf(" [-p] [--pidfile file]     Specifies the file to write the process ID to\n");
	printf("                           (default is /var/run/pptpd.pid).\n");
#if !defined(BSDUSER_PPP)
	printf(" [-s] [--speed baud]       Specifies the baud speed for the PPP daemon\n");
	printf("                           (default is 115200).\n");
#endif
	printf(" [-t] [--stimeout seconds] Specifies the timeout for the first packet. This is a DOS protection\n");
	printf("                           (default is 10).\n");
	printf(" [-T] [--ptimeout msec]     Specifies the maximum timeout for the packet.\n");
	printf("                           (default is 1000).\n");
	printf(" [-v] [--version]          Displays the pptpd version number.\n");
	printf(" [-w] [--logwtmp]          Update wtmp as users login.\n");
	printf(" [-C] [--connections n]    Limit on number of connections.\n");
	printf(" [-D] [--delegate]         Delegate IP allocation to pppd.\n");
	printf(" [-k] [--keep]             Keep connections after exit.\n");
	printf("                           (default do not keep).\n");

	printf("\n\nLogs and debugging go to syslog as DAEMON.");

	printf("\n\nCommand line options will override any default settings and any settings\n");
	printf("specified in the config file (default config file: %s).\n\n", PPTPD_CONFIG_FILE_DEFAULT);
}
Exemple #11
0
int main(int argc, const char **argv) {
	char *line;
	int i;

	if (argc<2) showusage (1);
	if (!strcmp (argv[1], "-v")) showversion ();
	if (!strcmp (argv[1], "-h")) showusage (0);
	if (!strcmp (argv[1], "-")) {
		argv[1] = "";
		if (argc == 2) {
			argv[2] = "-";
			argc++;
		}
	}
	if (argc == 2)
		return sdb_dump (argv[1], 0);
#if USE_MMAN
	signal (SIGINT, terminate);
	signal (SIGHUP, syncronize);
#endif
	if (!strcmp (argv[2], "[]")) {
		return sdb_dump (argv[1], 1);
	} if (!strcmp (argv[2], "="))
		return createdb (argv[1]);
	else if (!strcmp (argv[2], "-")) {
		if ((s = sdb_new (NULL, argv[1], 0))) {
			for (;(line = stdin_gets ());) {
				save = sdb_query (s, line);
				free (line);
			}
		}
	} else {
		s = sdb_new (NULL, argv[1], 0);
		if (!s) return 1;
		for (i=2; i<argc; i++)
			save = sdb_query (s, argv[i]);
	}
	terminate (0);
	return 0;
}
Exemple #12
0
int main(int argc , char **argv)
{
  
  showversion();
  
  printf("*****************\n");
  printf("*** banner #1 ***\n");
  printf("*****************\n");
  printf("%s",cbanner_1);

  printf("*****************\n");
  printf("*** banner #2 ***\n");
  printf("*****************\n");
  printf("%s",cbanner_2);

  printf("*****************\n");
  printf("*** banner #3 ***\n");
  printf("*****************\n");
  printf("%s",cbanner_3);

  exit(0);    
  
}
Exemple #13
0
void help(void)
{
    /*
     * Help message is an extended version of the usage message. So
     * start with that, plus a version heading.
     */
    showversion();
    usage(FALSE);
    fprintf(stderr,
	    "  -t    specify key type when generating (ed25519, ecdsa, rsa, "
							"dsa, rsa1)\n"
	    "  -b    specify number of bits when generating key\n"
	    "  -C    change or specify key comment\n"
	    "  -P    change key passphrase\n"
	    "  -q    quiet: do not display progress bar\n"
	    "  -O    specify output type:\n"
	    "           private             output PuTTY private key format\n"
	    "           private-openssh     export OpenSSH private key\n"
	    "           private-openssh-new export OpenSSH private key "
                                             "(force new file format)\n"
	    "           private-sshcom      export ssh.com private key\n"
	    "           public              RFC 4716 / ssh.com public key\n"
	    "           public-openssh      OpenSSH public key\n"
	    "           fingerprint         output the key fingerprint\n"
	    "  -o    specify output file\n"
	    "  -l    equivalent to `-O fingerprint'\n"
	    "  -L    equivalent to `-O public-openssh'\n"
	    "  -p    equivalent to `-O public'\n"
	    "  --old-passphrase file\n"
	    "        specify file containing old key passphrase\n"
	    "  --new-passphrase file\n"
	    "        specify file containing new key passphrase\n"
	    "  --random-device device\n"
	    "        specify device to read entropy from (e.g. /dev/urandom)\n"
	    );
}
Exemple #14
0
int main(int argc, char **argv)
{
	/* command line options */
	int c;

	/* function-local options */
	int foreground = FALSE;
	char *pid_file = NULL;

	/* config file */
	char *configFile = NULL;

	/* config file parsing temp strings */
	char tmp[MAX_CONFIG_STRING_SIZE], *tmpstr;

	/* open a connection to the syslog daemon */
	openlog("pptpd", LOG_PID, PPTP_FACILITY);
	syslog(LOG_ERR, "MGR: Config file not found!");

	/* process command line options */
	while (1) {
		int option_index = 0;
#ifdef BCRELAY
		char *optstring = "b:c:de:fhil:o:p:s:t:T:vwC:Dk";
#else
		char *optstring = "c:de:fhil:o:p:s:t:T:vwC:Dk";
#endif

		static struct option long_options[] =
		{
#ifdef BCRELAY
			{"bcrelay", 1, 0, 0},
#endif
			{"conf", 1, 0, 'c'},
			{"debug", 0, 0, 'd'},
			{"ppp", 1, 0, 'e'},
			{"fg", 0, 0, 'f'},
			{"help", 0, 0, 'h'},
			{"noipparam", 0, 0, 'i'},
			{"listen", 1, 0, 'l'},
			{"option", 1, 0, 'o'},
			{"pidfile", 1, 0, 'p'},
			{"speed", 1, 0, 's'},
			{"stimeout", 1, 0, 't'},
			{"ptimeout", 1, 0, 'T'},
			{"version", 0, 0, 'v'},
			{"logwtmp", 0, 0, 'w'},
			{"connections", 1, 0, 'C'},
			{"delegate", 0, 0, 'D'},
			{"keep", 0, 0, 'k'},
			{0, 0, 0, 0}
		};

		c = getopt_long(argc, argv, optstring, long_options, &option_index);
		if (c == -1)
			break;
		/* convert long options to short form */
		if (c == 0)
#ifdef BCRELAY
			c = "bcdefhilopstvwCDk"[option_index];
#else
			c = "cdefhilopstvwCDk"[option_index];
#endif
		switch (c) {
#ifdef BCRELAY
		case 'b': /* --bcrelay */
			if (bcrelay) free(bcrelay);
			bcrelay = strdup(optarg);
			break;
#endif

		case 'l': /* --listen */
			tmpstr = lookup(optarg);
			if (!tmpstr) {
				syslog(LOG_ERR, "MGR: Invalid listening address: %s!", optarg);
				return 1;
			}
			if (bindaddr) free(bindaddr);
			bindaddr = strdup(tmpstr);
			break;

		case 'h': /* --help */
			showusage(argv[0]);
			return 0;

		case 'i': /* --noipparam */
			pptp_noipparam = TRUE;
			break;

		case 'e': /* --ppp */
			if (ppp_binary) free(ppp_binary);
			ppp_binary = strdup(optarg);
			break;

		case 'd': /* --debug */
			pptp_debug = TRUE;
			break;

		case 'f': /* --fg */
			foreground = TRUE;
			break;

		case 'v': /* --version */
			showversion();
			return 0;

		case 'w': /* --logwtmp */
		        pptp_logwtmp = TRUE;
			break;

		case 'C': /* --connections */
		        pptp_connections = atoi(optarg);
			break;

		case 'D': /* --delegate */
		        pptp_delegate = TRUE;
			break;

		case 'o': /* --option */
			if (pppdoptstr) free(pppdoptstr);
			pppdoptstr = strdup(optarg);
			break;

		case 'p': /* --pidfile */
			if (pid_file) free(pid_file);
			pid_file = strdup(optarg);
			break;

		case 's': /* --speed */
			if (speedstr) free(speedstr);
			speedstr = strdup(optarg);
			break;

		case 't': /* --stimeout */
			pptp_stimeout = atoi(optarg);
			break;

		case 'T': /* --stimeout */
			pptp_ptimeout = atoi(optarg);
			break;
		case 'k': /* --keep */
			keep_connections = 1;
			break;

		case 'c': /* --conf */
			{
				FILE *f;
				if (!(f = fopen(optarg, "r"))) {
					syslog(LOG_ERR, "MGR: Config file not found!");
					return 1;
				}
				fclose(f);
				if(configFile) free(configFile);
				configFile = strdup(optarg);
				break;
			}

		default:
			showusage(argv[0]);
			return 1;
		}
	}

	/* Now that we have all the command line args.. lets open the
	 * conf file and add anything else (remembering not to override
	 * anything since the command line has more privilages :-)
	 */

	if (!configFile)
		configFile = strdup(PPTPD_CONFIG_FILE_DEFAULT);

	if (read_config_file(configFile, CONNECTIONS_KEYWORD, tmp) > 0) {
		pptp_connections = atoi(tmp);
		if (pptp_connections <= 0)
			pptp_connections = CONNECTIONS_DEFAULT;
	}

	slot_init(pptp_connections);

	if (!pptp_debug && read_config_file(configFile, DEBUG_KEYWORD, tmp) > 0)
		pptp_debug = TRUE;

#ifdef BCRELAY
	if (!bcrelay && read_config_file(configFile, BCRELAY_KEYWORD, tmp) > 0) 
		bcrelay = strdup(tmp);
#endif

	if (!pptp_stimeout && read_config_file(configFile, STIMEOUT_KEYWORD, tmp) > 0) {
		pptp_stimeout = atoi(tmp);
		if (pptp_stimeout <= 0)
			pptp_stimeout = STIMEOUT_DEFAULT;
	}

	if (!pptp_ptimeout && read_config_file(configFile, PTIMEOUT_KEYWORD, tmp) > 0) {
		pptp_ptimeout = atoi(tmp);
		if (pptp_ptimeout <= 0)
			pptp_ptimeout = PTIMEOUT_DEFAULT;
	}

	if (!pptp_noipparam && read_config_file(configFile, NOIPPARAM_KEYWORD, tmp) > 0) {
		pptp_noipparam = TRUE;
	}

	if (!bindaddr && read_config_file(configFile, LISTEN_KEYWORD, tmp) > 0) {
		tmpstr = lookup(tmp);
		if(!tmpstr) {
			syslog(LOG_ERR, "MGR: Invalid listening address: %s!", tmp);
			return 1;
		}
		bindaddr = strdup(tmpstr);
	}

	if (!speedstr && read_config_file(configFile, SPEED_KEYWORD, tmp) > 0)
		speedstr = strdup(tmp);

	if (!pppdoptstr && read_config_file(configFile, PPPD_OPTION_KEYWORD, tmp) > 0) {
		pppdoptstr = strdup(tmp);
	}

	if (!ppp_binary && read_config_file(configFile, PPP_BINARY_KEYWORD, tmp) > 0) {
		ppp_binary = strdup(tmp);
	}

	if (!pptp_logwtmp && read_config_file(configFile, LOGWTMP_KEYWORD, tmp) > 0) {
		pptp_logwtmp = TRUE;
	}

	if (!pptp_delegate && read_config_file(configFile, DELEGATE_KEYWORD, tmp) > 0) {
		pptp_delegate = TRUE;
	}

	if (read_config_file(configFile, KEEP_KEYWORD, tmp) > 0) {
		keep_connections = TRUE;
	}

	if (!pid_file)
		pid_file = strdup((read_config_file(configFile, PIDFILE_KEYWORD,
					tmp) > 0) ? tmp : PIDFILE_DEFAULT);

	if (!pptp_delegate) {
		/* NOTE: remote then local, reason can be seen at the end of processIPStr */

		/* grab the remoteip string from the config file */
		if (read_config_file(configFile, REMOTEIP_KEYWORD, tmp) <= 0) {
			/* use "smart" defaults */
			strlcpy(tmp, DEFAULT_REMOTE_IP_LIST, sizeof(tmp));
		}
		processIPStr(REMOTE, tmp);
	
		/* grab the localip string from the config file */
		if (read_config_file(configFile, LOCALIP_KEYWORD, tmp) <= 0) {
			/* use "smart" defaults */
			strlcpy(tmp, DEFAULT_LOCAL_IP_LIST, sizeof(tmp));
		}
		processIPStr(LOCAL, tmp);
	}

	free(configFile);

	/* if not yet set, adopt default PPP binary path */
	if (!ppp_binary) ppp_binary = strdup(PPP_BINARY);
	/* check that the PPP binary is executable */
	if (access(ppp_binary, X_OK) < 0) {
		syslog(LOG_ERR, "MGR: PPP binary %s not executable",
		       ppp_binary);
		return 1;
	}
	/* check that the PPP options file is readable */
	if (pppdoptstr && access(pppdoptstr, R_OK) < 0) {
		syslog(LOG_ERR, "MGR: PPP options file %s not readable",
		       pppdoptstr);
		return 1;
	}
#ifdef BCRELAY
	/* check that the bcrelay binary is executable */
	if (bcrelay && access(BCRELAY_BIN, X_OK) < 0) {
		syslog(LOG_ERR, "MGR: bcrelay binary %s not executable", 
		       BCRELAY_BIN);
		return 1;
	}
#endif

	syslog(LOG_INFO, "accel-pptpd-%s compiled for pppd-%s\n",VERSION, "2.4.2");

	if (!foreground) {
#if HAVE_DAEMON
		closelog();
		freopen("/dev/null", "r", stdin);
		daemon(0, 0);
		/* returns to child only */
		/* pid will have changed */
		openlog("pptpd", LOG_PID, PPTP_FACILITY);
#else	/* !HAVE_DAEMON */
		my_daemon(argc, argv);
		/* returns to child if !HAVE_FORK
		 * never returns if HAVE_FORK (re-execs with -f)
		 */
#endif
	}

#ifdef BCRELAY
      if (bcrelay) {
             syslog(LOG_DEBUG, "CTRL: BCrelay incoming interface is %s", bcrelay);
             /* Launch BCrelay  */
#ifndef HAVE_FORK
             switch(bcrelayfork = vfork()){
#else
             switch(bcrelayfork = fork()){
#endif
             case -1:        /* fork() error */
                   syslog(LOG_ERR, "CTRL: Error forking to exec bcrelay");
                   _exit(1);

             case 0:         /* child */
                   syslog(LOG_DEBUG, "CTRL (BCrelay Launcher): Launching BCrelay with pid %i", bcrelayfork);
                   launch_bcrelay();
                   syslog(LOG_ERR, "CTRL (BCrelay Launcher): Failed to launch BCrelay.");
                   _exit(1);
             }
       } /* End bcrelay */
#endif

#ifdef CONFIG_NETtel
	/* turn the NETtel VPN LED on */
	ledman_cmd(LEDMAN_CMD_ON, LEDMAN_VPN);
#endif
	/* after we have our final pid... */
	log_pid(pid_file);

	/* manage connections until SIGTERM */
	pptp_manager(argc, argv);
	
#ifdef BCRELAY
	if (bcrelayfork > 0) {
		syslog(LOG_DEBUG, "CTRL: Closing child BCrelay with pid %i", bcrelayfork);
		kill(bcrelayfork, SIGTERM);
	}
#endif

	slot_free();
	return 0;
}

static void log_pid(char *pid_file) {
        FILE    *f;
        pid_t   pid;

        pid = getpid();
        if ((f = fopen(pid_file, "w")) == NULL) {
                syslog(LOG_ERR, "PPTPD: failed to open(%s), errno=%d\n",
                        pid_file, errno);
                return;
        }
        fprintf(f, "%d\n", pid);
        fclose(f);
}
Exemple #15
0
int main(int argc, const char **argv) {
	char *line;
	const char *arg, *grep = NULL;
	int i, ret, fmt = MODE_DFLT;
	int db0 = 1, argi = 1;
	bool interactive = false;

	/* terminate flags */
	if (argc < 2) {
		return showusage (1);
	}
	arg = argv[1];

	if (arg[0] == '-') {// && arg[1] && arg[2]==0) {
		switch (arg[1]) {
		case 0:
			/* no-op */
			break;
		case '0':
			fmt = MODE_ZERO;
			db0++;
			argi++;
			if (db0 >= argc) {
				return showusage (1);
			}
			break;
		case 'g':
			db0 += 2;
			if (db0 >= argc) {
				return showusage (1);
			}
			grep = argv[2];
			argi += 2;
			break;
		case 'J':
			options |= SDB_OPTION_JOURNAL;
			db0++;
			argi++;
			if (db0 >= argc) {
				return showusage (1);
			}
			break;
		case 'c': return (argc < 3)? showusage (1) : showcount (argv[2]);
		case 'v': return showversion ();
		case 'h': return showusage (2);
		case 'e': return base64encode ();
		case 'd': return base64decode ();
		case 'D':
			if (argc == 4) {
				return dbdiff (argv[2], argv[3]);
			}
			return showusage (0);
		case 'j':
			if (argc > 2) {
				return sdb_dump (argv[db0 + 1], MODE_JSON);
			}
			return jsonIndent();
		default:
			eprintf ("Invalid flag %s\n", arg);
			break;
		}
	}

	/* sdb - */
	if (argi == 1 && !strcmp (argv[argi], "-")) {
		/* no database */
		argv[argi] = "";
		if (argc == db0 + 1) {
			interactive = true;
			/* if no argument passed */
			argv[argi] = "-";
			argc++;
			argi++;
		}
	}
	/* sdb dbname */
	if (argc - 1 == db0) {
		if (grep) {
			return sdb_grep (argv[db0], fmt, grep);
		}
		return sdb_dump (argv[db0], fmt);
	}
#if USE_MMAN
	signal (SIGINT, terminate);
	signal (SIGHUP, synchronize);
#endif
	ret = 0;
	if (interactive || !strcmp (argv[db0 + 1], "-")) {
		if ((s = sdb_new (NULL, argv[db0], 0))) {
			sdb_config (s, options);
			int kvs = db0 + 2;
			if (kvs < argc) {
				save |= insertkeys (s, argv + argi + 2, argc - kvs, '-');
			}
			for (;(line = stdin_slurp (NULL));) {
				save |= sdb_query (s, line);
				if (fmt) {
					fflush (stdout);
					write (1, "", 1);
				}
				free (line);
			}
		}
	} else if (!strcmp (argv[db0 + 1], "=")) {
		ret = createdb (argv[db0], NULL, 0);
	} else {
		s = sdb_new (NULL, argv[db0], 0);
		if (!s) {
			return 1;
		}
		sdb_config (s, options);
		for (i = db0 + 1; i < argc; i++) {
			save |= sdb_query (s, argv[i]);
			if (fmt) {
				fflush (stdout);
				write (1, "", 1);
			}
		}
	}
	terminate (0);
	return ret;
}
Exemple #16
0
bool CommandLine::Parse(int argc, char *argv[])
{
  if (argc<1)
  {
    return false;
  }

  // Split the program name into path and filename
  string path, name;
  DiskFile::SplitFilename(argv[0], path, name);
  argc--;
  argv++;

  if (argc>0)
  {
    if (argv[0][0] != 0 &&
        argv[0][0] == '-')
    {
      if (argv[0][1] != 0)
      {
        switch (argv[0][1])
        {
        case 'h':
          usage();
          return true;
        case 'V':
          showversion();
          if (argv[0][2] != 0 &&
              argv[0][2] == 'V')
          {
            cout << endl;
            banner();
          }
          return true;
        }
      }
    }
  }

  // Strip ".exe" from the end
  if (name.size() > 4 && 0 == stricmp(".exe", name.substr(name.length()-4).c_str()))
  {
    name = name.substr(0, name.length()-4);
  }

  // Check the resulting program name
  if (0 == stricmp("par2create", name.c_str()))
  {
    operation = opCreate;
  } 
  else if (0 == stricmp("par2verify", name.c_str()))
  {
    operation = opVerify;
  }
  else if (0 == stricmp("par2repair", name.c_str()))
  {
    operation = opRepair;
  }

  // Have we determined what operation we want?
  if (operation == opNone)
  {
    if (argc<2)
    {
      cerr << "Not enough command line arguments." << endl;
      return false;
    }

    switch (tolower(argv[0][0]))
    {
    case 'c':
      if (argv[0][1] == 0 || 0 == stricmp(argv[0], "create"))
        operation = opCreate;
      break;
    case 'v':
      if (argv[0][1] == 0 || 0 == stricmp(argv[0], "verify"))
        operation = opVerify;
      break;
    case 'r':
      if (argv[0][1] == 0 || 0 == stricmp(argv[0], "repair"))
        operation = opRepair;
      break;
    }

    if (operation == opNone)
    {
      cerr << "Invalid operation specified: " << argv[0] << endl;
      return false;
    }
    argc--;
    argv++;
  }

  bool options = true;
  list<string> a_filenames;

  while (argc>0)
  {
    if (argv[0][0])
    {
      if (options && argv[0][0] != '-')
        options = false;

      if (options)
      {
        switch (argv[0][1])
        {
        case 'a':
          {
            if (operation == opCreate)
            {
              string str = argv[0];
              if (str == "-a")
              {
                SetParFilename(argv[1]);
                argc--;
                argv++;
              }
              else
              {
                SetParFilename(str.substr(2));
              }
            }
          }
          break;
        case 'b':  // Set the block count
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify block count unless creating." << endl;
              return false;
            }
            if (blockcount > 0)
            {
              cerr << "Cannot specify block count twice." << endl;
              return false;
            }
            else if (blocksize > 0)
            {
              cerr << "Cannot specify both block count and block size." << endl;
              return false;
            }
            
            char *p = &argv[0][2];
            while (blockcount <= 3276 && *p && isdigit(*p))
            {
              blockcount = blockcount * 10 + (*p - '0');
              p++;
            }
            if (0 == blockcount || blockcount > 32768 || *p)
            {
              cerr << "Invalid block count option: " << argv[0] << endl;
              return false;
            }
          }
          break;

        case 's':  // Set the block size
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify block size unless creating." << endl;
              return false;
            }
            if (blocksize > 0)
            {
              cerr << "Cannot specify block size twice." << endl;
              return false;
            }
            else if (blockcount > 0)
            {
              cerr << "Cannot specify both block count and block size." << endl;
              return false;
            }

            char *p = &argv[0][2];
            while (blocksize <= 429496729 && *p && isdigit(*p))
            {
              blocksize = blocksize * 10 + (*p - '0');
              p++;
            }
            if (*p || blocksize == 0)
            {
              cerr << "Invalid block size option: " << argv[0] << endl;
              return false;
            }
            if (blocksize & 3)
            {
              cerr << "Block size must be a multiple of 4." << endl;
              return false;
            }
          }
          break;

        case 'r':  // Set the amount of redundancy required
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify redundancy unless creating." << endl;
              return false;
            }
            if (redundancyset)
            {
              cerr << "Cannot specify redundancy twice." << endl;
              return false;
            }
            else if (recoveryblockcountset)
            {
              cerr << "Cannot specify both redundancy and recovery block count." << endl;
              return false;
            }

            char *p = &argv[0][2];
            while (redundancy <= 10 && *p && isdigit(*p))
            {
              redundancy = redundancy * 10 + (*p - '0');
              p++;
            }
            if (redundancy > 100 || *p)
            {
              cerr << "Invalid redundancy option: " << argv[0] << endl;
              return false;
            }
            if (redundancy == 0 && recoveryfilecount > 0)
            {
              cerr << "Cannot set redundancy to 0 and file count > 0" << endl;
              return false;
            }
            redundancyset = true;
          }
          break;

        case 'c': // Set the number of recovery blocks to create
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify recovery block count unless creating." << endl;
              return false;
            }
            if (recoveryblockcountset)
            {
              cerr << "Cannot specify recovery block count twice." << endl;
              return false;
            }
            else if (redundancyset)
            {
              cerr << "Cannot specify both recovery block count and redundancy." << endl;
              return false;
            }

            char *p = &argv[0][2];
            while (recoveryblockcount <= 32768 && *p && isdigit(*p))
            {
              recoveryblockcount = recoveryblockcount * 10 + (*p - '0');
              p++;
            }
            if (recoveryblockcount > 32768 || *p)
            {
              cerr << "Invalid recoveryblockcount option: " << argv[0] << endl;
              return false;
            }
            if (recoveryblockcount == 0 && recoveryfilecount > 0)
            {
              cerr << "Cannot set recoveryblockcount to 0 and file count > 0" << endl;
              return false;
            }
            recoveryblockcountset = true;
          }
          break;

        case 'f':  // Specify the First block recovery number
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify first block number unless creating." << endl;
              return false;
            }
            if (firstblock > 0)
            {
              cerr << "Cannot specify first block twice." << endl;
              return false;
            }

            char *p = &argv[0][2];
            while (firstblock <= 3276 && *p && isdigit(*p))
            {
              firstblock = firstblock * 10 + (*p - '0');
              p++;
            }
            if (firstblock > 32768 || *p)
            {
              cerr << "Invalid first block option: " << argv[0] << endl;
              return false;
            }
          }
          break;

        case 'u':  // Specify uniformly sized recovery files
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify uniform files unless creating." << endl;
              return false;
            }
            if (argv[0][2])
            {
              cerr << "Invalid option: " << argv[0] << endl;
              return false;
            }
            if (recoveryfilescheme != scUnknown)
            {
              cerr << "Cannot specify two recovery file size schemes." << endl;
              return false;
            }

            recoveryfilescheme = scUniform;
          }
          break;

        case 'l':  // Limit the size of the recovery files
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify limit files unless creating." << endl;
              return false;
            }
            if (argv[0][2])
            {
              cerr << "Invalid option: " << argv[0] << endl;
              return false;
            }
            if (recoveryfilescheme != scUnknown)
            {
              cerr << "Cannot specify two recovery file size schemes." << endl;
              return false;
            }
            if (recoveryfilecount > 0)
            {
              cerr << "Cannot specify limited size and number of files at the same time." << endl;
              return false;
            }

            recoveryfilescheme = scLimited;
          }
          break;

        case 'n':  // Specify the number of recovery files
          {
            if (operation != opCreate)
            {
              cerr << "Cannot specify recovery file count unless creating." << endl;
              return false;
            }
            if (recoveryfilecount > 0)
            {
              cerr << "Cannot specify recovery file count twice." << endl;
              return false;
            }
            if (redundancyset && redundancy == 0)
            {
              cerr << "Cannot set file count when redundancy is set to 0." << endl;
              return false;
            }
            if (recoveryblockcountset && recoveryblockcount == 0)
            {
              cerr << "Cannot set file count when recovery block count is set to 0." << endl;
              return false;
            }
            if (recoveryfilescheme == scLimited)
            {
              cerr << "Cannot specify limited size and number of files at the same time." << endl;
              return false;
            }

            char *p = &argv[0][2];
            while (*p && isdigit(*p))
            {
              recoveryfilecount = recoveryfilecount * 10 + (*p - '0');
              p++;
            }
            if (recoveryfilecount == 0 || *p)
            {
              cerr << "Invalid recovery file count option: " << argv[0] << endl;
              return false;
            }
          }
          break;

        case 'm':  // Specify how much memory to use for output buffers
          {
            if (memorylimit > 0)
            {
              cerr << "Cannot specify memory limit twice." << endl;
              return false;
            }

            char *p = &argv[0][2];
            while (*p && isdigit(*p))
            {
              memorylimit = memorylimit * 10 + (*p - '0');
              p++;
            }
            if (memorylimit == 0 || *p)
            {
              cerr << "Invalid memory limit option: " << argv[0] << endl;
              return false;
            }
          }
          break;

        case 'v':
          {
            switch (noiselevel)
            {
            case nlUnknown:
              {
                if (argv[0][2] == 'v')
                  noiselevel = nlDebug;
                else
                  noiselevel = nlNoisy;
              }
              break;
            case nlNoisy:
            case nlDebug:
              noiselevel = nlDebug;
              break;
            default:
              cerr << "Cannot use both -v and -q." << endl;
              return false;
              break;
            }
          }
          break;

        case 'q':
          {
            switch (noiselevel)
            {
            case nlUnknown:
              {
                if (argv[0][2] == 'q')
                  noiselevel = nlSilent;
                else
                  noiselevel = nlQuiet;
              }
              break;
            case nlQuiet:
            case nlSilent:
              noiselevel = nlSilent;
              break;
            default:
              cerr << "Cannot use both -v and -q." << endl;
              return false;
              break;
            }
          }
          break;

        case 'p':
          {
            if (operation != opRepair && operation != opVerify)
            {
              cerr << "Cannot specify purge unless repairing or verifying." << endl;
              return false;
            }
            purgefiles = true;
          }
          break;

        case 'h':
          {
            usage();
            return false;
            break;
          }

        case 'R':
          {
            if (operation == opCreate)
            {
              recursive = true;
            }
            else
            {
              cerr << "Recursive has no impact except on creating." << endl;
            }
          }
          break;

        case '-':
          {
            argc--;
            argv++;
            options = false;
            continue;
          }
          break;
        default:
          {
            cerr << "Invalid option specified: " << argv[0] << endl;
            return false;
          }
        }
      }
      else if (parfilename.length() == 0)
      {
        string filename = argv[0];
        string::size_type where;
        if ((where = filename.find_first_of('*')) != string::npos ||
            (where = filename.find_first_of('?')) != string::npos)
        {
          cerr << "par2 file must not have a wildcard in it." << endl;
          return false;
        }

        SetParFilename(filename);
      }
      else
      {
        list<string> *filenames;

        string path;
        string name;
        DiskFile::SplitFilename(argv[0], path, name);
        filenames = DiskFile::FindFiles(path, name, recursive);

        list<string>::iterator fn = filenames->begin();
        while (fn != filenames->end())
        {
          // Convert filename from command line into a full path + filename
          string filename = DiskFile::GetCanonicalPathname(*fn);

          // Originally, all specified files were supposed to exist, or the program
          // would stop with an error message. This was not practical, for example in
          // a directory with files appearing and disappearing (an active download directory).
          // So the new rule is: when a specified file doesn't exist, it is silently skipped.
          if (!DiskFile::FileExists(filename))
          {
            cout << "Ignoring non-existent source file: " << filename << endl;
          }
          else
          {
            u64 filesize = DiskFile::GetFileSize(filename);

            // Ignore all 0 byte files
            if (filesize == 0)
            {
              cout << "Skipping 0 byte file: " << filename << endl;
            }
            else if (a_filenames.end() != find(a_filenames.begin(), a_filenames.end(), filename))
            {
              cout << "Skipping duplicate filename: " << filename << endl;
            }
            else
            {
              a_filenames.push_back(filename);
              extrafiles.push_back(ExtraFile(filename, filesize));

              // track the total size of the source files and how
              // big the largest one is.
              totalsourcesize += filesize;
              if (largestsourcesize < filesize)
              largestsourcesize = filesize;
            }
          } //end file exists

          ++fn;
        }
        delete filenames;
      }
    }

    argc--;
    argv++;
  }

  if (parfilename.length() == 0)
  {
    cerr << "You must specify a Recovery file." << endl;
    return false;
  }

  // Default noise level
  if (noiselevel == nlUnknown)
  {
    noiselevel = nlNormal;
  }

  // If we a creating, check the other parameters
  if (operation == opCreate)
  {
    // If no recovery file size scheme is specified then use Variable
    if (recoveryfilescheme == scUnknown)
    {
      recoveryfilescheme = scVariable;
    }

    // If neither block count not block size is specified
    if (blockcount == 0 && blocksize == 0)
    {
      // Use a block count of 2000
      blockcount = 2000;
    }

    // If we are creating, the source files must be given.
    if (extrafiles.size() == 0)
    {
      // Does the par filename include the ".par2" on the end?
      if (parfilename.length() > 5 && 0 == stricmp(parfilename.substr(parfilename.length()-5, 5).c_str(), ".par2"))
      {
        // Yes it does.
        cerr << "You must specify a list of files when creating." << endl;
        return false;
      }
      else
      {
        // No it does not.

        // In that case check to see if the file exists, and if it does
        // assume that you wish to create par2 files for it.

        u64 filesize = 0;
        if (DiskFile::FileExists(parfilename) &&
            (filesize = DiskFile::GetFileSize(parfilename)) > 0)
        {
          extrafiles.push_back(ExtraFile(parfilename, filesize));

          // track the total size of the source files and how
          // big the largest one is.
          totalsourcesize += filesize;
          if (largestsourcesize < filesize)
            largestsourcesize = filesize;
        }
        else
        {
          // The file does not exist or it is empty.

          cerr << "You must specify a list of files when creating." << endl;
          return false;
        }
      }
    }

    // Strip the ".par2" from the end of the filename of the main PAR2 file.
    if (parfilename.length() > 5 && 0 == stricmp(parfilename.substr(parfilename.length()-5, 5).c_str(), ".par2"))
    {
      parfilename = parfilename.substr(0, parfilename.length()-5);
    }

    // Assume a redundancy of 5% if neither redundancy or recoveryblockcount were set.
    if (!redundancyset && !recoveryblockcountset)
    {
      redundancy = 5;
    }
  }

  // Assume a memory limit of 16MB if not specified.
  if (memorylimit == 0)
  {
#ifdef WIN32
    u64 TotalPhysicalMemory = 0;

    HMODULE hLib = ::LoadLibraryA("kernel32.dll");
    if (NULL != hLib)
    {
      BOOL (WINAPI *pfn)(LPMEMORYSTATUSEX) = (BOOL (WINAPI*)(LPMEMORYSTATUSEX))::GetProcAddress(hLib, "GlobalMemoryStatusEx");

      if (NULL != pfn)
      {
        MEMORYSTATUSEX mse;
        mse.dwLength = sizeof(mse);
        if (pfn(&mse))
        {
          TotalPhysicalMemory = mse.ullTotalPhys;
        }
      }

      ::FreeLibrary(hLib);
    }

    if (TotalPhysicalMemory == 0)
    {
      MEMORYSTATUS ms;
      ::ZeroMemory(&ms, sizeof(ms));
      ::GlobalMemoryStatus(&ms);

      TotalPhysicalMemory = ms.dwTotalPhys;
    }

    if (TotalPhysicalMemory == 0)
    {
      // Assume 128MB
      TotalPhysicalMemory = 128 * 1048576;
    }

    // Half of total physical memory
    memorylimit = (size_t)(TotalPhysicalMemory / 1048576 / 2);
#else
    memorylimit = 16;
#endif
  }
  memorylimit *= 1048576;

  return true;
}
Exemple #17
0
int main(int argc, char **argv)
{
    char *infile = NULL;
    Filename *infilename = NULL, *outfilename = NULL;
    enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA, ED25519 } keytype = NOKEYGEN;
    char *outfile = NULL, *outfiletmp = NULL;
    enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_AUTO,
           OPENSSH_NEW, SSHCOM } outtype = PRIVATE;
    int bits = -1;
    char *comment = NULL, *origcomment = NULL;
    int change_passphrase = FALSE;
    int errs = FALSE, nogo = FALSE;
    int intype = SSH_KEYTYPE_UNOPENABLE;
    int sshver = 0;
    struct ssh2_userkey *ssh2key = NULL;
    struct RSAKey *ssh1key = NULL;
    unsigned char *ssh2blob = NULL;
    char *ssh2alg = NULL;
    const struct ssh_signkey *ssh2algf = NULL;
    int ssh2bloblen;
    char *old_passphrase = NULL, *new_passphrase = NULL;
    int load_encrypted;
    progfn_t progressfn = is_interactive() ? progress_update : no_progress;
    const char *random_device = NULL;

    /* ------------------------------------------------------------------
     * Parse the command line to figure out what we've been asked to do.
     */

    /*
     * If run with no arguments at all, print the usage message and
     * return success.
     */
    if (argc <= 1) {
	usage(TRUE);
	return 0;
    }

    /*
     * Parse command line arguments.
     */
    while (--argc) {
	char *p = *++argv;
	if (*p == '-') {
	    /*
	     * An option.
	     */
	    while (p && *++p) {
		char c = *p;
		switch (c) {
		  case '-':
		    /*
		     * Long option.
		     */
		    {
			char *opt, *val;
			opt = p++;     /* opt will have _one_ leading - */
			while (*p && *p != '=')
			    p++;	       /* find end of option */
			if (*p == '=') {
			    *p++ = '\0';
			    val = p;
			} else
                            val = NULL;

			if (!strcmp(opt, "-help")) {
                            if (val) {
                                errs = TRUE;
                                fprintf(stderr, "puttygen: option `-%s'"
                                        " expects no argument\n", opt);
                            } else {
                                help();
                                nogo = TRUE;
                            }
			} else if (!strcmp(opt, "-version")) {
                            if (val) {
                                errs = TRUE;
                                fprintf(stderr, "puttygen: option `-%s'"
                                        " expects no argument\n", opt);
                            } else {
                                showversion();
                                nogo = TRUE;
                            }
			} else if (!strcmp(opt, "-pgpfp")) {
                            if (val) {
                                errs = TRUE;
                                fprintf(stderr, "puttygen: option `-%s'"
                                        " expects no argument\n", opt);
                            } else {
                                /* support --pgpfp for consistency */
                                pgp_fingerprints();
                                nogo = TRUE;
                            }
			} else if (!strcmp(opt, "-old-passphrase")) {
			    if (!val && argc > 1)
				--argc, val = *++argv;
			    if (!val) {
				errs = TRUE;
				fprintf(stderr, "puttygen: option `-%s'"
					" expects an argument\n", opt);
			    } else {
				old_passphrase = readpassphrase(val);
				if (!old_passphrase)
				    errs = TRUE;
			    }
			} else if (!strcmp(opt, "-new-passphrase")) {
			    if (!val && argc > 1)
				--argc, val = *++argv;
			    if (!val) {
				errs = TRUE;
				fprintf(stderr, "puttygen: option `-%s'"
					" expects an argument\n", opt);
			    } else {
				new_passphrase = readpassphrase(val);
				if (!new_passphrase)
				    errs = TRUE;
			    }
			} else if (!strcmp(opt, "-random-device")) {
			    if (!val && argc > 1)
				--argc, val = *++argv;
			    if (!val) {
				errs = TRUE;
				fprintf(stderr, "puttygen: option `-%s'"
					" expects an argument\n", opt);
			    } else {
                                random_device = val;
			    }
			} else {
			    errs = TRUE;
			    fprintf(stderr,
				    "puttygen: no such option `-%s'\n", opt);
			}
		    }
		    p = NULL;
		    break;
		  case 'h':
		  case 'V':
		  case 'P':
		  case 'l':
		  case 'L':
		  case 'p':
		  case 'q':
		    /*
		     * Option requiring no parameter.
		     */
		    switch (c) {
		      case 'h':
			help();
			nogo = TRUE;
			break;
		      case 'V':
			showversion();
			nogo = TRUE;
			break;
		      case 'P':
			change_passphrase = TRUE;
			break;
		      case 'l':
			outtype = FP;
			break;
		      case 'L':
			outtype = PUBLICO;
			break;
		      case 'p':
			outtype = PUBLIC;
			break;
		      case 'q':
			progressfn = no_progress;
			break;
		    }
		    break;
		  case 't':
		  case 'b':
		  case 'C':
		  case 'O':
		  case 'o':
		    /*
		     * Option requiring parameter.
		     */
		    p++;
		    if (!*p && argc > 1)
			--argc, p = *++argv;
		    else if (!*p) {
			fprintf(stderr, "puttygen: option `-%c' expects a"
				" parameter\n", c);
			errs = TRUE;
		    }
		    /*
		     * Now c is the option and p is the parameter.
		     */
		    switch (c) {
		      case 't':
			if (!strcmp(p, "rsa") || !strcmp(p, "rsa2"))
			    keytype = RSA2, sshver = 2;
			else if (!strcmp(p, "rsa1"))
			    keytype = RSA1, sshver = 1;
			else if (!strcmp(p, "dsa") || !strcmp(p, "dss"))
			    keytype = DSA, sshver = 2;
                        else if (!strcmp(p, "ecdsa"))
                            keytype = ECDSA, sshver = 2;
                        else if (!strcmp(p, "ed25519"))
                            keytype = ED25519, sshver = 2;
			else {
			    fprintf(stderr,
				    "puttygen: unknown key type `%s'\n", p);
			    errs = TRUE;
			}
                        break;
		      case 'b':
			bits = atoi(p);
                        break;
		      case 'C':
			comment = p;
                        break;
		      case 'O':
			if (!strcmp(p, "public"))
			    outtype = PUBLIC;
			else if (!strcmp(p, "public-openssh"))
			    outtype = PUBLICO;
			else if (!strcmp(p, "private"))
			    outtype = PRIVATE;
			else if (!strcmp(p, "fingerprint"))
			    outtype = FP;
			else if (!strcmp(p, "private-openssh"))
			    outtype = OPENSSH_AUTO, sshver = 2;
			else if (!strcmp(p, "private-openssh-new"))
			    outtype = OPENSSH_NEW, sshver = 2;
			else if (!strcmp(p, "private-sshcom"))
			    outtype = SSHCOM, sshver = 2;
			else {
			    fprintf(stderr,
				    "puttygen: unknown output type `%s'\n", p);
			    errs = TRUE;
			}
                        break;
		      case 'o':
			outfile = p;
                        break;
		    }
		    p = NULL;	       /* prevent continued processing */
		    break;
		  default:
		    /*
		     * Unrecognised option.
		     */
		    errs = TRUE;
		    fprintf(stderr, "puttygen: no such option `-%c'\n", c);
		    break;
		}
	    }
	} else {
	    /*
	     * A non-option argument.
	     */
	    if (!infile)
		infile = p;
	    else {
		errs = TRUE;
		fprintf(stderr, "puttygen: cannot handle more than one"
			" input file\n");
	    }
	}
    }

    if (bits == -1) {
        /*
         * No explicit key size was specified. Default varies
         * depending on key type.
         */
        switch (keytype) {
          case ECDSA:
            bits = 384;
            break;
          case ED25519:
            bits = 256;
            break;
          default:
            bits = DEFAULT_RSADSA_BITS;
            break;
        }
    }

    if (keytype == ECDSA && (bits != 256 && bits != 384 && bits != 521)) {
        fprintf(stderr, "puttygen: invalid bits for ECDSA, choose 256, 384 or 521\n");
        errs = TRUE;
    }

    if (keytype == ED25519 && (bits != 256)) {
        fprintf(stderr, "puttygen: invalid bits for ED25519, choose 256\n");
        errs = TRUE;
    }

    if (keytype == RSA2 || keytype == RSA1 || keytype == DSA) {
        if (bits < 256) {
            fprintf(stderr, "puttygen: cannot generate %s keys shorter than"
                    " 256 bits\n", (keytype == DSA ? "DSA" : "RSA"));
            errs = TRUE;
        } else if (bits < DEFAULT_RSADSA_BITS) {
            fprintf(stderr, "puttygen: warning: %s keys shorter than"
                    " %d bits are probably not secure\n",
                    (keytype == DSA ? "DSA" : "RSA"), DEFAULT_RSADSA_BITS);
            /* but this is just a warning, so proceed anyway */
        }
    }

    if (errs)
	return 1;

    if (nogo)
	return 0;

    /*
     * If run with at least one argument _but_ not the required
     * ones, print the usage message and return failure.
     */
    if (!infile && keytype == NOKEYGEN) {
	usage(TRUE);
	return 1;
    }

    /* ------------------------------------------------------------------
     * Figure out further details of exactly what we're going to do.
     */

    /*
     * Bomb out if we've been asked to both load and generate a
     * key.
     */
    if (keytype != NOKEYGEN && infile) {
	fprintf(stderr, "puttygen: cannot both load and generate a key\n");
	return 1;
    }

    /* 
     * We must save the private part when generating a new key.
     */
    if (keytype != NOKEYGEN &&
	(outtype != PRIVATE && outtype != OPENSSH_AUTO &&
         outtype != OPENSSH_NEW && outtype != SSHCOM)) {
	fprintf(stderr, "puttygen: this would generate a new key but "
		"discard the private part\n");
	return 1;
    }

    /*
     * Analyse the type of the input file, in case this affects our
     * course of action.
     */
    if (infile) {
	infilename = filename_from_str(infile);

	intype = key_type(infilename);

	switch (intype) {
	  case SSH_KEYTYPE_UNOPENABLE:
	  case SSH_KEYTYPE_UNKNOWN:
	    fprintf(stderr, "puttygen: unable to load file `%s': %s\n",
		    infile, key_type_to_str(intype));
	    return 1;

	  case SSH_KEYTYPE_SSH1:
          case SSH_KEYTYPE_SSH1_PUBLIC:
	    if (sshver == 2) {
		fprintf(stderr, "puttygen: conversion from SSH-1 to SSH-2 keys"
			" not supported\n");
		return 1;
	    }
	    sshver = 1;
	    break;

	  case SSH_KEYTYPE_SSH2:
          case SSH_KEYTYPE_SSH2_PUBLIC_RFC4716:
          case SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH:
	  case SSH_KEYTYPE_OPENSSH_PEM:
	  case SSH_KEYTYPE_OPENSSH_NEW:
	  case SSH_KEYTYPE_SSHCOM:
	    if (sshver == 1) {
		fprintf(stderr, "puttygen: conversion from SSH-2 to SSH-1 keys"
			" not supported\n");
		return 1;
	    }
	    sshver = 2;
	    break;

	  case SSH_KEYTYPE_OPENSSH_AUTO:
          default:
            assert(0 && "Should never see these types on an input file");
	}
    }

    /*
     * Determine the default output file, if none is provided.
     * 
     * This will usually be equal to stdout, except that if the
     * input and output file formats are the same then the default
     * output is to overwrite the input.
     * 
     * Also in this code, we bomb out if the input and output file
     * formats are the same and no other action is performed.
     */
    if ((intype == SSH_KEYTYPE_SSH1 && outtype == PRIVATE) ||
	(intype == SSH_KEYTYPE_SSH2 && outtype == PRIVATE) ||
	(intype == SSH_KEYTYPE_OPENSSH_PEM && outtype == OPENSSH_AUTO) ||
	(intype == SSH_KEYTYPE_OPENSSH_NEW && outtype == OPENSSH_NEW) ||
	(intype == SSH_KEYTYPE_SSHCOM && outtype == SSHCOM)) {
	if (!outfile) {
	    outfile = infile;
	    outfiletmp = dupcat(outfile, ".tmp", NULL);
	}

	if (!change_passphrase && !comment) {
	    fprintf(stderr, "puttygen: this command would perform no useful"
		    " action\n");
	    return 1;
	}
    } else {
	if (!outfile) {
	    /*
	     * Bomb out rather than automatically choosing to write
	     * a private key file to stdout.
	     */
	    if (outtype == PRIVATE || outtype == OPENSSH_AUTO ||
                outtype == OPENSSH_NEW || outtype == SSHCOM) {
		fprintf(stderr, "puttygen: need to specify an output file\n");
		return 1;
	    }
	}
    }

    /*
     * Figure out whether we need to load the encrypted part of the
     * key. This will be the case if either (a) we need to write
     * out a private key format, or (b) the entire input key file
     * is encrypted.
     */
    if (outtype == PRIVATE || outtype == OPENSSH_AUTO ||
        outtype == OPENSSH_NEW || outtype == SSHCOM ||
	intype == SSH_KEYTYPE_OPENSSH_PEM ||
	intype == SSH_KEYTYPE_OPENSSH_NEW ||
        intype == SSH_KEYTYPE_SSHCOM)
	load_encrypted = TRUE;
    else
	load_encrypted = FALSE;

    if (load_encrypted && (intype == SSH_KEYTYPE_SSH1_PUBLIC ||
                           intype == SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 ||
                           intype == SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH)) {
        fprintf(stderr, "puttygen: cannot perform this action on a "
                "public-key-only input file\n");
        return 1;
    }

    /* ------------------------------------------------------------------
     * Now we're ready to actually do some stuff.
     */

    /*
     * Either load or generate a key.
     */
    if (keytype != NOKEYGEN) {
	char *entropy;
	char default_comment[80];
	struct tm tm;
	struct progress prog;

	prog.phase = -1;
	prog.current = -1;

	tm = ltime();
	if (keytype == DSA)
	    strftime(default_comment, 30, "dsa-key-%Y%m%d", &tm);
        else if (keytype == ECDSA)
            strftime(default_comment, 30, "ecdsa-key-%Y%m%d", &tm);
        else if (keytype == ED25519)
            strftime(default_comment, 30, "ed25519-key-%Y%m%d", &tm);
	else
	    strftime(default_comment, 30, "rsa-key-%Y%m%d", &tm);

	random_ref();
	entropy = get_random_data(bits / 8, random_device);
	if (!entropy) {
	    fprintf(stderr, "puttygen: failed to collect entropy, "
		    "could not generate key\n");
	    return 1;
	}
	random_add_heavynoise(entropy, bits / 8);
	smemclr(entropy, bits/8);
	sfree(entropy);

	if (keytype == DSA) {
	    struct dss_key *dsskey = snew(struct dss_key);
	    dsa_generate(dsskey, bits, progressfn, &prog);
	    ssh2key = snew(struct ssh2_userkey);
	    ssh2key->data = dsskey;
	    ssh2key->alg = &ssh_dss;
	    ssh1key = NULL;
        } else if (keytype == ECDSA) {
Exemple #18
0
int main(int argc, char **argv) {
	RSocket *s;
	RSocketHTTPRequest *rs;
	int c, timeout = 3;
	int dodaemon = 0;
	int dosandbox = 0;
	bool listenlocal = true;
	const char *port = "8080";

	while ((c = getopt (argc, argv, "adhp:sv")) != -1) {
		switch (c) {
		case 'a':
			listenlocal = false;
			break;
		case 's':
			dosandbox = 1;
			break;
		case 'd':
			dodaemon = 1;
			break;
		case 'h':
			return usage (1);
		case 'v':
			return showversion ();
		case 'p':
			port = optarg;
			break;
		default:
			return usage (0);
		}
	}
	if (optind != argc) {
		return usage (0);
	}

#if USE_IOS_JETSAM
	memorystatus_control (MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT, getpid (), 256, NULL, 0);
#endif
	if (dodaemon) {
#if LIBC_HAVE_FORK
		int pid = fork ();
#else
		int pid = -1;
#endif
		if (pid > 0) {
			printf ("%d\n", pid);
			return 0;
		}
	}
	s = r_socket_new (false);
	s->local = listenlocal;
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Cannot listen on %d\n", s->port);
		r_socket_free (s);
		return 1;
	}
	
	eprintf ("http://localhost:%d/\n", s->port);
	if (dosandbox && !r_sandbox_enable (true)) {
		eprintf ("sandbox: Cannot be enabled.\n");
		return 1;
	}
	while (!r_cons_singleton ()->breaked) {
		char *result_heap = NULL;
		const char *result = page_index;

		rs = r_socket_http_accept (s, timeout);
		if (!rs) continue;
		if (!strcmp (rs->method, "GET")) {
			if (!strncmp (rs->path, "/proc/kill/", 11)) {
				// TODO: show page here?
				int pid = atoi (rs->path + 11);
				if (pid > 0) {
					kill (pid, 9);
				}
			} else if (!strncmp (rs->path, "/file/open/", 11)) {
				int pid;
				int session_port = 3000 + r_num_rand (1024);
				char *filename = rs->path + 11;
				int filename_len = strlen (filename);
				char *cmd;

				if (!(cmd = malloc (filename_len + 40))) {
					perror ("malloc");
					return 1;
				}
				sprintf (cmd, "r2 -q %s-e http.port=%d -c=h \"%s\"",
					listenlocal? "": "-e http.bind=public ",
					session_port, filename);

				// TODO: use r_sys api to get pid when running in bg
				pid = r_sys_cmdbg (cmd);
				free (cmd);
				result = result_heap = malloc (1024 + filename_len);
				if (!result) {
					perror ("malloc");
					return 1;
				}
				sprintf (result_heap,
				"<html><body>"
				"<a href='/'>back</a><hr size=1/>"
				" - <a target='_blank' href='http://localhost:%d/'>open</a><br />"
				" - <a href='/proc/kill/%d'>kill</a><br />"
				"</body></html>", session_port, pid);
				eprintf ("\nchild pid %d\n\n", pid);
			}
		}
		r_socket_http_response (rs, 200, result, 0, NULL);
		r_socket_http_close (rs);
		free (result_heap);
		result_heap = NULL;
	}
	r_socket_free (s);
	return 0;
}
Exemple #19
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       fd        = -1;
    int32_t   dindex    = -1;
    char     *fdnam     = NULL;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    int i, ch = '\0', done = 0;
    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    if (!getenv("MOUNT_FUSEFS_CALL_BY_LIB")) {
        showhelp();
        /* NOTREACHED */
    }

    /* Kludge to make "<fsdaemon> --version" happy. */
    if ((argc == 2) &&
        ((!strncmp(argv[1], "--version", strlen("--version"))) ||
         (!strncmp(argv[1], "-v", strlen("-v"))))) {
        showversion(1);
    }

    /* Kludge to make "<fsdaemon> --help" happy. */
    if ((argc == 2) &&
        ((!strncmp(argv[1], "--help", strlen("--help"))) ||
         (!strncmp(argv[1], "-h", strlen("-h"))))) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    do {
        for (i = 0; i < 3; i++) {
            if (optind < argc && argv[optind][0] != '-') {
                if (mntpath) {
                    done = 1;
                    break;
                }
                if (fdnam)
                    mntpath = argv[optind];
                else
                    fdnam = argv[optind];
                optind++;
            }
        }

        switch(ch) {
        case 'o':
            getmntopts(optarg, mopts, &mntflags, &altflags);
            for (mv = mvals; mv->mv_mntflag; ++mv) {
                if (!(altflags & mv->mv_mntflag)) {
                    continue;
                }
                for (mo = mopts; mo->m_option; ++mo) {
                    char *p, *q;
                    if (mo->m_flag != mv->mv_mntflag) {
                        continue;
                    }
                    p = strstr(optarg, mo->m_option);
                    if (p) {
                        p += strlen(mo->m_option);
                        q = p;
                        while (*q != '\0' && *q != ',') {
                            q++;
                        }
                        mv->mv_len = q - p + 1;
                        mv->mv_value = malloc(mv->mv_len);
                        memcpy(mv->mv_value, p, mv->mv_len - 1);
                        ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                        break;
                    }
                }
            }
            break;

        case '\0':
            break;

        case 'v':
            showversion(1);
            break;

        case '?':
        case 'h':
        default:
            showhelp();
            break;
        }

        if (done) {
            break;
        }

    } while ((ch = getopt(argc, argv, "ho:v")) != -1);

    argc -= optind;
    argv += optind;

    if ((!fdnam) && argc > 0) {
        fdnam = *argv++;
        argc--;
    }

    if (!fdnam) {
        errx(EX_USAGE, "missing " OSXFUSE_DISPLAY_NAME
             " device file descriptor");
    }

    errno = 0;
    fd = (int)strtol(fdnam, NULL, 10);
    if ((errno == EINVAL) || (errno == ERANGE)) {
        errx(EX_USAGE, "invalid name (%s) for " OSXFUSE_DISPLAY_NAME
             " device file descriptor", fdnam);
    }

    signal_fd = fd;

    {
        char  ndev[MAXPATHLEN];
        char *ndevbas;
        struct stat sb;

        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME
                " device file descriptor");
        }
        args.rdev = sb.st_rdev;
        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(sb.st_rdev, S_IFCHR, ndevbas,
                  (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME,
                    strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME),
                             NULL, 10);
        if ((errno == EINVAL) || (errno == ERANGE) ||
            (dindex < 0) || (dindex > OSXFUSE_NDEVICES)) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME
                 " device unit (#%d)\n", dindex);
        }
    }

    signal_idx = dindex;

    atexit(signal_idx_atexit_handler);

    result = check_kext_status();

    switch (result) {

    case 0:
        break;

    case ESRCH:
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
             " kernel extension is not loaded");
        break;

    case EINVAL:
        errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
             " kernel extension has a mismatched version");
        break;

    default:
        errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
             " kernel extension (%d)", result);
        break;
    }

    if ((!mntpath) && argc > 0) {
        mntpath = *argv++;
        argc--;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    (void)checkpath(mntpath, args.mntpath);

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t) blocksize;
    args.daemon_timeout = (uint32_t) daemon_timeout;
    args.fsid           = (uint32_t) fsid;
    args.fssubtype      = (uint32_t) fssubtype;
    args.iosize         = (uint32_t) iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_idx = -1;

    exit(0);
}
Exemple #20
0
int main(int argc, char *argv[])
{
  int new_fd;
  struct sockaddr_in server_addr, conn_addr;
  int sin_size;
  int c;
  char isdaemon = 0;

  /* check parameters */
  while (( c = getopt(argc, argv, "Dv")) != -1)
    switch(c) {
    case 'D':
      isdaemon = 1;
      break;
    case 'v':
      showversion();
      exit(0);
      break;
    case '?':
      return 1;
    default:
      abort();
    }

  if (isdaemon)
    run_as_daemon();

  /* initialize the error logging */
  error_init("nettrafd", isdaemon);

  /* initialize the nettraf library - used to fetch information from the system */
  if (!nettraf_init())
    error_exit("Cannot initialize nettraf library");

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    error_sys_exit("socket");
  }

  memset(&server_addr, 0, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(NETTRAFD_PORT);
  server_addr.sin_addr.s_addr = INADDR_ANY;

  if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
    error_sys_exit("bind");
  }

  if (listen(sockfd, 10) == -1) {
    error_sys_exit("listen");
  }

  signal(SIGINT, (void *)&sighandler);

  while (1) {
    sin_size = sizeof(struct sockaddr_in);
    if ((new_fd = accept(sockfd, (struct sockaddr *)&conn_addr, &sin_size)) == -1) {
      error_sys_report("accept");
      continue;
    }
#ifdef DEBUG
    printf("server: got connection from %s\n", inet_ntoa(conn_addr.sin_addr));
#endif

#ifdef USE_LIBWRAP
    request_init(&request, RQ_DAEMON, "nettraf", RQ_FILE, 0, 0);
    fromhost(&request);
    if (! hosts_access(&request)) {
      char text[256];

      sprintf(text, "Connection from %s:%d REFUSED by LIBWRAP", inet_ntoa(conn_addr.sin_addr), ntohs(conn_addr.sin_port));
      error_report(text);
      close(new_fd);
    } else
#endif
    ntd_newconnection(new_fd, conn_addr);
  }

  /* should never reach this... */
  do_cleanup();
  exit(0);
}
Exemple #21
0
int main(int argc, const char **argv) {
	char *line;
	int i, ret, fmt = MODE_DFLT;
	int db0 = 1, argi = 1;
	int interactive = 0;

	/* terminate flags */
	if (argc<2) showusage (1);
	if (!strcmp (argv[1], "-d")) {
		if (argc == 4)
			return dbdiff (argv[2], argv[3]);
		showusage (0);
	}
	if (!strcmp (argv[1], "-v")) showversion ();
	if (!strcmp (argv[1], "-h")) showusage (2);
	if (!strcmp (argv[1], "-j")) {
		if (argc>2)
			return sdb_dump (argv[db0+1], MODE_JSON);
		eprintf ("Missing database filename after -j\n");
		return 1;
	}

	/* flags */
	if (!strcmp (argv[argi], "-0")) {
		fmt = MODE_ZERO;
		db0++;
		argi++;
	}
	if (!strcmp (argv[argi], "-")) {
		/* no database */
		argv[argi] = "";
		if (argc == db0+1) {
			interactive = 1;
			/* if no argument passed */
			argv[argi] = "-";
			argc++;
			argi++;
		}
	}
	if (argc-1 == db0)
		return sdb_dump (argv[db0], fmt);
#if USE_MMAN
	signal (SIGINT, terminate);
	signal (SIGHUP, syncronize);
#endif
	ret = 0;
	if (interactive || !strcmp (argv[db0+1], "-")) {
		if ((s = sdb_new (NULL, argv[db0], 0))) {
			save |= insertkeys (s, argv+3, argc-3, '-');
			sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP);
			for (;(line = stdin_gets ());) {
				save |= sdb_query (s, line);
				if (fmt) {
					fflush (stdout);
					write (1, "", 1);
				}
				free (line);
			}
		}
	} else if (!strcmp (argv[db0+1], "=")) {
		ret = createdb (argv[db0], argv+db0+2, argc-(db0+2));
	} else {
		s = sdb_new (NULL, argv[db0], 0);
		if (!s) return 1;
		sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP);
		for (i=db0+1; i<argc; i++) {
			save |= sdb_query (s, argv[i]);
			if (fmt) {
				fflush (stdout);
				write (1, "", 1);
			}
		}
	}
	terminate (0);
	return ret;
}
Exemple #22
0
int main(int argc, char **argv)
{
  char **infiles;
  char *outfile;
  int nfiles;
  int nogo;
  int errs;
  int reportcols;
  int debug;

  /*
   * Set up initial (default) parameters.
   */
  infiles = mknewa(char *, argc);
  outfile = NULL;
  nfiles = 0;
  nogo = errs = FALSE;
  reportcols = 0;
  debug = 0;

  if (argc == 1)
  {
    usage();
    exit(EXIT_SUCCESS);
  }

  /*
   * Parse command line arguments.
   */
  while (--argc)
  {
    char *p = *++argv;
    if (*p == '-')
    {
      /*
       * An option.
       */
      while (p && *++p)
      {
        char c = *p;
        switch (c)
        {
        case '-':
          /*
           * Long option.
           */
          {
            char *opt, *val;
            opt = p++;          /* opt will have _one_ leading - */
            while (*p && *p != '=')
              p++;              /* find end of option */
            if (*p == '=')
            {
              *p++ = '\0';
              val = p;
            } else
              val = NULL;
            if (!strcmp(opt, "-version"))
            {
              showversion();
              nogo = TRUE;
            } else if (!strcmp(opt, "-licence") ||
                       !strcmp(opt, "-license"))
            {
              licence();
              nogo = TRUE;
            } else if (!strcmp(opt, "-output"))
            {
              if (!val)
                errs = TRUE, error(err_optnoarg, opt);
              else
                outfile = val;
            } else if (!strcmp(opt, "-precise"))
            {
              reportcols = 1;
            } else
            {
              errs = TRUE, error(err_nosuchopt, opt);
            }
          }
          p = NULL;
          break;
        case 'V':
        case 'L':
        case 'P':
        case 'd':
          /*
           * Option requiring no parameter.
           */
          switch (c)
          {
          case 'V':
            showversion();
            nogo = TRUE;
            break;
          case 'L':
            licence();
            nogo = TRUE;
            break;
          case 'P':
            reportcols = 1;
            break;
          case 'd':
            debug = TRUE;
            break;
          }
          break;
        case 'o':
          /*
           * Option requiring parameter.
           */
          p++;
          if (!*p && argc > 1)
            --argc, p = *++argv;
          else if (!*p)
          {
            char opt[2];
            opt[0] = c;
            opt[1] = '\0';
            errs = TRUE, error(err_optnoarg, opt);
          }
          /*
           * Now c is the option and p is the parameter.
           */
          switch (c)
          {
          case 'o':
            outfile = p;
            break;
          }
          p = NULL;             /* prevent continued processing */
          break;
        default:
          /*
           * Unrecognised option.
           */
          {
            char opt[2];
            opt[0] = c;
            opt[1] = '\0';
            errs = TRUE, error(err_nosuchopt, opt);
          }
        }
      }
    } else
    {
      /*
       * A non-option argument.
       */
      infiles[nfiles++] = p;
    }
  }

  if (errs)
    exit(EXIT_FAILURE);
  if (nogo)
    exit(EXIT_SUCCESS);

  /*
   * Do the work.
   */
  if (nfiles == 0)
  {
    error(err_noinput);
    usage();
    exit(EXIT_FAILURE);
  }

  {
    input in;
    paragraph *sourceform, *p;
    indexdata *idx;
    keywordlist *keywords;

    in.filenames = infiles;
    in.nfiles = nfiles;
    in.currfp = NULL;
    in.currindex = 0;
    in.npushback = in.pushbacksize = 0;
    in.pushback = NULL;
    in.reportcols = reportcols;
    in.stack = NULL;

    idx = make_index();

    sourceform = read_input(&in, idx);
    if (!sourceform)
      exit(EXIT_FAILURE);

    sfree(in.pushback);

    mark_attr_ends(sourceform);

    sfree(infiles);

    keywords = get_keywords(sourceform);
    if (!keywords)
      exit(EXIT_FAILURE);
    gen_citations(sourceform, keywords);
    subst_keywords(sourceform, keywords);

    for (p = sourceform; p; p = p->next)
      if (p->type == para_IM)
        index_merge(idx, TRUE, p->keyword, p->words);

    build_index(idx);


    if (debug)
    {
      index_debug(idx);
      dbg_prtkws(keywords);
      dbg_prtsource(sourceform);
    }

    xhtml_backend(sourceform, keywords, idx);

    free_para_list(sourceform);
    free_keywords(keywords);
    cleanup_index(idx);
  }

  return 0;
}
Exemple #23
0
int main(int argc, char **argv) {
  regex_t preg;
  /* command line options */
  int c;
  char *ifout = "";
  char *ifin = "";

#ifndef BCRELAY
  fprintf(stderr,
	  "bcrelay: pptpd was compiled without support for bcrelay, exiting.\n"
	  "         run configure --with-bcrelay, make, and install.\n");
  exit(1);
#endif

        /* open a connection to the syslog daemon */
        openlog("bcrelay", LOG_PID, PPTP_FACILITY);

  while (1) {
                int option_index = 0;

                static struct option long_options[] =
                {
                        {"nolog", 0, 0, 0},
                        {"daemon", 0, 0, 0},
                        {"help", 0, 0, 0},
                        {"incoming", 1, 0, 0},
                        {"outgoing", 1, 0, 0},
                        {"ipsec", 1, 0, 0},
                        {"version", 0, 0, 0},
                        {0, 0, 0, 0}
                };

                c = getopt_long(argc, argv, "ndhi:o:s:v", long_options, &option_index);
                if (c == -1)
                        break;
                /* convert long options to short form */
                if (c == 0)
                        c = "ndhiosv"[option_index];
                switch (c) {
                case 'n':
                        vnologging = 1;
                        break;
                case 'd':
                        vdaemon = 1;
                        break;
                case 'h':
                        showusage(argv[0]);
                        return 0;
                case 'i':
                        ifin = strdup(optarg);
                        break;
                case 'o':
                        ifout = strdup(optarg);
                        break;
                case 's':
                        ipsec = strdup(optarg);
                        // Validate the ipsec parameters
                        regcomp(&preg, "ipsec[0-9]+:[0-9]+.[0-9]+.[0-9]+.255", REG_EXTENDED);
                        if (regexec(&preg, ipsec, 0, NULL, 0)) {
                                syslog(LOG_INFO,"Bad syntax: %s", ipsec);
                                fprintf(stderr, "\nBad syntax: %s\n", ipsec);
                                showusage(argv[0]);
                                return 0;
                        } else {
                                regfree(&preg);
                                break;
                        }
                case 'v':
                        showversion();
                        return 0;
                default:
                        showusage(argv[0]);
                        return 1;
                }
  }
  if (ifin == "") {
       syslog(LOG_INFO,"Incoming interface required!");
       showusage(argv[0]);
       _exit(1);
  }
  if (ifout == "" && ipsec == "") {
       syslog(LOG_INFO,"Listen-mode or outgoing or IPsec interface required!");
       showusage(argv[0]);
       _exit(1);
  } else {
        sprintf(interfaces,"%s|%s", ifin, ifout);
  }

  // If specified, become Daemon.
  if (vdaemon) {
#if HAVE_DAEMON
    closelog();
    freopen("/dev/null", "r", stdin);
    /* set noclose, we want stdout/stderr still attached if we can */
    daemon(0, 1);
    /* returns to child only */
    /* pid will have changed */
    openlog("bcrelay", LOG_PID, PPTP_FACILITY);
#else   /* !HAVE_DAEMON */
    my_daemon(argc, argv);
    /* returns to child if !HAVE_FORK
     * never returns if HAVE_FORK (re-execs without -d)
     */
#endif
  } else {
    syslog(LOG_INFO, "Running as child\n");
  }
  mainloop(argc,argv);
  _exit(0);
}
Exemple #24
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       cfd       = -1;
    char     *fdnam     = NULL;
    char     *dev       = NULL;
    int       r         = 0;
    char      devpath[MAXPATHLEN];
    int       fd        = -1;
    int32_t   dindex    = -1;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    // Drop to real uid and gid
    seteuid(getuid());
    setegid(getgid());

    if (!getenv("MOUNT_OSXFUSE_CALL_BY_LIB")) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    while (true) {
        static struct option long_options[] = {
            { "help",    no_argument, NULL, 'h' },
            { "version", no_argument, NULL, 'v' },
            { NULL, 0, NULL, 0 }
        };

        int c = getopt_long(argc, argv, "ho:qv", long_options, NULL);
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'o':
                getmntopts(optarg, mopts, &mntflags, &altflags);
                for (mv = mvals; mv->mv_mntflag; ++mv) {
                    if (!(altflags & mv->mv_mntflag)) {
                        continue;
                    }
                    for (mo = mopts; mo->m_option; ++mo) {
                        char *p, *q;
                        if (!mo->m_altloc || mo->m_flag != mv->mv_mntflag) {
                            continue;
                        }
                        p = strstr(optarg, mo->m_option);
                        if (p) {
                            p += strlen(mo->m_option);
                            q = p;
                            while (*q != '\0' && *q != ',') {
                                q++;
                            }
                            mv->mv_len = q - p + 1;
                            mv->mv_value = malloc(mv->mv_len);
                            memcpy(mv->mv_value, p, mv->mv_len - 1);
                            ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                            break;
                        }
                    }
                }
                break;

            case 'q':
                quiet_mode = true;
                break;

            case 'v':
                showversion(true);
                break;

            case 'h':
            case '?':
            default:
                showhelp();
                break;
        }
    }

    argc -= optind;
    argv += optind;

    if (argc >= 1) {
        mntpath = argv[0];
        argc--;
        argv++;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    {
        char *commfd;

        commfd = getenv("_FUSE_COMMFD");
        if (commfd == NULL) {
            errx(EX_USAGE, "mew style mounting requires commfd");
        }

        errno = 0;
        cfd = (int)strtol(commfd, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || cfd < 0) {
            errx(EX_USAGE, "invalid commfd");
        }
    }

    result = load_kext();
    if (result) {
        if (result == EINVAL) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too new for the operating system. Please downgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_OLD, NULL, 0);
        }
        if (result == ENOENT) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too old for the operating system. Please upgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_NEW, NULL, 0);
        } else if (result == EBUSY) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("FUSE version mismatch"),
                    CFSTR("FUSE has been updated but an incompatible or old version of the FUSE kernel extension is already loaded. It failed to unload, possibly because a FUSE volume is currently mounted.\n\nPlease eject all FUSE volumes and try again, or simply restart the system for changes to take effect."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_VERSION_MISMATCH, NULL, 0);
        }
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME " file system is not available (%d)", result);
    }

    result = check_kext_status();
    switch (result) {
        case 0:
            break;

        case ESRCH:
            errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
                 " kernel extension is not loaded");
            break;

        case EINVAL:
            errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension has a mismatched version");
            break;

        default:
            errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension (%d)", result);
            break;
    }

    fdnam = getenv("FUSE_DEV_FD");
    if (fdnam) {
        errno = 0;
        fd = (int)strtol(fdnam, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || fd < 0) {
            errx(EX_USAGE, "invalid value given in FUSE_DEV_FD");
        }

        goto mount;
    }

    dev = getenv("FUSE_DEV_NAME");
    if (dev) {
        fd = open(dev, O_RDWR);
        if (fd < 0) {
            errx(EX_USAGE, "failed to open device");
        }

        goto mount;
    }

    for (r = 0; r < OSXFUSE_NDEVICES; r++) {
        snprintf(devpath, MAXPATHLEN - 1,
                 _PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r);
        fd = open(devpath, O_RDWR);
        if (fd >= 0) {
            dindex = r;
            break;
        }
    }
    if (dindex == -1) {
        errx(EX_OSERR, "failed to open device");
    }

mount:
    signal_fd = fd;
    atexit(&signal_idx_atexit_handler);

    {
        struct stat sb;
        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME " device file descriptor");
        }
        args.rdev = sb.st_rdev;
    }

    if (dindex < 0) {
        char  ndev[MAXPATHLEN];
        char *ndevbas;

        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(args.rdev, S_IFCHR, ndevbas, (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME, strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME), NULL, 10);
        if (errno == EINVAL || errno == ERANGE || dindex < 0 || dindex > OSXFUSE_NDEVICES) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME " device unit (#%d)\n", dindex);
        }
    }

    while (true) {
        struct stat sb;

        if (realpath(mntpath, args.mntpath) != NULL &&
            stat(args.mntpath, &sb) == 0) {

            if (S_ISDIR(sb.st_mode)) {
                break;
            } else {
                errx(EX_USAGE, "%s: not a directory", args.mntpath);
            }

        } else if (errno == ENOENT) {
            bool volumes = strncmp(args.mntpath, "/Volumes/", 9) == 0 &&
                           strchr(args.mntpath + 9, '/') == NULL;

            if (volumes) {
                (void)seteuid(0);
                (void)setegid(0);
            }

            if (mkdir(args.mntpath, 0755)) {
                errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
            }

            if (volumes) {
                uid_t uid = getuid();
                gid_t gid = getgid();

                (void)chown(args.mntpath, uid, gid);
                (void)seteuid(uid);
                (void)setegid(gid);
            }

        } else {
            errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
        }
    }

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t)blocksize;
    args.daemon_timeout = (uint32_t)daemon_timeout;
    args.fsid           = (uint32_t)fsid;
    args.fssubtype      = (uint32_t)fssubtype;
    args.iosize         = (uint32_t)iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    if (cfd != -1) {
        result = send_fd(cfd, fd);
        if (result == -1) {
            err(EX_OSERR, "failed to send file descriptor");
        }
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_fd = -1;
    exit(0);
}
Exemple #25
0
int main(int argc, char **argv)
{
    char *infile = NULL;
    Filename infilename;
    enum { NOKEYGEN, RSA1, RSA2, DSA } keytype = NOKEYGEN;    
    char *outfile = NULL, *outfiletmp = NULL;
    Filename outfilename;
    enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE;
    int bits = 1024;
    char *comment = NULL, *origcomment = NULL;
    int change_passphrase = FALSE;
    int errs = FALSE, nogo = FALSE;
    int intype = SSH_KEYTYPE_UNOPENABLE;
    int sshver = 0;
    struct ssh2_userkey *ssh2key = NULL;
    struct RSAKey *ssh1key = NULL;
    char *ssh2blob = NULL, *ssh2alg = NULL;
    const struct ssh_signkey *ssh2algf = NULL;
    int ssh2bloblen;
    char *passphrase = NULL;
    int load_encrypted;
    progfn_t progressfn = is_interactive() ? progress_update : no_progress;

    /* ------------------------------------------------------------------
     * Parse the command line to figure out what we've been asked to do.
     */

    /*
     * If run with no arguments at all, print the usage message and
     * return success.
     */
    if (argc <= 1) {
	usage();
	return 0;
    }

    /*
     * Parse command line arguments.
     */
    while (--argc) {
	char *p = *++argv;
	if (*p == '-') {
	    /*
	     * An option.
	     */
	    while (p && *++p) {
		char c = *p;
		switch (c) {
		  case '-':
		    /*
		     * Long option.
		     */
		    {
			char *opt, *val;
			opt = p++;     /* opt will have _one_ leading - */
			while (*p && *p != '=')
			    p++;	       /* find end of option */
			if (*p == '=') {
			    *p++ = '\0';
			    val = p;
			} else
			    val = NULL;
			if (!strcmp(opt, "-help")) {
			    help();
			    nogo = TRUE;
			} else if (!strcmp(opt, "-version")) {
			    showversion();
			    nogo = TRUE;
			}
			/*
			 * A sample option requiring an argument:
			 * 
			 * else if (!strcmp(opt, "-output")) {
			 *     if (!val)
			 *         errs = TRUE, error(err_optnoarg, opt);
			 *     else
			 *         ofile = val;
			 * }
			 */
			else {
			    errs = TRUE;
			    fprintf(stderr,
				    "puttygen: no such option `--%s'\n", opt);
			}
		    }
		    p = NULL;
		    break;
		  case 'h':
		  case 'V':
		  case 'P':
		  case 'l':
		  case 'L':
		  case 'p':
		  case 'q':
		    /*
		     * Option requiring no parameter.
		     */
		    switch (c) {
		      case 'h':
			help();
			nogo = TRUE;
			break;
		      case 'V':
			showversion();
			nogo = TRUE;
			break;
		      case 'P':
			change_passphrase = TRUE;
			break;
		      case 'l':
			outtype = FP;
			break;
		      case 'L':
			outtype = PUBLICO;
			break;
		      case 'p':
			outtype = PUBLIC;
			break;
		      case 'q':
			progressfn = no_progress;
			break;
		    }
		    break;
		  case 't':
		  case 'b':
		  case 'C':
		  case 'O':
		  case 'o':
		    /*
		     * Option requiring parameter.
		     */
		    p++;
		    if (!*p && argc > 1)
			--argc, p = *++argv;
		    else if (!*p) {
			fprintf(stderr, "puttygen: option `-%c' expects a"
				" parameter\n", c);
			errs = TRUE;
		    }
		    /*
		     * Now c is the option and p is the parameter.
		     */
		    switch (c) {
		      case 't':
			if (!strcmp(p, "rsa") || !strcmp(p, "rsa2"))
			    keytype = RSA2, sshver = 2;
			else if (!strcmp(p, "rsa1"))
			    keytype = RSA1, sshver = 1;
			else if (!strcmp(p, "dsa") || !strcmp(p, "dss"))
			    keytype = DSA, sshver = 2;
			else {
			    fprintf(stderr,
				    "puttygen: unknown key type `%s'\n", p);
			    errs = TRUE;
			}
                        break;
		      case 'b':
			bits = atoi(p);
                        break;
		      case 'C':
			comment = p;
                        break;
		      case 'O':
			if (!strcmp(p, "public"))
			    outtype = PUBLIC;
			else if (!strcmp(p, "public-openssh"))
			    outtype = PUBLICO;
			else if (!strcmp(p, "private"))
			    outtype = PRIVATE;
			else if (!strcmp(p, "fingerprint"))
			    outtype = FP;
			else if (!strcmp(p, "private-openssh"))
			    outtype = OPENSSH, sshver = 2;
			else if (!strcmp(p, "private-sshcom"))
			    outtype = SSHCOM, sshver = 2;
			else {
			    fprintf(stderr,
				    "puttygen: unknown output type `%s'\n", p);
			    errs = TRUE;
			}
                        break;
		      case 'o':
			outfile = p;
                        break;
		    }
		    p = NULL;	       /* prevent continued processing */
		    break;
		  default:
		    /*
		     * Unrecognised option.
		     */
		    errs = TRUE;
		    fprintf(stderr, "puttygen: no such option `-%c'\n", c);
		    break;
		}
	    }
	} else {
	    /*
	     * A non-option argument.
	     */
	    if (!infile)
		infile = p;
	    else {
		errs = TRUE;
		fprintf(stderr, "puttygen: cannot handle more than one"
			" input file\n");
	    }
	}
    }

    if (errs)
	return 1;

    if (nogo)
	return 0;

    /*
     * If run with at least one argument _but_ not the required
     * ones, print the usage message and return failure.
     */
    if (!infile && keytype == NOKEYGEN) {
	usage();
	return 1;
    }

    /* ------------------------------------------------------------------
     * Figure out further details of exactly what we're going to do.
     */

    /*
     * Bomb out if we've been asked to both load and generate a
     * key.
     */
    if (keytype != NOKEYGEN && intype) {
	fprintf(stderr, "puttygen: cannot both load and generate a key\n");
	return 1;
    }

    /*
     * Analyse the type of the input file, in case this affects our
     * course of action.
     */
    if (infile) {
	infilename = filename_from_str(infile);

	intype = key_type(&infilename);

	switch (intype) {
	    /*
	     * It would be nice here to be able to load _public_
	     * key files, in any of a number of forms, and (a)
	     * convert them to other public key types, (b) print
	     * out their fingerprints. Or, I suppose, for real
	     * orthogonality, (c) change their comment!
	     * 
	     * In fact this opens some interesting possibilities.
	     * Suppose ssh2_userkey_loadpub() were able to load
	     * public key files as well as extracting the public
	     * key from private ones. And suppose I did the thing
	     * I've been wanting to do, where specifying a
	     * particular private key file for authentication
	     * causes any _other_ key in the agent to be discarded.
	     * Then, if you had an agent forwarded to the machine
	     * you were running Unix PuTTY or Plink on, and you
	     * needed to specify which of the keys in the agent it
	     * should use, you could do that by supplying a
	     * _public_ key file, thus not needing to trust even
	     * your encrypted private key file to the network. Ooh!
	     */

	  case SSH_KEYTYPE_UNOPENABLE:
	  case SSH_KEYTYPE_UNKNOWN:
	    fprintf(stderr, "puttygen: unable to load file `%s': %s\n",
		    infile, key_type_to_str(intype));
	    return 1;

	  case SSH_KEYTYPE_SSH1:
	    if (sshver == 2) {
		fprintf(stderr, "puttygen: conversion from SSH1 to SSH2 keys"
			" not supported\n");
		return 1;
	    }
	    sshver = 1;
	    break;

	  case SSH_KEYTYPE_SSH2:
	  case SSH_KEYTYPE_OPENSSH:
	  case SSH_KEYTYPE_SSHCOM:
	    if (sshver == 1) {
		fprintf(stderr, "puttygen: conversion from SSH2 to SSH1 keys"
			" not supported\n");
		return 1;
	    }
	    sshver = 2;
	    break;
	}
    }

    /*
     * Determine the default output file, if none is provided.
     * 
     * This will usually be equal to stdout, except that if the
     * input and output file formats are the same then the default
     * output is to overwrite the input.
     * 
     * Also in this code, we bomb out if the input and output file
     * formats are the same and no other action is performed.
     */
    if ((intype == SSH_KEYTYPE_SSH1 && outtype == PRIVATE) ||
	(intype == SSH_KEYTYPE_SSH2 && outtype == PRIVATE) ||
	(intype == SSH_KEYTYPE_OPENSSH && outtype == OPENSSH) ||
	(intype == SSH_KEYTYPE_SSHCOM && outtype == SSHCOM)) {
	if (!outfile) {
	    outfile = infile;
	    outfiletmp = dupcat(outfile, ".tmp", NULL);
	}

	if (!change_passphrase && !comment) {
	    fprintf(stderr, "puttygen: this command would perform no useful"
		    " action\n");
	    return 1;
	}
    } else {
	if (!outfile) {
	    /*
	     * Bomb out rather than automatically choosing to write
	     * a private key file to stdout.
	     */
	    if (outtype==PRIVATE || outtype==OPENSSH || outtype==SSHCOM) {
		fprintf(stderr, "puttygen: need to specify an output file\n");
		return 1;
	    }
	}
    }

    /*
     * Figure out whether we need to load the encrypted part of the
     * key. This will be the case if either (a) we need to write
     * out a private key format, or (b) the entire input key file
     * is encrypted.
     */
    if (outtype == PRIVATE || outtype == OPENSSH || outtype == SSHCOM ||
	intype == SSH_KEYTYPE_OPENSSH || intype == SSH_KEYTYPE_SSHCOM)
	load_encrypted = TRUE;
    else
	load_encrypted = FALSE;

    /* ------------------------------------------------------------------
     * Now we're ready to actually do some stuff.
     */

    /*
     * Either load or generate a key.
     */
    if (keytype != NOKEYGEN) {
	char *entropy;
	char default_comment[80];
	time_t t;
	struct tm *tm;
	struct progress prog;

	prog.phase = -1;
	prog.current = -1;

	time(&t);
	tm = localtime(&t);
	if (keytype == DSA)
	    strftime(default_comment, 30, "dsa-key-%Y%m%d", tm);
	else
	    strftime(default_comment, 30, "rsa-key-%Y%m%d", tm);

	random_init();
	entropy = get_random_data(bits / 8);
	random_add_heavynoise(entropy, bits / 8);
	memset(entropy, 0, bits/8);
	sfree(entropy);

	if (keytype == DSA) {
	    struct dss_key *dsskey = snew(struct dss_key);
	    dsa_generate(dsskey, bits, progressfn, &prog);
	    ssh2key = snew(struct ssh2_userkey);
	    ssh2key->data = dsskey;
	    ssh2key->alg = &ssh_dss;
	    ssh1key = NULL;
	} else {
Exemple #26
0
int main(int argc, char **argv) {
    char *pass = NULL;
    char *tty = NULL;
    char *command = NULL;
    char *remote_addr = NULL;
    char *service = NULL;
    char *protocol = NULL;
    struct addrinfo *tac_server;
    char *tac_server_name = NULL;
    char *tac_secret = NULL;
    int tac_fd;
    short int task_id = 0;
    char buf[40];
    int ret;
#ifndef USE_SYSTEM
    pid_t pid;
#endif
    struct areply arep;

    /* options */
    flag log_wtmp = 1;
    flag do_author = 0;
    flag do_authen = 0;
    flag do_account = 0;
    flag login_mode = 0;

    /* check argc */
    if (argc < 2) {
        showusage(argv[0]);
        exit(EXIT_ERR);
    }

    /* check for login mode */
    if (argc == 2 && isalpha(*argv[1])) {
        g_user = argv[1];
        do_author = do_authen = do_account = 1;
        command = DEFAULT_COMMAND;
        login_mode = 1;
    } else {
        int c;
        int opt_index;

        while ((c = getopt_long(argc, argv, opt_string, long_options,
                                &opt_index)) != EOF) {
            switch (c) {
                case 'T':
                    do_authen = 1;
                    break;
                case 'R':
                    do_author = 1;
                    break;
                case 'A':
                    do_account = 1;
                    break;
                case 'V':
                    showversion(argv[0]);
                    /*NOTREACHED*/
                    break;
                case 'h':
                    showusage(argv[0]);
                    /*NOTREACHED*/
                    break;
                case 'u':
                    g_user = optarg;
                    break;
                case 'r':
                    remote_addr = optarg;
                    break;
                case 'L':
                    // tac_login is a global variable initialized in libtac
                    xstrcpy(tac_login, optarg, sizeof(tac_login));
                    break;
                case 'p':
                    pass = optarg;
                    break;
                case 's':
                    tac_server_name = optarg;
                    break;
                case 'k':
                    tac_secret = optarg;
                    break;
                case 'c':
                    command = optarg;
                    break;
                case 'S':
                    service = optarg;
                    break;
                case 'P':
                    protocol = optarg;
                    break;
                case 'q':
                    quiet = 1;
                    break;
                case 'w':
                    log_wtmp = 0;
                    break;
                case 'n':
                    tac_encryption = 0;
                    break;
                case 'y':
                    tty = optarg;
                    break;
            }
        }
    }

    /* check available information and set to defaults if needed */
    if (do_authen + do_author + do_account == 0) {
        printf("error: one of -TRAVh options is required\n");
        exit(EXIT_ERR);
    }

    if (g_user == NULL) {
        printf("error: username is required.\n");
        exit(EXIT_ERR);
    }

    if (remote_addr == NULL) {
        printf("error: remote address is required.\n");
        exit(EXIT_ERR);
    }

    if (service == NULL) {
        printf("error: service is required.\n");
        exit(EXIT_ERR);
    }

    if (protocol == NULL) {
        printf("error: protocol is required.\n");
        exit(EXIT_ERR);
    }

    if (tac_server_name == NULL) {
        printf("error: server name is required.\n");
        exit(EXIT_ERR);
    }

    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    ret = getaddrinfo(tac_server_name, "tacacs", &hints, &tac_server);
    if (ret != 0) {
        printf("error: resolving name %s: %s", tac_server_name,
               gai_strerror(ret));
        exit(EXIT_ERR);
    }

    if (tac_secret == NULL) {
        printf("error: server secret is required.\n");
        exit(EXIT_ERR);
    }

    if (pass == NULL) {
        signal(SIGALRM, timeout_handler);
        alarm(GETPASS_TIMEOUT);
        pass = getpass(PASSWORD_PROMPT);
        alarm(0);
        signal(SIGALRM, SIG_DFL);
        if (!strlen(pass))
            exit(EXIT_ERR);
    }

    if (tty == NULL) {
        printf("error: tty name is required.\n");
        exit(EXIT_ERR);
    }

    /* open syslog before any TACACS+ calls */
    openlog("tacc", LOG_CONS | LOG_PID, LOG_AUTHPRIV);

    if (do_authen)
        authenticate(tac_server, tac_secret, g_user, pass, tty, remote_addr);

    if (do_author) {
        /* authorize user */
        struct tac_attrib *attr = NULL;
        tac_add_attrib(&attr, "service", service);
        tac_add_attrib(&attr, "protocol", protocol);

        tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
        if (tac_fd < 0) {
            if (!quiet)
                printf("Error connecting to TACACS+ server: %m\n");
            exit(EXIT_ERR);
        }

        tac_author_send(tac_fd, g_user, tty, remote_addr, attr);

        tac_author_read(tac_fd, &arep);
        if (arep.status != AUTHOR_STATUS_PASS_ADD
            && arep.status != AUTHOR_STATUS_PASS_REPL) {
            if (!quiet)
                printf("Authorization FAILED: %s\n", arep.msg);
            exit(EXIT_FAIL);
        } else {
            if (!quiet)
                printf("Authorization OK: %s\n", arep.msg);
        }

        tac_free_attrib(&attr);
    }

    /* we no longer need the password in our address space */
    bzero(pass, strlen(pass));
    pass = NULL;

    if (do_account) {
        /* start accounting */
        struct tac_attrib *attr = NULL;

        sprintf(buf, "%lu", time(0));
        tac_add_attrib(&attr, "start_time", buf);

        // this is not crypto but merely an identifier
        long rnd_id = random();
        memcpy(&task_id, &rnd_id, sizeof(task_id));

        sprintf(buf, "%hu", task_id);
        tac_add_attrib(&attr, "task_id", buf);
        tac_add_attrib(&attr, "service", service);
        tac_add_attrib(&attr, "protocol", protocol);

        tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
        if (tac_fd < 0) {
            if (!quiet)
                printf("Error connecting to TACACS+ server: %m\n");
            exit(EXIT_ERR);
        }

        tac_acct_send(tac_fd, TAC_PLUS_ACCT_FLAG_START, g_user, tty, remote_addr,
                      attr);

        ret = tac_acct_read(tac_fd, &arep);
        if (ret == 0) {
            if (!quiet)
                printf("Accounting: START failed: %s\n", arep.msg);
            syslog(LOG_INFO, "TACACS+ accounting start failed: %s", arep.msg);
        } else if (!login_mode && !quiet)
            printf("Accounting: START OK\n");

        close(tac_fd);

        tac_free_attrib(&attr);

    }

    /* log in local utmp */
    if (log_wtmp) {
#if defined(HAVE_PUTUTXLINE)
        struct timeval tv;

        gettimeofday(&tv, NULL);

        memset(&utmpx, 0, sizeof(utmpx));
        utmpx.ut_type = USER_PROCESS;
        utmpx.ut_pid = getpid();
        xstrcpy(utmpx.ut_line, tty, sizeof(utmpx.ut_line));
        strncpy(utmpx.ut_id, tty + C_STRLEN("tty"), sizeof(utmpx.ut_id));
        xstrcpy(utmpx.ut_host, "dialup", sizeof(utmpx.ut_host));
        utmpx.ut_tv.tv_sec = tv.tv_sec;
        utmpx.ut_tv.tv_usec = tv.tv_usec;
        xstrcpy(utmpx.ut_user, g_user, sizeof(utmpx.ut_user));
        /* ut_addr unused ... */
        setutxent();
        pututxline(&utmpx);
#elif defined(HAVE_LOGWTMP)
        logwtmp(tty, g_user, "dialup");
#endif
    }

    if (command != NULL) {
        int ret;

        syslog(LOG_DEBUG, "starting %s for %s", command, g_user);

        signal(SIGHUP, SIG_IGN);
        signal(SIGTERM, SIG_IGN);
        signal(SIGINT, SIG_IGN);
        signal(SIGCHLD, SIG_IGN);

#ifdef COMMAND_MESSAGE
        printf(COMMAND_MESSAGE);
#endif

#if USE_SYSTEM
        ret = system(command);
        if (ret < 0)
            syslog(LOG_WARNING, "command failed: %m");
        else
            syslog(LOG_NOTICE, "command exit code %u", ret);
#else
        pid=fork();

        if(pid == 0) {
            /* child */

            execl(DEFAULT_COMMAND, DEFAULT_COMMAND, ARGS, NULL);
            syslog(LOG_ERR, "execl() failed: %m");
            _exit(EXIT_FAIL);
        }

        if(pid < 0) {
            /* error */
            syslog(LOG_ERR, "fork failed: %m");
            exit(EXIT_FAIL);
        }

        if(pid > 0) {
            /* parent */
            int st, r;

            r=wait(&st);
        }
#endif
    }

    if (do_account) {
        /* stop accounting */
        struct tac_attrib *attr = NULL;
        sprintf(buf, "%lu", time(0));
        tac_add_attrib(&attr, "stop_time", buf);
        sprintf(buf, "%hu", task_id);
        tac_add_attrib(&attr, "task_id", buf);

        tac_fd = tac_connect_single(tac_server, tac_secret, NULL, 60);
        if (tac_fd < 0) {
            if (!quiet)
                printf("Error connecting to TACACS+ server: %m\n");
            exit(EXIT_ERR);
        }

        tac_acct_send(tac_fd, TAC_PLUS_ACCT_FLAG_STOP, g_user, tty, remote_addr,
                      attr);
        ret = tac_acct_read(tac_fd, &arep);
        if (ret == 0) {
            if (!quiet)
                printf("Accounting: STOP failed: %s", arep.msg);
            syslog(LOG_INFO, "TACACS+ accounting stop failed: %s\n", arep.msg);
        } else if (!login_mode && !quiet)
            printf("Accounting: STOP OK\n");

        close(tac_fd);

        tac_free_attrib(&attr);
    }

    /* logout from utmp */
    if (log_wtmp) {
#if defined(HAVE_PUTUTXLINE)
        utmpx.ut_type = DEAD_PROCESS;
        memset(utmpx.ut_line, 0, sizeof(utmpx.ut_line));
        memset(utmpx.ut_user, 0, sizeof(utmpx.ut_user));
        memset(utmpx.ut_host, 0, sizeof(utmpx.ut_host));
        utmpx.ut_tv.tv_sec = utmpx.ut_tv.tv_usec = 0;
        setutxent();
        pututxline(&utmpx);
#elif defined(HAVE_LOGWTMP)
        logwtmp(tty, "", "");
#endif
    }

    exit(EXIT_OK);
}