Merge pull request #190 from jtyr/master

Adding LDAP StartTLS support
This commit is contained in:
Naoki Takezoe
2013-11-15 09:10:38 -08:00
4 changed files with 66 additions and 9 deletions

View File

@@ -33,7 +33,9 @@ trait SystemSettingsControllerBase extends ControllerBase with FlashMapSupport {
"bindPassword" -> trim(label("Bind Password", optional(text()))),
"baseDN" -> trim(label("Base DN", text(required))),
"userNameAttribute" -> trim(label("User name attribute", text(required))),
"mailAttribute" -> trim(label("Mail address attribute", text(required)))
"mailAttribute" -> trim(label("Mail address attribute", text(required))),
"tls" -> trim(label("Enable TLS", optional(boolean()))),
"keystore" -> trim(label("Keystore", optional(text())))
)(Ldap.apply))
)(SystemSettings.apply)

View File

@@ -32,6 +32,8 @@ trait SystemSettingsService {
props.setProperty(LdapBaseDN, ldap.baseDN)
props.setProperty(LdapUserNameAttribute, ldap.userNameAttribute)
props.setProperty(LdapMailAddressAttribute, ldap.mailAttribute)
ldap.tls.foreach(x => props.setProperty(LdapTls, x.toString))
ldap.keystore.foreach(x => props.setProperty(LdapKeystore, x))
}
}
props.store(new java.io.FileOutputStream(GitBucketConf), null)
@@ -69,7 +71,9 @@ trait SystemSettingsService {
getOptionValue(props, LdapBindPassword, None),
getValue(props, LdapBaseDN, ""),
getValue(props, LdapUserNameAttribute, ""),
getValue(props, LdapMailAddressAttribute, "")))
getValue(props, LdapMailAddressAttribute, ""),
getOptionValue[Boolean](props, LdapTls, None),
getOptionValue(props, LdapKeystore, None)))
} else {
None
}
@@ -97,7 +101,9 @@ object SystemSettingsService {
bindPassword: Option[String],
baseDN: String,
userNameAttribute: String,
mailAttribute: String)
mailAttribute: String,
tls: Option[Boolean],
keystore: Option[String])
case class Smtp(
host: String,
@@ -129,6 +135,8 @@ object SystemSettingsService {
private val LdapBaseDN = "ldap.baseDN"
private val LdapUserNameAttribute = "ldap.username_attribute"
private val LdapMailAddressAttribute = "ldap.mail_attribute"
private val LdapTls = "ldap.tls"
private val LdapKeystore = "ldap.keystore"
private def getValue[A: ClassTag](props: java.util.Properties, key: String, default: A): A =
defining(props.getProperty(key)){ value =>

View File

@@ -3,6 +3,8 @@ package util
import util.ControlUtil._
import service.SystemSettingsService
import com.novell.ldap._
import java.security.Security
import org.slf4j.LoggerFactory
import service.SystemSettingsService.Ldap
import scala.annotation.tailrec
@@ -11,7 +13,8 @@ import scala.annotation.tailrec
*/
object LDAPUtil {
private val LDAP_VERSION: Int = 3
private val LDAP_VERSION: Int = LDAPConnection.LDAP_V3
private val logger = LoggerFactory.getLogger(getClass().getName())
/**
* Try authentication by LDAP using given configuration.
@@ -22,7 +25,9 @@ object LDAPUtil {
ldapSettings.host,
ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
ldapSettings.bindDN.getOrElse(""),
ldapSettings.bindPassword.getOrElse("")
ldapSettings.bindPassword.getOrElse(""),
ldapSettings.tls.getOrElse(false),
ldapSettings.keystore.getOrElse("")
) match {
case Some(conn) => {
withConnection(conn) { conn =>
@@ -41,7 +46,9 @@ object LDAPUtil {
ldapSettings.host,
ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
userDN,
password
password,
ldapSettings.tls.getOrElse(false),
ldapSettings.keystore.getOrElse("")
) match {
case Some(conn) => {
withConnection(conn) { conn =>
@@ -55,15 +62,41 @@ object LDAPUtil {
}
}
private def bind(host: String, port: Int, dn: String, password: String): Option[LDAPConnection] = {
val conn: LDAPConnection = new LDAPConnection
private def bind(host: String, port: Int, dn: String, password: String, tls: Boolean, keystore: String): Option[LDAPConnection] = {
if (tls) {
// Dynamically set Sun as the security provider
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider())
if (keystore.compareTo("") != 0) {
// Dynamically set the property that JSSE uses to identify
// the keystore that holds trusted root certificates
System.setProperty("javax.net.ssl.trustStore", keystore)
}
}
val conn: LDAPConnection = new LDAPConnection(new LDAPJSSEStartTLSFactory())
try {
// Connect to the server
conn.connect(host, port)
if (tls) {
// Secure the connection
conn.startTLS()
}
// Bind to the server
conn.bind(LDAP_VERSION, dn, password.getBytes)
Some(conn)
} catch {
case e: Exception => {
if (conn.isConnected) conn.disconnect()
// Provide more information if something goes wrong
logger.info("" + e)
if (conn.isConnected) {
conn.disconnect()
}
None
}
}

View File

@@ -94,6 +94,20 @@
<span id="error-ldap_mailAttribute" class="error"></span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="ldap.tls"@if(settings.ldap.flatMap(_.tls).getOrElse(false)){ checked}/> Enable TLS
</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ldapBindDN">Keystore</label>
<div class="controls">
<input type="text" id="ldapKeystore" name="ldap.keystore" value="@settings.ldap.map(_.keystore)"/>
<span id="error-ldap_keystore" class="error"></span>
</div>
</div>
</div>
<!--====================================================================-->
<!-- Notification email -->