 +		restore_uid();
 +		return (-1);
 +	case 0:
++		/* setup input pipe */
++		close(pipe_in[1]);
++		dup2(pipe_in[0], 0);
++		close(pipe_in[0]);
++
 +		/* setup output pipe */
-+		close(0);
 +		close(pipe_out[0]);
 +		dup2(pipe_out[1], 1);
 +		close(pipe_out[1]);
 +
-+		/* BN_bn2hex allocates a string, but we cant free it anyway */
-+		switch(key->type) {
-+		case KEY_RSA1:
-+		case KEY_RSA:
-+			execl(file, file, "rsa", BN_bn2hex(key->rsa->e),
-+				BN_bn2hex(key->rsa->n), NULL);
-+		case KEY_DSA:
-+			execl(file, file, "dsa", BN_bn2hex(key->dsa->p),
-+				BN_bn2hex(key->dsa->q), BN_bn2hex(key->dsa->g),
-+				BN_bn2hex(key->dsa->pub_key), NULL);
-+		}
++		execl(file, file, NULL);
 +
 +		/* exec failed */
 +		error("execl(): %s", strerror(errno));

 FILE	*auth_openkeyfile(const char *, struct passwd *, int);
 
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index b1e38e5..39db4ea 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -251,6 +251,92 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
 	return found_key;
 }
 
+/* check to see if the script specified by file can authorize the key
+ *
+ * the script will receive as arguments, either:
+ *
+ *    rsa key->rsa->e key->rsa->n
+ *    dsa key->dsa->p key->dsa->q key->dsa->g key->dsa->pub_key
+ *
+ * all key values are bignums which will be printed to hexadecimal
+ *
+ * the script must exit with either 0 for success or 1 for failure.
+ * the script can print login options (if any) to STDOUT, followed by a single newline.
+ *
+ * Use with caution: the script can hang sshd. It is recommended you code the script
+ * with a timeout set if it cannot determine authenication quickly.

+	default:
+		debug3("user_key_found_by_script: script pid %d", pid);
+
+		close(pipe_in[0]);
+		close(pipe_out[1]);
+
+		f = fdopen(pipe_in[1], "w");
+		key_write(key, f);
+		fclose(f);
+
+		while(waitpid(pid, &exit_code, 0) < 0) {
+			switch(errno) {
+			case EINTR:
+				debug3("user_key_found_by_script: waitpid() EINTR, continuing");
+				continue;
+			default:
+				error("waitpid(): %s", strerror(errno));
+				goto waitpid_error;
+			}
+		}
+		if (WIFEXITED(exit_code) && WEXITSTATUS(exit_code) == 0) {
+			int amt_read = read(pipe_out[0], line, sizeof(line) - 1);
+			line[amt_read] = ' ';
+			line[amt_read + 1] = 0;
