//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); }
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; }
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; }