[openssh] rebase to openssh-6.0p1 6.0p1-1 + 0.9.3-2

plautrba plautrba at fedoraproject.org
Mon Aug 6 19:34:22 UTC 2012


commit 65ba94ef1a502cb627ed76eedcda0c48b9d6563a
Author: Petr Lautrbach <plautrba at redhat.com>
Date:   Mon Aug 6 21:32:10 2012 +0200

    rebase to openssh-6.0p1
    6.0p1-1 + 0.9.3-2

 .gitignore                                         |    1 +
 ....9p1-audit1.patch => openssh-6.0p1-audit1.patch |  206 +-
 ....9p1-audit4.patch => openssh-6.0p1-audit4.patch |  149 +-
 ....9p1-audit5.patch => openssh-6.0p1-audit5.patch |  202 +-
 ...p1-entropy.patch => openssh-6.0p1-entropy.patch |  134 +-
 ...sh-5.9p1-ldap.patch => openssh-6.0p1-ldap.patch | 3338 ++++++++++----------
 openssh-6.0p1-role-mls.patch                       |  934 ++++++
 openssh.spec                                       |   42 +-
 sources                                            |    2 +-
 9 files changed, 2974 insertions(+), 2034 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 57ab32a..820c1ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ pam_ssh_agent_auth-0.9.2.tar.bz2
 /openssh-5.8p2-noacss.tar.bz2
 /openssh-5.9p1-noacss.tar.bz2
 /pam_ssh_agent_auth-0.9.3.tar.bz2
+/openssh-6.0p1-noacss.tar.bz2
diff --git a/openssh-5.9p1-audit1.patch b/openssh-6.0p1-audit1.patch
similarity index 86%
rename from openssh-5.9p1-audit1.patch
rename to openssh-6.0p1-audit1.patch
index 7a71332..9c927b0 100644
--- a/openssh-5.9p1-audit1.patch
+++ b/openssh-6.0p1-audit1.patch
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p0/audit-bsm.c.audit1 openssh-5.9p0/audit-bsm.c
---- openssh-5.9p0/audit-bsm.c.audit1	2011-01-17 11:15:29.000000000 +0100
-+++ openssh-5.9p0/audit-bsm.c	2011-08-30 10:46:57.704148875 +0200
-@@ -298,10 +298,23 @@ audit_connection_from(const char *host,
+diff -up openssh-6.0p1/audit-bsm.c.audit1 openssh-6.0p1/audit-bsm.c
+--- openssh-6.0p1/audit-bsm.c.audit1	2012-02-24 00:40:43.000000000 +0100
++++ openssh-6.0p1/audit-bsm.c	2012-08-06 20:33:24.416382804 +0200
+@@ -375,10 +375,23 @@ audit_connection_from(const char *host,
  #endif
  }
  
@@ -26,9 +26,78 @@ diff -up openssh-5.9p0/audit-bsm.c.audit1 openssh-5.9p0/audit-bsm.c
  }
  
  void
-diff -up openssh-5.9p0/audit-linux.c.audit1 openssh-5.9p0/audit-linux.c
---- openssh-5.9p0/audit-linux.c.audit1	2011-01-17 11:15:30.000000000 +0100
-+++ openssh-5.9p0/audit-linux.c	2011-08-30 10:46:58.059024733 +0200
+diff -up openssh-6.0p1/audit.c.audit1 openssh-6.0p1/audit.c
+--- openssh-6.0p1/audit.c.audit1	2011-01-17 11:15:30.000000000 +0100
++++ openssh-6.0p1/audit.c	2012-08-06 20:33:24.417382801 +0200
+@@ -140,6 +140,17 @@ audit_event(ssh_audit_event_t event)
+ }
+ 
+ /*
++ * Called when a child process has called, or will soon call,
++ * audit_session_open.
++ */
++void
++audit_count_session_open(void)
++{
++	debug("audit count session open euid %d user %s", geteuid(),
++	      audit_username());
++}
++
++/*
+  * Called when a user session is started.  Argument is the tty allocated to
+  * the session, or NULL if no tty was allocated.
+  *
+@@ -174,13 +185,29 @@ audit_session_close(struct logininfo *li
+ /*
+  * This will be called when a user runs a non-interactive command.  Note that
+  * it may be called multiple times for a single connection since SSH2 allows
+- * multiple sessions within a single connection.
++ * multiple sessions within a single connection.  Returns a "handle" for
++ * audit_end_command.
+  */
+-void
++int
+ audit_run_command(const char *command)
+ {
+ 	debug("audit run command euid %d user %s command '%.200s'", geteuid(),
+ 	    audit_username(), command);
++	return 0;
++}
++
++/*
++ * This will be called when the non-interactive command finishes.  Note that
++ * it may be called multiple times for a single connection since SSH2 allows
++ * multiple sessions within a single connection.  "handle" should come from
++ * the corresponding audit_run_command.
++ */
++void
++audit_end_command(int handle, const char *command)
++{
++	debug("audit end nopty exec  euid %d user %s command '%.200s'", geteuid(),
++	    audit_username(), command);
+ }
++
+ # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
+ #endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.0p1/audit.h.audit1 openssh-6.0p1/audit.h
+--- openssh-6.0p1/audit.h.audit1	2011-01-17 11:15:30.000000000 +0100
++++ openssh-6.0p1/audit.h	2012-08-06 20:33:24.417382801 +0200
+@@ -49,9 +49,11 @@ typedef enum ssh_audit_event_type ssh_au
+ 
+ void	audit_connection_from(const char *, int);
+ void	audit_event(ssh_audit_event_t);
++void	audit_count_session_open(void);
+ void	audit_session_open(struct logininfo *);
+ void	audit_session_close(struct logininfo *);
+-void	audit_run_command(const char *);
++int	audit_run_command(const char *);
++void 	audit_end_command(int, const char *);
+ ssh_audit_event_t audit_classify_auth(const char *);
+ 
+ #endif /* _SSH_AUDIT_H */
+diff -up openssh-6.0p1/audit-linux.c.audit1 openssh-6.0p1/audit-linux.c
+--- openssh-6.0p1/audit-linux.c.audit1	2011-01-17 11:15:30.000000000 +0100
++++ openssh-6.0p1/audit-linux.c	2012-08-06 20:33:24.416382804 +0200
 @@ -35,13 +35,20 @@
  
  #include "log.h"
@@ -244,78 +313,9 @@ diff -up openssh-5.9p0/audit-linux.c.audit1 openssh-5.9p0/audit-linux.c
  		break;
  
  	default:
-diff -up openssh-5.9p0/audit.c.audit1 openssh-5.9p0/audit.c
---- openssh-5.9p0/audit.c.audit1	2011-01-17 11:15:30.000000000 +0100
-+++ openssh-5.9p0/audit.c	2011-08-30 10:46:57.822025769 +0200
-@@ -140,6 +140,17 @@ audit_event(ssh_audit_event_t event)
- }
- 
- /*
-+ * Called when a child process has called, or will soon call,
-+ * audit_session_open.
-+ */
-+void
-+audit_count_session_open(void)
-+{
-+	debug("audit count session open euid %d user %s", geteuid(),
-+	      audit_username());
-+}
-+
-+/*
-  * Called when a user session is started.  Argument is the tty allocated to
-  * the session, or NULL if no tty was allocated.
-  *
-@@ -174,13 +185,29 @@ audit_session_close(struct logininfo *li
- /*
-  * This will be called when a user runs a non-interactive command.  Note that
-  * it may be called multiple times for a single connection since SSH2 allows
-- * multiple sessions within a single connection.
-+ * multiple sessions within a single connection.  Returns a "handle" for
-+ * audit_end_command.
-  */
--void
-+int
- audit_run_command(const char *command)
- {
- 	debug("audit run command euid %d user %s command '%.200s'", geteuid(),
- 	    audit_username(), command);
-+	return 0;
-+}
-+
-+/*
-+ * This will be called when the non-interactive command finishes.  Note that
-+ * it may be called multiple times for a single connection since SSH2 allows
-+ * multiple sessions within a single connection.  "handle" should come from
-+ * the corresponding audit_run_command.
-+ */
-+void
-+audit_end_command(int handle, const char *command)
-+{
-+	debug("audit end nopty exec  euid %d user %s command '%.200s'", geteuid(),
-+	    audit_username(), command);
- }
-+
- # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
- #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p0/audit.h.audit1 openssh-5.9p0/audit.h
---- openssh-5.9p0/audit.h.audit1	2011-01-17 11:15:30.000000000 +0100
-+++ openssh-5.9p0/audit.h	2011-08-30 10:46:57.952035525 +0200
-@@ -49,9 +49,11 @@ typedef enum ssh_audit_event_type ssh_au
- 
- void	audit_connection_from(const char *, int);
- void	audit_event(ssh_audit_event_t);
-+void	audit_count_session_open(void);
- void	audit_session_open(struct logininfo *);
- void	audit_session_close(struct logininfo *);
--void	audit_run_command(const char *);
-+int	audit_run_command(const char *);
-+void 	audit_end_command(int, const char *);
- ssh_audit_event_t audit_classify_auth(const char *);
- 
- #endif /* _SSH_AUDIT_H */
-diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
---- openssh-5.9p0/monitor.c.audit1	2011-08-05 22:15:18.000000000 +0200
-+++ openssh-5.9p0/monitor.c	2011-08-30 10:50:47.074038891 +0200
+diff -up openssh-6.0p1/monitor.c.audit1 openssh-6.0p1/monitor.c
+--- openssh-6.0p1/monitor.c.audit1	2012-08-06 20:33:24.410382828 +0200
++++ openssh-6.0p1/monitor.c	2012-08-06 20:33:24.418382797 +0200
 @@ -185,6 +185,7 @@ int mm_answer_gss_checkmic(int, Buffer *
  #ifdef SSH_AUDIT_EVENTS
  int mm_answer_audit_event(int, Buffer *);
@@ -324,7 +324,7 @@ diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
  #endif
  
  static int monitor_read_log(struct monitor *);
-@@ -271,6 +272,7 @@ struct mon_table mon_dispatch_postauth20
+@@ -272,6 +273,7 @@ struct mon_table mon_dispatch_postauth20
  #ifdef SSH_AUDIT_EVENTS
      {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
      {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
@@ -332,7 +332,7 @@ diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
  #endif
      {0, 0, NULL}
  };
-@@ -313,6 +315,7 @@ struct mon_table mon_dispatch_postauth15
+@@ -314,6 +316,7 @@ struct mon_table mon_dispatch_postauth15
  #ifdef SSH_AUDIT_EVENTS
      {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
      {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
@@ -340,7 +340,7 @@ diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
  #endif
      {0, 0, NULL}
  };
-@@ -1398,6 +1401,12 @@ mm_session_close(Session *s)
+@@ -1427,6 +1430,12 @@ mm_session_close(Session *s)
  		debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
  		session_pty_cleanup2(s);
  	}
@@ -353,7 +353,7 @@ diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
  	session_unused(s->self);
  }
  
-@@ -1720,11 +1729,44 @@ mm_answer_audit_command(int socket, Buff
+@@ -1751,11 +1760,44 @@ mm_answer_audit_command(int socket, Buff
  {
  	u_int len;
  	char *cmd;
@@ -399,9 +399,9 @@ diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
  	xfree(cmd);
  	return (0);
  }
-diff -up openssh-5.9p0/monitor.h.audit1 openssh-5.9p0/monitor.h
---- openssh-5.9p0/monitor.h.audit1	2011-06-20 06:42:23.000000000 +0200
-+++ openssh-5.9p0/monitor.h	2011-08-30 10:46:58.392112520 +0200
+diff -up openssh-6.0p1/monitor.h.audit1 openssh-6.0p1/monitor.h
+--- openssh-6.0p1/monitor.h.audit1	2011-06-20 06:42:23.000000000 +0200
++++ openssh-6.0p1/monitor.h	2012-08-06 20:33:24.418382797 +0200
 @@ -60,6 +60,7 @@ enum monitor_reqtype {
  	MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
  	MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
@@ -410,9 +410,9 @@ diff -up openssh-5.9p0/monitor.h.audit1 openssh-5.9p0/monitor.h
  	MONITOR_REQ_TERM,
  	MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
  	MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
-diff -up openssh-5.9p0/monitor_wrap.c.audit1 openssh-5.9p0/monitor_wrap.c
---- openssh-5.9p0/monitor_wrap.c.audit1	2011-06-20 06:42:23.000000000 +0200
-+++ openssh-5.9p0/monitor_wrap.c	2011-08-30 10:46:58.505031574 +0200
+diff -up openssh-6.0p1/monitor_wrap.c.audit1 openssh-6.0p1/monitor_wrap.c
+--- openssh-6.0p1/monitor_wrap.c.audit1	2012-08-06 20:33:24.384382930 +0200
++++ openssh-6.0p1/monitor_wrap.c	2012-08-06 20:33:24.419382793 +0200
 @@ -1188,10 +1188,11 @@ mm_audit_event(ssh_audit_event_t event)
  	buffer_free(&m);
  }
@@ -453,9 +453,9 @@ diff -up openssh-5.9p0/monitor_wrap.c.audit1 openssh-5.9p0/monitor_wrap.c
  	buffer_free(&m);
  }
  #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p0/monitor_wrap.h.audit1 openssh-5.9p0/monitor_wrap.h
---- openssh-5.9p0/monitor_wrap.h.audit1	2011-06-20 06:42:23.000000000 +0200
-+++ openssh-5.9p0/monitor_wrap.h	2011-08-30 10:46:58.616212835 +0200
+diff -up openssh-6.0p1/monitor_wrap.h.audit1 openssh-6.0p1/monitor_wrap.h
+--- openssh-6.0p1/monitor_wrap.h.audit1	2011-06-20 06:42:23.000000000 +0200
++++ openssh-6.0p1/monitor_wrap.h	2012-08-06 20:33:24.419382793 +0200
 @@ -74,7 +74,8 @@ void mm_sshpam_free_ctx(void *);
  #ifdef SSH_AUDIT_EVENTS
  #include "audit.h"
@@ -466,9 +466,9 @@ diff -up openssh-5.9p0/monitor_wrap.h.audit1 openssh-5.9p0/monitor_wrap.h
  #endif
  
  struct Session;
-diff -up openssh-5.9p0/session.c.audit1 openssh-5.9p0/session.c
---- openssh-5.9p0/session.c.audit1	2011-05-20 03:23:10.000000000 +0200
-+++ openssh-5.9p0/session.c	2011-08-30 10:46:58.756024849 +0200
+diff -up openssh-6.0p1/session.c.audit1 openssh-6.0p1/session.c
+--- openssh-6.0p1/session.c.audit1	2011-11-04 00:55:24.000000000 +0100
++++ openssh-6.0p1/session.c	2012-08-06 20:33:24.420382789 +0200
 @@ -742,6 +742,14 @@ do_exec_pty(Session *s, const char *comm
  	/* Parent.  Close the slave side of the pseudo tty. */
  	close(ttyfd);
@@ -599,9 +599,9 @@ diff -up openssh-5.9p0/session.c.audit1 openssh-5.9p0/session.c
 -		session_destroy_all(session_pty_cleanup2);
 +		session_destroy_all(do_cleanup_one_session);
  }
-diff -up openssh-5.9p0/session.h.audit1 openssh-5.9p0/session.h
---- openssh-5.9p0/session.h.audit1	2008-05-19 07:34:50.000000000 +0200
-+++ openssh-5.9p0/session.h	2011-08-30 10:46:58.884024597 +0200
+diff -up openssh-6.0p1/session.h.audit1 openssh-6.0p1/session.h
+--- openssh-6.0p1/session.h.audit1	2008-05-19 07:34:50.000000000 +0200
++++ openssh-6.0p1/session.h	2012-08-06 20:33:24.420382789 +0200
 @@ -60,6 +60,12 @@ struct Session {
  		char	*name;
  		char	*val;
@@ -626,11 +626,11 @@ diff -up openssh-5.9p0/session.h.audit1 openssh-5.9p0/session.h
  Session	*session_by_tty(char *);
  void	 session_close(Session *);
  void	 do_setusercontext(struct passwd *);
-diff -up openssh-5.9p0/sshd.c.audit1 openssh-5.9p0/sshd.c
---- openssh-5.9p0/sshd.c.audit1	2011-06-23 11:45:51.000000000 +0200
-+++ openssh-5.9p0/sshd.c	2011-08-30 10:46:59.009025421 +0200
-@@ -2364,7 +2364,8 @@ cleanup_exit(int i)
- 		do_cleanup(the_authctxt);
+diff -up openssh-6.0p1/sshd.c.audit1 openssh-6.0p1/sshd.c
+--- openssh-6.0p1/sshd.c.audit1	2012-08-06 20:33:24.392382898 +0200
++++ openssh-6.0p1/sshd.c	2012-08-06 20:33:24.421382785 +0200
+@@ -2381,7 +2381,8 @@ cleanup_exit(int i)
+ 	}
  #ifdef SSH_AUDIT_EVENTS
  	/* done after do_cleanup so it can cancel the PAM auth 'thread' */
 -	if (!use_privsep || mm_is_monitor())
diff --git a/openssh-5.9p1-audit4.patch b/openssh-6.0p1-audit4.patch
similarity index 78%
rename from openssh-5.9p1-audit4.patch
rename to openssh-6.0p1-audit4.patch
index 1ae1e71..73b8b14 100644
--- a/openssh-5.9p1-audit4.patch
+++ b/openssh-6.0p1-audit4.patch
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p1/audit-bsm.c.audit4 openssh-5.9p1/audit-bsm.c
---- openssh-5.9p1/audit-bsm.c.audit4	2012-07-27 14:27:56.149474798 +0200
-+++ openssh-5.9p1/audit-bsm.c	2012-07-27 14:27:56.164474882 +0200
-@@ -408,4 +408,10 @@ audit_kex_body(int ctos, char *enc, char
+diff -up openssh-6.0p1/audit-bsm.c.audit4 openssh-6.0p1/audit-bsm.c
+--- openssh-6.0p1/audit-bsm.c.audit4	2012-08-06 20:35:56.306789054 +0200
++++ openssh-6.0p1/audit-bsm.c	2012-08-06 20:35:56.314789022 +0200
+@@ -485,4 +485,10 @@ audit_kex_body(int ctos, char *enc, char
  {
  	/* not implemented */
  }
@@ -12,9 +12,9 @@ diff -up openssh-5.9p1/audit-bsm.c.audit4 openssh-5.9p1/audit-bsm.c
 +	/* not implemented */
 +}
  #endif /* BSM */
-diff -up openssh-5.9p1/audit.c.audit4 openssh-5.9p1/audit.c
---- openssh-5.9p1/audit.c.audit4	2012-07-27 14:27:56.150474804 +0200
-+++ openssh-5.9p1/audit.c	2012-07-27 14:27:56.165474888 +0200
+diff -up openssh-6.0p1/audit.c.audit4 openssh-6.0p1/audit.c
+--- openssh-6.0p1/audit.c.audit4	2012-08-06 20:35:56.307789050 +0200
++++ openssh-6.0p1/audit.c	2012-08-06 20:35:56.315789018 +0200
 @@ -143,6 +143,12 @@ audit_kex(int ctos, char *enc, char *mac
  	PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid()));
  }
@@ -44,9 +44,9 @@ diff -up openssh-5.9p1/audit.c.audit4 openssh-5.9p1/audit.c
 +}
  # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
  #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p1/audit.h.audit4 openssh-5.9p1/audit.h
---- openssh-5.9p1/audit.h.audit4	2012-07-27 14:27:56.151474810 +0200
-+++ openssh-5.9p1/audit.h	2012-07-27 14:27:56.165474888 +0200
+diff -up openssh-6.0p1/audit.h.audit4 openssh-6.0p1/audit.h
+--- openssh-6.0p1/audit.h.audit4	2012-08-06 20:35:56.308789046 +0200
++++ openssh-6.0p1/audit.h	2012-08-06 20:35:56.315789018 +0200
 @@ -62,5 +62,7 @@ void	audit_unsupported(int);
  void	audit_kex(int, char *, char *, char *);
  void	audit_unsupported_body(int);
@@ -55,9 +55,9 @@ diff -up openssh-5.9p1/audit.h.audit4 openssh-5.9p1/audit.h
 +void	audit_session_key_free_body(int ctos, pid_t, uid_t);
  
  #endif /* _SSH_AUDIT_H */
-diff -up openssh-5.9p1/audit-linux.c.audit4 openssh-5.9p1/audit-linux.c
---- openssh-5.9p1/audit-linux.c.audit4	2012-07-27 14:27:56.149474798 +0200
-+++ openssh-5.9p1/audit-linux.c	2012-07-27 14:27:56.166474894 +0200
+diff -up openssh-6.0p1/audit-linux.c.audit4 openssh-6.0p1/audit-linux.c
+--- openssh-6.0p1/audit-linux.c.audit4	2012-08-06 20:35:56.307789050 +0200
++++ openssh-6.0p1/audit-linux.c	2012-08-06 20:35:56.315789018 +0200
 @@ -294,6 +294,8 @@ audit_unsupported_body(int what)
  #endif
  }
@@ -108,9 +108,9 @@ diff -up openssh-5.9p1/audit-linux.c.audit4 openssh-5.9p1/audit-linux.c
 +}
 +
  #endif /* USE_LINUX_AUDIT */
-diff -up openssh-5.9p1/auditstub.c.audit4 openssh-5.9p1/auditstub.c
---- openssh-5.9p1/auditstub.c.audit4	2012-07-27 14:27:56.151474810 +0200
-+++ openssh-5.9p1/auditstub.c	2012-07-27 14:27:56.166474894 +0200
+diff -up openssh-6.0p1/auditstub.c.audit4 openssh-6.0p1/auditstub.c
+--- openssh-6.0p1/auditstub.c.audit4	2012-08-06 20:35:56.308789046 +0200
++++ openssh-6.0p1/auditstub.c	2012-08-06 20:35:56.316789015 +0200
 @@ -27,6 +27,8 @@
   * Red Hat author: Jan F. Chadima <jchadima at redhat.com>
   */
@@ -133,9 +133,9 @@ diff -up openssh-5.9p1/auditstub.c.audit4 openssh-5.9p1/auditstub.c
 +audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
 +{
 +}
-diff -up openssh-5.9p1/kex.c.audit4 openssh-5.9p1/kex.c
---- openssh-5.9p1/kex.c.audit4	2012-07-27 14:27:56.153474822 +0200
-+++ openssh-5.9p1/kex.c	2012-07-27 14:27:56.167474900 +0200
+diff -up openssh-6.0p1/kex.c.audit4 openssh-6.0p1/kex.c
+--- openssh-6.0p1/kex.c.audit4	2012-08-06 20:35:56.309789042 +0200
++++ openssh-6.0p1/kex.c	2012-08-06 20:35:56.317789011 +0200
 @@ -624,3 +624,34 @@ dump_digest(char *msg, u_char *digest, i
  	fprintf(stderr, "\n");
  }
@@ -171,9 +171,9 @@ diff -up openssh-5.9p1/kex.c.audit4 openssh-5.9p1/kex.c
 +	memset(&newkeys->comp, 0, sizeof(newkeys->comp));
 +}
 +
-diff -up openssh-5.9p1/kex.h.audit4 openssh-5.9p1/kex.h
---- openssh-5.9p1/kex.h.audit4	2010-09-24 14:11:14.000000000 +0200
-+++ openssh-5.9p1/kex.h	2012-07-27 14:27:56.168474905 +0200
+diff -up openssh-6.0p1/kex.h.audit4 openssh-6.0p1/kex.h
+--- openssh-6.0p1/kex.h.audit4	2010-09-24 14:11:14.000000000 +0200
++++ openssh-6.0p1/kex.h	2012-08-06 20:35:56.317789011 +0200
 @@ -156,6 +156,8 @@ void	 kexgex_server(Kex *);
  void	 kexecdh_client(Kex *);
  void	 kexecdh_server(Kex *);
@@ -183,10 +183,10 @@ diff -up openssh-5.9p1/kex.h.audit4 openssh-5.9p1/kex.h
  void
  kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
      BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
-diff -up openssh-5.9p1/mac.c.audit4 openssh-5.9p1/mac.c
---- openssh-5.9p1/mac.c.audit4	2011-08-17 02:29:03.000000000 +0200
-+++ openssh-5.9p1/mac.c	2012-07-27 14:27:56.168474905 +0200
-@@ -168,6 +168,20 @@ mac_clear(Mac *mac)
+diff -up openssh-6.0p1/mac.c.audit4 openssh-6.0p1/mac.c
+--- openssh-6.0p1/mac.c.audit4	2012-01-17 04:03:38.000000000 +0100
++++ openssh-6.0p1/mac.c	2012-08-06 20:35:56.318789007 +0200
+@@ -171,6 +171,20 @@ mac_clear(Mac *mac)
  	mac->umac_ctx = NULL;
  }
  
@@ -207,17 +207,17 @@ diff -up openssh-5.9p1/mac.c.audit4 openssh-5.9p1/mac.c
  /* XXX copied from ciphers_valid */
  #define	MAC_SEP	","
  int
-diff -up openssh-5.9p1/mac.h.audit4 openssh-5.9p1/mac.h
---- openssh-5.9p1/mac.h.audit4	2007-06-11 06:01:42.000000000 +0200
-+++ openssh-5.9p1/mac.h	2012-07-27 14:27:56.169474910 +0200
+diff -up openssh-6.0p1/mac.h.audit4 openssh-6.0p1/mac.h
+--- openssh-6.0p1/mac.h.audit4	2007-06-11 06:01:42.000000000 +0200
++++ openssh-6.0p1/mac.h	2012-08-06 20:35:56.318789007 +0200
 @@ -28,3 +28,4 @@ int	 mac_setup(Mac *, char *);
  int	 mac_init(Mac *);
  u_char	*mac_compute(Mac *, u_int32_t, u_char *, int);
  void	 mac_clear(Mac *);
 +void	 mac_destroy(Mac *);
-diff -up openssh-5.9p1/monitor.c.audit4 openssh-5.9p1/monitor.c
---- openssh-5.9p1/monitor.c.audit4	2012-07-27 14:27:56.154474827 +0200
-+++ openssh-5.9p1/monitor.c	2012-07-27 14:31:20.311655098 +0200
+diff -up openssh-6.0p1/monitor.c.audit4 openssh-6.0p1/monitor.c
+--- openssh-6.0p1/monitor.c.audit4	2012-08-06 20:35:56.310789038 +0200
++++ openssh-6.0p1/monitor.c	2012-08-06 20:35:56.319789003 +0200
 @@ -189,6 +189,7 @@ int mm_answer_audit_command(int, Buffer
  int mm_answer_audit_end_command(int, Buffer *);
  int mm_answer_audit_unsupported_body(int, Buffer *);
@@ -269,7 +269,7 @@ diff -up openssh-5.9p1/monitor.c.audit4 openssh-5.9p1/monitor.c
  	if (!authctxt->valid)
  		fatal("%s: authenticated invalid user", __func__);
  	if (strcmp(auth_method, "unknown") == 0)
-@@ -1952,11 +1953,13 @@ mm_get_keystate(struct monitor *pmonitor
+@@ -1953,11 +1954,13 @@ mm_get_keystate(struct monitor *pmonitor
  
  	blob = buffer_get_string(&m, &bloblen);
  	current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
@@ -283,7 +283,7 @@ diff -up openssh-5.9p1/monitor.c.audit4 openssh-5.9p1/monitor.c
  	xfree(blob);
  
  	/* Now get sequence numbers for the packets */
-@@ -2002,6 +2005,21 @@ mm_get_keystate(struct monitor *pmonitor
+@@ -2003,6 +2006,21 @@ mm_get_keystate(struct monitor *pmonitor
  	}
  
  	buffer_free(&m);
@@ -305,7 +305,7 @@ diff -up openssh-5.9p1/monitor.c.audit4 openssh-5.9p1/monitor.c
  }
  
  
-@@ -2448,4 +2466,22 @@ mm_answer_audit_kex_body(int sock, Buffe
+@@ -2449,4 +2467,22 @@ mm_answer_audit_kex_body(int sock, Buffe
  	return 0;
  }
  
@@ -328,9 +328,9 @@ diff -up openssh-5.9p1/monitor.c.audit4 openssh-5.9p1/monitor.c
 +	return 0;
 +}
  #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p1/monitor.h.audit4 openssh-5.9p1/monitor.h
---- openssh-5.9p1/monitor.h.audit4	2012-07-27 14:27:56.155474832 +0200
-+++ openssh-5.9p1/monitor.h	2012-07-27 14:27:56.171474920 +0200
+diff -up openssh-6.0p1/monitor.h.audit4 openssh-6.0p1/monitor.h
+--- openssh-6.0p1/monitor.h.audit4	2012-08-06 20:35:56.310789038 +0200
++++ openssh-6.0p1/monitor.h	2012-08-06 20:35:56.319789003 +0200
 @@ -63,6 +63,7 @@ enum monitor_reqtype {
  	MONITOR_ANS_AUDIT_COMMAND, MONITOR_REQ_AUDIT_END_COMMAND,
  	MONITOR_REQ_AUDIT_UNSUPPORTED, MONITOR_ANS_AUDIT_UNSUPPORTED,
@@ -339,9 +339,9 @@ diff -up openssh-5.9p1/monitor.h.audit4 openssh-5.9p1/monitor.h
  	MONITOR_REQ_TERM,
  	MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
  	MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
-diff -up openssh-5.9p1/monitor_wrap.c.audit4 openssh-5.9p1/monitor_wrap.c
---- openssh-5.9p1/monitor_wrap.c.audit4	2012-07-27 14:27:56.156474837 +0200
-+++ openssh-5.9p1/monitor_wrap.c	2012-07-27 14:27:56.172474926 +0200
+diff -up openssh-6.0p1/monitor_wrap.c.audit4 openssh-6.0p1/monitor_wrap.c
+--- openssh-6.0p1/monitor_wrap.c.audit4	2012-08-06 20:35:56.311789034 +0200
++++ openssh-6.0p1/monitor_wrap.c	2012-08-06 20:35:56.320788999 +0200
 @@ -653,12 +653,14 @@ mm_send_keystate(struct monitor *monitor
  		fatal("%s: conversion of newkeys failed", __func__);
  
@@ -377,9 +377,9 @@ diff -up openssh-5.9p1/monitor_wrap.c.audit4 openssh-5.9p1/monitor_wrap.c
 +	buffer_free(&m);
 +}
  #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p1/monitor_wrap.h.audit4 openssh-5.9p1/monitor_wrap.h
---- openssh-5.9p1/monitor_wrap.h.audit4	2012-07-27 14:27:56.157474843 +0200
-+++ openssh-5.9p1/monitor_wrap.h	2012-07-27 14:27:56.173474932 +0200
+diff -up openssh-6.0p1/monitor_wrap.h.audit4 openssh-6.0p1/monitor_wrap.h
+--- openssh-6.0p1/monitor_wrap.h.audit4	2012-08-06 20:35:56.311789034 +0200
++++ openssh-6.0p1/monitor_wrap.h	2012-08-06 20:35:56.320788999 +0200
 @@ -79,6 +79,7 @@ int mm_audit_run_command(const char *);
  void mm_audit_end_command(int, const char *);
  void mm_audit_unsupported_body(int);
@@ -388,9 +388,9 @@ diff -up openssh-5.9p1/monitor_wrap.h.audit4 openssh-5.9p1/monitor_wrap.h
  #endif
  
  struct Session;
-diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
---- openssh-5.9p1/packet.c.audit4	2012-07-27 14:27:56.099474520 +0200
-+++ openssh-5.9p1/packet.c	2012-07-27 14:27:56.174474938 +0200
+diff -up openssh-6.0p1/packet.c.audit4 openssh-6.0p1/packet.c
+--- openssh-6.0p1/packet.c.audit4	2012-08-06 20:35:56.282789147 +0200
++++ openssh-6.0p1/packet.c	2012-08-06 20:35:56.321788995 +0200
 @@ -60,6 +60,7 @@
  #include <signal.h>
  
@@ -399,7 +399,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  #include "buffer.h"
  #include "packet.h"
  #include "crc32.h"
-@@ -472,6 +473,13 @@ packet_get_connection_out(void)
+@@ -470,6 +471,13 @@ packet_get_connection_out(void)
  	return active_state->connection_out;
  }
  
@@ -413,7 +413,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  /* Closes the connection and clears and frees internal data structures. */
  
  void
-@@ -480,13 +488,6 @@ packet_close(void)
+@@ -478,13 +486,6 @@ packet_close(void)
  	if (!active_state->initialized)
  		return;
  	active_state->initialized = 0;
@@ -427,7 +427,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  	buffer_free(&active_state->input);
  	buffer_free(&active_state->output);
  	buffer_free(&active_state->outgoing_packet);
-@@ -495,8 +496,18 @@ packet_close(void)
+@@ -493,8 +494,18 @@ packet_close(void)
  		buffer_free(&active_state->compression_buffer);
  		buffer_compress_uninit();
  	}
@@ -448,7 +448,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  }
  
  /* Sets remote side protocol flags. */
-@@ -731,6 +742,23 @@ packet_send1(void)
+@@ -729,6 +740,23 @@ packet_send1(void)
  	 */
  }
  
@@ -472,7 +472,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  void
  set_newkeys(int mode)
  {
-@@ -756,18 +784,9 @@ set_newkeys(int mode)
+@@ -754,18 +782,9 @@ set_newkeys(int mode)
  	}
  	if (active_state->newkeys[mode] != NULL) {
  		debug("set_newkeys: rekeying");
@@ -493,7 +493,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  	}
  	active_state->newkeys[mode] = kex_get_newkeys(mode);
  	if (active_state->newkeys[mode] == NULL)
-@@ -1927,6 +1946,47 @@ packet_get_newkeys(int mode)
+@@ -1921,6 +1940,47 @@ packet_get_newkeys(int mode)
  	return (void *)active_state->newkeys[mode];
  }
  
@@ -541,7 +541,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  /*
   * Save the state for the real connection, and use a separate state when
   * resuming a suspended connection.
-@@ -1934,18 +1994,12 @@ packet_get_newkeys(int mode)
+@@ -1928,18 +1988,12 @@ packet_get_newkeys(int mode)
  void
  packet_backup_state(void)
  {
@@ -561,7 +561,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  }
  
  /*
-@@ -1962,9 +2016,7 @@ packet_restore_state(void)
+@@ -1956,9 +2010,7 @@ packet_restore_state(void)
  	backup_state = active_state;
  	active_state = tmp;
  	active_state->connection_in = backup_state->connection_in;
@@ -571,7 +571,7 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
  	len = buffer_len(&backup_state->input);
  	if (len > 0) {
  		buf = buffer_ptr(&backup_state->input);
-@@ -1972,4 +2024,10 @@ packet_restore_state(void)
+@@ -1966,4 +2018,10 @@ packet_restore_state(void)
  		buffer_clear(&backup_state->input);
  		add_recv_bytes(len);
  	}
@@ -582,18 +582,18 @@ diff -up openssh-5.9p1/packet.c.audit4 openssh-5.9p1/packet.c
 +	backup_state = NULL;
  }
 +
-diff -up openssh-5.9p1/packet.h.audit4 openssh-5.9p1/packet.h
---- openssh-5.9p1/packet.h.audit4	2011-05-15 00:43:13.000000000 +0200
-+++ openssh-5.9p1/packet.h	2012-07-27 14:27:56.175474944 +0200
-@@ -124,4 +124,5 @@ void	 packet_restore_state(void);
+diff -up openssh-6.0p1/packet.h.audit4 openssh-6.0p1/packet.h
+--- openssh-6.0p1/packet.h.audit4	2012-02-10 22:19:21.000000000 +0100
++++ openssh-6.0p1/packet.h	2012-08-06 20:35:56.321788995 +0200
+@@ -123,4 +123,5 @@ void	 packet_restore_state(void);
  void	*packet_get_input(void);
  void	*packet_get_output(void);
  
 +void	 packet_destroy_all(int, int);
  #endif				/* PACKET_H */
-diff -up openssh-5.9p1/session.c.audit4 openssh-5.9p1/session.c
---- openssh-5.9p1/session.c.audit4	2012-07-27 14:27:56.130474693 +0200
-+++ openssh-5.9p1/session.c	2012-07-27 14:27:56.176474950 +0200
+diff -up openssh-6.0p1/session.c.audit4 openssh-6.0p1/session.c
+--- openssh-6.0p1/session.c.audit4	2012-08-06 20:35:56.296789093 +0200
++++ openssh-6.0p1/session.c	2012-08-06 20:35:56.322788991 +0200
 @@ -1634,6 +1634,9 @@ do_child(Session *s, const char *command
  
  	/* remove hostkey from the child's memory */
@@ -604,10 +604,10 @@ diff -up openssh-5.9p1/session.c.audit4 openssh-5.9p1/session.c
  
  	/* Force a password change */
  	if (s->authctxt->force_pwchange) {
-diff -up openssh-5.9p1/sshd.c.audit4 openssh-5.9p1/sshd.c
---- openssh-5.9p1/sshd.c.audit4	2012-07-27 14:27:56.159474855 +0200
-+++ openssh-5.9p1/sshd.c	2012-07-27 14:27:56.178474961 +0200
-@@ -686,6 +686,8 @@ privsep_preauth(Authctxt *authctxt)
+diff -up openssh-6.0p1/sshd.c.audit4 openssh-6.0p1/sshd.c
+--- openssh-6.0p1/sshd.c.audit4	2012-08-06 20:35:56.312789030 +0200
++++ openssh-6.0p1/sshd.c	2012-08-06 20:35:56.323788987 +0200
+@@ -690,6 +690,8 @@ privsep_preauth(Authctxt *authctxt)
  	}
  }
  
@@ -616,7 +616,7 @@ diff -up openssh-5.9p1/sshd.c.audit4 openssh-5.9p1/sshd.c
  static void
  privsep_postauth(Authctxt *authctxt)
  {
-@@ -710,6 +712,10 @@ privsep_postauth(Authctxt *authctxt)
+@@ -714,6 +716,10 @@ privsep_postauth(Authctxt *authctxt)
  	else if (pmonitor->m_pid != 0) {
  		verbose("User child is on pid %ld", (long)pmonitor->m_pid);
  		buffer_clear(&loginmsg);
@@ -627,7 +627,7 @@ diff -up openssh-5.9p1/sshd.c.audit4 openssh-5.9p1/sshd.c
  		monitor_child_postauth(pmonitor);
  
  		/* NEVERREACHED */
-@@ -2001,6 +2007,7 @@ main(int ac, char **av)
+@@ -2005,6 +2011,7 @@ main(int ac, char **av)
  	 */
  	if (use_privsep) {
  		mm_send_keystate(pmonitor);
@@ -635,7 +635,7 @@ diff -up openssh-5.9p1/sshd.c.audit4 openssh-5.9p1/sshd.c
  		exit(0);
  	}
  
-@@ -2053,6 +2060,8 @@ main(int ac, char **av)
+@@ -2057,6 +2064,8 @@ main(int ac, char **av)
  	do_authenticated(authctxt);
  
  	/* The connection has been terminated. */
@@ -644,7 +644,7 @@ diff -up openssh-5.9p1/sshd.c.audit4 openssh-5.9p1/sshd.c
  	packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
  	packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
  	verbose("Transferred: sent %llu, received %llu bytes",
-@@ -2370,8 +2379,20 @@ do_ssh2_kex(void)
+@@ -2374,6 +2383,16 @@ do_ssh2_kex(void)
  void
  cleanup_exit(int i)
  {
@@ -658,8 +658,13 @@ diff -up openssh-5.9p1/sshd.c.audit4 openssh-5.9p1/sshd.c
 +		_exit(i);
 +	in_cleanup = 1;
 +
- 	if (the_authctxt)
+ 	if (the_authctxt) {
  		do_cleanup(the_authctxt);
+ 		if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) {
+@@ -2384,6 +2403,8 @@ cleanup_exit(int i)
+ 				    pmonitor->m_pid, strerror(errno));
+ 		}
+ 	}
 +	is_privsep_child = use_privsep && pmonitor != NULL && !mm_is_monitor();
 +	packet_destroy_all(1, is_privsep_child);
  #ifdef SSH_AUDIT_EVENTS
diff --git a/openssh-5.9p1-audit5.patch b/openssh-6.0p1-audit5.patch
similarity index 78%
rename from openssh-5.9p1-audit5.patch
rename to openssh-6.0p1-audit5.patch
index 144b4fe..70aa3ff 100644
--- a/openssh-5.9p1-audit5.patch
+++ b/openssh-6.0p1-audit5.patch
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p1/audit-bsm.c.audit5 openssh-5.9p1/audit-bsm.c
---- openssh-5.9p1/audit-bsm.c.audit5	2011-09-13 22:07:31.262575526 +0200
-+++ openssh-5.9p1/audit-bsm.c	2011-09-13 22:07:33.268491813 +0200
-@@ -414,4 +414,22 @@ audit_session_key_free_body(int ctos, pi
+diff -up openssh-6.0p1/audit-bsm.c.audit5 openssh-6.0p1/audit-bsm.c
+--- openssh-6.0p1/audit-bsm.c.audit5	2012-08-06 20:37:50.036345216 +0200
++++ openssh-6.0p1/audit-bsm.c	2012-08-06 20:37:50.046345177 +0200
+@@ -491,4 +491,22 @@ audit_session_key_free_body(int ctos, pi
  {
  	/* not implemented */
  }
@@ -24,10 +24,58 @@ diff -up openssh-5.9p1/audit-bsm.c.audit5 openssh-5.9p1/audit-bsm.c
 +	/* not implemented */
 +}
  #endif /* BSM */
-diff -up openssh-5.9p1/audit-linux.c.audit5 openssh-5.9p1/audit-linux.c
---- openssh-5.9p1/audit-linux.c.audit5	2011-09-13 22:07:31.400584308 +0200
-+++ openssh-5.9p1/audit-linux.c	2011-09-13 22:07:33.357460348 +0200
-@@ -350,4 +350,50 @@ audit_session_key_free_body(int ctos, pi
+diff -up openssh-6.0p1/audit.c.audit5 openssh-6.0p1/audit.c
+--- openssh-6.0p1/audit.c.audit5	2012-08-06 20:37:50.036345216 +0200
++++ openssh-6.0p1/audit.c	2012-08-06 20:37:50.047345173 +0200
+@@ -290,5 +290,24 @@ audit_session_key_free_body(int ctos, pi
+ 	debug("audit session key discard euid %u direction %d from pid %ld uid %u",
+ 		(unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
+ }
++
++/*
++ * This will be called on destroy private part of the server key
++ */
++void
++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++	debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
++		geteuid(), fp, (long)pid, (unsigned)uid);
++}
++
++/*
++ * This will be called on generation of the ephemeral server key
++ */
++void
++audit_generate_ephemeral_server_key(const char *)
++{
++	debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
++}
+ # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
+ #endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.0p1/audit.h.audit5 openssh-6.0p1/audit.h
+--- openssh-6.0p1/audit.h.audit5	2012-08-06 20:37:50.037345212 +0200
++++ openssh-6.0p1/audit.h	2012-08-06 20:37:50.047345173 +0200
+@@ -48,6 +48,8 @@ enum ssh_audit_event_type {
+ };
+ typedef enum ssh_audit_event_type ssh_audit_event_t;
+ 
++int	listening_for_clients(void);
++
+ void	audit_connection_from(const char *, int);
+ void	audit_event(ssh_audit_event_t);
+ void	audit_count_session_open(void);
+@@ -64,5 +66,7 @@ void	audit_unsupported_body(int);
+ void	audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
+ void	audit_session_key_free(int ctos);
+ void	audit_session_key_free_body(int ctos, pid_t, uid_t);
++void	audit_destroy_sensitive_data(const char *, pid_t, uid_t);
++void	audit_generate_ephemeral_server_key(const char *);
+ 
+ #endif /* _SSH_AUDIT_H */
+diff -up openssh-6.0p1/audit-linux.c.audit5 openssh-6.0p1/audit-linux.c
+--- openssh-6.0p1/audit-linux.c.audit5	2012-08-06 20:37:50.037345212 +0200
++++ openssh-6.0p1/audit-linux.c	2012-08-06 20:37:50.046345177 +0200
+@@ -356,4 +356,50 @@ audit_session_key_free_body(int ctos, pi
  		error("cannot write into audit");
  }
  
@@ -78,58 +126,10 @@ diff -up openssh-5.9p1/audit-linux.c.audit5 openssh-5.9p1/audit-linux.c
 +		error("cannot write into audit");
 +}
  #endif /* USE_LINUX_AUDIT */
-diff -up openssh-5.9p1/audit.c.audit5 openssh-5.9p1/audit.c
---- openssh-5.9p1/audit.c.audit5	2011-09-13 22:07:31.495458797 +0200
-+++ openssh-5.9p1/audit.c	2011-09-13 22:07:33.478458341 +0200
-@@ -290,5 +290,24 @@ audit_session_key_free_body(int ctos, pi
- 	debug("audit session key discard euid %u direction %d from pid %ld uid %u",
- 		(unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
- }
-+
-+/*
-+ * This will be called on destroy private part of the server key
-+ */
-+void
-+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
-+{
-+	debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
-+		geteuid(), fp, (long)pid, (unsigned)uid);
-+}
-+
-+/*
-+ * This will be called on generation of the ephemeral server key
-+ */
-+void
-+audit_generate_ephemeral_server_key(const char *)
-+{
-+	debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
-+}
- # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
- #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p1/audit.h.audit5 openssh-5.9p1/audit.h
---- openssh-5.9p1/audit.h.audit5	2011-09-13 22:07:31.616459125 +0200
-+++ openssh-5.9p1/audit.h	2011-09-13 22:07:33.612458074 +0200
-@@ -48,6 +48,8 @@ enum ssh_audit_event_type {
- };
- typedef enum ssh_audit_event_type ssh_audit_event_t;
- 
-+int	listening_for_clients(void);
-+
- void	audit_connection_from(const char *, int);
- void	audit_event(ssh_audit_event_t);
- void	audit_count_session_open(void);
-@@ -64,5 +66,7 @@ void	audit_unsupported_body(int);
- void	audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
- void	audit_session_key_free(int ctos);
- void	audit_session_key_free_body(int ctos, pid_t, uid_t);
-+void	audit_destroy_sensitive_data(const char *, pid_t, uid_t);
-+void	audit_generate_ephemeral_server_key(const char *);
- 
- #endif /* _SSH_AUDIT_H */
-diff -up openssh-5.9p1/key.c.audit5 openssh-5.9p1/key.c
---- openssh-5.9p1/key.c.audit5	2011-09-13 22:07:23.054490740 +0200
-+++ openssh-5.9p1/key.c	2011-09-13 22:07:33.721583661 +0200
-@@ -1799,6 +1799,30 @@ key_demote(const Key *k)
+diff -up openssh-6.0p1/key.c.audit5 openssh-6.0p1/key.c
+--- openssh-6.0p1/key.c.audit5	2012-08-06 20:37:49.992345388 +0200
++++ openssh-6.0p1/key.c	2012-08-06 20:37:50.048345169 +0200
+@@ -1794,6 +1794,30 @@ key_demote(const Key *k)
  }
  
  int
@@ -160,9 +160,9 @@ diff -up openssh-5.9p1/key.c.audit5 openssh-5.9p1/key.c
  key_is_cert(const Key *k)
  {
  	if (k == NULL)
-diff -up openssh-5.9p1/key.h.audit5 openssh-5.9p1/key.h
---- openssh-5.9p1/key.h.audit5	2011-09-13 22:07:23.160459285 +0200
-+++ openssh-5.9p1/key.h	2011-09-13 22:07:33.847459341 +0200
+diff -up openssh-6.0p1/key.h.audit5 openssh-6.0p1/key.h
+--- openssh-6.0p1/key.h.audit5	2012-08-06 20:37:49.993345384 +0200
++++ openssh-6.0p1/key.h	2012-08-06 20:37:50.049345165 +0200
 @@ -109,6 +109,7 @@ Key	*key_generate(int, u_int);
  Key	*key_from_private(const Key *);
  int	 key_type_from_name(char *);
@@ -171,9 +171,9 @@ diff -up openssh-5.9p1/key.h.audit5 openssh-5.9p1/key.h
  int	 key_type_plain(int);
  int	 key_to_certified(Key *, int);
  int	 key_drop_cert(Key *);
-diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
---- openssh-5.9p1/monitor.c.audit5	2011-09-13 22:07:32.285495537 +0200
-+++ openssh-5.9p1/monitor.c	2011-09-13 22:10:04.148554239 +0200
+diff -up openssh-6.0p1/monitor.c.audit5 openssh-6.0p1/monitor.c
+--- openssh-6.0p1/monitor.c.audit5	2012-08-06 20:37:50.040345200 +0200
++++ openssh-6.0p1/monitor.c	2012-08-06 20:37:50.049345165 +0200
 @@ -114,6 +114,8 @@ extern Buffer auth_debug;
  extern int auth_debug_init;
  extern Buffer loginmsg;
@@ -183,7 +183,7 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
  /* State exported from the child */
  
  struct {
-@@ -191,6 +193,7 @@ int mm_answer_audit_end_command(int, Buf
+@@ -190,6 +192,7 @@ int mm_answer_audit_end_command(int, Buf
  int mm_answer_audit_unsupported_body(int, Buffer *);
  int mm_answer_audit_kex_body(int, Buffer *);
  int mm_answer_audit_session_key_free_body(int, Buffer *);
@@ -199,7 +199,7 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
  #endif
  #ifdef BSD_AUTH
      {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
-@@ -285,6 +289,7 @@ struct mon_table mon_dispatch_postauth20
+@@ -284,6 +288,7 @@ struct mon_table mon_dispatch_postauth20
      {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
      {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
      {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
@@ -207,7 +207,7 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
  #endif
      {0, 0, NULL}
  };
-@@ -319,6 +324,7 @@ struct mon_table mon_dispatch_proto15[]
+@@ -318,6 +323,7 @@ struct mon_table mon_dispatch_proto15[]
      {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
      {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
      {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
@@ -215,7 +215,7 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
  #endif
      {0, 0, NULL}
  };
-@@ -334,6 +340,7 @@ struct mon_table mon_dispatch_postauth15
+@@ -333,6 +339,7 @@ struct mon_table mon_dispatch_postauth15
      {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
      {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
      {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
@@ -223,7 +223,7 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
  #endif
      {0, 0, NULL}
  };
-@@ -1716,6 +1723,8 @@ mm_answer_term(int sock, Buffer *req)
+@@ -1744,6 +1751,8 @@ mm_answer_term(int sock, Buffer *req)
  		sshpam_cleanup();
  #endif
  
@@ -232,7 +232,7 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
  	while (waitpid(pmonitor->m_pid, &status, 0) == -1)
  		if (errno != EINTR)
  			exit(1);
-@@ -2470,4 +2479,25 @@ mm_answer_audit_session_key_free_body(in
+@@ -2485,4 +2494,25 @@ mm_answer_audit_session_key_free_body(in
  	mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
  	return 0;
  }
@@ -258,9 +258,9 @@ diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c
 +	return 0;
 +}
  #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p1/monitor.h.audit5 openssh-5.9p1/monitor.h
---- openssh-5.9p1/monitor.h.audit5	2011-09-13 22:07:32.385522626 +0200
-+++ openssh-5.9p1/monitor.h	2011-09-13 22:07:34.098459356 +0200
+diff -up openssh-6.0p1/monitor.h.audit5 openssh-6.0p1/monitor.h
+--- openssh-6.0p1/monitor.h.audit5	2012-08-06 20:37:50.040345200 +0200
++++ openssh-6.0p1/monitor.h	2012-08-06 20:37:50.050345161 +0200
 @@ -64,6 +64,7 @@ enum monitor_reqtype {
  	MONITOR_REQ_AUDIT_UNSUPPORTED, MONITOR_ANS_AUDIT_UNSUPPORTED,
  	MONITOR_REQ_AUDIT_KEX, MONITOR_ANS_AUDIT_KEX,
@@ -269,10 +269,10 @@ diff -up openssh-5.9p1/monitor.h.audit5 openssh-5.9p1/monitor.h
  	MONITOR_REQ_TERM,
  	MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
  	MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
-diff -up openssh-5.9p1/monitor_wrap.c.audit5 openssh-5.9p1/monitor_wrap.c
---- openssh-5.9p1/monitor_wrap.c.audit5	2011-09-13 22:07:32.510521163 +0200
-+++ openssh-5.9p1/monitor_wrap.c	2011-09-13 22:07:34.610458275 +0200
-@@ -1559,4 +1559,20 @@ mm_audit_session_key_free_body(int ctos,
+diff -up openssh-6.0p1/monitor_wrap.c.audit5 openssh-6.0p1/monitor_wrap.c
+--- openssh-6.0p1/monitor_wrap.c.audit5	2012-08-06 20:37:50.041345196 +0200
++++ openssh-6.0p1/monitor_wrap.c	2012-08-06 20:37:50.050345161 +0200
+@@ -1539,4 +1539,20 @@ mm_audit_session_key_free_body(int ctos,
  				  &m);
  	buffer_free(&m);
  }
@@ -293,10 +293,10 @@ diff -up openssh-5.9p1/monitor_wrap.c.audit5 openssh-5.9p1/monitor_wrap.c
 +	buffer_free(&m);
 +}
  #endif /* SSH_AUDIT_EVENTS */
-diff -up openssh-5.9p1/monitor_wrap.h.audit5 openssh-5.9p1/monitor_wrap.h
---- openssh-5.9p1/monitor_wrap.h.audit5	2011-09-13 22:07:32.607520810 +0200
-+++ openssh-5.9p1/monitor_wrap.h	2011-09-13 22:07:34.716458214 +0200
-@@ -81,6 +81,7 @@ void mm_audit_end_command(int, const cha
+diff -up openssh-6.0p1/monitor_wrap.h.audit5 openssh-6.0p1/monitor_wrap.h
+--- openssh-6.0p1/monitor_wrap.h.audit5	2012-08-06 20:37:50.041345196 +0200
++++ openssh-6.0p1/monitor_wrap.h	2012-08-06 20:37:50.051345157 +0200
+@@ -80,6 +80,7 @@ void mm_audit_end_command(int, const cha
  void mm_audit_unsupported_body(int);
  void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
  void mm_audit_session_key_free_body(int, pid_t, uid_t);
@@ -304,9 +304,9 @@ diff -up openssh-5.9p1/monitor_wrap.h.audit5 openssh-5.9p1/monitor_wrap.h
  #endif
  
  struct Session;
-diff -up openssh-5.9p1/session.c.audit5 openssh-5.9p1/session.c
---- openssh-5.9p1/session.c.audit5	2011-09-13 22:07:32.973544819 +0200
-+++ openssh-5.9p1/session.c	2011-09-13 22:07:34.849585578 +0200
+diff -up openssh-6.0p1/session.c.audit5 openssh-6.0p1/session.c
+--- openssh-6.0p1/session.c.audit5	2012-08-06 20:37:50.043345189 +0200
++++ openssh-6.0p1/session.c	2012-08-06 20:37:50.052345153 +0200
 @@ -136,7 +136,7 @@ extern int log_stderr;
  extern int debug_flag;
  extern u_int utmp_len;
@@ -325,10 +325,10 @@ diff -up openssh-5.9p1/session.c.audit5 openssh-5.9p1/session.c
  	/* Don't audit this - both us and the parent would be talking to the
  	   monitor over a single socket, with no synchronization. */
  	packet_destroy_all(0, 1);
-diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
---- openssh-5.9p1/sshd.c.audit5	2011-09-13 22:07:33.106516378 +0200
-+++ openssh-5.9p1/sshd.c	2011-09-13 22:07:34.989470331 +0200
-@@ -254,7 +254,7 @@ Buffer loginmsg;
+diff -up openssh-6.0p1/sshd.c.audit5 openssh-6.0p1/sshd.c
+--- openssh-6.0p1/sshd.c.audit5	2012-08-06 20:37:50.044345185 +0200
++++ openssh-6.0p1/sshd.c	2012-08-06 20:37:50.053345149 +0200
+@@ -255,7 +255,7 @@ Buffer loginmsg;
  struct passwd *privsep_pw = NULL;
  
  /* Prototypes for various functions defined later in this file. */
@@ -337,7 +337,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  void demote_sensitive_data(void);
  
  static void do_ssh1_kex(void);
-@@ -273,6 +273,15 @@ close_listen_socks(void)
+@@ -274,6 +274,15 @@ close_listen_socks(void)
  	num_listen_socks = -1;
  }
  
@@ -353,7 +353,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  static void
  close_startup_pipes(void)
  {
-@@ -533,22 +542,47 @@ sshd_exchange_identification(int sock_in
+@@ -534,22 +543,47 @@ sshd_exchange_identification(int sock_in
  	}
  }
  
@@ -404,7 +404,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  			key_free(sensitive_data.host_certificates[i]);
  			sensitive_data.host_certificates[i] = NULL;
  		}
-@@ -562,6 +596,8 @@ void
+@@ -563,6 +597,8 @@ void
  demote_sensitive_data(void)
  {
  	Key *tmp;
@@ -413,7 +413,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  	int i;
  
  	if (sensitive_data.server_key) {
-@@ -570,13 +606,27 @@ demote_sensitive_data(void)
+@@ -571,13 +607,27 @@ demote_sensitive_data(void)
  		sensitive_data.server_key = tmp;
  	}
  
@@ -441,7 +441,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  		}
  		/* Certs do not need demotion */
  	}
-@@ -1145,6 +1195,7 @@ server_accept_loop(int *sock_in, int *so
+@@ -1149,6 +1199,7 @@ server_accept_loop(int *sock_in, int *so
  		if (received_sigterm) {
  			logit("Received signal %d; terminating.",
  			    (int) received_sigterm);
@@ -449,7 +449,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  			close_listen_socks();
  			unlink(options.pid_file);
  			exit(received_sigterm == SIGTERM ? 0 : 255);
-@@ -2050,7 +2101,7 @@ main(int ac, char **av)
+@@ -2054,7 +2105,7 @@ main(int ac, char **av)
  		privsep_postauth(authctxt);
  		/* the monitor process [priv] will not return */
  		if (!compat20)
@@ -458,7 +458,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  	}
  
  	packet_set_timeout(options.client_alive_interval,
-@@ -2061,6 +2112,7 @@ main(int ac, char **av)
+@@ -2065,6 +2116,7 @@ main(int ac, char **av)
  
  	/* The connection has been terminated. */
  	packet_destroy_all(1, 1);
@@ -466,7 +466,7 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  
  	packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
  	packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
-@@ -2289,7 +2341,7 @@ do_ssh1_kex(void)
+@@ -2293,7 +2345,7 @@ do_ssh1_kex(void)
  			session_id[i] = session_key[i] ^ session_key[i + 16];
  	}
  	/* Destroy the private and public keys. No longer. */
@@ -475,9 +475,9 @@ diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c
  
  	if (use_privsep)
  		mm_ssh1_session_id(session_id);
-@@ -2392,6 +2444,8 @@ cleanup_exit(int i)
- 	if (the_authctxt)
- 		do_cleanup(the_authctxt);
+@@ -2404,6 +2456,8 @@ cleanup_exit(int i)
+ 		}
+ 	}
  	is_privsep_child = use_privsep && pmonitor != NULL && !mm_is_monitor();
 +	if (sensitive_data.host_keys != NULL)
 +		destroy_sensitive_data(is_privsep_child);
diff --git a/openssh-5.9p1-entropy.patch b/openssh-6.0p1-entropy.patch
similarity index 74%
rename from openssh-5.9p1-entropy.patch
rename to openssh-6.0p1-entropy.patch
index b3dec46..e54d7e2 100644
--- a/openssh-5.9p1-entropy.patch
+++ b/openssh-6.0p1-entropy.patch
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p0/entropy.c.entropy openssh-5.9p0/entropy.c
---- openssh-5.9p0/entropy.c.entropy	2011-08-31 13:20:59.660150441 +0200
-+++ openssh-5.9p0/entropy.c	2011-08-31 13:21:05.072024970 +0200
-@@ -232,6 +232,9 @@ seed_rng(void)
+diff -up openssh-6.0p1/entropy.c.entropy openssh-6.0p1/entropy.c
+--- openssh-6.0p1/entropy.c.entropy	2012-08-06 20:51:59.131033413 +0200
++++ openssh-6.0p1/entropy.c	2012-08-06 20:51:59.171033257 +0200
+@@ -237,6 +237,9 @@ seed_rng(void)
  	memset(buf, '\0', sizeof(buf));
  
  #endif /* OPENSSL_PRNG_ONLY */
@@ -11,21 +11,21 @@ diff -up openssh-5.9p0/entropy.c.entropy openssh-5.9p0/entropy.c
  	if (RAND_status() != 1)
  		fatal("PRNG is not seeded");
  }
-diff -up openssh-5.9p0/openbsd-compat/Makefile.in.entropy openssh-5.9p0/openbsd-compat/Makefile.in
---- openssh-5.9p0/openbsd-compat/Makefile.in.entropy	2011-08-31 13:20:54.000000000 +0200
-+++ openssh-5.9p0/openbsd-compat/Makefile.in	2011-08-31 13:44:25.138151565 +0200
+diff -up openssh-6.0p1/openbsd-compat/Makefile.in.entropy openssh-6.0p1/openbsd-compat/Makefile.in
+--- openssh-6.0p1/openbsd-compat/Makefile.in.entropy	2012-08-06 20:51:59.100033534 +0200
++++ openssh-6.0p1/openbsd-compat/Makefile.in	2012-08-06 20:51:59.171033257 +0200
 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport
  
- COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
+ COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
  
 -PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o
 +PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o
  
  .c.o:
  	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
-diff -up openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy openssh-5.9p0/openbsd-compat/port-linux-prng.c
---- openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy	2011-08-31 13:21:05.382024083 +0200
-+++ openssh-5.9p0/openbsd-compat/port-linux-prng.c	2011-08-31 13:21:05.386024776 +0200
+diff -up openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.0p1/openbsd-compat/port-linux-prng.c
+--- openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy	2012-08-06 20:51:59.171033257 +0200
++++ openssh-6.0p1/openbsd-compat/port-linux-prng.c	2012-08-06 20:51:59.171033257 +0200
 @@ -0,0 +1,59 @@
 +/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */
 +
@@ -86,13 +86,15 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy openssh-5.9p0/op
 +			fatal ("EOF reading %s", random);
 +	}
 +}
-diff -up openssh-5.9p0/ssh-add.1.entropy openssh-5.9p0/ssh-add.1
---- openssh-5.9p0/ssh-add.1.entropy	2010-11-05 00:20:14.000000000 +0100
-+++ openssh-5.9p0/ssh-add.1	2011-08-31 13:21:05.597122030 +0200
-@@ -158,6 +158,20 @@ Identifies the path of a
- .Ux Ns -domain
- socket used to communicate with the agent.
- .El
+diff -up openssh-6.0p1/ssh.1.entropy openssh-6.0p1/ssh.1
+--- openssh-6.0p1/ssh.1.entropy	2012-08-06 20:51:59.139033382 +0200
++++ openssh-6.0p1/ssh.1	2012-08-06 20:51:59.174033245 +0200
+@@ -1269,6 +1269,23 @@ For more information, see the
+ .Cm PermitUserEnvironment
+ option in
+ .Xr sshd_config 5 .
++.Sh ENVIRONMENT
++.Bl -tag -width Ds -compact
 +.It Ev SSH_USE_STRONG_RNG
 +The reseeding of the OpenSSL random generator is usually done from
 +.Cm /dev/urandom .
@@ -107,20 +109,18 @@ diff -up openssh-5.9p0/ssh-add.1.entropy openssh-5.9p0/ssh-add.1
 +This setting is not recommended on the computers without the hardware
 +random generator because insufficient entropy causes the connection to 
 +be blocked until enough entropy is available.
++.El
  .Sh FILES
- .Bl -tag -width Ds
- .It Pa ~/.ssh/identity
-diff -up openssh-5.9p0/ssh-agent.1.entropy openssh-5.9p0/ssh-agent.1
---- openssh-5.9p0/ssh-agent.1.entropy	2010-12-01 01:50:35.000000000 +0100
-+++ openssh-5.9p0/ssh-agent.1	2011-08-31 13:21:05.735150196 +0200
-@@ -198,6 +198,24 @@ sockets used to contain the connection t
- These sockets should only be readable by the owner.
- The sockets should get automatically removed when the agent exits.
+ .Bl -tag -width Ds -compact
+ .It Pa ~/.rhosts
+diff -up openssh-6.0p1/ssh-add.1.entropy openssh-6.0p1/ssh-add.1
+--- openssh-6.0p1/ssh-add.1.entropy	2011-10-18 07:06:33.000000000 +0200
++++ openssh-6.0p1/ssh-add.1	2012-08-06 20:51:59.172033253 +0200
+@@ -161,6 +161,20 @@ Identifies the path of a
+ .Ux Ns -domain
+ socket used to communicate with the agent.
  .El
-+.Sh ENVIRONMENT
-+.Bl -tag -width Ds -compact
-+.Pp
-+.It Pa SSH_USE_STRONG_RNG
++.It Ev SSH_USE_STRONG_RNG
 +The reseeding of the OpenSSL random generator is usually done from
 +.Cm /dev/urandom .
 +If the 
@@ -134,16 +134,15 @@ diff -up openssh-5.9p0/ssh-agent.1.entropy openssh-5.9p0/ssh-agent.1
 +This setting is not recommended on the computers without the hardware
 +random generator because insufficient entropy causes the connection to 
 +be blocked until enough entropy is available.
-+.El
- .Sh SEE ALSO
- .Xr ssh 1 ,
- .Xr ssh-add 1 ,
-diff -up openssh-5.9p0/ssh-keygen.1.entropy openssh-5.9p0/ssh-keygen.1
---- openssh-5.9p0/ssh-keygen.1.entropy	2011-08-31 13:20:59.200212619 +0200
-+++ openssh-5.9p0/ssh-keygen.1	2011-08-31 13:21:06.077150115 +0200
-@@ -669,6 +669,24 @@ Contains Diffie-Hellman groups used for
- The file format is described in
- .Xr moduli 5 .
+ .Sh FILES
+ .Bl -tag -width Ds
+ .It Pa ~/.ssh/identity
+diff -up openssh-6.0p1/ssh-agent.1.entropy openssh-6.0p1/ssh-agent.1
+--- openssh-6.0p1/ssh-agent.1.entropy	2010-12-01 01:50:35.000000000 +0100
++++ openssh-6.0p1/ssh-agent.1	2012-08-06 20:51:59.172033253 +0200
+@@ -198,6 +198,24 @@ sockets used to contain the connection t
+ These sockets should only be readable by the owner.
+ The sockets should get automatically removed when the agent exits.
  .El
 +.Sh ENVIRONMENT
 +.Bl -tag -width Ds -compact
@@ -166,12 +165,12 @@ diff -up openssh-5.9p0/ssh-keygen.1.entropy openssh-5.9p0/ssh-keygen.1
  .Sh SEE ALSO
  .Xr ssh 1 ,
  .Xr ssh-add 1 ,
-diff -up openssh-5.9p0/ssh-keysign.8.entropy openssh-5.9p0/ssh-keysign.8
---- openssh-5.9p0/ssh-keysign.8.entropy	2010-08-31 14:41:14.000000000 +0200
-+++ openssh-5.9p0/ssh-keysign.8	2011-08-31 13:21:06.207024356 +0200
-@@ -78,6 +78,24 @@ must be set-uid root if host-based authe
- If these files exist they are assumed to contain public certificate
- information corresponding with the private keys above.
+diff -up openssh-6.0p1/sshd.8.entropy openssh-6.0p1/sshd.8
+--- openssh-6.0p1/sshd.8.entropy	2012-08-06 20:51:59.139033382 +0200
++++ openssh-6.0p1/sshd.8	2012-08-06 20:51:59.174033245 +0200
+@@ -943,6 +943,24 @@ concurrently for different ports, this c
+ started last).
+ The content of this file is not sensitive; it can be world-readable.
  .El
 +.Sh ENVIRONMENT
 +.Bl -tag -width Ds -compact
@@ -191,19 +190,20 @@ diff -up openssh-5.9p0/ssh-keysign.8.entropy openssh-5.9p0/ssh-keysign.8
 +random generator because insufficient entropy causes the connection to 
 +be blocked until enough entropy is available.
 +.El
+ .Sh IPV6
+ IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
  .Sh SEE ALSO
- .Xr ssh 1 ,
- .Xr ssh-keygen 1 ,
-diff -up openssh-5.9p0/ssh.1.entropy openssh-5.9p0/ssh.1
---- openssh-5.9p0/ssh.1.entropy	2011-08-31 13:21:00.835103535 +0200
-+++ openssh-5.9p0/ssh.1	2011-08-31 13:21:05.482032754 +0200
-@@ -1255,6 +1255,23 @@ For more information, see the
- .Cm PermitUserEnvironment
- option in
- .Xr sshd_config 5 .
+diff -up openssh-6.0p1/ssh-keygen.1.entropy openssh-6.0p1/ssh-keygen.1
+--- openssh-6.0p1/ssh-keygen.1.entropy	2011-10-18 07:05:21.000000000 +0200
++++ openssh-6.0p1/ssh-keygen.1	2012-08-06 20:51:59.173033249 +0200
+@@ -675,6 +675,24 @@ Contains Diffie-Hellman groups used for
+ The file format is described in
+ .Xr moduli 5 .
+ .El
 +.Sh ENVIRONMENT
 +.Bl -tag -width Ds -compact
-+.It Ev SSH_USE_STRONG_RNG
++.Pp
++.It Pa SSH_USE_STRONG_RNG
 +The reseeding of the OpenSSL random generator is usually done from
 +.Cm /dev/urandom .
 +If the 
@@ -218,15 +218,15 @@ diff -up openssh-5.9p0/ssh.1.entropy openssh-5.9p0/ssh.1
 +random generator because insufficient entropy causes the connection to 
 +be blocked until enough entropy is available.
 +.El
- .Sh FILES
- .Bl -tag -width Ds -compact
- .It Pa ~/.rhosts
-diff -up openssh-5.9p0/sshd.8.entropy openssh-5.9p0/sshd.8
---- openssh-5.9p0/sshd.8.entropy	2011-08-31 13:21:00.000000000 +0200
-+++ openssh-5.9p0/sshd.8	2011-08-31 13:46:27.341025537 +0200
-@@ -940,6 +940,24 @@ concurrently for different ports, this c
- started last).
- The content of this file is not sensitive; it can be world-readable.
+ .Sh SEE ALSO
+ .Xr ssh 1 ,
+ .Xr ssh-add 1 ,
+diff -up openssh-6.0p1/ssh-keysign.8.entropy openssh-6.0p1/ssh-keysign.8
+--- openssh-6.0p1/ssh-keysign.8.entropy	2010-08-31 14:41:14.000000000 +0200
++++ openssh-6.0p1/ssh-keysign.8	2012-08-06 20:51:59.173033249 +0200
+@@ -78,6 +78,24 @@ must be set-uid root if host-based authe
+ If these files exist they are assumed to contain public certificate
+ information corresponding with the private keys above.
  .El
 +.Sh ENVIRONMENT
 +.Bl -tag -width Ds -compact
@@ -246,6 +246,6 @@ diff -up openssh-5.9p0/sshd.8.entropy openssh-5.9p0/sshd.8
 +random generator because insufficient entropy causes the connection to 
 +be blocked until enough entropy is available.
 +.El
- .Sh IPV6
- IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
  .Sh SEE ALSO
+ .Xr ssh 1 ,
+ .Xr ssh-keygen 1 ,
diff --git a/openssh-5.9p1-ldap.patch b/openssh-6.0p1-ldap.patch
similarity index 95%
rename from openssh-5.9p1-ldap.patch
rename to openssh-6.0p1-ldap.patch
index bc6eb98..10389dc 100644
--- a/openssh-5.9p1-ldap.patch
+++ b/openssh-6.0p1-ldap.patch
@@ -1,6 +1,116 @@
-diff -up openssh-5.9p1/HOWTO.ldap-keys.ldap openssh-5.9p1/HOWTO.ldap-keys
---- openssh-5.9p1/HOWTO.ldap-keys.ldap	2011-09-13 11:17:05.178644691 +0200
-+++ openssh-5.9p1/HOWTO.ldap-keys	2011-09-13 11:17:05.181522429 +0200
+diff -up openssh-6.0p1/configure.ac.ldap openssh-6.0p1/configure.ac
+--- openssh-6.0p1/configure.ac.ldap	2012-08-06 20:41:38.392454225 +0200
++++ openssh-6.0p1/configure.ac	2012-08-06 20:41:38.398454202 +0200
+@@ -1523,6 +1523,106 @@ AC_ARG_WITH(authorized-keys-command,
+ 	]
+ )
+ 
++# Check whether user wants LDAP support
++LDAP_MSG="no"
++INSTALL_SSH_LDAP_HELPER=""
++AC_ARG_WITH(ldap,
++	[  --with-ldap[[=PATH]]      Enable LDAP pubkey support (optionally in PATH)],
++	[
++		if test "x$withval" != "xno" ; then
++
++			INSTALL_SSH_LDAP_HELPER="yes"
++			CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED"
++
++			if test "x$withval" != "xyes" ; then
++				CPPFLAGS="$CPPFLAGS -I${withval}/include"
++				LDFLAGS="$LDFLAGS -L${withval}/lib"
++			fi
++
++			AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support])
++			LDAP_MSG="yes"
++
++			AC_CHECK_HEADERS(lber.h)
++			AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate <ldap.h>))
++			AC_CHECK_HEADERS(ldap_ssl.h)
++
++			AC_ARG_WITH(ldap-lib,
++				[  --with-ldap-lib=type    select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]])
++
++			if test -z "$with_ldap_lib"; then
++				with_ldap_lib=auto
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then
++				AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes)
++				AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes)
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then
++				AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes)
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then
++				AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes)
++				if test -z "$found_ldap_lib"; then
++					AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes)
++				fi
++				if test -z "$found_ldap_lib"; then
++					AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes)
++				fi
++				if test -z "$found_ldap_lib"; then
++					AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes)
++				fi
++			fi
++
++			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then
++				AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes)
++			fi
++
++			if test -z "$found_ldap_lib"; then
++				AC_MSG_ERROR(could not locate a valid LDAP library)
++			fi
++
++			AC_MSG_CHECKING([for working LDAP support])
++			AC_TRY_COMPILE(
++				[#include <sys/types.h>
++				 #include <ldap.h>],
++				[(void)ldap_init(0, 0);],
++				[AC_MSG_RESULT(yes)],
++				[
++				    AC_MSG_RESULT(no) 
++					AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
++				])
++			AC_CHECK_FUNCS( \
++				ldap_init \
++				ldap_get_lderrno \
++				ldap_set_lderrno \
++				ldap_parse_result \
++				ldap_memfree \
++				ldap_controls_free \
++				ldap_set_option \
++				ldap_get_option \
++				ldapssl_init \
++				ldap_start_tls_s \
++				ldap_pvt_tls_set_option \
++				ldap_initialize \
++			)
++			AC_CHECK_FUNCS(ldap_set_rebind_proc,
++				AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc])
++				AC_TRY_COMPILE(
++					[#include <lber.h>
++					#include <ldap.h>],
++					[ldap_set_rebind_proc(0, 0, 0);],
++					[ac_cv_ldap_set_rebind_proc=3],
++					[ac_cv_ldap_set_rebind_proc=2])
++				AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
++				AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
++			)
++		fi
++	]
++)
++AC_SUBST(INSTALL_SSH_LDAP_HELPER)
++
+ dnl    Checks for library functions. Please keep in alphabetical order
+ AC_CHECK_FUNCS([ \
+ 	arc4random \
+diff -up openssh-6.0p1/HOWTO.ldap-keys.ldap openssh-6.0p1/HOWTO.ldap-keys
+--- openssh-6.0p1/HOWTO.ldap-keys.ldap	2012-08-06 20:41:38.399454198 +0200
++++ openssh-6.0p1/HOWTO.ldap-keys	2012-08-06 20:41:38.399454198 +0200
 @@ -0,0 +1,108 @@
 +
 +HOW TO START
@@ -110,1730 +220,1562 @@ diff -up openssh-5.9p1/HOWTO.ldap-keys.ldap openssh-5.9p1/HOWTO.ldap-keys
 +5) Author
 +    Jan F. Chadima <jchadima at redhat.com>
 +
-diff -up openssh-5.9p1/Makefile.in.ldap openssh-5.9p1/Makefile.in
---- openssh-5.9p1/Makefile.in.ldap	2011-09-13 11:17:04.064644353 +0200
-+++ openssh-5.9p1/Makefile.in	2011-09-13 11:20:16.996522219 +0200
-@@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh
- ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
- SFTP_SERVER=$(libexecdir)/sftp-server
- SSH_KEYSIGN=$(libexecdir)/ssh-keysign
-+SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper
-+SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper
- SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
- PRIVSEP_PATH=@PRIVSEP_PATH@
- SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
-@@ -58,8 +60,9 @@ XAUTH_PATH=@XAUTH_PATH@
- LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
- EXEEXT=@EXEEXT@
- MANFMT=@MANFMT@
-+INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@
- 
--TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
-+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT)
- 
- LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
- 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
-@@ -92,8 +95,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
- 	roaming_common.o roaming_serv.o \
- 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o sandbox-selinux.o
- 
--MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
--MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
-+MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out
-+MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5
- MANTYPE		= @MANTYPE@
- 
- CONFIGFILES=sshd_config.out ssh_config.out moduli.out
-@@ -161,6 +164,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss
- ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
- 	$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
- 
-+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o
-+	$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
-+
- ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
- 	$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
- 
-@@ -256,6 +262,10 @@ install-files:
- 	$(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
- 	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
- 	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
-+	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
-+		$(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \
-+		$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \
-+	fi
- 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
- 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
- 	$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
-@@ -272,6 +282,10 @@ install-files:
- 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
- 	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
- 	$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
-+	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
-+		$(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \
-+		$(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \
-+	fi
- 	-rm -f $(DESTDIR)$(bindir)/slogin
- 	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
-@@ -301,6 +315,13 @@ install-sysconf:
- 	else \
- 		echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \
- 	fi
-+	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
-+		if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \
-+			$(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \
-+		else \
-+			echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \
-+		fi ; \
-+	fi
- 
- host-key: ssh-keygen$(EXEEXT)
- 	@if [ -z "$(DESTDIR)" ] ; then \
-@@ -358,6 +379,8 @@ uninstall:
- 	-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
- 	-rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
- 	-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
-+	-rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT)
-+	-rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT)
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
-@@ -369,6 +392,7 @@ uninstall:
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
-+	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8
- 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
- 
- tests interop-tests:	$(TARGETS)
-diff -up openssh-5.9p1/configure.ac.ldap openssh-5.9p1/configure.ac
---- openssh-5.9p1/configure.ac.ldap	2011-09-13 11:17:04.488583772 +0200
-+++ openssh-5.9p1/configure.ac	2011-09-13 11:17:05.418529375 +0200
-@@ -1433,6 +1433,106 @@ AC_ARG_WITH(authorized-keys-command,
- 	]
- )
- 
-+# Check whether user wants LDAP support
-+LDAP_MSG="no"
-+INSTALL_SSH_LDAP_HELPER=""
-+AC_ARG_WITH(ldap,
-+	[  --with-ldap[[=PATH]]      Enable LDAP pubkey support (optionally in PATH)],
-+	[
-+		if test "x$withval" != "xno" ; then
+diff -up openssh-6.0p1/ldapbody.c.ldap openssh-6.0p1/ldapbody.c
+--- openssh-6.0p1/ldapbody.c.ldap	2012-08-06 20:41:38.399454198 +0200
++++ openssh-6.0p1/ldapbody.c	2012-08-06 20:41:38.399454198 +0200
+@@ -0,0 +1,494 @@
++/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/*
++ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
 +
-+			INSTALL_SSH_LDAP_HELPER="yes"
-+			CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED"
++#include "ldapincludes.h"
++#include "log.h"
++#include "xmalloc.h"
++#include "ldapconf.h"
++#include "ldapmisc.h"
++#include "ldapbody.h"
++#include <stdio.h>
++#include <unistd.h>
 +
-+			if test "x$withval" != "xyes" ; then
-+				CPPFLAGS="$CPPFLAGS -I${withval}/include"
-+				LDFLAGS="$LDFLAGS -L${withval}/lib"
-+			fi
++#define LDAPSEARCH_FORMAT "(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)"
++#define PUBKEYATTR "sshPublicKey"
++#define LDAP_LOGFILE	"%s/ldap.%d"
 +
-+			AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support])
-+			LDAP_MSG="yes"
++static FILE *logfile = NULL;
++static LDAP *ld;
 +
-+			AC_CHECK_HEADERS(lber.h)
-+			AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate <ldap.h>))
-+			AC_CHECK_HEADERS(ldap_ssl.h)
++static char *attrs[] = {
++    PUBKEYATTR,
++    NULL
++};
 +
-+			AC_ARG_WITH(ldap-lib,
-+				[  --with-ldap-lib=type    select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]])
-+
-+			if test -z "$with_ldap_lib"; then
-+				with_ldap_lib=auto
-+			fi
-+
-+			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then
-+				AC_CHECK_LIB(lber, main, LIBS="-llber $LIBS" found_ldap_lib=yes)
-+				AC_CHECK_LIB(ldap, main, LIBS="-lldap $LIBS" found_ldap_lib=yes)
-+			fi
-+
-+			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then
-+				AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes)
-+			fi
-+
-+			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then
-+				AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes)
-+				if test -z "$found_ldap_lib"; then
-+					AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes)
-+				fi
-+				if test -z "$found_ldap_lib"; then
-+					AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes)
-+				fi
-+				if test -z "$found_ldap_lib"; then
-+					AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes)
-+				fi
-+			fi
-+
-+			if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then
-+				AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes)
-+			fi
-+
-+			if test -z "$found_ldap_lib"; then
-+				AC_MSG_ERROR(could not locate a valid LDAP library)
-+			fi
-+
-+			AC_MSG_CHECKING([for working LDAP support])
-+			AC_TRY_COMPILE(
-+				[#include <sys/types.h>
-+				 #include <ldap.h>],
-+				[(void)ldap_init(0, 0);],
-+				[AC_MSG_RESULT(yes)],
-+				[
-+				    AC_MSG_RESULT(no) 
-+					AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
-+				])
-+			AC_CHECK_FUNCS( \
-+				ldap_init \
-+				ldap_get_lderrno \
-+				ldap_set_lderrno \
-+				ldap_parse_result \
-+				ldap_memfree \
-+				ldap_controls_free \
-+				ldap_set_option \
-+				ldap_get_option \
-+				ldapssl_init \
-+				ldap_start_tls_s \
-+				ldap_pvt_tls_set_option \
-+				ldap_initialize \
-+			)
-+			AC_CHECK_FUNCS(ldap_set_rebind_proc,
-+				AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc])
-+				AC_TRY_COMPILE(
-+					[#include <lber.h>
-+					#include <ldap.h>],
-+					[ldap_set_rebind_proc(0, 0, 0);],
-+					[ac_cv_ldap_set_rebind_proc=3],
-+					[ac_cv_ldap_set_rebind_proc=2])
-+				AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc)
-+				AC_DEFINE(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc])
-+			)
-+		fi
-+	]
-+)
-+AC_SUBST(INSTALL_SSH_LDAP_HELPER)
-+
- dnl    Checks for library functions. Please keep in alphabetical order
- AC_CHECK_FUNCS([ \
- 	arc4random \
-diff -up openssh-5.9p1/ldap-helper.c.ldap openssh-5.9p1/ldap-helper.c
---- openssh-5.9p1/ldap-helper.c.ldap	2011-09-13 11:17:05.527520185 +0200
-+++ openssh-5.9p1/ldap-helper.c	2011-09-13 11:17:05.531521117 +0200
-@@ -0,0 +1,155 @@
-+/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "ldapincludes.h"
-+#include "log.h"
-+#include "misc.h"
-+#include "xmalloc.h"
-+#include "ldapconf.h"
-+#include "ldapbody.h"
-+#include <string.h>
-+#include <unistd.h>
-+
-+static int config_debug = 0;
-+int config_exclusive_config_file = 0;
-+static char *config_file_name = "/etc/ssh/ldap.conf";
-+static char *config_single_user = NULL;
-+static int config_verbose = SYSLOG_LEVEL_VERBOSE;
-+int config_warning_config_file = 0;
-+extern char *__progname;
-+
-+static void
-+usage(void)
++void
++ldap_checkconfig (void)
 +{
-+	fprintf(stderr, "usage: %s [options]\n",
-+	    __progname);
-+	fprintf(stderr, "Options:\n");
-+	fprintf(stderr, "  -d          Output the log messages to stderr.\n");
-+	fprintf(stderr, "  -e          Check the config file for unknown commands.\n");
-+	fprintf(stderr, "  -f file     Use alternate config file (default is /etc/ssh/ldap.conf).\n");
-+	fprintf(stderr, "  -s user     Do not demonize, send the user's key to stdout.\n");
-+	fprintf(stderr, "  -v          Increase verbosity of the debug output (implies -d).\n");
-+	fprintf(stderr, "  -w          Warn on unknown commands in the config file.\n");
-+	exit(1);
++#ifdef HAVE_LDAP_INITIALIZE
++		if (options.host == NULL && options.uri == NULL)
++#else
++		if (options.host == NULL)
++#endif
++		    fatal ("missing  \"host\" in config file");
 +}
 +
-+/*
-+ * Main program for the ssh pka ldap agent.
-+ */
-+
-+int
-+main(int ac, char **av)
++#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
++static int
++_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid)
 +{
-+	int opt;
-+	FILE *outfile = NULL;
-+
-+	__progname = ssh_get_progname(av[0]);
-+
-+	log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
-+
-+	/*
-+	 * Initialize option structure to indicate that no values have been
-+	 * set.
-+	 */
-+	initialize_options();
-+
-+	/* Parse command-line arguments. */
-+	while ((opt = getopt(ac, av, "def:s:vw")) != -1) {
-+		switch (opt) {
-+		case 'd':
-+			config_debug = 1;
-+			break;
-+
-+		case 'e':
-+			config_exclusive_config_file = 1;
-+			config_warning_config_file = 1;
-+			break;
-+
-+		case 'f':
-+			config_file_name = optarg;
-+			break;
-+
-+		case 's':
-+			config_single_user = optarg;
-+			outfile = fdopen (dup (fileno (stdout)), "w");
-+			break;
-+
-+		case 'v':
-+			config_debug = 1;
-+			if (config_verbose < SYSLOG_LEVEL_DEBUG3)
-+			    config_verbose++;
-+			break;
-+
-+		case 'w':
-+			config_warning_config_file = 1;
-+			break;
++	struct timeval timeout;
++	int rc;
++#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
++	LDAPMessage *result;
++#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
 +
-+		case '?':
-+		default:
-+			usage();
-+			break;
++	debug2 ("Doing LDAP rebind to %s", options.binddn);
++	if (options.ssl == SSL_START_TLS) {
++		if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) {
++			error ("ldap_starttls_s: %s", ldap_err2string (rc));
++			return LDAP_OPERATIONS_ERROR;
 +		}
 +	}
 +
-+	/* Initialize loging */
-+	log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug);
-+
-+	if (ac != optind)
-+	    fatal ("illegal extra parameter %s", av[1]);
-+
-+	/* Ensure that fds 0 and 2 are open or directed to /dev/null */
-+	if (config_debug == 0)
-+	    sanitise_stdfd();
++#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE)
++	return ldap_simple_bind_s (ld, options.binddn, options.bindpw);
++#else
++	if (ldap_simple_bind(ld, options.binddn, options.bindpw) < 0)
++	    fatal ("ldap_simple_bind %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
 +
-+	/* Read config file */
-+	read_config_file(config_file_name);
-+	fill_default_options();
-+	if (config_verbose == SYSLOG_LEVEL_DEBUG3) {
-+		debug3 ("=== Configuration ===");
-+		dump_config();
-+		debug3 ("=== *** ===");
++	timeout.tv_sec = options.bind_timelimit;
++	timeout.tv_usec = 0;
++	result = NULL;
++	if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) {
++		error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
++		ldap_msgfree (result);
++		return LDAP_OPERATIONS_ERROR;
 +	}
++	debug3 ("LDAP rebind to %s succesfull", options.binddn);
++	return rc;
++#endif
++}
++#else
 +
-+	ldap_checkconfig();
-+	ldap_do_connect();
-+
-+	if (config_single_user) {
-+		process_user (config_single_user, outfile);
-+	} else {
-+		usage();
-+		fatal ("Not yet implemented");
-+/* TODO
-+ * open unix socket a run the loop on it
-+ */
-+	}
++static int
++_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit)
++{
++	if (freeit)
++	    return LDAP_SUCCESS;
 +
-+	ldap_do_close();
-+	return 0;
++	*whop = strdup (options.binddn);
++	*credp = strdup (options.bindpw);
++	*methodp = LDAP_AUTH_SIMPLE;
++	debug2 ("Doing LDAP rebind for %s", *whop);
++	return LDAP_SUCCESS;
 +}
++#endif
 +
-+/* Ugly hack */
-+void   *buffer_get_string(Buffer *b, u_int *l) { return NULL; }
-+void    buffer_put_string(Buffer *b, const void *f, u_int l) {}
++void
++ldap_do_connect(void)
++{
++	int rc, msgid, ld_errno = 0;
++	struct timeval timeout;
++#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
++	int parserc;
++	LDAPMessage *result;
++	LDAPControl **controls;
++	int reconnect = 0;
++#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
 +
-diff -up openssh-5.9p1/ldap-helper.h.ldap openssh-5.9p1/ldap-helper.h
---- openssh-5.9p1/ldap-helper.h.ldap	2011-09-13 11:17:05.619520027 +0200
-+++ openssh-5.9p1/ldap-helper.h	2011-09-13 11:17:05.621522622 +0200
-@@ -0,0 +1,32 @@
-+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
++	debug ("LDAP do connect");
 +
-+#ifndef LDAP_HELPER_H
-+#define LDAP_HELPER_H
++retry:
++	if (reconnect) {
++		debug3 ("Reconnecting with ld_errno %d", ld_errno);
++		if (options.bind_policy == 0 ||
++		    (ld_errno != LDAP_SERVER_DOWN && ld_errno != LDAP_TIMEOUT) ||
++			reconnect > 5)
++			    fatal ("Cannot connect to LDAP server");
++	
++		if (reconnect > 1)
++			sleep (reconnect - 1);
 +
-+extern int config_exclusive_config_file;
-+extern int config_warning_config_file;
++		if (ld != NULL) {
++			ldap_unbind (ld);
++			ld = NULL;
++		}
++		logit("reconnecting to LDAP server...");
++	}
 +
-+#endif /* LDAP_HELPER_H */
-diff -up openssh-5.9p1/ldap.conf.ldap openssh-5.9p1/ldap.conf
---- openssh-5.9p1/ldap.conf.ldap	2011-09-13 11:17:05.697522387 +0200
-+++ openssh-5.9p1/ldap.conf	2011-09-13 11:17:05.699522577 +0200
-@@ -0,0 +1,88 @@
-+# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $
-+#
-+# This is the example configuration file for the OpenSSH
-+# LDAP backend
-+# 
-+# see ssh-ldap.conf(5)
-+#
++	if (ld == NULL) {
++		int rc;
++		struct timeval tv;
 +
-+# URI with your LDAP server name. This allows to use
-+# Unix Domain Sockets to connect to a local LDAP Server.
-+#uri ldap://127.0.0.1/
-+#uri ldaps://127.0.0.1/   
-+#uri ldapi://%2fvar%2frun%2fldapi_sock/
-+# Note: %2f encodes the '/' used as directory separator
++#ifdef HAVE_LDAP_SET_OPTION
++		if (options.debug > 0) {
++#ifdef LBER_OPT_LOG_PRINT_FILE
++			if (options.logdir) {
++				char *logfilename;
++				int logfilenamelen;
 +
-+# Another way to specify your LDAP server is to provide an
-+# host name and the port of our LDAP server. Host name
-+# must be resolvable without using LDAP.
-+# Multiple hosts may be specified, each separated by a 
-+# space. How long nss_ldap takes to failover depends on
-+# whether your LDAP client library supports configurable
-+# network or connect timeouts (see bind_timelimit).
-+#host 127.0.0.1
++				logfilenamelen = strlen (LDAP_LOGFILE) + strlen ("000000") + strlen (options.logdir);
++				logfilename = xmalloc (logfilenamelen);
++				snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ());
++				logfilename[logfilenamelen - 1] = 0;
++				if ((logfile = fopen (logfilename, "a")) == NULL)
++				    fatal ("cannot append to %s: %s", logfilename, strerror (errno));
++				debug3 ("LDAP debug into %s", logfilename);
++				xfree (logfilename);
++				ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, logfile);
++			}
++#endif
++			if (options.debug) {
++#ifdef LBER_OPT_DEBUG_LEVEL
++				ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &options.debug);
++#endif /* LBER_OPT_DEBUG_LEVEL */
++#ifdef LDAP_OPT_DEBUG_LEVEL
++				(void) ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &options.debug);
++#endif /* LDAP_OPT_DEBUG_LEVEL */
++				debug3 ("Set LDAP debug to %d", options.debug);
++			}
++		}
++#endif /* HAVE_LDAP_SET_OPTION */
 +
-+# The port.
-+# Optional: default is 389.
-+#port 389
++		ld = NULL;
++#ifdef HAVE_LDAPSSL_INIT
++		if (options.host != NULL) {
++			if (options.ssl_on == SSL_LDAPS) {
++				if ((rc = ldapssl_client_init (options.sslpath, NULL)) != LDAP_SUCCESS)
++				    fatal ("ldapssl_client_init %s", ldap_err2string (rc));
++				debug3 ("LDAPssl client init");
++			}
 +
-+# The distinguished name to bind to the server with.
-+# Optional: default is to bind anonymously.
-+#binddn cn=openssh_keys,dc=example,dc=org
++			if (options.ssl_on != SSL_OFF) {
++				if ((ld = ldapssl_init (options.host, options.port, TRUE)) == NULL)
++				    fatal ("ldapssl_init failed");
++				debug3 ("LDAPssl init");
++			}
++		}
++#endif /* HAVE_LDAPSSL_INIT */
 +
-+# The credentials to bind with. 
-+# Optional: default is no credential.
-+#bindpw TopSecret
++		/* continue with opening */
++		if (ld == NULL) {
++#if defined (HAVE_LDAP_START_TLS_S) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS))
++			/* Some global TLS-specific options need to be set before we create our
++			 * session context, so we set them here. */
 +
-+# The distinguished name of the search base.
-+#base dc=example,dc=org
++#ifdef LDAP_OPT_X_TLS_RANDOM_FILE
++			/* rand file */
++			if (options.tls_randfile != NULL) {
++				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
++				    options.tls_randfile)) != LDAP_SUCCESS)
++					fatal ("ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE): %s",
++					    ldap_err2string (rc));
++				debug3 ("Set TLS random file %s", options.tls_randfile);
++			}
++#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */
 +
-+# The LDAP version to use (defaults to 3
-+# if supported by client library)
-+#ldap_version 3
++			/* ca cert file */
++			if (options.tls_cacertfile != NULL) {
++				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
++				    options.tls_cacertfile)) != LDAP_SUCCESS)
++					error ("ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE): %s",
++					    ldap_err2string (rc));
++				debug3 ("Set TLS CA cert file %s ", options.tls_cacertfile);
++			}
 +
-+# The search scope.
-+#scope sub
-+#scope one
-+#scope base
++			/* ca cert directory */
++			if (options.tls_cacertdir != NULL) {
++				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
++				    options.tls_cacertdir)) != LDAP_SUCCESS)
++					fatal ("ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR): %s",
++					    ldap_err2string (rc));
++				debug3 ("Set TLS CA cert dir %s ", options.tls_cacertdir);
++			}
 +
-+# Search timelimit
-+#timelimit 30
++			/* require cert? */
++			if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
++			    &options.tls_checkpeer)) != LDAP_SUCCESS)
++				fatal ("ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT): %s",
++				    ldap_err2string (rc));
++			debug3 ("Set TLS check peer to %d ", options.tls_checkpeer);
 +
-+# Bind/connect timelimit
-+#bind_timelimit 30
++			/* set cipher suite, certificate and private key: */
++			if (options.tls_ciphers != NULL) {
++				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
++				    options.tls_ciphers)) != LDAP_SUCCESS)
++					fatal ("ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE): %s",
++					    ldap_err2string (rc));
++				debug3 ("Set TLS ciphers to %s ", options.tls_ciphers);
++			}
 +
-+# Reconnect policy: hard (default) will retry connecting to
-+# the software with exponential backoff, soft will fail
-+# immediately.
-+#bind_policy hard
++			/* cert file */
++			if (options.tls_cert != NULL) {
++				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
++				    options.tls_cert)) != LDAP_SUCCESS)
++					fatal ("ldap_set_option(LDAP_OPT_X_TLS_CERTFILE): %s",
++					    ldap_err2string (rc));
++				debug3 ("Set TLS cert file %s ", options.tls_cert);
++			}
 +
-+# SSL setup, may be implied by URI also.
-+#ssl no
-+#ssl on
-+#ssl start_tls
++			/* key file */
++			if (options.tls_key != NULL) {
++				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
++				    options.tls_key)) != LDAP_SUCCESS)
++					fatal ("ldap_set_option(LDAP_OPT_X_TLS_KEYFILE): %s",
++					    ldap_err2string (rc));
++				debug3 ("Set TLS key file %s ", options.tls_key);
++			}
++#endif
++#ifdef HAVE_LDAP_INITIALIZE
++			if (options.uri != NULL) {
++				if ((rc = ldap_initialize (&ld, options.uri)) != LDAP_SUCCESS)
++					fatal ("ldap_initialize %s", ldap_err2string (rc));
++				debug3 ("LDAP initialize %s", options.uri);
++			}
++	}
++#endif /* HAVE_LDAP_INTITIALIZE */
 +
-+# OpenLDAP SSL options
-+# Require and verify server certificate (yes/no)
-+# Default is to use libldap's default behavior, which can be configured in
-+# /etc/openldap/ldap.conf using the TLS_REQCERT setting.  The default for
-+# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes".
-+#tls_checkpeer hard
++		/* continue with opening */
++		if ((ld == NULL) && (options.host != NULL)) {
++#ifdef HAVE_LDAP_INIT
++			if ((ld = ldap_init (options.host, options.port)) == NULL)
++			    fatal ("ldap_init failed");
++			debug3 ("LDAP init %s:%d", options.host, options.port);
++#else
++			if ((ld = ldap_open (options.host, options.port)) == NULL)
++			    fatal ("ldap_open failed");
++			debug3 ("LDAP open %s:%d", options.host, options.port);
++#endif /* HAVE_LDAP_INIT */
++		}
 +
-+# CA certificates for server certificate verification
-+# At least one of these are required if tls_checkpeer is "yes"
-+#tls_cacertfile /etc/ssl/ca.cert
-+#tls_cacertdir /etc/pki/tls/certs
++		if (ld == NULL)
++			fatal ("no way to open ldap");
 +
-+# Seed the PRNG if /dev/urandom is not provided
-+#tls_randfile /var/run/egd-pool
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
++		if (options.ssl == SSL_LDAPS) {
++			if ((rc = ldap_set_option (ld, LDAP_OPT_X_TLS, &options.tls_checkpeer)) != LDAP_SUCCESS)
++				fatal ("ldap_set_option(LDAP_OPT_X_TLS) %s", ldap_err2string (rc));
++			debug3 ("LDAP set LDAP_OPT_X_TLS_%d", options.tls_checkpeer);
++		}
++#endif /* LDAP_OPT_X_TLS */
 +
-+# SSL cipher suite
-+# See man ciphers for syntax
-+#tls_ciphers TLSv1
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION)
++		(void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION,
++		    &options.ldap_version);
++#else
++		ld->ld_version = options.ldap_version;
++#endif
++		debug3 ("LDAP set version to %d", options.ldap_version);
 +
-+# Client certificate and key
-+# Use these, if your server requires client authentication.
-+#tls_cert
-+#tls_key
++#if LDAP_SET_REBIND_PROC_ARGS == 3
++		ldap_set_rebind_proc (ld, _rebind_proc, NULL);
++#elif LDAP_SET_REBIND_PROC_ARGS == 2
++		ldap_set_rebind_proc (ld, _rebind_proc);
++#else
++#warning unknown LDAP_SET_REBIND_PROC_ARGS
++#endif
++		debug3 ("LDAP set rebind proc");
 +
-diff -up openssh-5.9p1/ldapbody.c.ldap openssh-5.9p1/ldapbody.c
---- openssh-5.9p1/ldapbody.c.ldap	2011-09-13 11:17:05.782571211 +0200
-+++ openssh-5.9p1/ldapbody.c	2011-09-13 11:17:05.785584958 +0200
-@@ -0,0 +1,494 @@
-+/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DEREF)
++		(void) ldap_set_option (ld, LDAP_OPT_DEREF, &options.deref);
++#else
++		ld->ld_deref = options.deref;
++#endif
++		debug3 ("LDAP set deref to %d", options.deref);
 +
-+#include "ldapincludes.h"
-+#include "log.h"
-+#include "xmalloc.h"
-+#include "ldapconf.h"
-+#include "ldapmisc.h"
-+#include "ldapbody.h"
-+#include <stdio.h>
-+#include <unistd.h>
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_TIMELIMIT)
++		(void) ldap_set_option (ld, LDAP_OPT_TIMELIMIT,
++		    &options.timelimit);
++#else
++		ld->ld_timelimit = options.timelimit;
++#endif
++		debug3 ("LDAP set timelimit to %d", options.timelimit);
 +
-+#define LDAPSEARCH_FORMAT "(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)"
-+#define PUBKEYATTR "sshPublicKey"
-+#define LDAP_LOGFILE	"%s/ldap.%d"
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_X_OPT_CONNECT_TIMEOUT)
++		/*
++		 * This is a new option in the Netscape SDK which sets 
++		 * the TCP connect timeout. For want of a better value,
++		 * we use the bind_timelimit to control this.
++		 */
++		timeout = options.bind_timelimit * 1000;
++		(void) ldap_set_option (ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout);
++		debug3 ("LDAP set opt connect timeout to %d", timeout);
++#endif
 +
-+static FILE *logfile = NULL;
-+static LDAP *ld;
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
++		tv.tv_sec = options.bind_timelimit;
++		tv.tv_usec = 0;
++		(void) ldap_set_option (ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
++		debug3 ("LDAP set opt network timeout to %ld.0", tv.tv_sec);
++#endif
 +
-+static char *attrs[] = {
-+    PUBKEYATTR,
-+    NULL
-+};
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_REFERRALS)
++		(void) ldap_set_option (ld, LDAP_OPT_REFERRALS,
++		    options.referrals ? LDAP_OPT_ON : LDAP_OPT_OFF);
++		debug3 ("LDAP set referrals to %d", options.referrals);
++#endif
 +
-+void
-+ldap_checkconfig (void)
-+{
-+#ifdef HAVE_LDAP_INITIALIZE
-+		if (options.host == NULL && options.uri == NULL)
-+#else
-+		if (options.host == NULL)
++#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_RESTART)
++		(void) ldap_set_option (ld, LDAP_OPT_RESTART,
++		    options.restart ? LDAP_OPT_ON : LDAP_OPT_OFF);
++		debug3 ("LDAP set restart to %d", options.restart);
 +#endif
-+		    fatal ("missing  \"host\" in config file");
-+}
 +
-+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-+static int
-+_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid)
-+{
-+	struct timeval timeout;
-+	int rc;
-+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
-+	LDAPMessage *result;
-+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
++#ifdef HAVE_LDAP_START_TLS_S
++		if (options.ssl == SSL_START_TLS) {
++			int version;
 +
-+	debug2 ("Doing LDAP rebind to %s", options.binddn);
-+	if (options.ssl == SSL_START_TLS) {
-+		if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) {
-+			error ("ldap_starttls_s: %s", ldap_err2string (rc));
-+			return LDAP_OPERATIONS_ERROR;
++			if (ldap_get_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)
++			    == LDAP_SUCCESS) {
++				if (version < LDAP_VERSION3) {
++					version = LDAP_VERSION3;
++					(void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION,
++					    &version);
++					debug3 ("LDAP set version to %d", version);
++				}
++			}
++
++			if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
++			    fatal ("ldap_starttls_s: %s", ldap_err2string (rc));
++			debug3 ("LDAP start TLS");
 +		}
++#endif /* HAVE_LDAP_START_TLS_S */
 +	}
 +
-+#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE)
-+	return ldap_simple_bind_s (ld, options.binddn, options.bindpw);
-+#else
-+	if (ldap_simple_bind(ld, options.binddn, options.bindpw) < 0)
-+	    fatal ("ldap_simple_bind %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
++	if ((msgid = ldap_simple_bind (ld, options.binddn,
++	    options.bindpw)) == -1) {
++		ld_errno = ldap_get_lderrno (ld, 0, 0);
++
++		error ("ldap_simple_bind %s", ldap_err2string (ld_errno));
++		reconnect++;
++		goto retry;
++	}
++	debug3 ("LDAP simple bind (%s)", options.binddn);
 +
 +	timeout.tv_sec = options.bind_timelimit;
 +	timeout.tv_usec = 0;
-+	result = NULL;
 +	if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) {
-+		error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
-+		ldap_msgfree (result);
-+		return LDAP_OPERATIONS_ERROR;
++		ld_errno = ldap_get_lderrno (ld, 0, 0);
++
++		error ("ldap_result %s", ldap_err2string (ld_errno));
++		reconnect++;
++		goto retry;
 +	}
-+	debug3 ("LDAP rebind to %s succesfull", options.binddn);
-+	return rc;
-+#endif
-+}
-+#else
++	debug3 ("LDAP result in time");
 +
-+static int
-+_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit)
-+{
-+	if (freeit)
-+	    return LDAP_SUCCESS;
++#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
++	controls = NULL;
++	if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, TRUE)) != LDAP_SUCCESS)
++	    fatal ("ldap_parse_result %s", ldap_err2string (parserc));
++	debug3 ("LDAP parse result OK");
 +
-+	*whop = strdup (options.binddn);
-+	*credp = strdup (options.bindpw);
-+	*methodp = LDAP_AUTH_SIMPLE;
-+	debug2 ("Doing LDAP rebind for %s", *whop);
-+	return LDAP_SUCCESS;
-+}
++	if (controls != NULL) {
++		ldap_controls_free (controls);
++	}
++#else
++	rc = ldap_result2error (session->ld, result, TRUE);
 +#endif
++	if (rc != LDAP_SUCCESS)
++	    fatal ("error trying to bind as user \"%s\" (%s)",
++		options.binddn, ldap_err2string (rc));
++
++	debug2 ("LDAP do connect OK");
++}
 +
 +void
-+ldap_do_connect(void)
++process_user (const char *user, FILE *output)
 +{
-+	int rc, msgid, ld_errno = 0;
++	LDAPMessage *res, *e;
++	char *buffer;
++	int bufflen, rc, i;
 +	struct timeval timeout;
-+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
-+	int parserc;
-+	LDAPMessage *result;
-+	LDAPControl **controls;
-+	int reconnect = 0;
-+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */
 +
-+	debug ("LDAP do connect");
++	debug ("LDAP process user");
 +
-+retry:
-+	if (reconnect) {
-+		debug3 ("Reconnecting with ld_errno %d", ld_errno);
-+		if (options.bind_policy == 0 ||
-+		    (ld_errno != LDAP_SERVER_DOWN && ld_errno != LDAP_TIMEOUT) ||
-+			reconnect > 5)
-+			    fatal ("Cannot connect to LDAP server");
-+	
-+		if (reconnect > 1)
-+			sleep (reconnect - 1);
++	/* quick check for attempts to be evil */
++	if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
++	    (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) {
++		logit ("illegal user name %s not processed", user);
++		return;
++	}
 +
-+		if (ld != NULL) {
-+			ldap_unbind (ld);
-+			ld = NULL;
-+		}
-+		logit("reconnecting to LDAP server...");
++	/* build  filter for LDAP request */
++	bufflen = strlen (LDAPSEARCH_FORMAT) + strlen (user);
++	if (options.ssh_filter != NULL)
++	    bufflen += strlen (options.ssh_filter);
++	buffer = xmalloc (bufflen);
++	snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL);
++	buffer[bufflen - 1] = 0;
++
++	debug3 ("LDAP search scope = %d %s", options.scope, buffer);
++
++	timeout.tv_sec = options.timelimit;
++	timeout.tv_usec = 0;
++	if ((rc = ldap_search_st(ld, options.base, options.scope, buffer, attrs, 0, &timeout, &res)) != LDAP_SUCCESS) {
++		error ("ldap_search_st(): %s", ldap_err2string (rc));
++		xfree (buffer);
++		return;
 +	}
 +
-+	if (ld == NULL) {
-+		int rc;
-+		struct timeval tv;
++	/* free */
++	xfree (buffer);
 +
-+#ifdef HAVE_LDAP_SET_OPTION
-+		if (options.debug > 0) {
-+#ifdef LBER_OPT_LOG_PRINT_FILE
-+			if (options.logdir) {
-+				char *logfilename;
-+				int logfilenamelen;
++	for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) {
++		int num;
++		struct berval **keys;
 +
-+				logfilenamelen = strlen (LDAP_LOGFILE) + strlen ("000000") + strlen (options.logdir);
-+				logfilename = xmalloc (logfilenamelen);
-+				snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ());
-+				logfilename[logfilenamelen - 1] = 0;
-+				if ((logfile = fopen (logfilename, "a")) == NULL)
-+				    fatal ("cannot append to %s: %s", logfilename, strerror (errno));
-+				debug3 ("LDAP debug into %s", logfilename);
-+				xfree (logfilename);
-+				ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, logfile);
-+			}
-+#endif
-+			if (options.debug) {
-+#ifdef LBER_OPT_DEBUG_LEVEL
-+				ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &options.debug);
-+#endif /* LBER_OPT_DEBUG_LEVEL */
-+#ifdef LDAP_OPT_DEBUG_LEVEL
-+				(void) ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &options.debug);
-+#endif /* LDAP_OPT_DEBUG_LEVEL */
-+				debug3 ("Set LDAP debug to %d", options.debug);
-+			}
-+		}
-+#endif /* HAVE_LDAP_SET_OPTION */
++		keys = ldap_get_values_len(ld, e, PUBKEYATTR);
++		num = ldap_count_values_len(keys);
++		for (i = 0 ; i < num ; i++) {
++			char *cp; //, *options = NULL;
 +
-+		ld = NULL;
-+#ifdef HAVE_LDAPSSL_INIT
-+		if (options.host != NULL) {
-+			if (options.ssl_on == SSL_LDAPS) {
-+				if ((rc = ldapssl_client_init (options.sslpath, NULL)) != LDAP_SUCCESS)
-+				    fatal ("ldapssl_client_init %s", ldap_err2string (rc));
-+				debug3 ("LDAPssl client init");
-+			}
++			for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++);
++			if (!*cp || *cp == '\n' || *cp == '#')
++			    continue;
 +
-+			if (options.ssl_on != SSL_OFF) {
-+				if ((ld = ldapssl_init (options.host, options.port, TRUE)) == NULL)
-+				    fatal ("ldapssl_init failed");
-+				debug3 ("LDAPssl init");
-+			}
++			/* We have found the desired key. */
++			fprintf (output, "%s\n", keys[i]->bv_val);
 +		}
-+#endif /* HAVE_LDAPSSL_INIT */
 +
-+		/* continue with opening */
-+		if (ld == NULL) {
-+#if defined (HAVE_LDAP_START_TLS_S) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS))
-+			/* Some global TLS-specific options need to be set before we create our
-+			 * session context, so we set them here. */
++		ldap_value_free_len(keys);
++	}
 +
-+#ifdef LDAP_OPT_X_TLS_RANDOM_FILE
-+			/* rand file */
-+			if (options.tls_randfile != NULL) {
-+				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
-+				    options.tls_randfile)) != LDAP_SUCCESS)
-+					fatal ("ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE): %s",
-+					    ldap_err2string (rc));
-+				debug3 ("Set TLS random file %s", options.tls_randfile);
-+			}
-+#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */
++	ldap_msgfree(res);
++	debug2 ("LDAP process user finished");
++}
 +
-+			/* ca cert file */
-+			if (options.tls_cacertfile != NULL) {
-+				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
-+				    options.tls_cacertfile)) != LDAP_SUCCESS)
-+					error ("ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE): %s",
-+					    ldap_err2string (rc));
-+				debug3 ("Set TLS CA cert file %s ", options.tls_cacertfile);
-+			}
++void
++ldap_do_close(void)
++{
++	int rc;
 +
-+			/* ca cert directory */
-+			if (options.tls_cacertdir != NULL) {
-+				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
-+				    options.tls_cacertdir)) != LDAP_SUCCESS)
-+					fatal ("ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR): %s",
-+					    ldap_err2string (rc));
-+				debug3 ("Set TLS CA cert dir %s ", options.tls_cacertdir);
-+			}
++	debug ("LDAP do close");
++	if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS)
++	    fatal ("ldap_unbind_ext: %s",
++                                    ldap_err2string (rc));
 +
-+			/* require cert? */
-+			if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
-+			    &options.tls_checkpeer)) != LDAP_SUCCESS)
-+				fatal ("ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT): %s",
-+				    ldap_err2string (rc));
-+			debug3 ("Set TLS check peer to %d ", options.tls_checkpeer);
++	ld = NULL;
++	debug2 ("LDAP do close OK");
++	return;
++}
++
+diff -up openssh-6.0p1/ldapbody.h.ldap openssh-6.0p1/ldapbody.h
+--- openssh-6.0p1/ldapbody.h.ldap	2012-08-06 20:41:38.399454198 +0200
++++ openssh-6.0p1/ldapbody.h	2012-08-06 20:41:38.400454194 +0200
+@@ -0,0 +1,37 @@
++/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/*
++ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
 +
-+			/* set cipher suite, certificate and private key: */
-+			if (options.tls_ciphers != NULL) {
-+				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
-+				    options.tls_ciphers)) != LDAP_SUCCESS)
-+					fatal ("ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE): %s",
-+					    ldap_err2string (rc));
-+				debug3 ("Set TLS ciphers to %s ", options.tls_ciphers);
-+			}
++#ifndef LDAPBODY_H
++#define LDAPBODY_H
 +
-+			/* cert file */
-+			if (options.tls_cert != NULL) {
-+				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
-+				    options.tls_cert)) != LDAP_SUCCESS)
-+					fatal ("ldap_set_option(LDAP_OPT_X_TLS_CERTFILE): %s",
-+					    ldap_err2string (rc));
-+				debug3 ("Set TLS cert file %s ", options.tls_cert);
-+			}
++#include <stdio.h>
 +
-+			/* key file */
-+			if (options.tls_key != NULL) {
-+				if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
-+				    options.tls_key)) != LDAP_SUCCESS)
-+					fatal ("ldap_set_option(LDAP_OPT_X_TLS_KEYFILE): %s",
-+					    ldap_err2string (rc));
-+				debug3 ("Set TLS key file %s ", options.tls_key);
-+			}
-+#endif
-+#ifdef HAVE_LDAP_INITIALIZE
-+			if (options.uri != NULL) {
-+				if ((rc = ldap_initialize (&ld, options.uri)) != LDAP_SUCCESS)
-+					fatal ("ldap_initialize %s", ldap_err2string (rc));
-+				debug3 ("LDAP initialize %s", options.uri);
-+			}
-+	}
-+#endif /* HAVE_LDAP_INTITIALIZE */
++void ldap_checkconfig(void);
++void ldap_do_connect(void);
++void process_user(const char *, FILE *);
++void ldap_do_close(void);
 +
-+		/* continue with opening */
-+		if ((ld == NULL) && (options.host != NULL)) {
-+#ifdef HAVE_LDAP_INIT
-+			if ((ld = ldap_init (options.host, options.port)) == NULL)
-+			    fatal ("ldap_init failed");
-+			debug3 ("LDAP init %s:%d", options.host, options.port);
-+#else
-+			if ((ld = ldap_open (options.host, options.port)) == NULL)
-+			    fatal ("ldap_open failed");
-+			debug3 ("LDAP open %s:%d", options.host, options.port);
-+#endif /* HAVE_LDAP_INIT */
-+		}
++#endif /* LDAPBODY_H */
 +
-+		if (ld == NULL)
-+			fatal ("no way to open ldap");
+diff -up openssh-6.0p1/ldapconf.c.ldap openssh-6.0p1/ldapconf.c
+--- openssh-6.0p1/ldapconf.c.ldap	2012-08-06 20:41:38.400454194 +0200
++++ openssh-6.0p1/ldapconf.c	2012-08-06 20:41:38.400454194 +0200
+@@ -0,0 +1,682 @@
++/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/*
++ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
-+		if (options.ssl == SSL_LDAPS) {
-+			if ((rc = ldap_set_option (ld, LDAP_OPT_X_TLS, &options.tls_checkpeer)) != LDAP_SUCCESS)
-+				fatal ("ldap_set_option(LDAP_OPT_X_TLS) %s", ldap_err2string (rc));
-+			debug3 ("LDAP set LDAP_OPT_X_TLS_%d", options.tls_checkpeer);
-+		}
-+#endif /* LDAP_OPT_X_TLS */
++#include "ldapincludes.h"
++#include "ldap-helper.h"
++#include "log.h"
++#include "misc.h"
++#include "xmalloc.h"
++#include "ldapconf.h"
++#include <unistd.h>
++#include <string.h>
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION)
-+		(void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION,
-+		    &options.ldap_version);
-+#else
-+		ld->ld_version = options.ldap_version;
-+#endif
-+		debug3 ("LDAP set version to %d", options.ldap_version);
++/* Keyword tokens. */
 +
-+#if LDAP_SET_REBIND_PROC_ARGS == 3
-+		ldap_set_rebind_proc (ld, _rebind_proc, NULL);
-+#elif LDAP_SET_REBIND_PROC_ARGS == 2
-+		ldap_set_rebind_proc (ld, _rebind_proc);
-+#else
-+#warning unknown LDAP_SET_REBIND_PROC_ARGS
-+#endif
-+		debug3 ("LDAP set rebind proc");
++typedef enum {
++	lBadOption,
++	lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN,
++	lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit,
++	lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals,
++	lRestart, lTLS_CheckPeer, lTLS_CaCertFile,
++	lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key,
++	lTLS_RandFile, lLogDir, lDebug, lSSH_Filter,
++	lDeprecated, lUnsupported
++} OpCodes;
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DEREF)
-+		(void) ldap_set_option (ld, LDAP_OPT_DEREF, &options.deref);
-+#else
-+		ld->ld_deref = options.deref;
-+#endif
-+		debug3 ("LDAP set deref to %d", options.deref);
++/* Textual representations of the tokens. */
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_TIMELIMIT)
-+		(void) ldap_set_option (ld, LDAP_OPT_TIMELIMIT,
-+		    &options.timelimit);
-+#else
-+		ld->ld_timelimit = options.timelimit;
-+#endif
-+		debug3 ("LDAP set timelimit to %d", options.timelimit);
++static struct {
++	const char *name;
++	OpCodes opcode;
++} keywords[] = {
++	{ "URI", lURI },
++	{ "Base", lBase },
++	{ "BindDN", lBindDN },
++	{ "BindPW", lBindPW },
++	{ "RootBindDN", lRootBindDN },
++	{ "Host", lHost },
++	{ "Port", lPort },
++	{ "Scope", lScope },
++	{ "Deref", lDeref },
++	{ "TimeLimit", lTimeLimit },
++	{ "TimeOut", lTimeLimit },
++	{ "Bind_Timelimit", lBind_TimeLimit },
++	{ "Network_TimeOut", lBind_TimeLimit },
++/*
++ * Todo
++ * SIZELIMIT
++ */
++	{ "Ldap_Version", lLdap_Version },
++	{ "Version", lLdap_Version },
++	{ "Bind_Policy", lBind_Policy },
++	{ "SSLPath", lSSLPath },
++	{ "SSL", lSSL },
++	{ "Referrals", lReferrals },
++	{ "Restart", lRestart },
++	{ "TLS_CheckPeer", lTLS_CheckPeer },
++	{ "TLS_ReqCert", lTLS_CheckPeer },
++	{ "TLS_CaCertFile", lTLS_CaCertFile },
++	{ "TLS_CaCert", lTLS_CaCertFile },
++	{ "TLS_CaCertDir", lTLS_CaCertDir },
++	{ "TLS_Ciphers", lTLS_Ciphers },
++	{ "TLS_Cipher_Suite", lTLS_Ciphers },
++	{ "TLS_Cert", lTLS_Cert },
++	{ "TLS_Certificate", lTLS_Cert },
++	{ "TLS_Key", lTLS_Key },
++	{ "TLS_RandFile", lTLS_RandFile },
++/*
++ * Todo
++ * TLS_CRLCHECK
++ * TLS_CRLFILE
++ */
++	{ "LogDir", lLogDir },
++	{ "Debug", lDebug },
++	{ "SSH_Filter", lSSH_Filter },
++	{ NULL, lBadOption }
++};
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_X_OPT_CONNECT_TIMEOUT)
-+		/*
-+		 * This is a new option in the Netscape SDK which sets 
-+		 * the TCP connect timeout. For want of a better value,
-+		 * we use the bind_timelimit to control this.
-+		 */
-+		timeout = options.bind_timelimit * 1000;
-+		(void) ldap_set_option (ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout);
-+		debug3 ("LDAP set opt connect timeout to %d", timeout);
-+#endif
++/* Configuration ptions. */
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
-+		tv.tv_sec = options.bind_timelimit;
-+		tv.tv_usec = 0;
-+		(void) ldap_set_option (ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
-+		debug3 ("LDAP set opt network timeout to %ld.0", tv.tv_sec);
-+#endif
++Options options;
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_REFERRALS)
-+		(void) ldap_set_option (ld, LDAP_OPT_REFERRALS,
-+		    options.referrals ? LDAP_OPT_ON : LDAP_OPT_OFF);
-+		debug3 ("LDAP set referrals to %d", options.referrals);
-+#endif
++/*
++ * Returns the number of the token pointed to by cp or oBadOption.
++ */
 +
-+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_RESTART)
-+		(void) ldap_set_option (ld, LDAP_OPT_RESTART,
-+		    options.restart ? LDAP_OPT_ON : LDAP_OPT_OFF);
-+		debug3 ("LDAP set restart to %d", options.restart);
-+#endif
++static OpCodes
++parse_token(const char *cp, const char *filename, int linenum)
++{
++	u_int i;
 +
-+#ifdef HAVE_LDAP_START_TLS_S
-+		if (options.ssl == SSL_START_TLS) {
-+			int version;
++	for (i = 0; keywords[i].name; i++)
++		if (strcasecmp(cp, keywords[i].name) == 0)
++			return keywords[i].opcode;
 +
-+			if (ldap_get_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)
-+			    == LDAP_SUCCESS) {
-+				if (version < LDAP_VERSION3) {
-+					version = LDAP_VERSION3;
-+					(void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION,
-+					    &version);
-+					debug3 ("LDAP set version to %d", version);
-+				}
-+			}
++	if (config_warning_config_file) 
++	    logit("%s: line %d: Bad configuration option: %s",
++		filename, linenum, cp);
++	return lBadOption;
++}
 +
-+			if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
-+			    fatal ("ldap_starttls_s: %s", ldap_err2string (rc));
-+			debug3 ("LDAP start TLS");
-+		}
-+#endif /* HAVE_LDAP_START_TLS_S */
-+	}
++/*
++ * Processes a single option line as used in the configuration files. This
++ * only sets those values that have not already been set.
++ */
++#define WHITESPACE " \t\r\n"
 +
-+	if ((msgid = ldap_simple_bind (ld, options.binddn,
-+	    options.bindpw)) == -1) {
-+		ld_errno = ldap_get_lderrno (ld, 0, 0);
++static int
++process_config_line(char *line, const char *filename, int linenum)
++{
++	char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg;
++	char *rootbinddn = NULL;
++	int opcode, *intptr, value;
++	size_t len;
 +
-+		error ("ldap_simple_bind %s", ldap_err2string (ld_errno));
-+		reconnect++;
-+		goto retry;
++	/* Strip trailing whitespace */
++	for (len = strlen(line) - 1; len > 0; len--) {
++		if (strchr(WHITESPACE, line[len]) == NULL)
++			break;
++		line[len] = '\0';
 +	}
-+	debug3 ("LDAP simple bind (%s)", options.binddn);
 +
-+	timeout.tv_sec = options.bind_timelimit;
-+	timeout.tv_usec = 0;
-+	if ((rc = ldap_result (ld, msgid, FALSE, &timeout, &result)) < 1) {
-+		ld_errno = ldap_get_lderrno (ld, 0, 0);
++	s = line;
++	/* Get the keyword. (Each line is supposed to begin with a keyword). */
++	if ((keyword = strdelim(&s)) == NULL)
++		return 0;
++	/* Ignore leading whitespace. */
++	if (*keyword == '\0')
++		keyword = strdelim(&s);
++	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
++		return 0;
 +
-+		error ("ldap_result %s", ldap_err2string (ld_errno));
-+		reconnect++;
-+		goto retry;
-+	}
-+	debug3 ("LDAP result in time");
++	opcode = parse_token(keyword, filename, linenum);
 +
-+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE)
-+	controls = NULL;
-+	if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, TRUE)) != LDAP_SUCCESS)
-+	    fatal ("ldap_parse_result %s", ldap_err2string (parserc));
-+	debug3 ("LDAP parse result OK");
++	switch (opcode) {
++	case lBadOption:
++		/* don't panic, but count bad options */
++		return -1;
++		/* NOTREACHED */
 +
-+	if (controls != NULL) {
-+		ldap_controls_free (controls);
-+	}
-+#else
-+	rc = ldap_result2error (session->ld, result, TRUE);
-+#endif
-+	if (rc != LDAP_SUCCESS)
-+	    fatal ("error trying to bind as user \"%s\" (%s)",
-+		options.binddn, ldap_err2string (rc));
++	case lHost:
++		xstringptr = &options.host;
++parse_xstring:
++		if (!s || *s == '\0')
++		    fatal("%s line %d: missing dn",filename,linenum);
++		if (*xstringptr == NULL)
++		    *xstringptr = xstrdup(s);
++		return 0;
 +
-+	debug2 ("LDAP do connect OK");
-+}
++	case lURI:
++		xstringptr = &options.uri;
++		goto parse_xstring;
 +
-+void
-+process_user (const char *user, FILE *output)
-+{
-+	LDAPMessage *res, *e;
-+	char *buffer;
-+	int bufflen, rc, i;
-+	struct timeval timeout;
++	case lBase:
++		xstringptr = &options.base;
++		goto parse_xstring;
 +
-+	debug ("LDAP process user");
++	case lBindDN:
++		xstringptr = &options.binddn;
++		goto parse_xstring;
 +
-+	/* quick check for attempts to be evil */
-+	if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
-+	    (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) {
-+		logit ("illegal user name %s not processed", user);
-+		return;
-+	}
++	case lBindPW:
++		charptr = &options.bindpw;
++parse_string:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (*charptr == NULL)
++			*charptr = xstrdup(arg);
++		break;
 +
-+	/* build  filter for LDAP request */
-+	bufflen = strlen (LDAPSEARCH_FORMAT) + strlen (user);
-+	if (options.ssh_filter != NULL)
-+	    bufflen += strlen (options.ssh_filter);
-+	buffer = xmalloc (bufflen);
-+	snprintf(buffer, bufflen, LDAPSEARCH_FORMAT, user, (options.ssh_filter != NULL) ? options.ssh_filter : NULL);
-+	buffer[bufflen - 1] = 0;
++	case lRootBindDN:
++		xstringptr = &rootbinddn;
++		goto parse_xstring;
 +
-+	debug3 ("LDAP search scope = %d %s", options.scope, buffer);
++	case lScope:
++		intptr = &options.scope;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing sub/one/base argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcasecmp (arg, "sub") == 0 || strcasecmp (arg, "subtree") == 0)
++			value = LDAP_SCOPE_SUBTREE;
++		else if (strcasecmp (arg, "one") == 0)
++			value = LDAP_SCOPE_ONELEVEL;
++		else if (strcasecmp (arg, "base") == 0)
++			value = LDAP_SCOPE_BASE;
++		else
++			fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
 +
-+	timeout.tv_sec = options.timelimit;
-+	timeout.tv_usec = 0;
-+	if ((rc = ldap_search_st(ld, options.base, options.scope, buffer, attrs, 0, &timeout, &res)) != LDAP_SUCCESS) {
-+		error ("ldap_search_st(): %s", ldap_err2string (rc));
-+		xfree (buffer);
-+		return;
-+	}
++	case lDeref:
++		intptr = &options.scope;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing never/searching/finding/always argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (!strcasecmp (arg, "never"))
++			value = LDAP_DEREF_NEVER;
++		else if (!strcasecmp (arg, "searching"))
++			value = LDAP_DEREF_SEARCHING;
++		else if (!strcasecmp (arg, "finding"))
++			value = LDAP_DEREF_FINDING;
++		else if (!strcasecmp (arg, "always"))
++			value = LDAP_DEREF_ALWAYS;
++		else
++			fatal("%.200s line %d: Bad never/searching/finding/always argument.", filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
 +
-+	/* free */
-+	xfree (buffer);
++	case lPort:
++		intptr = &options.port;
++parse_int:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (arg[0] < '0' || arg[0] > '9')
++			fatal("%.200s line %d: Bad number.", filename, linenum);
 +
-+	for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) {
-+		int num;
-+		struct berval **keys;
++		/* Octal, decimal, or hex format? */
++		value = strtol(arg, &endofnumber, 0);
++		if (arg == endofnumber)
++			fatal("%.200s line %d: Bad number.", filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
 +
-+		keys = ldap_get_values_len(ld, e, PUBKEYATTR);
-+		num = ldap_count_values_len(keys);
-+		for (i = 0 ; i < num ; i++) {
-+			char *cp; //, *options = NULL;
++	case lTimeLimit:
++		intptr = &options.timelimit;
++parse_time:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: missing time value.",
++			    filename, linenum);
++		if ((value = convtime(arg)) == -1)
++			fatal("%s line %d: invalid time value.",
++			    filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
 +
-+			for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++);
-+			if (!*cp || *cp == '\n' || *cp == '#')
-+			    continue;
++	case lBind_TimeLimit:
++		intptr = &options.bind_timelimit;
++		goto parse_time;
 +
-+			/* We have found the desired key. */
-+			fprintf (output, "%s\n", keys[i]->bv_val);
-+		}
++	case lLdap_Version:
++		intptr = &options.ldap_version;
++		goto parse_int;
 +
-+		ldap_value_free_len(keys);
-+	}
++	case lBind_Policy:
++		intptr = &options.bind_policy;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing soft/hard argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 0)
++			value = 1;
++		else if (strcasecmp(arg, "soft") == 0)
++			value = 0;
++		else
++			fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum);
++		if (*intptr == -1)
++		break;
 +
-+	ldap_msgfree(res);
-+	debug2 ("LDAP process user finished");
-+}
++	case lSSLPath:
++		charptr = &options.sslpath;
++		goto parse_string;
 +
-+void
-+ldap_do_close(void)
-+{
-+	int rc;
++	case lSSL:
++		intptr = &options.ssl;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing yes/no/start_tls argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
++			value = SSL_LDAPS;
++		else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
++			value = SSL_OFF;
++		else if (!strcasecmp (arg, "start_tls"))
++			value = SSL_START_TLS;
++		else
++			fatal("%.200s line %d: Bad yes/no/start_tls argument.", filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
++
++	case lReferrals:
++		intptr = &options.referrals;
++parse_flag:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
++			value = 1;
++		else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
++			value = 0;
++		else
++			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
 +
-+	debug ("LDAP do close");
-+	if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS)
-+	    fatal ("ldap_unbind_ext: %s",
-+                                    ldap_err2string (rc));
++	case lRestart:
++		intptr = &options.restart;
++		goto parse_flag;
 +
-+	ld = NULL;
-+	debug2 ("LDAP do close OK");
-+	return;
-+}
++	case lTLS_CheckPeer:
++		intptr = &options.tls_checkpeer;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing never/hard/demand/alow/try argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcasecmp(arg, "never") == 0 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
++			value = LDAP_OPT_X_TLS_NEVER;
++		else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
++			value = LDAP_OPT_X_TLS_HARD;
++		else if (strcasecmp(arg, "demand") == 0)
++			value = LDAP_OPT_X_TLS_DEMAND;
++		else if (strcasecmp(arg, "allow") == 0)
++			value = LDAP_OPT_X_TLS_ALLOW;
++		else if (strcasecmp(arg, "try") == 0)
++			value = LDAP_OPT_X_TLS_TRY;
++		else
++			fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum);
++		if (*intptr == -1)
++		break;
 +
-diff -up openssh-5.9p1/ldapbody.h.ldap openssh-5.9p1/ldapbody.h
---- openssh-5.9p1/ldapbody.h.ldap	2011-09-13 11:17:05.861522789 +0200
-+++ openssh-5.9p1/ldapbody.h	2011-09-13 11:17:05.863522010 +0200
-@@ -0,0 +1,37 @@
-+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
++	case lTLS_CaCertFile:
++		charptr = &options.tls_cacertfile;
++		goto parse_string;
 +
-+#ifndef LDAPBODY_H
-+#define LDAPBODY_H
++	case lTLS_CaCertDir:
++		charptr = &options.tls_cacertdir;
++		goto parse_string;
 +
-+#include <stdio.h>
++	case lTLS_Ciphers:
++		xstringptr = &options.tls_ciphers;
++		goto parse_xstring;
 +
-+void ldap_checkconfig(void);
-+void ldap_do_connect(void);
-+void process_user(const char *, FILE *);
-+void ldap_do_close(void);
++	case lTLS_Cert:
++		charptr = &options.tls_cert;
++		goto parse_string;
 +
-+#endif /* LDAPBODY_H */
++	case lTLS_Key:
++		charptr = &options.tls_key;
++		goto parse_string;
 +
-diff -up openssh-5.9p1/ldapconf.c.ldap openssh-5.9p1/ldapconf.c
---- openssh-5.9p1/ldapconf.c.ldap	2011-09-13 11:17:05.937548294 +0200
-+++ openssh-5.9p1/ldapconf.c	2011-09-13 11:17:05.941547073 +0200
-@@ -0,0 +1,682 @@
-+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
-+/*
-+ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
++	case lTLS_RandFile:
++		charptr = &options.tls_randfile;
++		goto parse_string;
 +
-+#include "ldapincludes.h"
-+#include "ldap-helper.h"
-+#include "log.h"
-+#include "misc.h"
-+#include "xmalloc.h"
-+#include "ldapconf.h"
-+#include <unistd.h>
-+#include <string.h>
++	case lLogDir:
++		charptr = &options.logdir;
++		goto parse_string;
 +
-+/* Keyword tokens. */
++	case lDebug:
++		intptr = &options.debug;
++		goto parse_int;
 +
-+typedef enum {
-+	lBadOption,
-+	lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN,
-+	lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit,
-+	lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals,
-+	lRestart, lTLS_CheckPeer, lTLS_CaCertFile,
-+	lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key,
-+	lTLS_RandFile, lLogDir, lDebug, lSSH_Filter,
-+	lDeprecated, lUnsupported
-+} OpCodes;
++	case lSSH_Filter:
++		xstringptr = &options.ssh_filter;
++		goto parse_xstring;
 +
-+/* Textual representations of the tokens. */
++	case lDeprecated:
++		debug("%s line %d: Deprecated option \"%s\"",
++		    filename, linenum, keyword);
++		return 0;
 +
-+static struct {
-+	const char *name;
-+	OpCodes opcode;
-+} keywords[] = {
-+	{ "URI", lURI },
-+	{ "Base", lBase },
-+	{ "BindDN", lBindDN },
-+	{ "BindPW", lBindPW },
-+	{ "RootBindDN", lRootBindDN },
-+	{ "Host", lHost },
-+	{ "Port", lPort },
-+	{ "Scope", lScope },
-+	{ "Deref", lDeref },
-+	{ "TimeLimit", lTimeLimit },
-+	{ "TimeOut", lTimeLimit },
-+	{ "Bind_Timelimit", lBind_TimeLimit },
-+	{ "Network_TimeOut", lBind_TimeLimit },
-+/*
-+ * Todo
-+ * SIZELIMIT
-+ */
-+	{ "Ldap_Version", lLdap_Version },
-+	{ "Version", lLdap_Version },
-+	{ "Bind_Policy", lBind_Policy },
-+	{ "SSLPath", lSSLPath },
-+	{ "SSL", lSSL },
-+	{ "Referrals", lReferrals },
-+	{ "Restart", lRestart },
-+	{ "TLS_CheckPeer", lTLS_CheckPeer },
-+	{ "TLS_ReqCert", lTLS_CheckPeer },
-+	{ "TLS_CaCertFile", lTLS_CaCertFile },
-+	{ "TLS_CaCert", lTLS_CaCertFile },
-+	{ "TLS_CaCertDir", lTLS_CaCertDir },
-+	{ "TLS_Ciphers", lTLS_Ciphers },
-+	{ "TLS_Cipher_Suite", lTLS_Ciphers },
-+	{ "TLS_Cert", lTLS_Cert },
-+	{ "TLS_Certificate", lTLS_Cert },
-+	{ "TLS_Key", lTLS_Key },
-+	{ "TLS_RandFile", lTLS_RandFile },
-+/*
-+ * Todo
-+ * TLS_CRLCHECK
-+ * TLS_CRLFILE
-+ */
-+	{ "LogDir", lLogDir },
-+	{ "Debug", lDebug },
-+	{ "SSH_Filter", lSSH_Filter },
-+	{ NULL, lBadOption }
-+};
++	case lUnsupported:
++		error("%s line %d: Unsupported option \"%s\"",
++		    filename, linenum, keyword);
++		return 0;
 +
-+/* Configuration ptions. */
++	default:
++		fatal("process_config_line: Unimplemented opcode %d", opcode);
++	}
 +
-+Options options;
++	/* Check that there is no garbage at end of line. */
++	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
++		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
++		    filename, linenum, arg);
++	}
++	return 0;
++}
 +
 +/*
-+ * Returns the number of the token pointed to by cp or oBadOption.
++ * Reads the config file and modifies the options accordingly.  Options
++ * should already be initialized before this call.  This never returns if
++ * there is an error.  If the file does not exist, this returns 0.
 + */
 +
-+static OpCodes
-+parse_token(const char *cp, const char *filename, int linenum)
++void
++read_config_file(const char *filename)
 +{
-+	u_int i;
++	FILE *f;
++	char line[1024];
++	int active, linenum;
++	int bad_options = 0;
++	struct stat sb;
 +
-+	for (i = 0; keywords[i].name; i++)
-+		if (strcasecmp(cp, keywords[i].name) == 0)
-+			return keywords[i].opcode;
++	if ((f = fopen(filename, "r")) == NULL)
++		fatal("fopen %s: %s", filename, strerror(errno));
 +
-+	if (config_warning_config_file) 
-+	    logit("%s: line %d: Bad configuration option: %s",
-+		filename, linenum, cp);
-+	return lBadOption;
++	if (fstat(fileno(f), &sb) == -1)
++		fatal("fstat %s: %s", filename, strerror(errno));
++	if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
++	    (sb.st_mode & 022) != 0))
++		fatal("Bad owner or permissions on %s", filename);
++
++	debug("Reading configuration data %.200s", filename);
++
++	/*
++	 * Mark that we are now processing the options.  This flag is turned
++	 * on/off by Host specifications.
++	 */
++	active = 1;
++	linenum = 0;
++	while (fgets(line, sizeof(line), f)) {
++		/* Update line number counter. */
++		linenum++;
++		if (process_config_line(line, filename, linenum) != 0)
++			bad_options++;
++	}
++	fclose(f);
++	if ((bad_options > 0) && config_exclusive_config_file) 
++		fatal("%s: terminating, %d bad configuration options",
++		    filename, bad_options);
 +}
 +
 +/*
-+ * Processes a single option line as used in the configuration files. This
-+ * only sets those values that have not already been set.
++ * Initializes options to special values that indicate that they have not yet
++ * been set.  Read_config_file will only set options with this value. Options
++ * are processed in the following order: command line, user config file,
++ * system config file.  Last, fill_default_options is called.
 + */
-+#define WHITESPACE " \t\r\n"
 +
-+static int
-+process_config_line(char *line, const char *filename, int linenum)
++void
++initialize_options(void)
 +{
-+	char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg;
-+	char *rootbinddn = NULL;
-+	int opcode, *intptr, value;
-+	size_t len;
-+
-+	/* Strip trailing whitespace */
-+	for (len = strlen(line) - 1; len > 0; len--) {
-+		if (strchr(WHITESPACE, line[len]) == NULL)
-+			break;
-+		line[len] = '\0';
-+	}
-+
-+	s = line;
-+	/* Get the keyword. (Each line is supposed to begin with a keyword). */
-+	if ((keyword = strdelim(&s)) == NULL)
-+		return 0;
-+	/* Ignore leading whitespace. */
-+	if (*keyword == '\0')
-+		keyword = strdelim(&s);
-+	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
-+		return 0;
-+
-+	opcode = parse_token(keyword, filename, linenum);
-+
-+	switch (opcode) {
-+	case lBadOption:
-+		/* don't panic, but count bad options */
-+		return -1;
-+		/* NOTREACHED */
-+
-+	case lHost:
-+		xstringptr = &options.host;
-+parse_xstring:
-+		if (!s || *s == '\0')
-+		    fatal("%s line %d: missing dn",filename,linenum);
-+		if (*xstringptr == NULL)
-+		    *xstringptr = xstrdup(s);
-+		return 0;
-+
-+	case lURI:
-+		xstringptr = &options.uri;
-+		goto parse_xstring;
++	memset(&options, 'X', sizeof(options));
++	options.host = NULL;
++	options.uri = NULL;
++	options.base = NULL;
++	options.binddn = NULL;
++	options.bindpw = NULL;
++	options.scope = -1;
++	options.deref = -1;
++	options.port = -1;
++	options.timelimit = -1;
++	options.bind_timelimit = -1;
++	options.ldap_version = -1;
++	options.bind_policy = -1;
++	options.sslpath = NULL;
++	options.ssl = -1;
++	options.referrals = -1;
++	options.restart = -1;
++	options.tls_checkpeer = -1;
++	options.tls_cacertfile = NULL;
++	options.tls_cacertdir = NULL;
++	options.tls_ciphers = NULL;
++	options.tls_cert = NULL;
++	options.tls_key = NULL;
++	options.tls_randfile = NULL;
++	options.logdir = NULL;
++	options.debug = -1;
++	options.ssh_filter = NULL;
++}
 +
-+	case lBase:
-+		xstringptr = &options.base;
-+		goto parse_xstring;
++/*
++ * Called after processing other sources of option data, this fills those
++ * options for which no value has been specified with their default values.
++ */
 +
-+	case lBindDN:
-+		xstringptr = &options.binddn;
-+		goto parse_xstring;
++void
++fill_default_options(void)
++{
++	if (options.uri != NULL) {
++		LDAPURLDesc *ludp;
 +
-+	case lBindPW:
-+		charptr = &options.bindpw;
-+parse_string:
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing argument.", filename, linenum);
-+		if (*charptr == NULL)
-+			*charptr = xstrdup(arg);
-+		break;
++		if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) {
++			if (options.ssl == -1) {
++				if (strcmp (ludp->lud_scheme, "ldap") == 0)
++				    options.ssl = 2;
++				if (strcmp (ludp->lud_scheme, "ldapi") == 0)
++				    options.ssl = 0;
++				else if (strcmp (ludp->lud_scheme, "ldaps") == 0)
++				    options.ssl = 1;
++			}
++			if (options.host == NULL)
++			    options.host = xstrdup (ludp->lud_host);
++			if (options.port == -1)
++			    options.port = ludp->lud_port;
 +
-+	case lRootBindDN:
-+		xstringptr = &rootbinddn;
-+		goto parse_xstring;
++			ldap_free_urldesc (ludp);
++		}
++	} 
++	if (options.ssl == -1)
++	    options.ssl = SSL_START_TLS;
++	if (options.port == -1)
++	    options.port = (options.ssl == 0) ? 389 : 636;
++	if (options.uri == NULL) {
++		int len;
++#define MAXURILEN 4096
 +
-+	case lScope:
-+		intptr = &options.scope;
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing sub/one/base argument.", filename, linenum);
-+		value = 0;	/* To avoid compiler warning... */
-+		if (strcasecmp (arg, "sub") == 0 || strcasecmp (arg, "subtree") == 0)
-+			value = LDAP_SCOPE_SUBTREE;
-+		else if (strcasecmp (arg, "one") == 0)
-+			value = LDAP_SCOPE_ONELEVEL;
-+		else if (strcasecmp (arg, "base") == 0)
-+			value = LDAP_SCOPE_BASE;
-+		else
-+			fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
++		options.uri = xmalloc (MAXURILEN);
++		len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d",
++		    (options.ssl == 0) ? "" : "s", options.host, options.port);
++		options.uri[MAXURILEN - 1] = 0;
++		options.uri = xrealloc (options.uri, len + 1, 1);
++	}
++	if (options.binddn == NULL)
++	    options.binddn = "";
++	if (options.bindpw == NULL)
++	    options.bindpw = "";
++	if (options.scope == -1)
++	    options.scope = LDAP_SCOPE_SUBTREE;
++	if (options.deref == -1)
++	    options.deref = LDAP_DEREF_NEVER;
++	if (options.timelimit == -1)
++	    options.timelimit = 10;
++	if (options.bind_timelimit == -1)
++	    options.bind_timelimit = 10;
++	if (options.ldap_version == -1)
++	    options.ldap_version = 3;
++	if (options.bind_policy == -1)
++	    options.bind_policy = 1;
++	if (options.referrals == -1)
++	    options.referrals = 1;
++	if (options.restart == -1)
++	    options.restart = 1;
++	if (options.tls_checkpeer == -1)
++	    options.tls_checkpeer = LDAP_OPT_X_TLS_HARD;
++	if (options.debug == -1)
++	    options.debug = 0;
++	if (options.ssh_filter == NULL)
++	    options.ssh_filter = "";
++}
 +
-+	case lDeref:
-+		intptr = &options.scope;
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing never/searching/finding/always argument.", filename, linenum);
-+		value = 0;	/* To avoid compiler warning... */
-+		if (!strcasecmp (arg, "never"))
-+			value = LDAP_DEREF_NEVER;
-+		else if (!strcasecmp (arg, "searching"))
-+			value = LDAP_DEREF_SEARCHING;
-+		else if (!strcasecmp (arg, "finding"))
-+			value = LDAP_DEREF_FINDING;
-+		else if (!strcasecmp (arg, "always"))
-+			value = LDAP_DEREF_ALWAYS;
-+		else
-+			fatal("%.200s line %d: Bad never/searching/finding/always argument.", filename, linenum);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
++static const char *
++lookup_opcode_name(OpCodes code)
++{
++	u_int i;
 +
-+	case lPort:
-+		intptr = &options.port;
-+parse_int:
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing argument.", filename, linenum);
-+		if (arg[0] < '0' || arg[0] > '9')
-+			fatal("%.200s line %d: Bad number.", filename, linenum);
++	for (i = 0; keywords[i].name != NULL; i++)
++	    if (keywords[i].opcode == code)
++		return(keywords[i].name);
++	return "UNKNOWN";
++}
 +
-+		/* Octal, decimal, or hex format? */
-+		value = strtol(arg, &endofnumber, 0);
-+		if (arg == endofnumber)
-+			fatal("%.200s line %d: Bad number.", filename, linenum);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
++static void
++dump_cfg_string(OpCodes code, const char *val)
++{
++	if (val == NULL)
++	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
++	else
++	    debug3("%s %s", lookup_opcode_name(code), val);
++}
 +
-+	case lTimeLimit:
-+		intptr = &options.timelimit;
-+parse_time:
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%s line %d: missing time value.",
-+			    filename, linenum);
-+		if ((value = convtime(arg)) == -1)
-+			fatal("%s line %d: invalid time value.",
-+			    filename, linenum);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
++static void
++dump_cfg_int(OpCodes code, int val)
++{
++	if (val == -1)
++	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
++	else
++	    debug3("%s %d", lookup_opcode_name(code), val);
++}
 +
-+	case lBind_TimeLimit:
-+		intptr = &options.bind_timelimit;
-+		goto parse_time;
++struct names {
++	int value;
++	char *name;
++};
 +
-+	case lLdap_Version:
-+		intptr = &options.ldap_version;
-+		goto parse_int;
++static void
++dump_cfg_namedint(OpCodes code, int val, struct names *names)
++{
++	u_int i;
 +
-+	case lBind_Policy:
-+		intptr = &options.bind_policy;
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing soft/hard argument.", filename, linenum);
-+		value = 0;	/* To avoid compiler warning... */
-+		if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 0)
-+			value = 1;
-+		else if (strcasecmp(arg, "soft") == 0)
-+			value = 0;
-+		else
-+			fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum);
-+		if (*intptr == -1)
-+		break;
++	if (val == -1)
++	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
++	else {
++		for (i = 0; names[i].value != -1; i++)
++	 	    if (names[i].value == val) {
++	    		debug3("%s %s", lookup_opcode_name(code), names[i].name);
++			    return;
++		}
++		debug3("%s unknown: %d", lookup_opcode_name(code), val);
++	}
++}
 +
-+	case lSSLPath:
-+		charptr = &options.sslpath;
-+		goto parse_string;
++static struct names _yesnotls[] = {
++	{ 0, "No" },
++	{ 1, "Yes" },
++	{ 2, "Start_TLS" },
++	{ -1, NULL }};
 +
-+	case lSSL:
-+		intptr = &options.ssl;
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing yes/no/start_tls argument.", filename, linenum);
-+		value = 0;	/* To avoid compiler warning... */
-+		if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
-+			value = SSL_LDAPS;
-+		else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
-+			value = SSL_OFF;
-+		else if (!strcasecmp (arg, "start_tls"))
-+			value = SSL_START_TLS;
-+		else
-+			fatal("%.200s line %d: Bad yes/no/start_tls argument.", filename, linenum);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
++static struct names _scope[] = {
++	{ LDAP_SCOPE_BASE, "Base" },
++	{ LDAP_SCOPE_ONELEVEL, "One" },
++	{ LDAP_SCOPE_SUBTREE, "Sub"},
++	{ -1, NULL }};
 +
-+	case lReferrals:
-+		intptr = &options.referrals;
-+parse_flag:
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
-+		value = 0;	/* To avoid compiler warning... */
-+		if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
-+			value = 1;
-+		else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
-+			value = 0;
-+		else
-+			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
++static struct names _deref[] = {
++	{ LDAP_DEREF_NEVER, "Never" },
++	{ LDAP_DEREF_SEARCHING, "Searching" },
++	{ LDAP_DEREF_FINDING, "Finding" },
++	{ LDAP_DEREF_ALWAYS, "Always" },
++	{ -1, NULL }};
 +
-+	case lRestart:
-+		intptr = &options.restart;
-+		goto parse_flag;
++static struct names _yesno[] = {
++	{ 0, "No" },
++	{ 1, "Yes" },
++	{ -1, NULL }};
 +
-+	case lTLS_CheckPeer:
-+		intptr = &options.tls_checkpeer;
-+		arg = strdelim(&s);
-+		if (!arg || *arg == '\0')
-+			fatal("%.200s line %d: Missing never/hard/demand/alow/try argument.", filename, linenum);
-+		value = 0;	/* To avoid compiler warning... */
-+		if (strcasecmp(arg, "never") == 0 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0)
-+			value = LDAP_OPT_X_TLS_NEVER;
-+		else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0)
-+			value = LDAP_OPT_X_TLS_HARD;
-+		else if (strcasecmp(arg, "demand") == 0)
-+			value = LDAP_OPT_X_TLS_DEMAND;
-+		else if (strcasecmp(arg, "allow") == 0)
-+			value = LDAP_OPT_X_TLS_ALLOW;
-+		else if (strcasecmp(arg, "try") == 0)
-+			value = LDAP_OPT_X_TLS_TRY;
-+		else
-+			fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum);
-+		if (*intptr == -1)
-+		break;
++static struct names _bindpolicy[] = {
++	{ 0, "Soft" },
++	{ 1, "Hard" },
++	{ -1, NULL }};
 +
-+	case lTLS_CaCertFile:
-+		charptr = &options.tls_cacertfile;
-+		goto parse_string;
++static struct names _checkpeer[] = {
++	{ LDAP_OPT_X_TLS_NEVER, "Never" },
++	{ LDAP_OPT_X_TLS_HARD, "Hard" },
++	{ LDAP_OPT_X_TLS_DEMAND, "Demand" },
++	{ LDAP_OPT_X_TLS_ALLOW, "Allow" },
++	{ LDAP_OPT_X_TLS_TRY, "TRY" },
++	{ -1, NULL }};
 +
-+	case lTLS_CaCertDir:
-+		charptr = &options.tls_cacertdir;
-+		goto parse_string;
++void
++dump_config(void)
++{
++	dump_cfg_string(lURI, options.uri);
++	dump_cfg_string(lHost, options.host);
++	dump_cfg_int(lPort, options.port);
++	dump_cfg_namedint(lSSL, options.ssl, _yesnotls);
++	dump_cfg_int(lLdap_Version, options.ldap_version);
++	dump_cfg_int(lTimeLimit, options.timelimit);
++	dump_cfg_int(lBind_TimeLimit, options.bind_timelimit);
++	dump_cfg_string(lBase, options.base);
++	dump_cfg_string(lBindDN, options.binddn);
++	dump_cfg_string(lBindPW, options.bindpw);
++	dump_cfg_namedint(lScope, options.scope, _scope);
++	dump_cfg_namedint(lDeref, options.deref, _deref);
++	dump_cfg_namedint(lReferrals, options.referrals, _yesno);
++	dump_cfg_namedint(lRestart, options.restart, _yesno);
++	dump_cfg_namedint(lBind_Policy, options.bind_policy, _bindpolicy);
++	dump_cfg_string(lSSLPath, options.sslpath);
++	dump_cfg_namedint(lTLS_CheckPeer, options.tls_checkpeer, _checkpeer);
++	dump_cfg_string(lTLS_CaCertFile, options.tls_cacertfile);
++	dump_cfg_string(lTLS_CaCertDir, options.tls_cacertdir);
++	dump_cfg_string(lTLS_Ciphers, options.tls_ciphers);
++	dump_cfg_string(lTLS_Cert, options.tls_cert);
++	dump_cfg_string(lTLS_Key, options.tls_key);
++	dump_cfg_string(lTLS_RandFile, options.tls_randfile);
++	dump_cfg_string(lLogDir, options.logdir);
++	dump_cfg_int(lDebug, options.debug);
++	dump_cfg_string(lSSH_Filter, options.ssh_filter);
++}
 +
-+	case lTLS_Ciphers:
-+		xstringptr = &options.tls_ciphers;
-+		goto parse_xstring;
+diff -up openssh-6.0p1/ldapconf.h.ldap openssh-6.0p1/ldapconf.h
+--- openssh-6.0p1/ldapconf.h.ldap	2012-08-06 20:41:38.400454194 +0200
++++ openssh-6.0p1/ldapconf.h	2012-08-06 20:41:38.400454194 +0200
+@@ -0,0 +1,71 @@
++/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/*
++ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
 +
-+	case lTLS_Cert:
-+		charptr = &options.tls_cert;
-+		goto parse_string;
++#ifndef LDAPCONF_H
++#define LDAPCONF_H
 +
-+	case lTLS_Key:
-+		charptr = &options.tls_key;
-+		goto parse_string;
++#define SSL_OFF          0
++#define SSL_LDAPS        1
++#define SSL_START_TLS    2
 +
-+	case lTLS_RandFile:
-+		charptr = &options.tls_randfile;
-+		goto parse_string;
++/* Data structure for representing option data. */
 +
-+	case lLogDir:
-+		charptr = &options.logdir;
-+		goto parse_string;
++typedef struct {
++	char *host;
++	char *uri;
++	char *base;
++	char *binddn;
++	char *bindpw;
++	int scope;
++	int deref;
++	int port;
++	int timelimit;
++	int bind_timelimit;
++	int ldap_version;
++	int bind_policy;
++	char *sslpath;
++	int ssl;
++	int referrals;
++	int restart;
++	int tls_checkpeer;
++	char *tls_cacertfile;
++	char *tls_cacertdir;
++	char *tls_ciphers;
++	char *tls_cert;
++	char *tls_key;
++	char *tls_randfile;
++	char *logdir;
++	int debug;
++	char *ssh_filter;
++}       Options;
 +
-+	case lDebug:
-+		intptr = &options.debug;
-+		goto parse_int;
++extern Options options;
 +
-+	case lSSH_Filter:
-+		xstringptr = &options.ssh_filter;
-+		goto parse_xstring;
++void read_config_file(const char *);
++void initialize_options(void);
++void fill_default_options(void);
++void dump_config(void);
++
++#endif /* LDAPCONF_H */
+diff -up openssh-6.0p1/ldap.conf.ldap openssh-6.0p1/ldap.conf
+--- openssh-6.0p1/ldap.conf.ldap	2012-08-06 20:41:38.401454190 +0200
++++ openssh-6.0p1/ldap.conf	2012-08-06 20:41:38.401454190 +0200
+@@ -0,0 +1,88 @@
++# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $
++#
++# This is the example configuration file for the OpenSSH
++# LDAP backend
++# 
++# see ssh-ldap.conf(5)
++#
 +
-+	case lDeprecated:
-+		debug("%s line %d: Deprecated option \"%s\"",
-+		    filename, linenum, keyword);
-+		return 0;
++# URI with your LDAP server name. This allows to use
++# Unix Domain Sockets to connect to a local LDAP Server.
++#uri ldap://127.0.0.1/
++#uri ldaps://127.0.0.1/   
++#uri ldapi://%2fvar%2frun%2fldapi_sock/
++# Note: %2f encodes the '/' used as directory separator
 +
-+	case lUnsupported:
-+		error("%s line %d: Unsupported option \"%s\"",
-+		    filename, linenum, keyword);
-+		return 0;
++# Another way to specify your LDAP server is to provide an
++# host name and the port of our LDAP server. Host name
++# must be resolvable without using LDAP.
++# Multiple hosts may be specified, each separated by a 
++# space. How long nss_ldap takes to failover depends on
++# whether your LDAP client library supports configurable
++# network or connect timeouts (see bind_timelimit).
++#host 127.0.0.1
 +
-+	default:
-+		fatal("process_config_line: Unimplemented opcode %d", opcode);
-+	}
++# The port.
++# Optional: default is 389.
++#port 389
 +
-+	/* Check that there is no garbage at end of line. */
-+	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
-+		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
-+		    filename, linenum, arg);
-+	}
-+	return 0;
-+}
++# The distinguished name to bind to the server with.
++# Optional: default is to bind anonymously.
++#binddn cn=openssh_keys,dc=example,dc=org
 +
-+/*
-+ * Reads the config file and modifies the options accordingly.  Options
-+ * should already be initialized before this call.  This never returns if
-+ * there is an error.  If the file does not exist, this returns 0.
-+ */
++# The credentials to bind with. 
++# Optional: default is no credential.
++#bindpw TopSecret
 +
-+void
-+read_config_file(const char *filename)
-+{
-+	FILE *f;
-+	char line[1024];
-+	int active, linenum;
-+	int bad_options = 0;
-+	struct stat sb;
++# The distinguished name of the search base.
++#base dc=example,dc=org
 +
-+	if ((f = fopen(filename, "r")) == NULL)
-+		fatal("fopen %s: %s", filename, strerror(errno));
++# The LDAP version to use (defaults to 3
++# if supported by client library)
++#ldap_version 3
 +
-+	if (fstat(fileno(f), &sb) == -1)
-+		fatal("fstat %s: %s", filename, strerror(errno));
-+	if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
-+	    (sb.st_mode & 022) != 0))
-+		fatal("Bad owner or permissions on %s", filename);
++# The search scope.
++#scope sub
++#scope one
++#scope base
 +
-+	debug("Reading configuration data %.200s", filename);
++# Search timelimit
++#timelimit 30
 +
-+	/*
-+	 * Mark that we are now processing the options.  This flag is turned
-+	 * on/off by Host specifications.
-+	 */
-+	active = 1;
-+	linenum = 0;
-+	while (fgets(line, sizeof(line), f)) {
-+		/* Update line number counter. */
-+		linenum++;
-+		if (process_config_line(line, filename, linenum) != 0)
-+			bad_options++;
-+	}
-+	fclose(f);
-+	if ((bad_options > 0) && config_exclusive_config_file) 
-+		fatal("%s: terminating, %d bad configuration options",
-+		    filename, bad_options);
-+}
++# Bind/connect timelimit
++#bind_timelimit 30
 +
-+/*
-+ * Initializes options to special values that indicate that they have not yet
-+ * been set.  Read_config_file will only set options with this value. Options
-+ * are processed in the following order: command line, user config file,
-+ * system config file.  Last, fill_default_options is called.
-+ */
++# Reconnect policy: hard (default) will retry connecting to
++# the software with exponential backoff, soft will fail
++# immediately.
++#bind_policy hard
 +
-+void
-+initialize_options(void)
-+{
-+	memset(&options, 'X', sizeof(options));
-+	options.host = NULL;
-+	options.uri = NULL;
-+	options.base = NULL;
-+	options.binddn = NULL;
-+	options.bindpw = NULL;
-+	options.scope = -1;
-+	options.deref = -1;
-+	options.port = -1;
-+	options.timelimit = -1;
-+	options.bind_timelimit = -1;
-+	options.ldap_version = -1;
-+	options.bind_policy = -1;
-+	options.sslpath = NULL;
-+	options.ssl = -1;
-+	options.referrals = -1;
-+	options.restart = -1;
-+	options.tls_checkpeer = -1;
-+	options.tls_cacertfile = NULL;
-+	options.tls_cacertdir = NULL;
-+	options.tls_ciphers = NULL;
-+	options.tls_cert = NULL;
-+	options.tls_key = NULL;
-+	options.tls_randfile = NULL;
-+	options.logdir = NULL;
-+	options.debug = -1;
-+	options.ssh_filter = NULL;
-+}
++# SSL setup, may be implied by URI also.
++#ssl no
++#ssl on
++#ssl start_tls
 +
-+/*
-+ * Called after processing other sources of option data, this fills those
-+ * options for which no value has been specified with their default values.
-+ */
++# OpenLDAP SSL options
++# Require and verify server certificate (yes/no)
++# Default is to use libldap's default behavior, which can be configured in
++# /etc/openldap/ldap.conf using the TLS_REQCERT setting.  The default for
++# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes".
++#tls_checkpeer hard
 +
-+void
-+fill_default_options(void)
-+{
-+	if (options.uri != NULL) {
-+		LDAPURLDesc *ludp;
++# CA certificates for server certificate verification
++# At least one of these are required if tls_checkpeer is "yes"
++#tls_cacertfile /etc/ssl/ca.cert
++#tls_cacertdir /etc/pki/tls/certs
 +
-+		if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) {
-+			if (options.ssl == -1) {
-+				if (strcmp (ludp->lud_scheme, "ldap") == 0)
-+				    options.ssl = 2;
-+				if (strcmp (ludp->lud_scheme, "ldapi") == 0)
-+				    options.ssl = 0;
-+				else if (strcmp (ludp->lud_scheme, "ldaps") == 0)
-+				    options.ssl = 1;
-+			}
-+			if (options.host == NULL)
-+			    options.host = xstrdup (ludp->lud_host);
-+			if (options.port == -1)
-+			    options.port = ludp->lud_port;
++# Seed the PRNG if /dev/urandom is not provided
++#tls_randfile /var/run/egd-pool
 +
-+			ldap_free_urldesc (ludp);
-+		}
-+	} 
-+	if (options.ssl == -1)
-+	    options.ssl = SSL_START_TLS;
-+	if (options.port == -1)
-+	    options.port = (options.ssl == 0) ? 389 : 636;
-+	if (options.uri == NULL) {
-+		int len;
-+#define MAXURILEN 4096
++# SSL cipher suite
++# See man ciphers for syntax
++#tls_ciphers TLSv1
 +
-+		options.uri = xmalloc (MAXURILEN);
-+		len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d",
-+		    (options.ssl == 0) ? "" : "s", options.host, options.port);
-+		options.uri[MAXURILEN - 1] = 0;
-+		options.uri = xrealloc (options.uri, len + 1, 1);
-+	}
-+	if (options.binddn == NULL)
-+	    options.binddn = "";
-+	if (options.bindpw == NULL)
-+	    options.bindpw = "";
-+	if (options.scope == -1)
-+	    options.scope = LDAP_SCOPE_SUBTREE;
-+	if (options.deref == -1)
-+	    options.deref = LDAP_DEREF_NEVER;
-+	if (options.timelimit == -1)
-+	    options.timelimit = 10;
-+	if (options.bind_timelimit == -1)
-+	    options.bind_timelimit = 10;
-+	if (options.ldap_version == -1)
-+	    options.ldap_version = 3;
-+	if (options.bind_policy == -1)
-+	    options.bind_policy = 1;
-+	if (options.referrals == -1)
-+	    options.referrals = 1;
-+	if (options.restart == -1)
-+	    options.restart = 1;
-+	if (options.tls_checkpeer == -1)
-+	    options.tls_checkpeer = LDAP_OPT_X_TLS_HARD;
-+	if (options.debug == -1)
-+	    options.debug = 0;
-+	if (options.ssh_filter == NULL)
-+	    options.ssh_filter = "";
-+}
++# Client certificate and key
++# Use these, if your server requires client authentication.
++#tls_cert
++#tls_key
 +
-+static const char *
-+lookup_opcode_name(OpCodes code)
-+{
-+	u_int i;
+diff -up openssh-6.0p1/ldap-helper.c.ldap openssh-6.0p1/ldap-helper.c
+--- openssh-6.0p1/ldap-helper.c.ldap	2012-08-06 20:41:38.401454190 +0200
++++ openssh-6.0p1/ldap-helper.c	2012-08-06 20:41:38.401454190 +0200
+@@ -0,0 +1,155 @@
++/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/*
++ * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
 +
-+	for (i = 0; keywords[i].name != NULL; i++)
-+	    if (keywords[i].opcode == code)
-+		return(keywords[i].name);
-+	return "UNKNOWN";
-+}
++#include "ldapincludes.h"
++#include "log.h"
++#include "misc.h"
++#include "xmalloc.h"
++#include "ldapconf.h"
++#include "ldapbody.h"
++#include <string.h>
++#include <unistd.h>
 +
-+static void
-+dump_cfg_string(OpCodes code, const char *val)
-+{
-+	if (val == NULL)
-+	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
-+	else
-+	    debug3("%s %s", lookup_opcode_name(code), val);
-+}
++static int config_debug = 0;
++int config_exclusive_config_file = 0;
++static char *config_file_name = "/etc/ssh/ldap.conf";
++static char *config_single_user = NULL;
++static int config_verbose = SYSLOG_LEVEL_VERBOSE;
++int config_warning_config_file = 0;
++extern char *__progname;
 +
 +static void
-+dump_cfg_int(OpCodes code, int val)
++usage(void)
 +{
-+	if (val == -1)
-+	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
-+	else
-+	    debug3("%s %d", lookup_opcode_name(code), val);
++	fprintf(stderr, "usage: %s [options]\n",
++	    __progname);
++	fprintf(stderr, "Options:\n");
++	fprintf(stderr, "  -d          Output the log messages to stderr.\n");
++	fprintf(stderr, "  -e          Check the config file for unknown commands.\n");
++	fprintf(stderr, "  -f file     Use alternate config file (default is /etc/ssh/ldap.conf).\n");
++	fprintf(stderr, "  -s user     Do not demonize, send the user's key to stdout.\n");
++	fprintf(stderr, "  -v          Increase verbosity of the debug output (implies -d).\n");
++	fprintf(stderr, "  -w          Warn on unknown commands in the config file.\n");
++	exit(1);
 +}
 +
-+struct names {
-+	int value;
-+	char *name;
-+};
++/*
++ * Main program for the ssh pka ldap agent.
++ */
 +
-+static void
-+dump_cfg_namedint(OpCodes code, int val, struct names *names)
++int
++main(int ac, char **av)
 +{
-+	u_int i;
++	int opt;
++	FILE *outfile = NULL;
 +
-+	if (val == -1)
-+	    debug3("%s <UNDEFINED>", lookup_opcode_name(code));
-+	else {
-+		for (i = 0; names[i].value != -1; i++)
-+	 	    if (names[i].value == val) {
-+	    		debug3("%s %s", lookup_opcode_name(code), names[i].name);
-+			    return;
++	__progname = ssh_get_progname(av[0]);
++
++	log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
++
++	/*
++	 * Initialize option structure to indicate that no values have been
++	 * set.
++	 */
++	initialize_options();
++
++	/* Parse command-line arguments. */
++	while ((opt = getopt(ac, av, "def:s:vw")) != -1) {
++		switch (opt) {
++		case 'd':
++			config_debug = 1;
++			break;
++
++		case 'e':
++			config_exclusive_config_file = 1;
++			config_warning_config_file = 1;
++			break;
++
++		case 'f':
++			config_file_name = optarg;
++			break;
++
++		case 's':
++			config_single_user = optarg;
++			outfile = fdopen (dup (fileno (stdout)), "w");
++			break;
++
++		case 'v':
++			config_debug = 1;
++			if (config_verbose < SYSLOG_LEVEL_DEBUG3)
++			    config_verbose++;
++			break;
++
++		case 'w':
++			config_warning_config_file = 1;
++			break;
++
++		case '?':
++		default:
++			usage();
++			break;
 +		}
-+		debug3("%s unknown: %d", lookup_opcode_name(code), val);
 +	}
-+}
 +
-+static struct names _yesnotls[] = {
-+	{ 0, "No" },
-+	{ 1, "Yes" },
-+	{ 2, "Start_TLS" },
-+	{ -1, NULL }};
++	/* Initialize loging */
++	log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug);
 +
-+static struct names _scope[] = {
-+	{ LDAP_SCOPE_BASE, "Base" },
-+	{ LDAP_SCOPE_ONELEVEL, "One" },
-+	{ LDAP_SCOPE_SUBTREE, "Sub"},
-+	{ -1, NULL }};
++	if (ac != optind)
++	    fatal ("illegal extra parameter %s", av[1]);
 +
-+static struct names _deref[] = {
-+	{ LDAP_DEREF_NEVER, "Never" },
-+	{ LDAP_DEREF_SEARCHING, "Searching" },
-+	{ LDAP_DEREF_FINDING, "Finding" },
-+	{ LDAP_DEREF_ALWAYS, "Always" },
-+	{ -1, NULL }};
++	/* Ensure that fds 0 and 2 are open or directed to /dev/null */
++	if (config_debug == 0)
++	    sanitise_stdfd();
 +
-+static struct names _yesno[] = {
-+	{ 0, "No" },
-+	{ 1, "Yes" },
-+	{ -1, NULL }};
++	/* Read config file */
++	read_config_file(config_file_name);
++	fill_default_options();
++	if (config_verbose == SYSLOG_LEVEL_DEBUG3) {
++		debug3 ("=== Configuration ===");
++		dump_config();
++		debug3 ("=== *** ===");
++	}
 +
-+static struct names _bindpolicy[] = {
-+	{ 0, "Soft" },
-+	{ 1, "Hard" },
-+	{ -1, NULL }};
++	ldap_checkconfig();
++	ldap_do_connect();
 +
-+static struct names _checkpeer[] = {
-+	{ LDAP_OPT_X_TLS_NEVER, "Never" },
-+	{ LDAP_OPT_X_TLS_HARD, "Hard" },
-+	{ LDAP_OPT_X_TLS_DEMAND, "Demand" },
-+	{ LDAP_OPT_X_TLS_ALLOW, "Allow" },
-+	{ LDAP_OPT_X_TLS_TRY, "TRY" },
-+	{ -1, NULL }};
++	if (config_single_user) {
++		process_user (config_single_user, outfile);
++	} else {
++		usage();
++		fatal ("Not yet implemented");
++/* TODO
++ * open unix socket a run the loop on it
++ */
++	}
 +
-+void
-+dump_config(void)
-+{
-+	dump_cfg_string(lURI, options.uri);
-+	dump_cfg_string(lHost, options.host);
-+	dump_cfg_int(lPort, options.port);
-+	dump_cfg_namedint(lSSL, options.ssl, _yesnotls);
-+	dump_cfg_int(lLdap_Version, options.ldap_version);
-+	dump_cfg_int(lTimeLimit, options.timelimit);
-+	dump_cfg_int(lBind_TimeLimit, options.bind_timelimit);
-+	dump_cfg_string(lBase, options.base);
-+	dump_cfg_string(lBindDN, options.binddn);
-+	dump_cfg_string(lBindPW, options.bindpw);
-+	dump_cfg_namedint(lScope, options.scope, _scope);
-+	dump_cfg_namedint(lDeref, options.deref, _deref);
-+	dump_cfg_namedint(lReferrals, options.referrals, _yesno);
-+	dump_cfg_namedint(lRestart, options.restart, _yesno);
-+	dump_cfg_namedint(lBind_Policy, options.bind_policy, _bindpolicy);
-+	dump_cfg_string(lSSLPath, options.sslpath);
-+	dump_cfg_namedint(lTLS_CheckPeer, options.tls_checkpeer, _checkpeer);
-+	dump_cfg_string(lTLS_CaCertFile, options.tls_cacertfile);
-+	dump_cfg_string(lTLS_CaCertDir, options.tls_cacertdir);
-+	dump_cfg_string(lTLS_Ciphers, options.tls_ciphers);
-+	dump_cfg_string(lTLS_Cert, options.tls_cert);
-+	dump_cfg_string(lTLS_Key, options.tls_key);
-+	dump_cfg_string(lTLS_RandFile, options.tls_randfile);
-+	dump_cfg_string(lLogDir, options.logdir);
-+	dump_cfg_int(lDebug, options.debug);
-+	dump_cfg_string(lSSH_Filter, options.ssh_filter);
++	ldap_do_close();
++	return 0;
 +}
 +
-diff -up openssh-5.9p1/ldapconf.h.ldap openssh-5.9p1/ldapconf.h
---- openssh-5.9p1/ldapconf.h.ldap	2011-09-13 11:17:06.016522201 +0200
-+++ openssh-5.9p1/ldapconf.h	2011-09-13 11:17:06.018522083 +0200
-@@ -0,0 +1,71 @@
-+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
++/* Ugly hack */
++void   *buffer_get_string(Buffer *b, u_int *l) { return NULL; }
++void    buffer_put_string(Buffer *b, const void *f, u_int l) {}
++
+diff -up openssh-6.0p1/ldap-helper.h.ldap openssh-6.0p1/ldap-helper.h
+--- openssh-6.0p1/ldap-helper.h.ldap	2012-08-06 20:41:38.401454190 +0200
++++ openssh-6.0p1/ldap-helper.h	2012-08-06 20:41:38.401454190 +0200
+@@ -0,0 +1,32 @@
++/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
 +/*
 + * Copyright (c) 2009 Jan F. Chadima.  All rights reserved.
 + *
@@ -1858,55 +1800,16 @@ diff -up openssh-5.9p1/ldapconf.h.ldap openssh-5.9p1/ldapconf.h
 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
-+#ifndef LDAPCONF_H
-+#define LDAPCONF_H
-+
-+#define SSL_OFF          0
-+#define SSL_LDAPS        1
-+#define SSL_START_TLS    2
-+
-+/* Data structure for representing option data. */
-+
-+typedef struct {
-+	char *host;
-+	char *uri;
-+	char *base;
-+	char *binddn;
-+	char *bindpw;
-+	int scope;
-+	int deref;
-+	int port;
-+	int timelimit;
-+	int bind_timelimit;
-+	int ldap_version;
-+	int bind_policy;
-+	char *sslpath;
-+	int ssl;
-+	int referrals;
-+	int restart;
-+	int tls_checkpeer;
-+	char *tls_cacertfile;
-+	char *tls_cacertdir;
-+	char *tls_ciphers;
-+	char *tls_cert;
-+	char *tls_key;
-+	char *tls_randfile;
-+	char *logdir;
-+	int debug;
-+	char *ssh_filter;
-+}       Options;
-+
-+extern Options options;
++#ifndef LDAP_HELPER_H
++#define LDAP_HELPER_H
 +
-+void read_config_file(const char *);
-+void initialize_options(void);
-+void fill_default_options(void);
-+void dump_config(void);
++extern int config_exclusive_config_file;
++extern int config_warning_config_file;
 +
-+#endif /* LDAPCONF_H */
-diff -up openssh-5.9p1/ldapincludes.h.ldap openssh-5.9p1/ldapincludes.h
---- openssh-5.9p1/ldapincludes.h.ldap	2011-09-13 11:17:06.123519312 +0200
-+++ openssh-5.9p1/ldapincludes.h	2011-09-13 11:17:06.126518977 +0200
++#endif /* LDAP_HELPER_H */
+diff -up openssh-6.0p1/ldapincludes.h.ldap openssh-6.0p1/ldapincludes.h
+--- openssh-6.0p1/ldapincludes.h.ldap	2012-08-06 20:41:38.402454186 +0200
++++ openssh-6.0p1/ldapincludes.h	2012-08-06 20:41:38.402454186 +0200
 @@ -0,0 +1,41 @@
 +/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
 +/*
@@ -1949,9 +1852,9 @@ diff -up openssh-5.9p1/ldapincludes.h.ldap openssh-5.9p1/ldapincludes.h
 +#endif
 +
 +#endif /* LDAPINCLUDES_H */
-diff -up openssh-5.9p1/ldapmisc.c.ldap openssh-5.9p1/ldapmisc.c
---- openssh-5.9p1/ldapmisc.c.ldap	2011-09-13 11:17:06.195508388 +0200
-+++ openssh-5.9p1/ldapmisc.c	2011-09-13 11:17:06.197507964 +0200
+diff -up openssh-6.0p1/ldapmisc.c.ldap openssh-6.0p1/ldapmisc.c
+--- openssh-6.0p1/ldapmisc.c.ldap	2012-08-06 20:41:38.402454186 +0200
++++ openssh-6.0p1/ldapmisc.c	2012-08-06 20:41:38.402454186 +0200
 @@ -0,0 +1,79 @@
 +
 +#include "ldapincludes.h"
@@ -2032,9 +1935,9 @@ diff -up openssh-5.9p1/ldapmisc.c.ldap openssh-5.9p1/ldapmisc.c
 +}
 +#endif
 +
-diff -up openssh-5.9p1/ldapmisc.h.ldap openssh-5.9p1/ldapmisc.h
---- openssh-5.9p1/ldapmisc.h.ldap	2011-09-13 11:17:06.273496889 +0200
-+++ openssh-5.9p1/ldapmisc.h	2011-09-13 11:17:06.276496151 +0200
+diff -up openssh-6.0p1/ldapmisc.h.ldap openssh-6.0p1/ldapmisc.h
+--- openssh-6.0p1/ldapmisc.h.ldap	2012-08-06 20:41:38.402454186 +0200
++++ openssh-6.0p1/ldapmisc.h	2012-08-06 20:41:38.402454186 +0200
 @@ -0,0 +1,35 @@
 +/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */
 +/*
@@ -2071,9 +1974,106 @@ diff -up openssh-5.9p1/ldapmisc.h.ldap openssh-5.9p1/ldapmisc.h
 +
 +#endif /* LDAPMISC_H */
 +
-diff -up openssh-5.9p1/openssh-lpk-openldap.schema.ldap openssh-5.9p1/openssh-lpk-openldap.schema
---- openssh-5.9p1/openssh-lpk-openldap.schema.ldap	2011-09-13 11:17:06.349485171 +0200
-+++ openssh-5.9p1/openssh-lpk-openldap.schema	2011-09-13 11:17:06.351484488 +0200
+diff -up openssh-6.0p1/Makefile.in.ldap openssh-6.0p1/Makefile.in
+--- openssh-6.0p1/Makefile.in.ldap	2012-08-06 20:41:38.336454444 +0200
++++ openssh-6.0p1/Makefile.in	2012-08-06 20:41:38.403454183 +0200
+@@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh
+ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
+ SFTP_SERVER=$(libexecdir)/sftp-server
+ SSH_KEYSIGN=$(libexecdir)/ssh-keysign
++SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper
++SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper
+ SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
+ PRIVSEP_PATH=@PRIVSEP_PATH@
+ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
+@@ -58,8 +60,9 @@ XAUTH_PATH=@XAUTH_PATH@
+ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
+ EXEEXT=@EXEEXT@
+ MANFMT=@MANFMT@
++INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@
+ 
+-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT)
+ 
+ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+ 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
+@@ -93,8 +96,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw
+ 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
+ 	sandbox-seccomp-filter.o
+ 
+-MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
+-MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
++MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out
++MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5
+ MANTYPE		= @MANTYPE@
+ 
+ CONFIGFILES=sshd_config.out ssh_config.out moduli.out
+@@ -162,6 +165,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss
+ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
+ 	$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
+ 
++ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o
++	$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
++
+ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
+ 	$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ 
+@@ -257,6 +263,10 @@ install-files:
+ 	$(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
+ 	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
+ 	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
++	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
++		$(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \
++		$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \
++	fi
+ 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
+ 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
+ 	$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
+@@ -273,6 +283,10 @@ install-files:
+ 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
+ 	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
+ 	$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
++	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
++		$(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \
++		$(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \
++	fi
+ 	-rm -f $(DESTDIR)$(bindir)/slogin
+ 	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+@@ -302,6 +316,13 @@ install-sysconf:
+ 	else \
+ 		echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \
+ 	fi
++	if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \
++		if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \
++			$(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \
++		else \
++			echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \
++		fi ; \
++	fi
+ 
+ host-key: ssh-keygen$(EXEEXT)
+ 	@if [ -z "$(DESTDIR)" ] ; then \
+@@ -359,6 +380,8 @@ uninstall:
+ 	-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
++	-rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT)
++	-rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
+@@ -370,6 +393,7 @@ uninstall:
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
++	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+ 
+ tests interop-tests:	$(TARGETS)
+diff -up openssh-6.0p1/openssh-lpk-openldap.schema.ldap openssh-6.0p1/openssh-lpk-openldap.schema
+--- openssh-6.0p1/openssh-lpk-openldap.schema.ldap	2012-08-06 20:41:38.404454179 +0200
++++ openssh-6.0p1/openssh-lpk-openldap.schema	2012-08-06 20:41:38.404454179 +0200
 @@ -0,0 +1,21 @@
 +#
 +# LDAP Public Key Patch schema for use with openssh-ldappubkey
@@ -2096,9 +2096,9 @@ diff -up openssh-5.9p1/openssh-lpk-openldap.schema.ldap openssh-5.9p1/openssh-lp
 +	DESC 'MANDATORY: OpenSSH LPK objectclass'
 +	MUST ( sshPublicKey $ uid ) 
 +	)
-diff -up openssh-5.9p1/openssh-lpk-sun.schema.ldap openssh-5.9p1/openssh-lpk-sun.schema
---- openssh-5.9p1/openssh-lpk-sun.schema.ldap	2011-09-13 11:17:06.420474045 +0200
-+++ openssh-5.9p1/openssh-lpk-sun.schema	2011-09-13 11:17:06.422473843 +0200
+diff -up openssh-6.0p1/openssh-lpk-sun.schema.ldap openssh-6.0p1/openssh-lpk-sun.schema
+--- openssh-6.0p1/openssh-lpk-sun.schema.ldap	2012-08-06 20:41:38.404454179 +0200
++++ openssh-6.0p1/openssh-lpk-sun.schema	2012-08-06 20:41:38.404454179 +0200
 @@ -0,0 +1,23 @@
 +#
 +# LDAP Public Key Patch schema for use with openssh-ldappubkey
@@ -2123,100 +2123,9 @@ diff -up openssh-5.9p1/openssh-lpk-sun.schema.ldap openssh-5.9p1/openssh-lpk-sun
 +	DESC 'MANDATORY: OpenSSH LPK objectclass'
 +	MUST ( sshPublicKey $ uid ) 
 +	)
-diff -up openssh-5.9p1/ssh-ldap-helper.8.ldap openssh-5.9p1/ssh-ldap-helper.8
---- openssh-5.9p1/ssh-ldap-helper.8.ldap	2011-09-13 11:17:06.504461435 +0200
-+++ openssh-5.9p1/ssh-ldap-helper.8	2011-09-13 11:17:06.506460976 +0200
-@@ -0,0 +1,79 @@
-+.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $
-+.\"
-+.\" Copyright (c) 2010 Jan F. Chadima.  All rights reserved.
-+.\"
-+.\" Permission to use, copy, modify, and distribute this software for any
-+.\" purpose with or without fee is hereby granted, provided that the above
-+.\" copyright notice and this permission notice appear in all copies.
-+.\"
-+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+.\"
-+.Dd $Mdocdate: April 29 2010 $
-+.Dt SSH-LDAP-HELPER 8
-+.Os
-+.Sh NAME
-+.Nm ssh-ldap-helper
-+.Nd sshd helper program for ldap support
-+.Sh SYNOPSIS
-+.Nm ssh-ldap-helper
-+.Op Fl devw
-+.Op Fl f Ar file
-+.Op Fl s Ar user
-+.Sh DESCRIPTION
-+.Nm
-+is used by
-+.Xr sshd 1
-+to access keys provided by an LDAP.
-+.Nm
-+is disabled by default and can only be enabled in the
-+sshd configuration file
-+.Pa /etc/ssh/sshd_config
-+by setting
-+.Cm AuthorizedKeysCommand
-+to
-+.Dq /usr/libexec/ssh-ldap-wrapper .
-+.Pp
-+.Nm
-+is not intended to be invoked by the user, but from
-+.Xr sshd 8 via
-+.Xr ssh-ldap-wrapper .
-+.Pp
-+The options are as follows:
-+.Bl -tag -width Ds
-+.It Fl d
-+Set the debug mode; 
-+.Nm
-+prints all logs to stderr instead of syslog.
-+.It Fl e
-+Implies \-w;
-+.Nm
-+halts if it encounters an unknown item in the ldap.conf file.
-+.It Fl f
-+.Nm
-+uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default).
-+.It Fl s
-+.Nm
-+prints out the user's keys to stdout and exits.
-+.It Fl v
-+Implies \-d;
-+increases verbosity.
-+.It Fl w
-+.Nm
-+writes warnings about unknown items in the ldap.conf configuration file.
-+.El
-+.Sh SEE ALSO
-+.Xr sshd 8 ,
-+.Xr sshd_config 5 ,
-+.Xr ssh-ldap.conf 5 ,
-+.Sh HISTORY
-+.Nm
-+first appeared in
-+OpenSSH 5.5 + PKA-LDAP .
-+.Sh AUTHORS
-+.An Jan F. Chadima Aq jchadima at redhat.com
-diff -up openssh-5.9p1/ssh-ldap-wrapper.ldap openssh-5.9p1/ssh-ldap-wrapper
---- openssh-5.9p1/ssh-ldap-wrapper.ldap	2011-09-13 11:17:06.574455869 +0200
-+++ openssh-5.9p1/ssh-ldap-wrapper	2011-09-13 11:17:06.576475704 +0200
-@@ -0,0 +1,4 @@
-+#!/bin/sh
-+
-+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1"
-+
-diff -up openssh-5.9p1/ssh-ldap.conf.5.ldap openssh-5.9p1/ssh-ldap.conf.5
---- openssh-5.9p1/ssh-ldap.conf.5.ldap	2011-09-13 11:17:06.650522542 +0200
-+++ openssh-5.9p1/ssh-ldap.conf.5	2011-09-13 11:17:06.653474746 +0200
+diff -up openssh-6.0p1/ssh-ldap.conf.5.ldap openssh-6.0p1/ssh-ldap.conf.5
+--- openssh-6.0p1/ssh-ldap.conf.5.ldap	2012-08-06 20:41:38.405454175 +0200
++++ openssh-6.0p1/ssh-ldap.conf.5	2012-08-06 20:41:38.405454175 +0200
 @@ -0,0 +1,376 @@
 +.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $
 +.\"
@@ -2594,3 +2503,94 @@ diff -up openssh-5.9p1/ssh-ldap.conf.5.ldap openssh-5.9p1/ssh-ldap.conf.5
 +OpenSSH 5.5 + PKA-LDAP .
 +.Sh AUTHORS
 +.An Jan F. Chadima Aq jchadima at redhat.com
+diff -up openssh-6.0p1/ssh-ldap-helper.8.ldap openssh-6.0p1/ssh-ldap-helper.8
+--- openssh-6.0p1/ssh-ldap-helper.8.ldap	2012-08-06 20:41:38.405454175 +0200
++++ openssh-6.0p1/ssh-ldap-helper.8	2012-08-06 20:41:38.405454175 +0200
+@@ -0,0 +1,79 @@
++.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $
++.\"
++.\" Copyright (c) 2010 Jan F. Chadima.  All rights reserved.
++.\"
++.\" Permission to use, copy, modify, and distribute this software for any
++.\" purpose with or without fee is hereby granted, provided that the above
++.\" copyright notice and this permission notice appear in all copies.
++.\"
++.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++.\"
++.Dd $Mdocdate: April 29 2010 $
++.Dt SSH-LDAP-HELPER 8
++.Os
++.Sh NAME
++.Nm ssh-ldap-helper
++.Nd sshd helper program for ldap support
++.Sh SYNOPSIS
++.Nm ssh-ldap-helper
++.Op Fl devw
++.Op Fl f Ar file
++.Op Fl s Ar user
++.Sh DESCRIPTION
++.Nm
++is used by
++.Xr sshd 1
++to access keys provided by an LDAP.
++.Nm
++is disabled by default and can only be enabled in the
++sshd configuration file
++.Pa /etc/ssh/sshd_config
++by setting
++.Cm AuthorizedKeysCommand
++to
++.Dq /usr/libexec/ssh-ldap-wrapper .
++.Pp
++.Nm
++is not intended to be invoked by the user, but from
++.Xr sshd 8 via
++.Xr ssh-ldap-wrapper .
++.Pp
++The options are as follows:
++.Bl -tag -width Ds
++.It Fl d
++Set the debug mode; 
++.Nm
++prints all logs to stderr instead of syslog.
++.It Fl e
++Implies \-w;
++.Nm
++halts if it encounters an unknown item in the ldap.conf file.
++.It Fl f
++.Nm
++uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default).
++.It Fl s
++.Nm
++prints out the user's keys to stdout and exits.
++.It Fl v
++Implies \-d;
++increases verbosity.
++.It Fl w
++.Nm
++writes warnings about unknown items in the ldap.conf configuration file.
++.El
++.Sh SEE ALSO
++.Xr sshd 8 ,
++.Xr sshd_config 5 ,
++.Xr ssh-ldap.conf 5 ,
++.Sh HISTORY
++.Nm
++first appeared in
++OpenSSH 5.5 + PKA-LDAP .
++.Sh AUTHORS
++.An Jan F. Chadima Aq jchadima at redhat.com
+diff -up openssh-6.0p1/ssh-ldap-wrapper.ldap openssh-6.0p1/ssh-ldap-wrapper
+--- openssh-6.0p1/ssh-ldap-wrapper.ldap	2012-08-06 20:41:38.405454175 +0200
++++ openssh-6.0p1/ssh-ldap-wrapper	2012-08-06 20:41:38.405454175 +0200
+@@ -0,0 +1,4 @@
++#!/bin/sh
++
++exec /usr/libexec/openssh/ssh-ldap-helper -s "$1"
++
diff --git a/openssh-6.0p1-role-mls.patch b/openssh-6.0p1-role-mls.patch
new file mode 100644
index 0000000..e23150f
--- /dev/null
+++ b/openssh-6.0p1-role-mls.patch
@@ -0,0 +1,934 @@
+diff -up openssh-6.0p1/auth.h.role-mls openssh-6.0p1/auth.h
+--- openssh-6.0p1/auth.h.role-mls	2012-06-24 16:57:17.540262700 +0200
++++ openssh-6.0p1/auth.h	2012-06-24 16:49:35.802071204 +0200
+@@ -59,6 +59,9 @@ struct Authctxt {
+ 	char		*service;
+ 	struct passwd	*pw;		/* set if 'valid' */
+ 	char		*style;
++#ifdef WITH_SELINUX
++	char		*role;
++#endif
+ 	void		*kbdintctxt;
+ 	void		*jpake_ctx;
+ #ifdef BSD_AUTH
+diff -up openssh-6.0p1/auth-pam.c.role-mls openssh-6.0p1/auth-pam.c
+--- openssh-6.0p1/auth-pam.c.role-mls	2012-06-24 16:57:17.532262382 +0200
++++ openssh-6.0p1/auth-pam.c	2012-06-24 16:49:35.803071166 +0200
+@@ -1074,7 +1074,7 @@ is_pam_session_open(void)
+  * during the ssh authentication process.
+  */
+ int
+-do_pam_putenv(char *name, char *value)
++do_pam_putenv(char *name, const char *value)
+ {
+ 	int ret = 1;
+ #ifdef HAVE_PAM_PUTENV
+diff -up openssh-6.0p1/auth-pam.h.role-mls openssh-6.0p1/auth-pam.h
+--- openssh-6.0p1/auth-pam.h.role-mls	2012-06-24 16:57:17.515261702 +0200
++++ openssh-6.0p1/auth-pam.h	2012-06-24 16:49:35.804071128 +0200
+@@ -38,7 +38,7 @@ void do_pam_session(void);
+ void do_pam_set_tty(const char *);
+ void do_pam_setcred(int );
+ void do_pam_chauthtok(void);
+-int do_pam_putenv(char *, char *);
++int do_pam_putenv(char *, const char *);
+ char ** fetch_pam_environment(void);
+ char ** fetch_pam_child_environment(void);
+ void free_pam_environment(char **);
+diff -up openssh-6.0p1/auth1.c.role-mls openssh-6.0p1/auth1.c
+--- openssh-6.0p1/auth1.c.role-mls	2012-06-24 16:57:17.505261305 +0200
++++ openssh-6.0p1/auth1.c	2012-06-24 16:49:35.805071090 +0200
+@@ -468,6 +468,9 @@ do_authentication(Authctxt *authctxt)
+ {
+ 	u_int ulen;
+ 	char *user, *style = NULL;
++#ifdef WITH_SELINUX
++	char *role=NULL;
++#endif
+ 
+ 	/* Get the name of the user that we wish to log in as. */
+ 	packet_read_expect(SSH_CMSG_USER);
+@@ -476,11 +479,24 @@ do_authentication(Authctxt *authctxt)
+ 	user = packet_get_cstring(&ulen);
+ 	packet_check_eom();
+ 
++#ifdef WITH_SELINUX
++	if ((role = strchr(user, '/')) != NULL)
++		*role++ = '\0';
++#endif
++
+ 	if ((style = strchr(user, ':')) != NULL)
+ 		*style++ = '\0';
++#ifdef WITH_SELINUX
++	else
++		if (role && (style = strchr(role, ':')) != NULL)
++			*style++ = '\0';
++#endif
+ 
+ 	authctxt->user = user;
+ 	authctxt->style = style;
++#ifdef WITH_SELINUX
++	authctxt->role = role;
++#endif
+ 
+ 	/* Verify that the user is a valid user. */
+ 	if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
+diff -up openssh-6.0p1/auth2.c.role-mls openssh-6.0p1/auth2.c
+--- openssh-6.0p1/auth2.c.role-mls	2012-06-24 16:57:17.507261384 +0200
++++ openssh-6.0p1/auth2.c	2012-06-24 16:49:35.806071052 +0200
+@@ -216,6 +216,9 @@ input_userauth_request(int type, u_int32
+ 	Authctxt *authctxt = ctxt;
+ 	Authmethod *m = NULL;
+ 	char *user, *service, *method, *active_methods, *style = NULL;
++#ifdef WITH_SELINUX
++	char *role = NULL;
++#endif
+ 	int authenticated = 0;
+ 
+ 	if (authctxt == NULL)
+@@ -227,6 +230,11 @@ input_userauth_request(int type, u_int32
+ 	debug("userauth-request for user %s service %s method %s", user, service, method);
+ 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+ 
++#ifdef WITH_SELINUX
++	if ((role = strchr(user, '/')) != NULL)
++		*role++ = 0;
++#endif
++
+ 	if ((style = strchr(user, ':')) != NULL)
+ 		*style++ = 0;
+ 
+@@ -249,8 +257,15 @@ input_userauth_request(int type, u_int32
+ 		    use_privsep ? " [net]" : "");
+ 		authctxt->service = xstrdup(service);
+ 		authctxt->style = style ? xstrdup(style) : NULL;
+-		if (use_privsep)
++#ifdef WITH_SELINUX
++		authctxt->role = role ? xstrdup(role) : NULL;
++#endif
++		if (use_privsep) {
+ 			mm_inform_authserv(service, style);
++#ifdef WITH_SELINUX
++			mm_inform_authrole(role);
++#endif
++		}
+ 		userauth_banner();
+ 	} else if (strcmp(user, authctxt->user) != 0 ||
+ 	    strcmp(service, authctxt->service) != 0) {
+diff -up openssh-6.0p1/auth2-gss.c.role-mls openssh-6.0p1/auth2-gss.c
+--- openssh-6.0p1/auth2-gss.c.role-mls	2012-06-24 16:57:17.522261982 +0200
++++ openssh-6.0p1/auth2-gss.c	2012-06-24 16:49:35.806071052 +0200
+@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple
+ 	Authctxt *authctxt = ctxt;
+ 	Gssctxt *gssctxt;
+ 	int authenticated = 0;
++	char *micuser;
+ 	Buffer b;
+ 	gss_buffer_desc mic, gssbuf;
+ 	u_int len;
+@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple
+ 	mic.value = packet_get_string(&len);
+ 	mic.length = len;
+ 
+-	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
++#ifdef WITH_SELINUX
++	if (authctxt->role && (strlen(authctxt->role) > 0))
++		xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
++	else
++#endif
++		micuser = authctxt->user;
++	ssh_gssapi_buildmic(&b, micuser, authctxt->service,
+ 	    "gssapi-with-mic");
+ 
+ 	gssbuf.value = buffer_ptr(&b);
+@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple
+ 		logit("GSSAPI MIC check failed");
+ 
+ 	buffer_free(&b);
++	if (micuser != authctxt->user)
++		xfree(micuser);
+ 	xfree(mic.value);
+ 
+ 	authctxt->postponed = 0;
+diff -up openssh-6.0p1/auth2-hostbased.c.role-mls openssh-6.0p1/auth2-hostbased.c
+--- openssh-6.0p1/auth2-hostbased.c.role-mls	2012-06-24 16:57:17.535262501 +0200
++++ openssh-6.0p1/auth2-hostbased.c	2012-06-24 16:49:35.807071014 +0200
+@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt)
+ 	buffer_put_string(&b, session_id2, session_id2_len);
+ 	/* reconstruct packet */
+ 	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+-	buffer_put_cstring(&b, authctxt->user);
++#ifdef WITH_SELINUX
++	if (authctxt->role) {
++		buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
++		buffer_append(&b, authctxt->user, strlen(authctxt->user));
++		buffer_put_char(&b, '/');
++		buffer_append(&b, authctxt->role, strlen(authctxt->role));
++	} else 
++#endif
++		buffer_put_cstring(&b, authctxt->user);
+ 	buffer_put_cstring(&b, service);
+ 	buffer_put_cstring(&b, "hostbased");
+ 	buffer_put_string(&b, pkalg, alen);
+diff -up openssh-6.0p1/auth2-pubkey.c.role-mls openssh-6.0p1/auth2-pubkey.c
+--- openssh-6.0p1/auth2-pubkey.c.role-mls	2012-06-24 16:57:17.517261782 +0200
++++ openssh-6.0p1/auth2-pubkey.c	2012-06-24 16:49:35.807071014 +0200
+@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt)
+ 		}
+ 		/* reconstruct packet */
+ 		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+-		buffer_put_cstring(&b, authctxt->user);
++#ifdef WITH_SELINUX
++		if (authctxt->role) {
++			buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
++			buffer_append(&b, authctxt->user, strlen(authctxt->user));
++			buffer_put_char(&b, '/');
++			buffer_append(&b, authctxt->role, strlen(authctxt->role));
++		} else 
++#endif
++			buffer_put_cstring(&b, authctxt->user);
+ 		buffer_put_cstring(&b,
+ 		    datafellows & SSH_BUG_PKSERVICE ?
+ 		    "ssh-userauth" :
+diff -up openssh-6.0p1/misc.c.role-mls openssh-6.0p1/misc.c
+--- openssh-6.0p1/misc.c.role-mls	2012-06-24 17:02:27.116348979 +0200
++++ openssh-6.0p1/misc.c	2012-06-24 16:58:09.631883672 +0200
+@@ -427,6 +427,7 @@ char *
+ colon(char *cp)
+ {
+ 	int flag = 0;
++	int start = 1;
+ 
+ 	if (*cp == ':')		/* Leading colon is part of file name. */
+ 		return NULL;
+@@ -442,6 +443,13 @@ colon(char *cp)
+ 			return (cp);
+ 		if (*cp == '/')
+ 			return NULL;
++		if (start) {
++		/* Slash on beginning or after dots only denotes file name. */
++			if (*cp == '/')
++				return (0);
++			if (*cp != '.')
++				start = 0;
++		}
+ 	}
+ 	return NULL;
+ }
+diff -up openssh-6.0p1/monitor.c.role-mls openssh-6.0p1/monitor.c
+--- openssh-6.0p1/monitor.c.role-mls	2012-06-24 16:57:17.510261504 +0200
++++ openssh-6.0p1/monitor.c	2012-06-24 16:49:35.809070938 +0200
+@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *);
+ int mm_answer_pwnamallow(int, Buffer *);
+ int mm_answer_auth2_read_banner(int, Buffer *);
+ int mm_answer_authserv(int, Buffer *);
++#ifdef WITH_SELINUX
++int mm_answer_authrole(int, Buffer *);
++#endif
+ int mm_answer_authpassword(int, Buffer *);
+ int mm_answer_bsdauthquery(int, Buffer *);
+ int mm_answer_bsdauthrespond(int, Buffer *);
+@@ -232,6 +235,9 @@ struct mon_table mon_dispatch_proto20[]
+     {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
+     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
+     {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
++#ifdef WITH_SELINUX
++    {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
++#endif
+     {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
+     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
+ #ifdef USE_PAM
+@@ -835,6 +841,9 @@ mm_answer_pwnamallow(int sock, Buffer *m
+ 	else {
+ 		/* Allow service/style information on the auth context */
+ 		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
++#ifdef WITH_SELINUX
++		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
++#endif
+ 		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
+ 	}
+ #ifdef USE_PAM
+@@ -878,6 +887,25 @@ mm_answer_authserv(int sock, Buffer *m)
+ 	return (0);
+ }
+ 
++#ifdef WITH_SELINUX
++int
++mm_answer_authrole(int sock, Buffer *m)
++{
++	monitor_permit_authentications(1);
++
++	authctxt->role = buffer_get_string(m, NULL);
++	debug3("%s: role=%s",
++	    __func__, authctxt->role);
++
++	if (strlen(authctxt->role) == 0) {
++		xfree(authctxt->role);
++		authctxt->role = NULL;
++	}
++
++	return (0);
++}
++#endif
++
+ int
+ mm_answer_authpassword(int sock, Buffer *m)
+ {
+@@ -1254,7 +1282,7 @@ static int
+ monitor_valid_userblob(u_char *data, u_int datalen)
+ {
+ 	Buffer b;
+-	char *p;
++	char *p, *r;
+ 	u_int len;
+ 	int fail = 0;
+ 
+@@ -1280,6 +1308,8 @@ monitor_valid_userblob(u_char *data, u_i
+ 	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
+ 		fail++;
+ 	p = buffer_get_string(&b, NULL);
++	if ((r = strchr(p, '/')) != NULL)
++		*r = '\0';
+ 	if (strcmp(authctxt->user, p) != 0) {
+ 		logit("wrong user name passed to monitor: expected %s != %.100s",
+ 		    authctxt->user, p);
+@@ -1311,7 +1341,7 @@ monitor_valid_hostbasedblob(u_char *data
+     char *chost)
+ {
+ 	Buffer b;
+-	char *p;
++	char *p, *r;
+ 	u_int len;
+ 	int fail = 0;
+ 
+@@ -1328,6 +1358,8 @@ monitor_valid_hostbasedblob(u_char *data
+ 	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
+ 		fail++;
+ 	p = buffer_get_string(&b, NULL);
++	if ((r = strchr(p, '/')) != NULL)
++		*r = '\0';
+ 	if (strcmp(authctxt->user, p) != 0) {
+ 		logit("wrong user name passed to monitor: expected %s != %.100s",
+ 		    authctxt->user, p);
+diff -up openssh-6.0p1/monitor.h.role-mls openssh-6.0p1/monitor.h
+--- openssh-6.0p1/monitor.h.role-mls	2012-06-24 16:57:17.520261902 +0200
++++ openssh-6.0p1/monitor.h	2012-06-24 16:49:35.809070938 +0200
+@@ -31,6 +31,9 @@
+ enum monitor_reqtype {
+ 	MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
+ 	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
++#ifdef WITH_SELINUX
++	MONITOR_REQ_AUTHROLE,
++#endif
+ 	MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
+ 	MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
+ 	MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
+diff -up openssh-6.0p1/monitor_wrap.c.role-mls openssh-6.0p1/monitor_wrap.c
+--- openssh-6.0p1/monitor_wrap.c.role-mls	2012-06-24 16:57:17.537262580 +0200
++++ openssh-6.0p1/monitor_wrap.c	2012-06-24 16:49:35.810070900 +0200
+@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char *
+ 	buffer_free(&m);
+ }
+ 
++/* Inform the privileged process about role */
++
++#ifdef WITH_SELINUX
++void
++mm_inform_authrole(char *role)
++{
++	Buffer m;
++
++	debug3("%s entering", __func__);
++
++	buffer_init(&m);
++	buffer_put_cstring(&m, role ? role : "");
++
++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
++
++	buffer_free(&m);
++}
++#endif
++
+ /* Do the password authentication */
+ int
+ mm_auth_password(Authctxt *authctxt, char *password)
+diff -up openssh-6.0p1/monitor_wrap.h.role-mls openssh-6.0p1/monitor_wrap.h
+--- openssh-6.0p1/monitor_wrap.h.role-mls	2012-06-24 16:57:17.513261623 +0200
++++ openssh-6.0p1/monitor_wrap.h	2012-06-24 16:49:35.811070862 +0200
+@@ -42,6 +42,9 @@ int mm_is_monitor(void);
+ DH *mm_choose_dh(int, int, int);
+ int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
+ void mm_inform_authserv(char *, char *);
++#ifdef WITH_SELINUX
++void mm_inform_authrole(char *);
++#endif
+ struct passwd *mm_getpwnamallow(const char *);
+ char *mm_auth2_read_banner(void);
+ int mm_auth_password(struct Authctxt *, char *);
+diff -up openssh-6.0p1/openbsd-compat/Makefile.in.role-mls openssh-6.0p1/openbsd-compat/Makefile.in
+--- openssh-6.0p1/openbsd-compat/Makefile.in.role-mls	2012-06-24 16:57:17.525262102 +0200
++++ openssh-6.0p1/openbsd-compat/Makefile.in	2012-06-24 16:51:38.087889399 +0200
+@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport
+ 
+ COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
+ 
+-PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
++PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o
+ 
+ .c.o:
+ 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+diff -up openssh-6.0p1/openbsd-compat/port-linux.c.role-mls openssh-6.0p1/openbsd-compat/port-linux.c
+--- openssh-6.0p1/openbsd-compat/port-linux.c.role-mls	2012-06-24 16:57:17.527262182 +0200
++++ openssh-6.0p1/openbsd-compat/port-linux.c	2012-06-24 17:00:55.621978528 +0200
+@@ -31,68 +31,271 @@
+ 
+ #include "log.h"
+ #include "xmalloc.h"
++#include "servconf.h"
+ #include "port-linux.h"
++#include "key.h"
++#include "hostfile.h"
++#include "auth.h"
+ 
+ #ifdef WITH_SELINUX
+ #include <selinux/selinux.h>
+ #include <selinux/flask.h>
++#include <selinux/context.h>
+ #include <selinux/get_context_list.h>
++#include <selinux/get_default_type.h>
++#include <selinux/av_permissions.h>
++
++#ifdef HAVE_LINUX_AUDIT
++#include <libaudit.h>
++#include <unistd.h>
++#endif
+ 
+ #ifndef SSH_SELINUX_UNCONFINED_TYPE
+ # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:"
+ #endif
+ 
+-/* Wrapper around is_selinux_enabled() to log its return value once only */
+-int
+-ssh_selinux_enabled(void)
++extern ServerOptions options;
++extern Authctxt *the_authctxt;
++extern int inetd_flag;
++extern int rexeced_flag;
++
++/* Send audit message */
++static int
++send_audit_message(int success, security_context_t default_context,
++		       security_context_t selected_context)
++{
++	int rc=0;
++#ifdef HAVE_LINUX_AUDIT
++	char *msg = NULL;
++	int audit_fd = audit_open();
++	security_context_t default_raw=NULL;
++	security_context_t selected_raw=NULL;
++	rc = -1;
++	if (audit_fd < 0) {
++		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
++					errno == EAFNOSUPPORT)
++				return 0; /* No audit support in kernel */
++		error("Error connecting to audit system.");
++		return rc;
++	}
++	if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
++		error("Error translating default context.");
++		default_raw = NULL;
++	}
++	if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
++		error("Error translating selected context.");
++		selected_raw = NULL;
++	}
++	if (asprintf(&msg, "sshd: default-context=%s selected-context=%s",
++		     default_raw ? default_raw : (default_context ? default_context: "?"),
++		     selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) {
++		error("Error allocating memory.");
++		goto out;
++	}
++	if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
++				   msg, NULL, NULL, NULL, success) <= 0) {
++		error("Error sending audit message.");
++		goto out;
++	}
++	rc = 0;
++      out:
++	free(msg);
++	freecon(default_raw);
++	freecon(selected_raw);
++	close(audit_fd);
++#endif
++	return rc;
++}
++
++static int
++mls_range_allowed(security_context_t src, security_context_t dst)
+ {
+-	static int enabled = -1;
++	struct av_decision avd;
++	int retval;
++	unsigned int bit = CONTEXT__CONTAINS;
++
++	debug("%s: src:%s dst:%s", __func__, src, dst);
++	retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd);
++	if (retval || ((bit & avd.allowed) != bit))
++		return 0;
++
++	return 1;
++}
++
++static int
++get_user_context(const char *sename, const char *role, const char *lvl,
++	security_context_t *sc) {
++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
++	if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) {
++	        /* User may have requested a level completely outside of his 
++	           allowed range. We get a context just for auditing as the
++	           range check below will certainly fail for default context. */
++#endif
++		if (get_default_context(sename, NULL, sc) != 0) {
++			*sc = NULL;
++			return -1;
++		}
++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
++	}
++#endif
++	if (role != NULL && role[0]) {
++		context_t con;
++		char *type=NULL;
++		if (get_default_type(role, &type) != 0) {
++			error("get_default_type: failed to get default type for '%s'",
++				role);
++			goto out;
++		}
++		con = context_new(*sc);
++		if (!con) {
++			goto out;
++		}
++		context_role_set(con, role);
++		context_type_set(con, type);
++		freecon(*sc);
++		*sc = strdup(context_str(con));
++		context_free(con);
++		if (!*sc) 
++			return -1;
++	}
++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
++	if (lvl != NULL && lvl[0]) {
++		/* verify that the requested range is obtained */
++		context_t con;
++		security_context_t obtained_raw;
++		security_context_t requested_raw;
++		con = context_new(*sc);
++		if (!con) {
++			goto out;
++		}
++		context_range_set(con, lvl);
++		if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) {
++			context_free(con);
++			goto out;
++		}
++		if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) {
++			freecon(obtained_raw);
++			context_free(con);
++			goto out;
++		}
+ 
+-	if (enabled == -1) {
+-		enabled = (is_selinux_enabled() == 1);
+-		debug("SELinux support %s", enabled ? "enabled" : "disabled");
++		debug("get_user_context: obtained context '%s' requested context '%s'",
++			obtained_raw, requested_raw);
++		if (strcmp(obtained_raw, requested_raw)) {
++			/* set the context to the real requested one but fail */
++			freecon(requested_raw);
++			freecon(obtained_raw);
++			freecon(*sc);
++			*sc = strdup(context_str(con));
++			context_free(con);
++			return -1;
++		}
++		freecon(requested_raw);
++		freecon(obtained_raw);
++		context_free(con);
+ 	}
++#endif
++	return 0;
++      out:
++	freecon(*sc);
++	*sc = NULL;
++	return -1;
++}
+ 
+-	return (enabled);
++static void
++ssh_selinux_get_role_level(char **role, const char **level)
++{
++	*role = NULL;
++	*level = NULL;
++	if (the_authctxt) {
++		if (the_authctxt->role != NULL) {
++			char *slash;
++			*role = xstrdup(the_authctxt->role);
++			if ((slash = strchr(*role, '/')) != NULL) {
++				*slash = '\0';
++				*level = slash + 1;
++			}
++		}
++	}
+ }
+ 
+ /* Return the default security context for the given username */
+ static security_context_t
+-ssh_selinux_getctxbyname(char *pwname)
++ssh_selinux_getctxbyname(char *pwname,
++	security_context_t *default_sc, security_context_t *user_sc)
+ {
+-	security_context_t sc = NULL;
+-	char *sename = NULL, *lvl = NULL;
+-	int r;
++	char *sename, *lvl;
++	char *role;
++	const char *reqlvl;
++	int r = 0;
++	context_t con = NULL;
++ 
++	ssh_selinux_get_role_level(&role, &reqlvl);
+ 
+ #ifdef HAVE_GETSEUSERBYNAME
+-	if (getseuserbyname(pwname, &sename, &lvl) != 0)
+-		return NULL;
++	if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
++		sename = NULL;
++		lvl = NULL;
++	}
+ #else
+ 	sename = pwname;
+-	lvl = NULL;
++	lvl = "";
+ #endif
+ 
++	if (r == 0) {
+ #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
+-	r = get_default_context_with_level(sename, lvl, NULL, &sc);
++		r = get_default_context_with_level(sename, lvl, NULL, default_sc);
+ #else
+-	r = get_default_context(sename, NULL, &sc);
++		r = get_default_context(sename, NULL, default_sc);
+ #endif
++	}
++
++	if (r == 0) {
++		/* If launched from xinetd, we must use current level */
++		if (inetd_flag && !rexeced_flag) {
++			security_context_t sshdsc=NULL;
++
++			if (getcon_raw(&sshdsc) < 0)
++				fatal("failed to allocate security context");
++
++			if ((con=context_new(sshdsc)) == NULL)
++				fatal("failed to allocate selinux context");
++			reqlvl = context_range_get(con);
++			freecon(sshdsc);
++			if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0)
++			    /* we actually don't change level */
++			    reqlvl = "";
++
++			debug("%s: current connection level '%s'", __func__, reqlvl);
+ 
+-	if (r != 0) {
+-		switch (security_getenforce()) {
+-		case -1:
+-			fatal("%s: ssh_selinux_getctxbyname: "
+-			    "security_getenforce() failed", __func__);
+-		case 0:
+-			error("%s: Failed to get default SELinux security "
+-			    "context for %s", __func__, pwname);
+-			sc = NULL;
+-			break;
+-		default:
+-			fatal("%s: Failed to get default SELinux security "
+-			    "context for %s (in enforcing mode)",
+-			    __func__, pwname);
+ 		}
++		
++		if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) {
++			r = get_user_context(sename, role, reqlvl, user_sc);
++		
++			if (r == 0 && reqlvl != NULL && reqlvl[0]) {
++				security_context_t default_level_sc = *default_sc;
++				if (role != NULL && role[0]) {
++					if (get_user_context(sename, role, lvl, &default_level_sc) < 0)
++						default_level_sc = *default_sc;
++				}
++				/* verify that the requested range is contained in the user range */
++				if (mls_range_allowed(default_level_sc, *user_sc)) {
++					logit("permit MLS level %s (user range %s)", reqlvl, lvl);
++				} else {
++					r = -1;
++					error("deny MLS level %s (user range %s)", reqlvl, lvl);
++				}
++				if (default_level_sc != *default_sc)
++					freecon(default_level_sc);
++			}
++		} else {
++			*user_sc = *default_sc;
++		}
++	}
++	if (r != 0) {
++		error("%s: Failed to get default SELinux security "
++		    "context for %s", __func__, pwname);
+ 	}
+ 
+ #ifdef HAVE_GETSEUSERBYNAME
+@@ -102,7 +305,42 @@ ssh_selinux_getctxbyname(char *pwname)
+ 		xfree(lvl);
+ #endif
+ 
+-	return sc;
++	if (role != NULL)
++		xfree(role);
++	if (con)
++		context_free(con);
++ 
++	return (r);
++}
++
++/* Setup environment variables for pam_selinux */
++static int
++ssh_selinux_setup_pam_variables(void)
++{
++	const char *reqlvl;
++	char *role;
++	char *use_current;
++	int rv;
++
++	debug3("%s: setting execution context", __func__);
++
++	ssh_selinux_get_role_level(&role, &reqlvl);
++
++	rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
++	
++	if (inetd_flag && !rexeced_flag) {
++		use_current = "1";
++	} else {
++		use_current = "";
++		rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
++	}
++
++	rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
++
++	if (role != NULL)
++		xfree(role);
++	
++	return rv;
+ }
+ 
+ /* Set the execution context to the default for the specified user */
+@@ -110,28 +348,71 @@ void
+ ssh_selinux_setup_exec_context(char *pwname)
+ {
+ 	security_context_t user_ctx = NULL;
++	int r = 0;
++	security_context_t default_ctx = NULL;
+ 
+ 	if (!ssh_selinux_enabled())
+ 		return;
+ 
++	if (options.use_pam) {
++		/* do not compute context, just setup environment for pam_selinux */
++		if (ssh_selinux_setup_pam_variables()) {
++			switch (security_getenforce()) {
++			case -1:
++				fatal("%s: security_getenforce() failed", __func__);
++			case 0:
++				error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.",
++				    __func__);
++			break;
++			default:
++				fatal("%s: SELinux PAM variable setup failure. Aborting connection.",
++				    __func__);
++			}
++		}
++		return;
++	}
++
+ 	debug3("%s: setting execution context", __func__);
+ 
+-	user_ctx = ssh_selinux_getctxbyname(pwname);
+-	if (setexeccon(user_ctx) != 0) {
++	r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
++	if (r >= 0) {
++		r = setexeccon(user_ctx);
++		if (r < 0) {
++			error("%s: Failed to set SELinux execution context %s for %s",
++			    __func__, user_ctx, pwname);
++		} 
++#ifdef HAVE_SETKEYCREATECON
++		else if (setkeycreatecon(user_ctx) < 0) {
++			error("%s: Failed to set SELinux keyring creation context %s for %s",
++			    __func__, user_ctx, pwname);
++		}
++#endif
++	}
++	if (user_ctx == NULL) {
++		user_ctx = default_ctx;
++	}
++	if (r < 0 || user_ctx != default_ctx) {
++		/* audit just the case when user changed a role or there was
++		   a failure */
++		send_audit_message(r >= 0, default_ctx, user_ctx);
++	}
++	if (r < 0) {
+ 		switch (security_getenforce()) {
+ 		case -1:
+ 			fatal("%s: security_getenforce() failed", __func__);
+ 		case 0:
+-			error("%s: Failed to set SELinux execution "
+-			    "context for %s", __func__, pwname);
++			error("%s: SELinux failure. Continuing in permissive mode.",
++			    __func__);
+ 			break;
+ 		default:
+-			fatal("%s: Failed to set SELinux execution context "
+-			    "for %s (in enforcing mode)", __func__, pwname);
++			fatal("%s: SELinux failure. Aborting connection.",
++			    __func__);
+ 		}
+ 	}
+-	if (user_ctx != NULL)
++	if (user_ctx != NULL && user_ctx != default_ctx)
+ 		freecon(user_ctx);
++	if (default_ctx != NULL)
++		freecon(default_ctx);
+ 
+ 	debug3("%s: done", __func__);
+ }
+@@ -149,7 +430,10 @@ ssh_selinux_setup_pty(char *pwname, cons
+ 
+ 	debug3("%s: setting TTY context on %s", __func__, tty);
+ 
+-	user_ctx = ssh_selinux_getctxbyname(pwname);
++	if (getexeccon(&user_ctx) < 0) {
++		error("%s: getexeccon: %s", __func__, strerror(errno));
++		goto out;
++	}
+ 
+ 	/* XXX: should these calls fatal() upon failure in enforcing mode? */
+ 
+@@ -221,21 +505,6 @@ ssh_selinux_change_context(const char *n
+ 	xfree(newctx);
+ }
+ 
+-void
+-ssh_selinux_setfscreatecon(const char *path)
+-{
+-	security_context_t context;
+-
+-	if (!ssh_selinux_enabled())
+-		return;
+-	if (path == NULL) {
+-		setfscreatecon(NULL);
+-		return;
+-	}
+-	if (matchpathcon(path, 0700, &context) == 0)
+-		setfscreatecon(context);
+-}
+-
+ #endif /* WITH_SELINUX */
+ 
+ #ifdef LINUX_OOM_ADJUST
+diff -up openssh-6.0p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.0p1/openbsd-compat/port-linux_part_2.c
+--- openssh-6.0p1/openbsd-compat/port-linux_part_2.c.role-mls	2012-06-24 16:57:17.530262302 +0200
++++ openssh-6.0p1/openbsd-compat/port-linux_part_2.c	2012-06-24 16:49:35.813070786 +0200
+@@ -0,0 +1,75 @@
++/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */
++
++/*
++ * Copyright (c) 2005 Daniel Walsh <dwalsh at redhat.com>
++ * Copyright (c) 2006 Damien Miller <djm at openbsd.org>
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * Linux-specific portability code - just SELinux support at present
++ */
++
++#include "includes.h"
++
++#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
++#include <errno.h>
++#include <stdarg.h>
++#include <string.h>
++#include <stdio.h>
++
++#include "log.h"
++#include "xmalloc.h"
++#include "port-linux.h"
++#include "key.h"
++#include "hostfile.h"
++#include "auth.h"
++
++#ifdef WITH_SELINUX
++#include <selinux/selinux.h>
++#include <selinux/flask.h>
++#include <selinux/get_context_list.h>
++
++/* Wrapper around is_selinux_enabled() to log its return value once only */
++int
++ssh_selinux_enabled(void)
++{
++	static int enabled = -1;
++
++	if (enabled == -1) {
++		enabled = (is_selinux_enabled() == 1);
++		debug("SELinux support %s", enabled ? "enabled" : "disabled");
++	}
++
++	return (enabled);
++}
++
++void
++ssh_selinux_setfscreatecon(const char *path)
++{
++	security_context_t context;
++
++	if (!ssh_selinux_enabled())
++		return;
++	if (path == NULL) {
++		setfscreatecon(NULL);
++		return;
++	}
++	if (matchpathcon(path, 0700, &context) == 0)
++		setfscreatecon(context);
++}
++
++#endif /* WITH_SELINUX */
++
++#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
+diff -up openssh-6.0p1/sshd.c.role-mls openssh-6.0p1/sshd.c
+--- openssh-6.0p1/sshd.c.role-mls	2012-06-24 17:02:56.543257378 +0200
++++ openssh-6.0p1/sshd.c	2012-06-24 16:58:09.634883844 +0200
+@@ -2090,6 +2090,9 @@ main(int ac, char **av)
+ 		restore_uid();
+ 	}
+ #endif
++#ifdef WITH_SELINUX
++	ssh_selinux_setup_exec_context(authctxt->pw->pw_name);
++#endif
+ #ifdef USE_PAM
+ 	if (options.use_pam) {
+ 		do_pam_setcred(1);
diff --git a/openssh.spec b/openssh.spec
index 1f077ef..23985f7 100644
--- a/openssh.spec
+++ b/openssh.spec
@@ -74,10 +74,10 @@
 %endif
 
 # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
-%define openssh_ver 5.9p1
-%define openssh_rel 26
+%define openssh_ver 6.0p1
+%define openssh_rel 1
 %define pam_ssh_agent_ver 0.9.3
-%define pam_ssh_agent_rel 1
+%define pam_ssh_agent_rel 2
 
 Summary: An open source implementation of SSH protocol versions 1 and 2
 Name: openssh
@@ -123,15 +123,15 @@ Patch104: openssh-5.9p1-required-authentications.patch
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1402
 Patch200: openssh-5.8p1-audit0.patch
 # -"-
-Patch201: openssh-5.9p1-audit1.patch
+Patch201: openssh-6.0p1-audit1.patch
 # -"-
 Patch202: openssh-5.9p1-audit2.patch
 # -"-
 Patch203: openssh-5.9p1-audit3.patch
 # -"-
-Patch204: openssh-5.9p1-audit4.patch
+Patch204: openssh-6.0p1-audit4.patch
 # -"-
-Patch205: openssh-5.9p1-audit5.patch
+Patch205: openssh-6.0p1-audit5.patch
 
 # --- pam_ssh-agent ---
 # make it build reusing the openssh sources
@@ -140,27 +140,24 @@ Patch300: pam_ssh_agent_auth-0.9.3-build.patch
 Patch301: pam_ssh_agent_auth-0.9.2-seteuid.patch
 # explicitly make pam callbacks visible
 Patch302: pam_ssh_agent_auth-0.9.2-visibility.patch
-
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
-Patch400: openssh-5.9p1-role.patch
-#?
-Patch401: openssh-5.9p1-mls.patch
+Patch400: openssh-6.0p1-role-mls.patch
 #?
 Patch402: openssh-5.9p1-sftp-chroot.patch
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1940
-Patch403: openssh-5.9p1-sesandbox.patch
+#Patch403: openssh-5.9p1-sesandbox.patch
 #https://bugzilla.redhat.com/show_bug.cgi?id=781634
 Patch404: openssh-5.9p1-privsep-selinux.patch
 
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1663
 Patch500: openssh-5.9p1-akc.patch
 #?-- unwanted child :(
-Patch501: openssh-5.9p1-ldap.patch
+Patch501: openssh-6.0p1-ldap.patch
 #?
 Patch502: openssh-5.9p1-keycat.patch
 
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1668
-Patch600: openssh-5.9p1-keygen.patch
+#Patch600: openssh-5.9p1-keygen.patch
 #http6://bugzilla.mindrot.org/show_bug.cgi?id=1644
 Patch601: openssh-5.2p1-allow-ip-opts.patch
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1701
@@ -197,7 +194,7 @@ Patch706: openssh-5.8p1-localdomain.patch
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
 Patch707: openssh-5.9p1-redhat.patch
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :)
-Patch708: openssh-5.9p1-entropy.patch
+Patch708: openssh-6.0p1-entropy.patch
 #https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX)
 Patch709: openssh-5.9p1-vendor.patch
 #?
@@ -424,10 +421,9 @@ popd
 %endif
 
 %if %{WITH_SELINUX}
-%patch400 -p1 -b .role
-%patch401 -p1 -b .mls
+%patch400 -p1 -b .role-mls
 %patch402 -p1 -b .sftp-chroot
-%patch403 -p1 -b .sesandbox
+#%patch403 -p1 -b .sesandbox
 %patch404 -p1 -b .privsep-selinux
 %endif
 
@@ -437,7 +433,7 @@ popd
 %endif
 %patch502 -p1 -b .keycat
 
-%patch600 -p1 -b .keygen
+#%patch600 -p1 -b .keygen
 %patch601 -p1 -b .ip-opts
 %patch602 -p1 -b .randclean
 %patch603 -p1 -b .glob
@@ -542,10 +538,11 @@ fi
 %endif
 %if %{WITH_SELINUX}
 	--with-selinux --with-audit=linux \
-%if 1
-	--with-sandbox=selinux \
+%if 0
+#seccomp_filter cannot be build right now
+	--with-sandbox=seccomp_filter \
 %else
-	--with-sandbox=no \
+	--with-sandbox=rlimit \
 %endif
 %endif
 %if %{kerberos5}
@@ -807,6 +804,9 @@ fi
 %endif
 
 %changelog
+* Mon Aug 06 2012 Petr Lautrbach <plautrba at redhat.com> 6.0p1-1 + 0.9.3-2
+- new upstream release
+
 * Mon Aug 06 2012 Petr Lautrbach <plautrba at redhat.com> 5.9p1-26 + 0.9.3-1
 - change SELinux context also for root user (#827109)
 
diff --git a/sources b/sources
index 96ec085..584f61b 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-085cfbb262f1b8b875aadea6fba60b1b  openssh-5.9p1-noacss.tar.bz2
+a7223e1a501bdd60a183bed87b6ce485  openssh-6.0p1-noacss.tar.bz2
 9872ca1983e566ff5a89c240529e223d  pam_ssh_agent_auth-0.9.3.tar.bz2


More information about the scm-commits mailing list