UnboundID SASL cannot acquire password - java

Relating to my other question: UnboundID LDAP DIGEST-MD5 binding cause NPE
I'm using ApacheDS as the server and UnboundID as the API.
I followed the suggested answer and the NPE is gone. However, now I'm getting this error.
LDAPException(resultCode=49 (invalid credentials), errorMessage='INVALID_CREDENTIALS: DIGEST-MD5: cannot acquire password for 'dn:uid=blah,ou=dev,dc=blah,dc=com in realm : mizar.com', diagnosticMessage='INVALID_CREDENTIALS: DIGEST-MD5: cannot acquire password for dn:uid=blah,ou=dev,dc=blah,dc=com in realm : blah.com')
at com.unboundid.ldap.sdk.LDAPConnection.bind(LDAPConnection.java:1881)
at UnboundDemo.main(UnboundDemo.java:40)
Code as follows:
conn = new LDAPConnection("1.1.1.1",389);
mdBind = new DIGESTMD5BindRequest("dn:uid=blah,ou=dev,dc=blah,dc=com", null, "test", "blah.com",null);
bindResult = conn.bind(mdBind);
System.out.println("MD5 bind success!");
Here's the ApacheDS SASL configuration from the Directory Studio config page:
SASL Host: 1.1.1.1
SASL Principal: ldap/ldap.example.com#EXAMPLE.COM
Search Base Dn: ou=dev,dc=blah,dc=com
The ApacheDS doc didn't explain what the SASL Principal is so I'm starting to think that it may be a mis-config on my part. The main idea here is to test UnboundID against a number of SASL mechanism.

It is likely the case that the ApacheDS server isn't configured to store passwords in a format that allows it to determine the clear-text value for the password.
The primary attractive property of the DIGEST-MD5 and CRAM-MD5 SASL mechanisms is that the password is combined with other information and encoded with a one-way digest before being sent to the server. This ensures that the password is not transmitted in the clear, so that it is protected against anyone who can observe the communication without the need to secure the rest of the communication. However, the ability to authenticate with one of these mechanisms requires that the server be able to determine the clear-text version of the password so that it can perform the same cryptographic processing as the client.
If you're just looking to test the UnboundID LDAP SDK's ability to perform SASL authentication, then I'd recommend using the PLAIN mechanism, since it shouldn't impose any special requirements on the user entry. If you really want to use DIGEST-MD5, then you'll need to ensure that the server has access to the clear-text representations of the passwords for the users that need to authenticate with that mechanism.
Neil

Related

Do we need Certificate for Kafka SASL_SSL?

I am confused on SASL_SSL. Do we need SSL certificate configured for the Kafka producer application ? Or is it just the username and password ? What is the difference between SASL_SSL and SASL_PLAINTEXT ? I am sending message from a plain java application to a topic.
SASL_SSL used TLS encryption like SSL so you will need to create a certificate, and with SASL_SSL you need to specify an authentication method.
This page should help you https://developer.confluent.io/learn-kafka/security/authentication-ssl-and-sasl-ssl/
SASL_PLAINTEXT doesn't use TLS encryption (SASL_PLAIN does and this uses the username/password authentication).
It really all depends on your security requirements. SASL_SSL is mainly used when integrating with a existing authentication server but this increases your vulnerability to attacks.

Java mail smtp protocol wiht google account in 2023

Well there are a lot of discussion on this topic,
but looks like that google enforce its security policy and now, if is it still possible, is hard to find a way to send and mail by the smtp protocol using google
my java application works properly, it is not a fact of code, i use it to send mail by outlook365 or hotmail
the point here is how to configure the properties to pass to the session
Session session = Session.getInstance(prop,auth)
and how to configure the google account to accept an smpt call
to be precise I'm using a google workspace account and not a standard#gmail account
regarding the properties should not be a big doubt, this are listed in several pages of google:
regarding the google account, look like there are 3 strategies:
https://support.google.com/a/answer/176600?hl=en
Option 1: Send email with SMTP relay:
after configured the routing form my domain this is the log received
mail.smtp.starttls.enable=true
mail.smtp.port=587
mail.smtp.auth=true
mail.smtp.host=smtp-relay.gmail.com
mail.smtp.ssl.protocols=TLSv1.2
mail.smtp.ssl.trust=smtp-relay.gmail.com --> in this way a consider valid their certificate
but go head...
DEBUG SMTP: protocolConnect login, host=smtp-relay.gmail.com, user=myuser#my.domain, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN failed
Caused by: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/?p=BadCredentials
Option 2: Send email with the Gmail SMTP server
tested but this is no more possible, google removed in the 2022 the creation of app password
Option 3: Send email with the restricted Gmail SMTP server
not valid approach, you can send only mail in your organization
if sameone succed could be nice to hear
Apps passwords can be used to login to googles smtp server you need to have 2fa enabled on your google account in order to create an apps password.
Simply create an apps password and use it in place of your standard gmail password in your code.
Quick fix for SMTP username and password not accepted error
How to create a Apps Password for connecting to Google's SMTP server.
Another option would be to use XOauth2 and authorize a user to access their gmail account. This can be used if you cant enable 2fa on the account.

LDAP bind authentication with Jetty

I am trying to secure Confluent Control Center 7.2.2 with the jetty LdapLoginModule. I have the following jaas configuration working.
c3 {
org.eclipse.jetty.jaas.spi.LdapLoginModule required
useLdaps="true"
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
hostname="ldaps.xxxx.xxxxx"
port="xxx"
bindDn=<user principal name>
bindPassword=<user password>
authenticationMethod="simple"
forceBindingLogin="true"
userBaseDn="DC=xxxx,DC=xxxx,DC=xxx,DC=xx"
userRdnAttribute="userPrincipalName"
userIdAttribute="userPrincipalName"
userObjectClass="user"
roleBaseDn="OU=xxxxxx,OU=xxx,OU=xxxxx,DC=xxxx,DC=xxxx,DC=xxx,DC=xx"
roleNameAttribute="cn"
roleMemberAttribute="member"
roleObjectClass="group";
};
I would like to avoid passing a bindDn and bindPassword and use the authenticating user credentials to bind instead. My understanding is that forceBindingLogin set to true should make that possible.
forceBindingLogin
Indicate whether to bind as the user that is authenticating (true), otherwise bind as the manager and perform a search to verify user password (false).
Although when I remove bindDn and bindPassword from my config I get the following error:
DAP: error code 1 - 000004DC: LdapErr: DSID-0C090A71, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v3839
It looks like bindDn is still used when forceBindingLogin is set to true.
I noticed that in the Confluence documentation, the bindDn config went from optional to required between 6.1.9 and 6.2.0. Jetty was upgraded to 9.4.39, but there is no mention as to why bindDn would now be required.
I don't have experience with Confluent Control Center, but have been dealing with a lot of Java applications and OAuth that uses LDAP authentication during the years. As a DevOps I had to also manage a few LDAP instances myself so I will be rather speaking from that background.
The authentication process with OpenLDAP requires one of the following to be true:
Allows anonymous (connection) binding
This configuration allows you to connect to the LDAP server as an anonymous user and lookup any object in the tree and therefore find any groups, users, etc.
Manager/User dn (connection) binding
This configuration mandates you to connect to the LDAP server as a pre-configured user that has access to lookup objects in the tree and find the requested groups,users,etc. You can have many Manager DNs configured to access different parts of the LDAP tree.
Notice I mentioned CONNECTION binding - think of this as how you would connect to Postgres or MySQL. You need to have some credentials in order to lookup tables or if anonymous is enabled you can do pretty much anything.
The same thing applies to LDAP servers -- anonymous binding will allow you to establish a connection and lookup anything and manager / user dn requires authentication before the connection can be established.
People are not always deeply aware of LDAP's architecture and the documentation doesn't really help there. As such, the terminology makes you jump to the rational conclusion you jumped to:
#alex: I would like to avoid passing a bindDn and bindPassword and use the authenticating user credentials to bind instead
This would work only when the LDAP server is configured to allow Anonymous connections. If it is configured to require Manager/User DN connection:
When you bind as the user the authentication will likely pass (unless LDAP is configured not to allow that at all).
Once it succeeds it you would attempt to lookup the authorization objects (roles / groups / etc). At this point it will fail due to the inability to do the needed lookups and finally the result will be failed login.
To validate if this is the case you are ending in you should:
Use some tool to the LDAP server (you can try Apache Directory Studio
Setup a connection with binds as the bespoken user (i.e. my-username; not the manager dn, not a read-only dn)
Once you are connected try to lookup the userBaseDn and roleBaseDn DN's -- you are most likely not going to see any of the roles.
If the above is true then what you want is not possible with the current LDAP server setup.
If not -- then the LDAP server truly allows you to bind as the user and to lookup the directory tree. In this case you should open up a bug report with Confluent.

How to protect password sending through httpclient method in java

From SCAVA security scan tool it is reported that some of my code lines are subject to vulnerability.
The vulnerability classification is :
Insufficient_Sensitive_Transport_Layer
The vulnerable code contains
httpclient.addHeader() method sending password to login a server/api.
Application is in java langauge.
From google, I got to know that we can add some encryption method to avoid this vulnerability.
HttpGet getMethod = null;
getMethod = new HttpGet("http/https url to connect");
getMethod.addHeader(USERNAME,PASSWORD); // Vulnerability reported in
//this line as it is sending the password without any protection.
How can i prevent this vulnerability and pass the password in a secure way through some encryption method.
Thanks in advance.
Enable Transport Layer Security (TLS) each time you have to send credentials as plain text. If you have correctly configured https:// with latest secure version of TLS the communication will be secure.
Moreover, there are situations where sending plain text credentials can't be avoided e.g. user login process. Automatic scanning tools might not be smart enough to distinguish valid use cases and raise a false-positive.

jdbcDigestAuthentication only works when providing the hash

I started a project setting up basic authentication. I now want to switch to Digest Authentication. The problem is that the authentication is validated only if I provide the hash of the actual password, and not the actual password.
I did the following to switch from BASIC to DIGEST:
changed in my web.xml the auth-method to DIGEST
changed the JAAS context of my JDBC Realm to "jdbcDigestRealm"
in my db, I used to have "password" as a password, I changed in to the result of MD5(webuser:postgres:webuser) (where webuser is the login, webuser is the password, and postgres is the realm), in other words I set the password in my table to c3c2681ed07a5a2a5cb772061a8385e8.
The problem I have is that the login popup is displayed by the browser when I try to access the resource, but using "webuser" as the password doesn't work. However, using "c3c2681ed07a5a2a5cb772061a8385e8" as the password works. It looks like I'm still in BASIC authentication mode.
Any clue ?
Thank you !
The DIGEST auth-method is same as HTTP Digest Authentication. It just encrypts the communication between the browser and the server. The server still has the password in plain text.
From http://java.boot.by/wcd-guide/ch05s03.html:
The difference between basic and digest authentication is that on the
network connection between the browser and the server, the password is
encrypted, even on a non-SSL connection. In the server, the password
can be stored in clear text or encrypted text, which is true for all
login methods and is independent of the choice that the application
deployer makes.
You should set the digest-algorithm property of your JDBC Realm to MD5. After that the JDBC Realm will hash the password.
Perhaps you may need to change the digest algorithm in the realm view from glassfish console to MD5. Default value from GlassFish 3.0.* is still MD5, but from GlassFish 3.1.* has changed to SHA-256. This could be solution.
Adem

Categories

Resources