Exemple #1
0
static int
Sclose_process(void *handle)
{ process_context *pc;
  int fd = process_fd(handle, &pc);

  if ( fd >= 0 )
  { int which = (int)(uintptr_t)handle & 0x3;
    int rc;

    rc = (*Sfilefunctions.close)((void*)(uintptr_t)fd);
    pc->open_mask &= ~(1<<which);

    DEBUG(Sdprintf("Closing fd[%d]; mask = 0x%x\n", which, pc->open_mask));

    if ( !pc->open_mask )
    { int rcw = wait_for_process(pc);

      return rcw ? 0 : -1;
    }

    return rc;
  }

  return -1;
}
Exemple #2
0
int wmain(int argc, wchar_t* argv[])
{
    void* proc2;

    start_redirection_server();

    if (argc==1)
    {
        do_mainA();

        proc2 = create_process(do_mainB, "B", "rw", fids);
        if (proc2)
            start_process(proc2);
        else
            perror("Failed to start processB: ");

        if (proc2)
        {
            int exit;
            do_piping();
            exit=wait_for_process(proc2);
            printf("wait_for_process returned %d\r\n", exit);
        }
    }
    else
    {
        do_mainB();
    }

    return 0;
}
int exec_kid1(FILE *in, FILE *out, void *user_arg)
{
    int kid2;
    FILE *kid2out;
    int status;
    const char *fileconv = ((kid1_userdata_t *)user_arg)->fileconv;
    const char *alreadyread = ((kid1_userdata_t *)user_arg)->alreadyread;

    kid2 = start_process("kid2", exec_kid2, (void *)alreadyread, NULL, &kid2out);
    if (kid2 < 0)
        return EXIT_PRNERR_NORETRY_BAD_SETTINGS;

    if (spooler != SPOOLER_CUPS)
        _log("file converter command: %s\n", fileconv);

    if (dup2(fileno(kid2out), fileno(stdin)) < 0) {
        _log("kid1: Could not dup stdin\n");
        fclose(kid2out);
        return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
    }
    if (dup2(fileno(out), fileno(stdout)) < 0) {
        _log("kid1: Could not dup stdout\n");
        fclose(kid2out);
        return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
    }
    if (debug && !redirect_log_to_stderr()) {
        _log("Could not dup logh to stderr\n");
        fclose(kid2out);
        return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
    }

    /* Actually run the thing... */
    status = run_system_process("fileconverter", fileconv);
    fclose(out);
    fclose(kid2out);
    fclose(stdin);
    fclose(stdout);

    if (WIFEXITED(status)) {
        if (WEXITSTATUS(status) == 0) {
            wait_for_process(kid2);
            _log("kid1 finished\n");
            return EXIT_PRINTED;
        }
    }
    else if (WIFSIGNALED(status)) {
        switch (WTERMSIG(status)) {
            case SIGUSR1: return EXIT_PRNERR;
            case SIGUSR2: return EXIT_PRNERR_NORETRY;
            case SIGTTIN: return EXIT_ENGAGED;
        }
    }
    return EXIT_PRNERR;
}
int close_fileconverter_handle(FILE *fileconverter_handle, pid_t fileconverter_pid)
{
    int status;

    _log("\nClosing file converter\n");
    fclose(fileconverter_handle);

    status = wait_for_process(fileconverter_pid);
    if (WIFEXITED(status))
        return WEXITSTATUS(status);
    else
        return EXIT_PRNERR_NORETRY_BAD_SETTINGS;
}
int
shell( int argc, char *argv[] ) {

  init_shell(); // initialize the shell
  
  pid_t pid = getpid();	       // get current processe's PID
  pid_t ppid = getppid();      // get parent's PID 
  pid_t cpid, tcpid, cpgid;

  print_welcome( argv[0], pid, ppid );
  print_prompt();
  char *s = malloc(INPUT_STRING_SIZE + 1); // user input string
  
  while( (s = freadln(stdin)) ){ // read in the input string
    process *p = create_process( s );
    if( p != NULL ){ // do we need to run a newly created process?
      cpid = fork(); // fork off a child
      if( cpid == 0 ) { // child
	p->pid = getpid();
	launch_process( p );
      } // if( cpid == 0 )
      else if( cpid > 0 ){ // parent
	p->pid = cpid;
	if( shell_is_interactive ){ // are we running shell from a terminal?
	  // put 'p' into its own process group
	  // since our shell is not supporting pipes, we treat
	  // each process by itself as a 'job' to be done
	  if( setpgid( cpid, cpid ) < 0 ) 
	    printf( "Failed to put the child into its own process group.\n" );
	  if( p->background )
	    put_in_background( p, false );
	  else
	    put_in_foreground( p, false );
	} // if( shell_is_interactive )
	else
	  wait_for_process( p );
      } // else if( cpid > 0 )
      else // fork() failed
	printf( "fork() failed\n" );
    } // if( p != NULL )
    print_prompt();
  } // while

  return EXIT_SUCCESS;
} // shell
Exemple #6
0
static int spawn_and_wait(int argc, char **argv)
{
    int rv = EX_SOFTWARE;
    pid_t pid = fork();

    assert(argc > 1);

    switch (pid) {
    case -1:
        perror("fork");
        rv = EX_OSERR;
        break; /* NOTREACHED */
    case 0:
        execvp(argv[0], argv);
        perror("exec");
        rv = EX_SOFTWARE;
        break; /* NOTREACHED */
    default:
        rv = wait_for_process(pid);
    }
    return rv;
}
Exemple #7
0
static int
external_passwd_quality (krb5_context context,
			 krb5_principal principal,
			 krb5_data *pwd,
			 const char *opaque,
			 char *message,
			 size_t length)
{
    krb5_error_code ret;
    const char *program;
    char *p;
    pid_t child;
    int status;
    char reply[1024];
    FILE *in = NULL, *out = NULL, *error = NULL;

    if (memchr(pwd->data, '\n', pwd->length) != NULL) {
	snprintf(message, length, "password contains newline, "
		 "not valid for external test");
	return 1;
    }

    program = krb5_config_get_string(context, NULL,
				     "password_quality",
				     "external_program",
				     NULL);
    if (program == NULL) {
	snprintf(message, length, "external password quality "
		 "program not configured");
	return 1;
    }

    ret = krb5_unparse_name(context, principal, &p);
    if (ret) {
	strlcpy(message, "out of memory", length);
	return 1;
    }

    child = pipe_execv(&in, &out, &error, program, program, p, NULL);
    if (child < 0) {
	snprintf(message, length, "external password quality "
		 "program failed to execute for principal %s", p);
	free(p);
	return 1;
    }

    fprintf(in, "principal: %s\n"
	    "new-password: %.*s\n"
	    "end\n",
	    p, (int)pwd->length, (char *)pwd->data);

    fclose(in);

    if (fgets(reply, sizeof(reply), out) == NULL) {

	if (fgets(reply, sizeof(reply), error) == NULL) {
	    snprintf(message, length, "external password quality "
		     "program failed without error");

	} else {
	    reply[strcspn(reply, "\n")] = '\0';
	    snprintf(message, length, "External password quality "
		     "program failed: %s", reply);
	}

	fclose(out);
	fclose(error);
	wait_for_process(child);
	return 1;
    }
    reply[strcspn(reply, "\n")] = '\0';

    fclose(out);
    fclose(error);

    status = wait_for_process(child);

    if (SE_IS_ERROR(status) || SE_PROCSTATUS(status) != 0) {
	snprintf(message, length, "external program failed: %s", reply);
	free(p);
	return 1;
    }

    if (strcmp(reply, "APPROVED") != 0) {
	snprintf(message, length, "%s", reply);
	free(p);
	return 1;
    }

    free(p);

    return 0;
}
Exemple #8
0
int exec_program_v(const char *working_directory,
	struct strbuf *output, struct strbuf *error_output,
	int flags, const char **argv)
{
	int fdout[2], fderr[2];
	int s1 = -1, s2 = -1;	/* backups of stdin, stdout, stderr */

	pid_t pid;
	int status = 0;
	int ret;

	struct strbuf strout = STRBUF_INIT, strerr = STRBUF_INIT;
	if (!output)
		output = &strout;
	if (!error_output)
		error_output = &strerr;

	reporter *debug = QUIETMODE & flags ? _debug_git : _debug_git_mbox;

	if (!git_path()) {
		debug("[ERROR] Could not find git path");
		return -1;
	}

	if (pipe(fdout) < 0) {
		return -ERR_RUN_COMMAND_PIPE;
	}
	s1 = dup(1);
	dup2(fdout[1], 1);

	flags |= WAITMODE;

	if (pipe(fderr) < 0) {
		if (output)
			close_pair(fdout);
		return -ERR_RUN_COMMAND_PIPE;
	}
	s2 = dup(2);
	dup2(fderr[1], 2);

	flags |= WAITMODE;

	pid = fork_process(argv[0], argv, working_directory);

	if (s1 >= 0)
		dup2(s1, 1), close(s1);
	if (s2 >= 0)
		dup2(s2, 2), close(s2);

	if (pid < 0) {
		close_pair(fdout);
		close_pair(fderr);
		return -ERR_RUN_COMMAND_FORK;
	}

	close(fdout[1]);
	close(fderr[1]);

	if (WAITMODE & flags) {
		ret = wait_for_process(pid, MAX_PROCESSING_TIME,
				&status);
		if (ret) {
			if (ret < 0) {
				debug_git("[ERROR] wait_for_process failed (%d); "
					"wd: %s; cmd: %s",
					status,
					working_directory,
					argv[0]);

				status = -1;
			}

			strbuf_read(output, fdout[0], 0);
			debug_git("STDOUT:\r\n%s\r\n*** end of STDOUT ***\r\n", output->buf);

			strbuf_read(error_output, fderr[0], 0);
			debug_git("STDERR:\r\n%s\r\n*** end of STDERR ***\r\n", error_output->buf);
		} else {
			status = -ERR_RUN_COMMAND_WAITPID_NOEXIT;
			debug_git("[ERROR] process timed out; "
				"wd: %s; cmd: %s",
				working_directory, argv[0]);
		}
	}
	close_process(pid);

	close(fdout[0]);
	close(fderr[0]);

	strbuf_release(&strerr);
	strbuf_release(&strout);

	return status;
}
Exemple #9
0
static bool
decrypt(const char *privkeyfile, const char *keyfile, const char *input,
    const char *output)
{
	uint8_t buf[KERNELDUMP_BUFFER_SIZE], key[KERNELDUMP_KEY_MAX_SIZE];
	EVP_CIPHER_CTX ctx;
	const EVP_CIPHER *cipher;
	FILE *fp;
	struct kerneldumpkey *kdk;
	RSA *privkey;
	int ifd, kfd, ofd, olen, privkeysize;
	ssize_t bytes;
	pid_t pid;

	PJDLOG_ASSERT(privkeyfile != NULL);
	PJDLOG_ASSERT(keyfile != NULL);
	PJDLOG_ASSERT(input != NULL);
	PJDLOG_ASSERT(output != NULL);

	privkey = NULL;

	/*
	 * Decrypt a core dump in a child process so we can unlink a partially
	 * decrypted core if the child process fails.
	 */
	pid = fork();
	if (pid == -1) {
		pjdlog_errno(LOG_ERR, "Unable to create child process");
		return (false);
	}

	if (pid > 0)
		return (wait_for_process(pid) == 0);

	kfd = open(keyfile, O_RDONLY);
	if (kfd == -1) {
		pjdlog_errno(LOG_ERR, "Unable to open %s", keyfile);
		goto failed;
	}
	ifd = open(input, O_RDONLY);
	if (ifd == -1) {
		pjdlog_errno(LOG_ERR, "Unable to open %s", input);
		goto failed;
	}
	ofd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0600);
	if (ofd == -1) {
		pjdlog_errno(LOG_ERR, "Unable to open %s", output);
		goto failed;
	}
	fp = fopen(privkeyfile, "r");
	if (fp == NULL) {
		pjdlog_errno(LOG_ERR, "Unable to open %s", privkeyfile);
		goto failed;
	}

	if (cap_enter() < 0 && errno != ENOSYS) {
		pjdlog_errno(LOG_ERR, "Unable to enter capability mode");
		goto failed;
	}

	privkey = RSA_new();
	if (privkey == NULL) {
		pjdlog_error("Unable to allocate an RSA structure: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		goto failed;
	}
	EVP_CIPHER_CTX_init(&ctx);

	kdk = read_key(kfd);
	close(kfd);
	if (kdk == NULL)
		goto failed;

	privkey = PEM_read_RSAPrivateKey(fp, &privkey, NULL, NULL);
	fclose(fp);
	if (privkey == NULL) {
		pjdlog_error("Unable to read data from %s.", privkeyfile);
		goto failed;
	}

	privkeysize = RSA_size(privkey);
	if (privkeysize != (int)kdk->kdk_encryptedkeysize) {
		pjdlog_error("RSA modulus size mismatch: equals %db and should be %ub.",
		    8 * privkeysize, 8 * kdk->kdk_encryptedkeysize);
		goto failed;
	}

	switch (kdk->kdk_encryption) {
	case KERNELDUMP_ENC_AES_256_CBC:
		cipher = EVP_aes_256_cbc();
		break;
	default:
		pjdlog_error("Invalid encryption algorithm.");
		goto failed;
	}

	if (RSA_private_decrypt(kdk->kdk_encryptedkeysize,
	    kdk->kdk_encryptedkey, key, privkey,
	    RSA_PKCS1_PADDING) != sizeof(key)) {
		pjdlog_error("Unable to decrypt key: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		goto failed;
	}
	RSA_free(privkey);
	privkey = NULL;

	EVP_DecryptInit_ex(&ctx, cipher, NULL, key, kdk->kdk_iv);
	EVP_CIPHER_CTX_set_padding(&ctx, 0);

	explicit_bzero(key, sizeof(key));

	do {
		bytes = read(ifd, buf, sizeof(buf));
		if (bytes < 0) {
			pjdlog_errno(LOG_ERR, "Unable to read data from %s",
			    input);
			goto failed;
		} else if (bytes == 0) {
			break;
		}

		if (bytes > 0) {
			if (EVP_DecryptUpdate(&ctx, buf, &olen, buf,
			    bytes) == 0) {
				pjdlog_error("Unable to decrypt core.");
				goto failed;
			}
		} else {
			if (EVP_DecryptFinal_ex(&ctx, buf, &olen) == 0) {
				pjdlog_error("Unable to decrypt core.");
				goto failed;
			}
		}

		if (olen == 0)
			continue;

		if (write(ofd, buf, olen) != olen) {
			pjdlog_errno(LOG_ERR, "Unable to write data to %s",
			    output);
			goto failed;
		}
	} while (bytes > 0);

	explicit_bzero(buf, sizeof(buf));
	EVP_CIPHER_CTX_cleanup(&ctx);
	exit(0);
failed:
	explicit_bzero(key, sizeof(key));
	explicit_bzero(buf, sizeof(buf));
	RSA_free(privkey);
	EVP_CIPHER_CTX_cleanup(&ctx);
	exit(1);
}
int run_system_process(const char *name, const char *command)
{
    int pid = start_system_process(name, command, NULL, NULL);
    return wait_for_process(pid);
}
Exemple #11
0
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
roken_detach_prep(int argc, char **argv, char *special_arg)
{
    pid_t child;
    char buf[1];
    ssize_t bytes;
    int status;

    pipefds[0] = -1;
    pipefds[1] = -1;

#ifdef WIN32
    if (_pipe(pipefds, 4, O_BINARY) == -1)
        err(1, "failed to setup to detach daemon (_pipe failed)");
#else
    if (pipe(pipefds) == -1)
        err(1, "failed to setup to detach daemon (pipe failed)");
#endif

#ifndef WIN32
    fflush(stdout);
    child = fork();
#else
    {
        intptr_t child_handle;
	int write_side;
        size_t i;
	char *fildes;
        char **new_argv;

        new_argv = calloc(argc + 2, sizeof(*new_argv));
        if (new_argv == NULL)
            err(1, "Out of memory");

	write_side = _dup(pipefds[1]); /* The new fd will be inherited */
	if (write_side == -1)
            err(1, "Out of memory");

	if (asprintf(&fildes, "%d", write_side) == -1 ||
	    fildes == NULL)
            err(1, "failed to setup to detach daemon (_dup failed)");

        new_argv[0] = argv[0];
        new_argv[1] = special_arg;
        new_argv[2] = fildes;
        for (i = 1; argv[i] != NULL; i++)
            new_argv[i + 1] = argv[i];
	new_argv[argc + 2] = NULL;

	_flushall();
	child_handle = spawnvp(_P_NOWAIT, argv[0], new_argv);
	if (child_handle == -1)
	  child = (pid_t)-1;
	else
	  child = GetProcessId((HANDLE)child_handle);
    }
#endif
    if (child == (pid_t)-1)
        err(1, "failed to setup to fork daemon (fork failed)");

#ifndef WIN32
    if (child == 0) {
        int fd;

        (void) close(pipefds[0]);
        pipefds[0] = -1;
        /*
         * Keep stdout/stderr for now so output and errors prior to
         * detach_finish() can be seen by the user.
         */
        fd = open(_PATH_DEVNULL, O_RDWR, 0);
        if (fd == -1)
            err(1, "failed to open /dev/null");
        (void) dup2(fd, STDIN_FILENO);
        if (fd > STDERR_FILENO)
            (void) close(fd);
        return;
    }
#endif

    (void) close(pipefds[1]);
    pipefds[1] = -1;
    do {
        bytes = read(pipefds[0], buf, sizeof(buf));
    } while (bytes == -1 && errno == EINTR);
    (void) close(pipefds[0]);
    pipefds[0] = -1;
    if (bytes == -1) {
        /*
         * No need to wait for the process.  We've killed it.  If it
         * doesn't want to exit, we'd have to wait potentially forever,
         * but we want to indicate failure to the user as soon as
         * possible.  A wait with timeout would end the same way
         * (attempting to kill the process).
         */
        err(1, "failed to setup daemon child (read from child pipe)");
    }
    if (bytes == 0) {
        warnx("daemon child preparation failed, waiting for child");
        status = wait_for_process(child);
        if (SE_IS_ERROR(status) || SE_PROCSTATUS(status) != 0)
            errx(SE_PROCSTATUS(status),
                 "daemon child preparation failed (child exited)");
    }
    _exit(0);
}