Пример #1
0
TEST(fv_converter, key_matcher) {
  ASSERT_TRUE(exact_match("hoge").match("hoge"));
  ASSERT_FALSE(exact_match("hoge").match("foo"));

  ASSERT_TRUE(prefix_match("ho").match("hoge"));
  ASSERT_TRUE(prefix_match("hoge").match("hoge"));
  ASSERT_TRUE(prefix_match("").match("hoge"));
  ASSERT_FALSE(prefix_match("hogehgoe").match("hoge"));

  ASSERT_TRUE(suffix_match("ge").match("hoge"));
  ASSERT_TRUE(suffix_match("hoge").match("hoge"));
  ASSERT_TRUE(suffix_match("").match("hoge"));
  ASSERT_FALSE(suffix_match("hogehgoe").match("hoge"));
}
Пример #2
0
int winscp_regular_request(char *request)
{
	/*
	 * winscp uses one of two requests to terminate each command.
	 * we must determine which (if any) is terminating this request. fun!
	 */
	char *new_request=NULL;
	int retval=0;
	int retzero=1;
	new_request=strend(request, WINSCP_EOF_REQ_ZERO);
	if (NULL == new_request)
	{
		retzero=0;
		new_request=strend(request, WINSCP_EOF_REQ_STATUS);
		if (NULL == new_request)
		{
			new_request=strend(request, WINSCP_EOF_REQ_RETVAL);
			if (NULL == new_request)
			{
				printf ("command wasn't terminated with %s, %s or %s\n",
					WINSCP_EOF_REQ_RETVAL, WINSCP_EOF_REQ_ZERO, WINSCP_EOF_REQ_STATUS);
				return(-1);	/* bogus termination */
			}
		}
	}
	/*
	 *	here is where we fool winscp clients into believing we are a real shell
	 */
	if ((exact_match(new_request, "echo \"$status\"")) ||
		(exact_match(new_request, "echo \"$?\"")))
	{
		printf ("0\n");
		fflush(stdout);
	}
	/*
	 *  ignore unalias and unset commands
	 */
	else if ((NULL!=strbeg(new_request,"unset ")) ||
		(NULL!=strbeg(new_request,"unalias ")))
		retval=0;
	else
	{
		retval=process_ssh_request(new_request);
		if (retzero)		/* ignore actual retval if winscp wants us to */
			retval=0;
	}
	free(new_request);
	return(retval);
}
Пример #3
0
// ./lect01 abacabadabacabaeabacabadabacabafabacabadabacabaeabacabadabacabagabacabadabacabaeabacabadabacabafabacabadabacabaeabacabadabacaba llolkloll
// ./lect01 abacabadabacabaeabacabadabacabafabacabadabacabaeabacabadabacabagabacabadabacabaeabacabadabacabafabacabadabacabaeabacabadabacaba abadaba
// gcc -O3 lect01.c -o lect01
int main(int argc, char const *argv[])
{
	for( int i = argc ; i-- ; ) {
		printf( "%s\n", argv[ i ] );
		size_t *b = boundary( argv[ i ], strlen( argv[ i ] ) );

		for( int j = 0 ; j < strlen( argv[ i ] ) ; ++j )
			printf("%2d ", b[ j ] );
		printf( "\n" );

		free( b );
	}

		size_t *b = boundary( "participate in parachute", 24 );

		for( int j = 0 ; j < 24 ; ++j )
			printf("%c %2d\n", "participate in parachute"[ j ], b[ j ] );
		printf( "\n" );
		free( b );

// Do some matching
	match_t *matches = exact_match( argv[ 1 ], strlen( argv[ 1 ] ), argv[ 2 ], strlen( argv[ 2 ] ) );

	for( size_t m = 0 ; m < matches->nMatches ; ++m ) {
		printf("%d\n", matches->match[ m ] );
	}

	free( matches );
	return 0;
}
Пример #4
0
void *
delete_match_strict_entry( struct ofp_match match, uint16_t priority ) {
  if ( _match_table_head == NULL ) {
    die( "match table is not initialized." );
  }

  pthread_mutex_lock( _match_table_head->mutex );
  void *data = NULL;
  if ( exact_match( &match ) ) {
    data = delete_exact_match_strict_entry( _match_table_head->exact_table, &match );
  }
  else {
    // wildcards flags are set
    data = delete_wildcards_match_strict_entry( &_match_table_head->wildcards_table, &match, priority );
  }
  pthread_mutex_unlock( _match_table_head->mutex );
  return data;
}
Пример #5
0
bool
update_match_entry( struct ofp_match match, uint16_t priority, void *data ) {
  if ( _match_table_head == NULL ) {
    die( "match table is not initialized." );
  }

  pthread_mutex_lock( _match_table_head->mutex );
  bool result;
  if ( exact_match( &match ) ) {
    result = update_exact_match_entry( _match_table_head->exact_table, &match, data );
  }
  else {
    // wildcards flags are set
    result = update_wildcards_match_entry( _match_table_head->wildcards_table, &match, priority, data );
  }
  pthread_mutex_unlock( _match_table_head->mutex );
  return result;
}
Пример #6
0
void *
lookup_match_strict_entry( struct ofp_match match, uint16_t priority ) {
  if ( _match_table_head == NULL ) {
    die( "match table is not initialized." );
  }

  pthread_mutex_lock( _match_table_head->mutex );
  match_entry *entry;
  if ( exact_match( &match ) ) {
    entry = lookup_exact_match_strict_entry( _match_table_head->exact_table, &match );
  }
  else {
    entry = lookup_wildcards_match_strict_entry( _match_table_head->wildcards_table, &match, priority );
  }
  void *data = ( entry != NULL ? entry->data : NULL );
  pthread_mutex_unlock( _match_table_head->mutex );
  return data;
}
Пример #7
0
bool contains_word( const char*& argument, const char* word, char* arg )
{
  const char*  s1  = argument;
  const char*  s2;

  for( ; *s1 != '\0'; ) {
    if( exact_match( s2 = s1, word ) ) {
      for( ; s1 != argument && *(s1-1) == ' '; s1-- );
      memcpy( arg, argument, s1-argument );
      arg[s1-argument] = '\0';
      argument = s2;
      return TRUE;
      } 
    for( ; *s1 != '\0' && *s1 != ' '; s1++ );
    for( ; *s1 == ' '; s1++ );
    }

  return FALSE;
}
Пример #8
0
void do_shedit( char_data* ch, char* argument )
{
  char                  buf  [MAX_STRING_LENGTH ];
  mob_data*          keeper;
  shop_data*           shop;
  char_data*         victim;
  species_data*     species;
  int                number;
  
  for( shop = shop_list; shop != NULL; shop = shop->next )
    if( ch->in_room == shop->room ) 
      break;  

  if( *argument != '\0' && !can_edit( ch, ch->in_room ) )
    return;

  if( exact_match( argument, "new" ) ) {
    if( shop != NULL ) {
      send( ch, "There is already a shop here.\r\n" );
      return;
      }
    shop = new shop_data;
    shop->room = ch->in_room;
    shop->custom = NULL;
    shop->keeper = -1;
    shop->repair = 0;
    shop->materials = 0;
    shop->buy_type[0] = 0;
    shop->buy_type[1] = 0;
    shop->next = shop_list;
    shop_list = shop;
    send( ch, "New shop created here.\r\n" );
    return;
    }

  if( shop == NULL ) {
    send( ch, "There is no shop associated with this room.\r\n" );
    return;
    }

  if( *argument == '\0' ) {
    species = get_species( shop->keeper ); 
    sprintf( buf, "Shop Keeper: %s  [ Vnum: %d ]\r\n\r\n", ( species == NULL
      ? "none" : species->descr->name ), shop->keeper );
    sprintf( buf+strlen( buf ), "Repair: %d\r\n\r\n", shop->repair );
    send( buf, ch );
    return;
    }
  
  if( exact_match( argument, "delete" ) ) {
    remove( shop_list, shop );
    for( int i = 0; i < mob_list; i++ )
      if( mob_list[i]->pShop == shop )
        mob_list[i]->pShop = NULL;
    send( ch, "Shop deleted.\r\n" );
    return;
    }
   
  if( matches( argument, "keeper" ) ) {
    if( ( victim = one_character( ch, argument, "set keepr",
      ch->array ) ) == NULL )
      return;

    if( ( keeper = mob( victim ) ) == NULL ) {
      send( ch, "Players can not be shop keepers.\r\n" );
      return;
      }
    shop->keeper = keeper->species->vnum;
    keeper->pShop = shop;
    send( ch, "Shop keeper set to %s.\r\n", keeper->descr->name );
    return;
    }

  if( matches( argument, "repair" ) ) {
    if( ( number = atoi( argument ) ) < 0 || number > 10 ) {
      send( ch,
        "A shop's repair level must be between 0 and 10.\r\n" ); 
      return;
      }
    shop->repair = number;
    send( ch, "The shop's repair level is set to %d.\r\n", number );
    } 
}
Пример #9
0
int process_ssh_request(char *request)
{
	char **av, **tmp_av, **tenv;
	char *flat_request,*tmpstring, *tmprequest;
	char bad_winscp3str[] = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server exec sftp-server";
	int retval;
	int reqlen=strlen(request);
	char **env = NULL;

	debug(LOG_DEBUG, "processing request: \"%s\"\n", request);

	tmprequest=strdup(request);

#ifdef WINSCP_COMPAT			

	bad_winscp3str[57]=10;
	bad_winscp3str[127]=10;
			
	if(strcmp(request,bad_winscp3str)==0)
	{
	    /*
		 * switch out the command to use, winscp wont know the difference
	 	 */
		free(tmprequest);
		tmprequest=strdup(PROG_SFTP_SERVER);
	    syslog(LOG_DEBUG, "winscp3 compat correcting to: \"[%s]\"\n", PROG_SFTP_SERVER);
	}
#endif

	
#ifdef GFTP_COMPAT 
	/*
	 *	gFTP compatibility hack
	 */
	if (NULL != (tmpstring=strbeg(request, "echo -n xsftp ; ")))
	{
		free(tmprequest);
		tmprequest=strdup(tmpstring);
		printf("xsftp");
		fflush(stdout);
	}
#endif

#ifdef RESTRICTIVE_FILENAMES
	/*
	 * we flat out reject special chars
	 */
	if (!valid_chars(tmprequest))
	{
		debug(LOG_DEBUG, "rejected because of invalid chars (%s)", logstamp());
		free(tmprequest);
		return(-1);
	}
#endif

#ifdef WINSCP_COMPAT
	if (strbeg(tmprequest,PROG_CD))
	{
		char *destdir=(char *)malloc(reqlen);
		if (destdir == NULL)
		{
			perror("malloc");
			exit(EXIT_FAILURE);
		}

		/*
		 * well, now that scponly is a persistent shell
		 * i have to maintain a $PWD.  damn.
		 * we're going to INSIST upon a double quote
		 * encapsulated new directory to change to.
		 */
		if ((tmprequest[(reqlen-1)]=='"') && (tmprequest[3]=='"'))
		{
			bzero(destdir,reqlen);
			strncpy(destdir,&tmprequest[4],reqlen-5);
			debug(LOG_INFO, "chdir: %s (%s)", tmprequest, logstamp());
			retval=chdir(destdir);
			free(destdir);
			free(tmprequest);
			return(retval);
		}
		syslog(LOG_ERR, "bogus chdir request: %s (%s)", tmprequest, logstamp());
		free(tmprequest);
		return(-1);
	}
#endif

	/*
	 * convert request string to an arg_vector
	 */
	av = build_arg_vector(tmprequest);

	/*
	 * clean any path info from request and substitute our known pathnames
	 */
	av[0] = substitute_known_path(av[0]);
	
	/*
	 * we only process wildcards for scp commands
	 */
#ifdef ENABLE_WILDCARDS
#ifdef ENABLE_SCP2
	if (exact_match(av[0],PROG_SCP))
		av = expand_wildcards(av);
#endif
#endif

/*
 *	check for a compile time chdir configuration
 */
#ifdef ENABLE_DEFAULT_CHDIR
	if (exact_match(av[0],PROG_SFTP_SERVER))
	{
		syslog(LOG_INFO, "changing initial directory to %s", DEFAULT_CHDIR);
		chdir(DEFAULT_CHDIR);
	}
#endif
	

	flat_request = flatten_vector(av);

	/* 
	 * Use a temp arg vector since getopt will permute the command line arguments
	 * for anything that it does not know about.  If all rsync options are well
	 * defined this isn't necessary.
	 */
	tmp_av = build_arg_vector(flat_request);
	if(check_dangerous_args(tmp_av))
	{
		syslog(LOG_ERR, "requested command (%s) tried to use disallowed argument (%s))", 
			flat_request, logstamp());
		exit(EXIT_FAILURE);
	}
	discard_vector(tmp_av);

	if (valid_arg_vector(av))
	{

/*														   
 * Unison needs the HOME environment variable be set to the directory						  
 * where the .unison directory resides.										
 */														    
#ifdef USE_SAFE_ENVIRONMENT
		safeenv[0] = NULL;
		filter_allowed_env_vars();
		tenv = safeenv;
		if (debuglevel) {
			while (NULL != *tenv) {
				syslog(LOG_DEBUG, "Environment contains \"%s\"", *tenv++);
			}
		}
		env = safeenv;
#endif

#ifdef UNISON_COMPAT
		/* the HOME environment variable should have been set above, but I need to make sure
		 * that it's value as read from the environment is replaced with the actual value
		 * as it exists within the chroot, which is what the applications will expect to see.
		 */
		if (replace_env_entry("HOME",homedir) && (((strlen(homedir) + 6 ) > FILENAME_MAX) || !mysetenv("HOME",homedir)))
		{
			syslog(LOG_ERR, "could not set HOME environment variable (%s)", logstamp());
			exit(EXIT_FAILURE);
		}
		debug(LOG_DEBUG, "set non-chrooted HOME environment variable to %s (%s)", homedir, logstamp());
#endif 
		syslog(LOG_INFO, "running: %s (%s)", flat_request, logstamp());

#ifdef WINSCP_COMPAT
		if (winscp_mode)
		{
			int status=0;
			if (fork() == 0)
				retval=execve(av[0],av,env);
			else
			{
				wait(&status);
				fflush(stdout);
				fflush(stderr);
				discard_vector(av);
#ifdef USE_SAFE_ENVIRONMENT											    
				discard_child_vectors(safeenv);
#endif
				free(flat_request);
				free(tmprequest);
				return(WEXITSTATUS(status));
			}
		}
		else
#endif
		{
			debug(LOG_DEBUG, "about to exec \"%s\" (%s)", av[0], logstamp());
			retval=execve(av[0],av,env);
		}
		syslog(LOG_ERR, "failed: %s with error %s(%u) (%s)", flat_request, strerror(errno), errno, logstamp());
		free(flat_request);
		discard_vector(av);
#ifdef USE_SAFE_ENVIRONMENT
		discard_child_vectors(safeenv);
#endif
#ifdef WINSCP_COMPAT
		if (winscp_mode)
		{
			free(tmprequest);
			return(-1);
		}
		else
#endif 
			exit(errno);
	}

	/*
	 *	reaching this point in the code means the request isnt one of
	 *	our accepted commands
 	 */
	if (debuglevel)
	{
		if (exact_match(flat_request,tmprequest))
			syslog (LOG_ERR, "denied request: %s [%s]", tmprequest, logstamp());
		else
			syslog (LOG_ERR, "denied request: %s (resolved to: %s) [%s]", tmprequest, flat_request, logstamp());
	}
	free(flat_request); 
#ifdef WINSCP_COMPAT
	if (winscp_mode)
	{
		printf ("command not permitted by scponly\n");
		free(tmprequest);
		return(-1);
	}
	else
#endif 
		exit(EXIT_FAILURE);
}
Пример #10
0
int process_pre_chroot_request(char ** av) {

	char *flat_request = NULL;
	char *env[2] = { NULL, NULL };
	int retval = -1;
	
	/* revert to real user so I'm not changing the passwd as root */
	debug(LOG_DEBUG, "handling pre-chroot request");
	debug(LOG_DEBUG, "setting uid to %u", getuid());

	if (-1==(seteuid(getuid())))
	{
		syslog (LOG_ERR, "couldn't revert to my real uid. seteuid: %m");
		exit(EXIT_FAILURE);
	}

	av[0] = substitute_known_path(av[0]);
	flat_request = flatten_vector(av);
	
	/* 
	 * sanity check, substitute_known_path should have given the exact path,
	 * ONLY execute if an exact match was found
	 */
	if (
#ifdef PASSWD_COMPAT
		(!exact_match(av[0], PROG_PASSWD))
#else
		1
#endif
#ifdef QUOTA_COMPAT
		&& (!exact_match(av[0], PROG_QUOTA))
#endif
	) {
		syslog(LOG_ERR, "Invalid pre-chroot request attempted: '%s' [%s]", av[0], logstamp());
		exit(EXIT_FAILURE);
	}
	
	if(check_dangerous_args(av))
	{
		syslog(LOG_ERR, "requested command (%s) tried to use disallowed argument [%s])", 
			flat_request, logstamp());
		exit(EXIT_FAILURE);
	}

	if (valid_arg_vector(av))
	{
		int status = 0;
		
		debug(LOG_DEBUG, "about to fork (%s) [%s]",flat_request,logstamp());
		
		if (fork() == 0)
			retval=execve(av[0],av,env);
		else
		{
			wait(&status);
			fflush(stdout);
			fflush(stderr);
			free(flat_request);
			
			debug(LOG_DEBUG, "forked child returned... [%s]",logstamp());
			
			return WEXITSTATUS(status);
		}

	} else {
		syslog(LOG_ERR, "invalid argument vector (%s) [%s]", 
			flat_request,logstamp());
		free(flat_request);
		
		exit(EXIT_FAILURE);
	}
	return retval;
}
Пример #11
0
int main (int argc, char **argv) 
{
	FILE *debugfile;
	int logopts = LOG_PID|LOG_NDELAY;
	int chars_read = 0;
#ifdef CHROOT_CHECKDIR
	struct stat	homedirstat;
#endif

	/*
	 * set debuglevel.  any nonzero number will result in debugging info to log
	 */
	if (NULL!=(debugfile=fopen(DEBUGFILE,"r")))
	{
		chars_read = fscanf(debugfile,"%d",&debuglevel);
		if (chars_read < 1)
			debuglevel = 0;
		fclose(debugfile);
	}
#ifndef UNIX_COMPAT
	if (debuglevel > 1) /* debuglevel 1 will still log to syslog */
		logopts |= LOG_PERROR;
#endif

#ifdef UNIX_COMPAT 
	openlog(PACKAGE_NAME, logopts, LOG_AUTH);
#elif IRIX_COMPAT
	openlog(PACKAGE_NAME, logopts, LOG_AUTH);
#else
	if (debuglevel > 1) /* debuglevel 1 will still log to syslog */
		logopts |= LOG_PERROR;
	openlog(PACKAGE_NAME, logopts, LOG_AUTHPRIV);
#endif

	if (debuglevel > 0)
		debug = syslog;
	else
		debug = noop_syslog;

#ifdef HAVE_GETOPT_H
	scponly_getopt_long = getopt_long;
#else
	debug(LOG_INFO, "using netbsd's bundled getopt_long");
	scponly_getopt_long = netbsd_getopt_long;
#endif

#ifdef CHROOTED_NAME
	/*
	 *	is this a chroot'ed scponly installation?
	 */
#ifdef WINSCP_COMPAT
	if ((argc==3 && (0==strncmp(argv[0],CHROOTED_NAME,FILENAME_MAX)) ) || 
		( argc==1 && (0==strncmp(&argv[0][1],CHROOTED_NAME,FILENAME_MAX ))))

#else
	if (0==strncmp(argv[0],CHROOTED_NAME,FILENAME_MAX))
#endif
	{
		debug(LOG_INFO, "chrooted binary in place, will chroot()");
		chrooted=1;
	}
#endif /* CHROOTED_NAME */

	if (debuglevel)
	{
		int i;
		syslog(LOG_DEBUG, "%d arguments in total.", argc);
		for (i=0;i<argc;i++)
			syslog(LOG_DEBUG, "\targ %u is %s", i, argv[i]);
	}

#ifdef UNIX_COMPAT
	debug(LOG_DEBUG, "opened log at LOG_AUTH, opts 0x%08x", logopts);
#else
	debug(LOG_DEBUG, "opened log at LOG_AUTHPRIV, opts 0x%08x", logopts);
#endif

	if (getuid()==0)
	{	
		syslog(LOG_ERR, "root login denied [%s]", logstamp());
		exit(EXIT_FAILURE);
	}

#ifdef WINSCP_COMPAT
	if ((argc!=3) && (argc!=1))
#else
	if (argc!=3)
#endif
	{
		debug(LOG_ERR, "incorrect number of args");
		exit(EXIT_FAILURE);
	}
	if (!get_uservar())
	{
		syslog(LOG_ERR, "%s is misconfigured. contact sysadmin.", argv[0]);
		exit (EXIT_FAILURE);
	}

#ifdef CHROOTED_NAME
	if (chrooted)
	{
		char **av = NULL;
		char *tmprequest = NULL;
		char *root_dir = chrootdir;
		char chdir_path[FILENAME_MAX];
		

		strcpy(chrootdir, homedir);
		strcpy(chdir_path, "/");
		while((root_dir = strchr(root_dir, '/')) != NULL) 
		{
			if (strncmp(root_dir, "//", 2) == 0) 
			{
				snprintf(chdir_path, FILENAME_MAX, "%s", root_dir + 1);
				/* make sure HOME will be set to something correct if used*/
				debug(LOG_DEBUG, "Setting homedir to %s", chdir_path);
				strcpy(homedir, chdir_path);
				*root_dir = '\0';
				break;
			}
			root_dir++;
		}
#ifdef CHROOT_CHECKDIR
		bzero(&homedirstat, sizeof(struct stat));
		if (-1 == stat(chrootdir, &homedirstat))
		{
			syslog (LOG_ERR, "couldnt stat chroot dir: %s with errno %u", chrootdir, errno);
			exit(EXIT_FAILURE);
		}
		if (0 == (homedirstat.st_mode | S_IFDIR))
		{
			syslog (LOG_ERR, "chroot dir is not a directory: %s", chrootdir);
			exit(EXIT_FAILURE);
		}
		if (homedirstat.st_uid != 0)
		{
			syslog (LOG_ERR, "chroot dir not owned by root: %s", chrootdir);
			exit(EXIT_FAILURE);
		}
		if (0 != (homedirstat.st_mode & S_IWOTH))
		{
			syslog (LOG_ERR, "chroot dir writable by other: %s", chrootdir);
			exit(EXIT_FAILURE);
		}
		if (0 != (homedirstat.st_mode & S_IWGRP))
		{
			syslog (LOG_ERR, "chroot dir writable by group: %s", chrootdir);
			exit(EXIT_FAILURE);
		}
#endif

/* already within CHROOTED_NAME block */
#if defined(PASSWD_COMPAT) || defined(QUOTA_COMPAT)
		
		/*
		 * perhaps we need to refactor so we don't have to exit right
		 * in the middle of the code, but we can't chroot and expect to be
		 * able to change the password and have it be of any use unless
		 * there is some additional process that scponly is unaware of
		 * happening on the back end.
		 */
		tmprequest = strdup(argv[2]);
		av = build_arg_vector(tmprequest);
		free(tmprequest);
		if (
#ifdef PASSWD_COMPAT
			(exact_match(av[0],"passwd"))
			|| (exact_match(av[0],PROG_PASSWD))
#else
			0
#endif
#ifdef QUOTA_COMPAT
			|| (exact_match(av[0],"quota"))
			|| (exact_match(av[0],PROG_QUOTA))
#endif
		) {
			int status = process_pre_chroot_request(av);
			discard_vector(av);
			
			if (status) {
				syslog(LOG_ERR, "process_pre_chroot_request(%s) failed with code %i [%s]",
					argv[2],WEXITSTATUS(status),logstamp());
				exit(EXIT_FAILURE);
			}
			debug(LOG_DEBUG, "scponly completed");
			exit(EXIT_SUCCESS);
		} else {
			discard_vector(av);
		}

#endif /* passwd or quota */

		debug(LOG_DEBUG, "chrooting to dir: \"%s\"", chrootdir);
		if (-1==(chroot(chrootdir)))
		{
			debug(LOG_ERR, "chroot: %m");
			syslog(LOG_ERR, "couldn't chroot to %s [%s]", chrootdir, logstamp());
			exit(EXIT_FAILURE);
		}
		
		debug(LOG_DEBUG, "chdiring to dir: \"%s\"", chdir_path);					     
		if (-1==(chdir(chdir_path)))										   
		{													      
			debug(LOG_ERR, "chdir: %m");								 
			syslog (LOG_ERR, "couldn't chdir to %s [%s]", chdir_path, logstamp());				      
			exit(EXIT_FAILURE);     
		}
	}
#endif /* CHROOTED_NAME */

	debug(LOG_DEBUG, "setting uid to %u", getuid());
	if (-1==(seteuid(getuid())))
	{
		syslog(LOG_ERR, "couldn't revert to my real uid. seteuid: %m");
		exit(EXIT_FAILURE);
	}

#ifdef WINSCP_COMPAT
	if (argc==1)
	{
		debug(LOG_DEBUG, "entering WinSCP compatibility mode [%s]",logstamp());
		if (-1==process_winscp_requests())
		{
			syslog(LOG_ERR, "failed WinSCP compatibility mode [%s]", logstamp());
			exit(EXIT_FAILURE);
		}
	}
#else
	if (0)	{}	/*  placeholder */
#endif
	else if (-1==process_ssh_request(argv[2]))
	{
		syslog(LOG_ERR, "bad request: %s [%s]", argv[2], logstamp());
		exit(EXIT_FAILURE);
	}
	debug(LOG_DEBUG, "scponly completed");
	exit(EXIT_SUCCESS);
}