Making connection to Zookeeper from AuthenticationProvider in Zookeeper - apache-zookeeper

I'm making AuthenticationProvider that during authentication connects to Zookeeper (the same it is running on) and check in node if this user gave correct password.
Basically the flow looks smth like this:
#Override
public KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte[] authData) {
final String usernameColonPassword = new String(authData);
String[] split = usernameColonPassword.split(":");
final String username = split[0];
final String password = split[1];
byte[] binary = curator.getData().forPath(ATUH_NODE); // here error is thrown
// check is password is correct
}
The problem is that all the time I'm getting KeeperErrorCode = ConnectionLoss at line when curator get data. What is the reason of this behavior? During an authentication I'm not allowed to do connection to Zookeeper that is authorizing client?
Below full stacktrace:
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for XXX
at org.apache.zookeeper.KeeperException.create(KeeperException.java:99)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
at org.apache.zookeeper.ZooKeeper.exists(ZooKeeper.java:1045)
at org.apache.curator.framework.imps.ExistsBuilderImpl$2.call(ExistsBuilderImpl.java:172)
at org.apache.curator.framework.imps.ExistsBuilderImpl$2.call(ExistsBuilderImpl.java:161)
at org.apache.curator.RetryLoop.callWithRetry(RetryLoop.java:107)
at org.apache.curator.framework.imps.ExistsBuilderImpl.pathInForeground(ExistsBuilderImpl.java:157)
at org.apache.curator.framework.imps.ExistsBuilderImpl.forPath(ExistsBuilderImpl.java:148)
at org.apache.curator.framework.imps.ExistsBuilderImpl.forPath(ExistsBuilderImpl.java:36)

As I found it is impossible. At this point zookeeper is having some kind of lock/semaphore and he's not accepting new connections from this thread.

Related

MqttBrowserClient fails to connect due to missing conack package

I am trying to make webapp over flutter which will connect to HIVE broker. I took the broker name from the official website, set the port number to 8000 just like mentioned there and still get the error message as below:
error is mqtt-client::NoConnectionException: The maximum allowed connection attempts ({1}) were exceeded. The broker is not responding to the connection request message (Missing Connection Acknowledgement?
I really have no clue how to proceed. Can someone please help?
Below is my code:
MqttBrowserClient mq = MqttBrowserClient(
'wss://broker.mqttdashboard.com:8000', '',
maxConnectionAttempts: 1);
/*
MqttBrowserClient mq = MqttBrowserClient('ws://test.mosquitto.org', 'client-1',
maxConnectionAttempts: 1);
*/
class mqttService {
Future<MqttBrowserClient?> connectToServer() async {
try {
final connMess = MqttConnectMessage()
.withClientIdentifier('clientz5tWzoydVL')
.authenticateAs('a14guguliye', 'z5tWzoydVL')
.withWillTopic('willtopic')
.withWillMessage('My Will message')
.startClean() // Non persistent session for testing
.withWillQos(MqttQos.atLeastOnce);
mq.port = 1883;
mq.keepAlivePeriod = 50;
mq.connectionMessage = connMess;
mq.websocketProtocols = MqttClientConstants.protocolsSingleDefault;
mq.onConnected = onConnected;
var status = await mq.connect();
return mq;
} catch (e) {
print("error is " + e.toString());
mq.disconnect();
return null;
}
}
}
That port 8000 may be open but the HiveMQ broker may not be listening.
Make sure that the broker is fully booted and binds to that IP:Port combo.
In the HiveMQ broker startup output, you should see something similar to:
Started Websocket Listener on address 0.0.0.0 and on port 8000
If needed, the HiveMQ Broker configuration documentation is here.
You can use the public HiveMQ MQTT Websocket demo client to test your connection to make sure it's not a local code issue.
As a last option, use Wireshark to monitor MQTT traffic with a filter of tcp.port == 8000 and mqtt

Generate SPNEGO Token Failured

I tried to generate the token which can be used as the HTTP header to authenticate to the HDFS WebHDFS URL and Oozie REST API URL.
I referenced the url below to have the below code to generate the Negotiate token.
https://www.ibm.com/support/knowledgecenter/en/SS7JFU_8.5.5/com.ibm.websphere.express.doc/ae/tsec_SPNEGO_token.html
public class TokenCreation {
private static final String SPNEGO_OID = "1.3.6.1.5.5.2";
private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
public static byte[] genToken(String principal) {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
byte[] spnegoToken = new byte[0];
try {
Oid spnegoMechOid = new Oid(SPNEGO_OID);
Oid krb5MechOid = new Oid(KERBEROS_OID);
GSSCredential clientGssCreds = null;
GSSManager manager = GSSManager.getInstance();
GSSName gssUserName = manager.createName(principal, GSSName.NT_USER_NAME, krb5MechOid);
clientGssCreds = manager.createCredential(gssUserName.canonicalize(krb5MechOid),
GSSCredential.INDEFINITE_LIFETIME,
krb5MechOid,
GSSCredential.INITIATE_ONLY);
clientGssCreds.add(gssUserName,
GSSCredential.INDEFINITE_LIFETIME,
GSSCredential.INDEFINITE_LIFETIME,
spnegoMechOid, GSSCredential.INITIATE_ONLY);
GSSName gssServerName = manager.createName(principal, GSSName.NT_USER_NAME);
GSSContext clientContext = manager.createContext(gssServerName.canonicalize(spnegoMechOid),
spnegoMechOid,
clientGssCreds,
GSSContext.DEFAULT_LIFETIME);
// optional enable GSS credential delegation
clientContext.requestCredDeleg(true);
// create a SPNEGO token for the target server
spnegoToken = clientContext.initSecContext(spnegoToken, 0, spnegoToken.length);
} catch (GSSException e) {
e.printStackTrace();
}
return spnegoToken;
}
But after running the above code, I always got the below prompt:
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.c.u.security.KrbUtils - after loginUserFromKeytab............AtoimcUser:HTTP/host1.exmaple.com#EXAMPLE.COM
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>User Name is HTTP/host1.exmaple.com#EXAMPLE.COM
2019-09-25 14:12:51 760 [INFO] [pool-2-thread-1] c.s.n.app.oozie.OozieAppCaller - ->>>>>>Mode is KERBEROS
>>>KinitOptions cache name is /tmp/krb5cc_0
Kerberos username [root]: ^C^C^C
Kerberos password for root:
You can see at the end of the above output log.
The "Kerberos username" is always prompt to ask for username.
Also I have tried to manually run kinit the keytab.
and the above class can generate the token successfully.
But manually run kinit is NOT the way I wanted.
Would you please help it?
Thanks.
Kerberos and SPNEGO support in Java is cumbersome unfortunately.
I've created a small library to simplify some Kerberos use cases: https://github.com/bedrin/kerb4j
You can use it like this to generate SPNEGO token:
SpnegoClient spnegoClient = SpnegoClient.loginWithKeyTab("svc_consumer", "/opt/myapp/consumer.keytab");
URL url = new URL("http://api.provider.acme.com/api/operation1");
SpnegoContext context = spnegoClient.createContext("http://provider.acme.com"); // Will result in HTTP/provider.acme.com SPN
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", context.createTokenAsAuthroizationHeader());

Java PostgreSQL: Suppress error output when connection failed

I am connecting to a postgreSQL database with java.
The user inputs a username and a password in the command line and then I test the connection. I have put a try-catch block around it, but it still prints an error message when the connection fails. I don't want the user to see this message, I just want to handle the error myself, as can usually be achieved by a try-catch construct. However, in this particular case the message gets printed anyway. How can I suppress the message here?
Relevant code:
import java.sql.*;
public class ChessDatabase {
private Connection chessDB;
private String username;
private String password;
ChessDatabase(String username, String password) {
this.username = username;
this.password = password;
}
public boolean isConnected() {
try {
chessDB = DriverManager.getConnection("jdbc:postgresql://[...]", username, password);
} catch (Exception e) {
return false;
}
return true;
}
}
Error message:
Jun 25, 2018 3:38:24 PM org.postgresql.core.v3.ConnectionFactoryImpl log
WARNING: SQLException occurred while connecting to [...]
org.postgresql.util.PSQLException: FATAL: PAM authentication failed for user "[...]"
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:473)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:205)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
at org.postgresql.Driver.makeConnection(Driver.java:452)
at org.postgresql.Driver.connect(Driver.java:254)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
at ChessDatabase.isConnected(ChessDatabase.java:35)
[...]
Jun 25, 2018 3:38:24 PM org.postgresql.Driver connect
SEVERE: Connection error:
org.postgresql.util.PSQLException: FATAL: PAM authentication failed for user "[...]"
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:473)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:205)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
at org.postgresql.Driver.makeConnection(Driver.java:452)
at org.postgresql.Driver.connect(Driver.java:254)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
at ChessDatabase.isConnected(ChessDatabase.java:35)
[...]
PS: Just for clarification, the connection works and no error message is printed if username and password are correct. So the issue is not getting rid of the error, just of the message.
Thanks to the link JB Nizet provided, I could find that I can append "?loggerLevel=OFF" to the first parameter in DriverManager.getConnection(). That way the message does not get printed.

javax.security.sasl.SaslException: Authentication failed: the server presented no authentication mechanisms in Wildfly 10.1

I am new to EJBs, and I am trying to perform remote invocations on stateless and stateful beans that I have deployed on a pod in my project that is based on Wildfly 10.1 in the new OpenShift 3 (Origin). The code that I am using for initializing the client context looks like:
Properties clientProperties = new Properties();
clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
clientProperties.put("remote.connections", "default");
clientProperties.put("remote.connection.default.host", "localhost");
clientProperties.put("remote.connection.default.port", "8080");
clientProperties.put("remote.connection.default.username", "****");
clientProperties.put("remote.connection.default.password", "****"); clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new
PropertiesBasedEJBClientConfiguration(clientProperties)));
Properties contextProperties = new Properties();
contextProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
contextProperties.put(Context.SECURITY_PRINCIPAL, "****"); //username
contextProperties.put(Context.SECURITY_CREDENTIALS, "****"); //password
Context context = new InitialContext(contextProperties);
String appName = "CloudEAR";
String moduleName = "CloudEjb";
String distinctName = "";
String beanName = "Calculator";
String qualifiedRemoteView = "cloudEJB.view.CalculatorRemote";
String lookupString = "ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + qualifiedRemoteView;
Calculator calculator = (CalculatorRemote) context.lookup(lookupString);
int sum = calculator.sum(10, 10);
And the error message that I get is:
WARN: Could not register a EJB receiver for connection to localhost:8080
javax.security.sasl.SaslException: Authentication failed: the server presented no authentication mechanisms
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:378)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:240)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:198)
at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:112)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.ChannelListeners$DelegatingChannelListener.handleEvent(ChannelListeners.java:1092)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:567)
at ...asynchronous invocation...(Unknown Source)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:272)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:388)
Initially I tried using the "jboss-ejb-client.properties" file, but that wasn't even able to make the remote connection. Now I am manually creating and configuring the EJBClientContext, and at least is successfully connecting to the remote server, but the invocation filas because of authentication failures.
I remember that we used to solve this issue by removing the "security realm" argument in "standalone.xml" files in older versions of OpenShift; however I am not able to find that file in the new version anymore. I have been looking at concepts such as secrets, volumes etc. but I really don't have a clear understanding how this works. When I create a new secret and try to associate it with my pod, the new deployment procedure fails. I would really appreciate any help.

Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

I am getting the following error when setting up an email service with spring boot while trying to connect to round cube:
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
This leads me to think roundcude is not using a SSL connection and I should not use port 143. Therefore I try and use port 25, but I get the following error when I do.
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
application.properties
#email setup
spring.mail.host = mail.email address.com
spring.mail.username = email address
spring.mail.password = my password
spring.mail.properties.mail.smtp.auth= true
spring.mail.port = 25 or port 145
spring.mail.properties.mail.smtp.socketFactory.class= javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback= false
spring.mail.properties.mail.smtp.ssl.enable = true
Email service
#Component
public class EmailServiceImpl implements EmailService {
#Autowired
private JavaMailSender javaMailSender;
#Override
public void sendEmail(String toAddress, String fromAddress,
String subject, String body) {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom(fromAddress);
simpleMailMessage.setTo(toAddress);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(body);
javaMailSender.send(simpleMailMessage);
}
}
I looked at roundcube's documentation and apparently is uses port 143 so this is rather confusing. This making me think I am setting this up wrong.
I also tried gmail but since I have a two factor authentication I ran into more issue so I decided to use roundcube which is what I would rather use anyway.
Advice?
It seems you're trying to connect to SMTP using non-secure ports. Usually secure ports would be 587 or 465.
This is the configuration that works for me to send e-mail using GMail:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=my-email#gmail.com
spring.mail.password=my-password
spring.mail.properties.mail.smtp.auth = true
spring.mail.properties.mail.smtp.starttls.enable = true
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.connectiontimeout = 60000
spring.mail.properties.mail.smtp.timeout = 60000