예제 #1
0
//Starts the server and listens for connections
void Server::start(){

	//check if directory exists
	//If it doesn't , try to create the directory

	char temp[1024];

	//Get address info purposes
	struct sockaddr_storage otherAddr, otherAddr2;		//Connectors address information
	socklen_t otherAddrLen, otherAddrLen2;
	int rv;
	int i;

	//Socket purposes
	int newfd;
	int newfd2;

	//port numbers
	unsigned short dataPort;

	//Handling child processes
	struct sigaction sa;

	//Char buffers
	char buffer[DATA_SIZE];

	//String vector
	vector<string> tokens;

	//extra string(s)
	string errMsg = INVCOM;


	//Copy the string into character array
	//since chdir() takes char * as argument
	strncpy( temp, rootDir.c_str() , sizeof(temp) );
	temp[ sizeof(temp) - 1 ] = 0;

	//Check if directory is valid
	//If no directory create one
	if( !validDir(temp) ){

		if( mkdir(temp, 0777) != 0 ){
			perror("mkdir");
			exit(1);
		}

	}

	//change directory
	//call chdir()
	if(chdir(temp) != 0){
		//If chdir fails
		perror("chdir");
		exit(1);
	}

	if ( !getPWD() ){
		cout << "Unable to get cwd" << endl;
		exit(1);
	}

	//We have now changed the program's pwd to root directory 
	//Now create a socket and bind to the control port and start listening
	//for connections

	cs = controlSock = createSocket( controlPort);
	if(verbose)
		cout << "Control socket created" << endl;

	ds = dataSock = createSocket("0");
	if(verbose)
		cout << "Data socket created" << endl;

	dataPort = getPort(dataSock);

	//Now we have successfully created the socket 
	//and bound it to the control port
	//Start listening for connections
	//Entering the listening loop

	if ( listen (controlSock , BACKLOG) != 0 ) {
		perror("listen");
		close(controlSock);
		exit(1);
	}

	if( listen(dataSock , BACKLOG) != 0 ){
		perror("listen");
		close(dataSock);
		exit(1);
	}

	//handle dead processes
	sa.sa_handler = sigchldHandler;		//read all dead processes
	sigemptyset( &sa.sa_mask );
	sa.sa_flags = SA_RESTART;
	if( sigaction( SIGCHLD, &sa , NULL ) == -1 ){
		perror("sigaction");
		exit(1);
	}

	//Handle user interrupts
	signal(SIGINT, userIntHandler);

	cout << "Waiting for connections ... " << endl;

	while(1){

		otherAddrLen = sizeof ( otherAddr) ;
		newfd = accept ( controlSock , (struct sockaddr *) &otherAddr , &otherAddrLen );
		cout << "Connection from " << getIPFromAddr(&otherAddr) << ":" << getPortFromAddr(&otherAddr) << endl;
		commsock = newfd;

		send(newfd, (unsigned short *)&dataPort, 2, 0);

		otherAddrLen2 = sizeof otherAddr2;
		newfd2 = accept(dataSock, (struct sockaddr *) &otherAddr2, &otherAddrLen2 );
		datacommsock = newfd2;
		cout << "Connection to data socket from client port " << getPortFromAddr(&otherAddr2) << endl;

		if( fork() == 0 ){
			//The code in this block is executed by the child process
			close(controlSock);  //Child doesn't require the control socket
			close(dataSock);

			if(verbose){
				cout << "Closing listener sockets" << endl;
				cout << "Child process created for communication with client" << endl;
			}

			if (dup2( newfd , 0 ) != 0 ){
				perror("dup2");
				exit(1);
			}

			do{
				
				if(fgets( buffer, DATA_SIZE, stdin ) == NULL){
					close(newfd);
					exit(1);
				}

				//Remove carriage return and new line characters
				for(rv = 0; rv < DATA_SIZE ; rv++){

					if(buffer[rv] == '\r'){
						buffer[rv] = 0;
						break;
					}

					if(buffer[rv] == '\n'){
						buffer[rv] = 0;
						break;
					}
				}
				
				//Read buffer and find what command it is
				//Call the corresponding method

				string s(buffer);		//convert the character array into string
				if(verbose){
					cout << "Received command " + s << endl;
				}

				istringstream iss(s);

				//copy the tokens into the string vector
				copy( istream_iterator<string>(iss),
				 istream_iterator<string>() ,
				 back_inserter<vector<string> >(tokens) );


				//Copied the tokens into tokens
				rv = tokens.size();
				if(rv > 0){
					//If there is atleast one word
					if(tokens[0].compare("ls") == 0){
						//The client requested a file listing
						ls(s, newfd2);
					}
					else if(tokens[0].compare("quit") == 0){
						//The client closed the connection
						break;
					}
					else if(tokens[0].compare("cd") == 0){
						//The client requested a directory change
						if(rv == 2){
							cd(tokens[1], newfd2);
						}
						else{
							sendMessage( errMsg.c_str() , errMsg.length() , ERROR, NF, dataSock );
						}
					}
					else if( tokens[0].compare("pwd") == 0 ){
						//Client requested a pwd
						PWD(newfd2);
					}
					else if(tokens[0].compare("get") == 0){
						string temp="";
						for(i=1; i < rv;i++){
							temp = temp + tokens[i] + " ";
						}
						temp = temp.substr(0, temp.length()-1 );
						getFile(temp, newfd2);
					}
					else if(tokens[0].compare("put") == 0){
						string temp="";
						for(i=1; i < rv;i++){
							temp = temp + tokens[i] + " ";
						}
						temp = temp.substr(0, temp.length()-1 );
						putFile(temp, newfd2);
					}
					else{
						sendMessage( errMsg.c_str() , errMsg.length() , ERROR, NF, newfd2 );
					}
				}

				tokens.clear();		//clear the tokens

			}while (1);

			//The client closed the connection
			//So, close the socket and quit the child process
			close(newfd);		
			close(newfd2);	
			cout << "Connection closed" << endl;
			exit(1);
		}
		close(newfd);

	}

	close(controlSock);
	

}
예제 #2
0
int RefreshProxyThruMyProxy(Proxy * proxy)
{
	char * proxy_filename = proxy->proxy_filename;
	MyProxyEntry * myProxyEntry = NULL;
	MyString args_string;
	int pid;

	// Starting from the most recent myproxy entry
	// Find an entry with a password
	int found = FALSE;
	proxy->myproxy_entries.Rewind();
	while (proxy->myproxy_entries.Next (myProxyEntry)) {
		if (myProxyEntry->myproxy_password ||
			GetMyProxyPasswordFromSchedD (myProxyEntry->cluster_id,
										  myProxyEntry->proc_id,
										  &(myProxyEntry->myproxy_password))) {
			found=TRUE;

			//. Now move it to the front of the list
			proxy->myproxy_entries.DeleteCurrent();
			proxy->myproxy_entries.Prepend(myProxyEntry);
			break;
		}
	}

	if (!found) {
		// We're screwed - can't get MyProxy passwords for any entry
		return FALSE;
	}

	// Make sure we're not called more often than necessary and if
	time_t now=time(NULL);
	if ((myProxyEntry->get_delegation_pid != FALSE) ||
		(now - myProxyEntry->last_invoked_time < 30)) {

		dprintf (D_ALWAYS,
			 "proxy %s too soon or myproxy-get-delegation already started\n",
				 proxy_filename);
		return FALSE;
	}
	myProxyEntry->last_invoked_time=now;


	// If you don't have a myproxy password, ask SchedD for it
	if (!myProxyEntry->myproxy_password) {
		// Will there ever be a case when there is no MyProxy password needed at all?
		return FALSE;
	}

	// Initialize reaper, if needed
	if (myproxyGetDelegationReaperId == 0 ) {
		myproxyGetDelegationReaperId = daemonCore->Register_Reaper(
					   "GetDelegationReaper",
					   (ReaperHandler) &MyProxyGetDelegationReaper,
					   "GetDelegation Reaper");
 	}

	// Set up environnment for myproxy-get-delegation
	Env myEnv;
	std::string buff;

	if (myProxyEntry->myproxy_server_dn) {
		formatstr( buff, "MYPROXY_SERVER_DN=%s",
				 myProxyEntry->myproxy_server_dn);
		myEnv.SetEnv(buff.c_str());
		dprintf (D_FULLDEBUG, "%s\n", buff.c_str());
	}


	formatstr(buff, "X509_USER_PROXY=%s", proxy_filename);
	myEnv.SetEnv (buff.c_str());
	dprintf (D_FULLDEBUG, "%s\n", buff.c_str());


	// Print password (this will end up in stdin for myproxy-get-delegation)
	if (pipe (myProxyEntry->get_delegation_password_pipe)) {
		dprintf(D_ALWAYS,
				"Failed to pipe(2) in RefreshProxyThruMyProxy "
				"for writing password, aborting\n");
		return FALSE;
	}
	int written = write (myProxyEntry->get_delegation_password_pipe[1],
		   myProxyEntry->myproxy_password,
		   strlen (myProxyEntry->myproxy_password));
	if (written < (int) strlen (myProxyEntry->myproxy_password)) {
		dprintf(D_ALWAYS, "Failed to write to pipe in RefreshProxyThruMyProxy %d\n", errno);
		return FALSE;
    }
	written = write (myProxyEntry->get_delegation_password_pipe[1], "\n", 1);
	if (written < 1) {
		dprintf(D_ALWAYS, "Failed to write to pipe in RefreshProxyThruMyProxy %d\n", errno);
		return FALSE;
	}


	// Figure out user name;
	char * username = my_username(0);	


	// Figure out myproxy host and port
	char * myproxy_host = getHostFromAddr (myProxyEntry->myproxy_host);
	int myproxy_port = getPortFromAddr (myProxyEntry->myproxy_host);

	// args
	ArgList args;
	args.AppendArg(proxy_filename);
	args.AppendArg("-v");
	args.AppendArg("-o");
	args.AppendArg(proxy_filename);
	args.AppendArg("-s");
	args.AppendArg(myproxy_host);
	args.AppendArg("-d");
	args.AppendArg("-t");
	args.AppendArg(myProxyEntry->new_proxy_lifetime);
	args.AppendArg("-S");
	args.AppendArg("-l");
	args.AppendArg(username);


	// Optional port argument
	if (myproxy_port) {
		args.AppendArg("-p");
		args.AppendArg(myproxy_port);
	}

	// Optional credential name argument
	if (myProxyEntry->myproxy_credential_name) {
		args.AppendArg("-k");
		args.AppendArg(myProxyEntry->myproxy_credential_name);
	}

	free (username);
	free (myproxy_host);

	// Create temporary file to store myproxy-get-delegation's stderr
	myProxyEntry->get_delegation_err_filename = create_temp_file();
	if(!myProxyEntry->get_delegation_err_filename) {
		dprintf( D_ALWAYS, "Failed to create temp file");
	} else {
		MSC_SUPPRESS_WARNING_FIXME(6031) // warning: return value of 'chmod' ignored.
		chmod (myProxyEntry->get_delegation_err_filename, 0600);
		myProxyEntry->get_delegation_err_fd = safe_open_wrapper_follow(myProxyEntry->get_delegation_err_filename,O_RDWR);
		if (myProxyEntry->get_delegation_err_fd == -1) {
			dprintf (D_ALWAYS, "Error opening file %s\n",
					 myProxyEntry->get_delegation_err_filename);
		}
	}


	int arrIO[3];
	arrIO[0]=myProxyEntry->get_delegation_password_pipe[0]; //stdin
	arrIO[1]=myProxyEntry->get_delegation_err_fd;
	arrIO[2]=myProxyEntry->get_delegation_err_fd; // stderr

	char * myproxy_get_delegation_pgm = param ("MYPROXY_GET_DELEGATION");
	if (!myproxy_get_delegation_pgm) {
		dprintf (D_ALWAYS, "MYPROXY_GET_DELEGATION not defined in config file\n");
		goto error_exit;
	}


	args.GetArgsStringForDisplay(&args_string);
	dprintf (D_ALWAYS, "Calling %s %s\n", myproxy_get_delegation_pgm, args_string.Value());

	pid = daemonCore->Create_Process (
					myproxy_get_delegation_pgm,
					args,
					PRIV_USER_FINAL,
					myproxyGetDelegationReaperId,
					FALSE,
					&myEnv,
					NULL,	// cwd
					NULL,  // process family info
					NULL,  // socket inherit
					arrIO); // in/out/err streams

	free (myproxy_get_delegation_pgm);

	if (pid == FALSE) {
		dprintf (D_ALWAYS, "Failed to run myproxy-get-delegation\n");
		goto error_exit;
	}

	myProxyEntry->get_delegation_pid = pid;

	return TRUE;

 error_exit:
	myProxyEntry->get_delegation_pid=FALSE;

	if (myProxyEntry->get_delegation_err_fd >= 0) {
		close (myProxyEntry->get_delegation_err_fd);
		myProxyEntry->get_delegation_err_fd=-1;
	}

	if (myProxyEntry->get_delegation_err_filename) {
		MSC_SUPPRESS_WARNING_FIXME(6031) // warning: return value of 'unlink' ignored.
		unlink (myProxyEntry->get_delegation_err_filename);// Remove the tempora
		free (myProxyEntry->get_delegation_err_filename);
		myProxyEntry->get_delegation_err_filename=NULL;
	}

	if (myProxyEntry->get_delegation_password_pipe[0] >= 0) {
		close (myProxyEntry->get_delegation_password_pipe[0]);
		myProxyEntry->get_delegation_password_pipe[0]=-1;
	}
	if (myProxyEntry->get_delegation_password_pipe[1] >= 0 ) {
		close (myProxyEntry->get_delegation_password_pipe[1]);
		myProxyEntry->get_delegation_password_pipe[1]=-1;
	}

	return FALSE;
}
예제 #3
0
파일: credd.cpp 프로젝트: blueskyll/condor
int RefreshProxyThruMyProxy(X509CredentialWrapper * proxy)
{
  const char * proxy_filename = proxy->GetStorageName();
  char * myproxy_host = NULL;
  int status;

  if (((X509Credential*)proxy->cred)->GetMyProxyServerHost() == NULL) {
    dprintf (D_ALWAYS, "Skipping %s\n", proxy->cred->GetName());
    return FALSE;
  }

  // First check if a refresh process is already running
  time_t now = time(NULL);

  if (proxy->get_delegation_pid != GET_DELEGATION_PID_NONE) {
    time_t time_started = proxy->get_delegation_proc_start_time;

    // If the old "refresh proxy" proc is still running, kill it
    if (now - time_started > 500) {
      dprintf (D_FULLDEBUG, "MyProxy refresh process pid=%d still running, "
			  "sending signal %d\n",
			   proxy->get_delegation_pid, SIGKILL);
      daemonCore->Send_Signal (proxy->get_delegation_pid, SIGKILL);
	  // Wait for reaper to cleanup.
    } else {
      dprintf (D_FULLDEBUG, "MyProxy refresh process pid=%d still running, "
			  "letting it finish\n",
			   proxy->get_delegation_pid);
	}
	return FALSE;
  }

  proxy->get_delegation_proc_start_time = now;

  // Set up environnment for myproxy-get-delegation
  Env myEnv;
  MyString strBuff;

  if (((X509Credential*)proxy->cred)->GetMyProxyServerDN()) {
    strBuff="MYPROXY_SERVER_DN=";
    strBuff+= ((X509Credential*)proxy->cred)->GetMyProxyServerDN();
    myEnv.SetEnv (strBuff.Value());
    dprintf (D_FULLDEBUG, "%s\n", strBuff.Value());
  }

  strBuff="X509_USER_PROXY=";
  strBuff+=proxy->GetStorageName();
  dprintf (D_FULLDEBUG, "%s\n", strBuff.Value());

  // Get password (this will end up in stdin for myproxy-get-delegation)
  const char * myproxy_password =((X509Credential*)proxy->cred)->GetRefreshPassword();
  if (myproxy_password == NULL ) {
    dprintf (D_ALWAYS, "No MyProxy password specified for %s:%s\n",
	     proxy->cred->GetName(),
	     proxy->cred->GetOwner());
    myproxy_password = "";
  }

  status = pipe (proxy->get_delegation_password_pipe);
  if (status == -1) {
	dprintf (D_ALWAYS, "get_delegation pipe() failed: %s\n", strerror(errno) );
	proxy->get_delegation_reset();
	return FALSE;
  }
  // TODO: check write() return values for errors, short writes.
  int written = write (proxy->get_delegation_password_pipe[1],
	 myproxy_password,
	 strlen (myproxy_password));

  if (written < (long)strlen(myproxy_password)) {
	dprintf (D_ALWAYS, "Write to proxy delegation pipe failed (%s)", strerror(errno));
	proxy->get_delegation_reset();
	return FALSE;
  }

  written = write (proxy->get_delegation_password_pipe[1], "\n", 1);
  if (written < 1) {
	dprintf (D_ALWAYS, "Write newline to proxy delegation pipe failed (%s)", strerror(errno) );
	proxy->get_delegation_reset();
	return FALSE;
  }


  // Figure out user name;
  const char * username = proxy->cred->GetOrigOwner();

  // Figure out myproxy host and port
  myproxy_host = getHostFromAddr (((X509Credential*)proxy->cred)->GetMyProxyServerHost());
  int myproxy_port = getPortFromAddr (((X509Credential*)proxy->cred)->GetMyProxyServerHost());

  // construct arguments
  ArgList args;
  args.AppendArg("--verbose ");

  args.AppendArg("--out");
  args.AppendArg(proxy_filename);

  args.AppendArg("--pshost");
  args.AppendArg(myproxy_host);
  if ( myproxy_host != NULL ) {
	  free ( myproxy_host );
  }

  args.AppendArg("--dn_as_username");

  args.AppendArg("--proxy_lifetime");	// hours
  args.AppendArg(6);

  args.AppendArg("--stdin_pass");

  args.AppendArg("--username");
  args.AppendArg(username);

  // Optional port argument
  if (myproxy_port) {
	  args.AppendArg("--psport");
	  args.AppendArg(myproxy_port);
  }

  // Optional credential name
  if	(	((X509Credential*)proxy->cred)->GetCredentialName() && 
  			( ((X509Credential*)proxy->cred)->GetCredentialName() )[0] ) {
	  args.AppendArg("--credname");
	  args.AppendArg(((X509Credential*)proxy->cred)->GetCredentialName());
  }


  // Create temporary file to store myproxy-get-delegation's stderr
  // The file will be owned by the "condor" user

  priv_state priv = set_condor_priv();
  proxy->get_delegation_err_filename = create_temp_file();
  if (proxy->get_delegation_err_filename == NULL) {
	dprintf (D_ALWAYS, "get_delegation create_temp_file() failed: %s\n",
			strerror(errno) );
	proxy->get_delegation_reset();
	return FALSE;
  }
  status = chmod (proxy->get_delegation_err_filename, 0600);
  if (status == -1) {
	dprintf (D_ALWAYS, "chmod() get_delegation_err_filename %s failed: %s\n",
			proxy->get_delegation_err_filename, strerror(errno) );
	proxy->get_delegation_reset();
	return FALSE;
  }


  proxy->get_delegation_err_fd = safe_open_wrapper_follow(proxy->get_delegation_err_filename,O_RDWR);
  if (proxy->get_delegation_err_fd == -1) {
    dprintf (D_ALWAYS, "Error opening get_delegation file %s: %s\n",
	     proxy->get_delegation_err_filename, strerror(errno) );
	proxy->get_delegation_reset();
	return FALSE;
  }
  set_priv (priv);


  int arrIO[3];
  arrIO[0]=proxy->get_delegation_password_pipe[0]; //stdin
  arrIO[1]=-1; //proxy->get_delegation_err_fd;
  arrIO[2]=proxy->get_delegation_err_fd; // stderr


  char * myproxy_get_delegation_pgm = param ("MYPROXY_GET_DELEGATION");
  if (!myproxy_get_delegation_pgm) {
    dprintf (D_ALWAYS, "MYPROXY_GET_DELEGATION not defined in config file\n");
    return FALSE;
  }
  MyString args_string;
  args.GetArgsStringForDisplay(&args_string);
  dprintf (D_ALWAYS, "Calling %s %s\n", myproxy_get_delegation_pgm, args_string.Value());

  int pid = daemonCore->Create_Process (
					myproxy_get_delegation_pgm,		// name
					args,				 			// args
					PRIV_USER_FINAL,				// priv
					myproxyGetDelegationReaperId,	// reaper_id
					FALSE,							// want_command_port
					FALSE,							// want_command_port
					&myEnv,							// env
					NULL,							// cwd		
					NULL,							// family_info
					NULL,							// sock_inherit_list
					arrIO);							// in/out/err streams
  													// nice_inc
													// job_opt_mask
  free (myproxy_get_delegation_pgm);
  myproxy_get_delegation_pgm = NULL;


  

  if (pid == FALSE) {
    dprintf (D_ALWAYS, "Failed to run myproxy-get-delegation\n");
	proxy->get_delegation_reset();
    return FALSE;
  }

  proxy->get_delegation_pid = pid;

  return TRUE;
}