SASL authorization failing while connecting to XMPP server - xmpp

I am trying to connect to gmail using SMACK API through XMPP server. but getting the
error : SASL authentication failed using mechanism PLAIN
you can check a glimpse of code. I got it from net only
ConnectionConfiguration connConfig = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
connection = new XMPPConnection(connConfig);
connection.connect();
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
I checked in the smack debug window. it says in XML :
< invalid-authzid />
I am already having account on gmail and my gtalk is also running.

You need to set the authentication before you connect viz
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
must appear before connection.connect().
See my blog.

ConnectionConfiguration cc = new ConnectionConfiguration(
"vietnam.agilemobile.com", 5222, vietnam.agilemobile.com");
XMPPConnection connection = new XMPPConnection(cc);
try {
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
connection.connect();
Log.e("LOGIN", "" + 111);
// You have to put this code before you login
Log.e("LOGIN", "" + 222);
// You have to specify your gmail addres WITH #gmail.com at the end
connection.login("nemodo", "123456", "resource");
Log.e("LOGIN", "" + 333);
// See if you are authenticated
System.out.println(connection.isAuthenticated());
} catch (XMPPException e1) {
e1.printStackTrace();
}
I also get this mistake, but i can not work.

For anyone looking for possible solutions to this many years after this was originally asked and answered, I recently was able to get past this authentication error by explicitly setting the authzid value on the XMPPTCPConnectionConfiguration.
I was running into an issue where my connection configuration worked fine for some client XMPP servers, but not for others, even though they were all using SASL PLAIN authentication. After some troubleshooting, I learned that the ones that were failing were expecting an authzid value. After adjusting my code to set this, it works in both the environments that were working before, as well as the environments that were failing.
Here is how I am building my connection configuration:
XMPPTCPConnectionConfiguration.builder()
.setHost(XMPP_DOMAIN)
.setXmppDomain(XMPP_DOMAIN)
.setPort(XMPP_PORT)
.setCompressionEnabled(true) // optional, not all servers will support this
.setUsernameAndPassword(XMPP_USER, XMPP_PASSWORD)
.setResource(XMPP_RESOURCE)
.setAuthzid(JidCreate.entityBareFrom(String.format("%s#%s", XMPP_USER, XMPP_DOMAIN))) // <-- this was the change I needed
.build();
Specifically I needed to add this line:
.setAuthzid(JidCreate.entityBareFrom(String.format("%s#%s", XMPP_USER, XMPP_DOMAIN)))

Related

Liferay 7 MailService.sendMail from a custom portlet doesn't work only on HOST SERVER

I have a strange problem with a custom portlet on Liferay 7 to solve:
MailService.sendMail is working from MY COMPUTER with google smtp and a personal account: this means that the code is working...
On my HOST SERVER sending emails with the final-smtp works correctly: I tried both root and liferay user with telnet final-smtp port.
On the Liferay server on HOST SERVER, send e-mails works correctly: if I forget the password, Liferay send me the e-mail.
But ... if I try to send email with my portlet from Liferay on HOST SERVER it doesn't work without any error. I'm using Liferay MailService.sendMail. I post the code but it works (on MY COMPUTER).
I get the service in this way:
#Reference(unbind = "-")
protected void setMailService(MailService mailService) {
_mailService = mailService;
}
And the calling code is in the following:
InternetAddress fromAddress = null;
String newsletterPrefix = null;
InternetAddress toAddress = null;
try {
String smtpUser = PropsUtil.get(
"newsletter.send.mail.smtp.user");
String smtpToUser = PropsUtil.get(
"newsletter.send.mail.smtp.to.user");
if (Validator.isNotNull(smtpUser)) {
fromAddress = new InternetAddress(smtpUser);
}
if (Validator.isNotNull(smtpToUser)) {
toAddress = new InternetAddress(smtpToUser);
}
}
catch (Exception e) {
_log.error(e, e);
result = false;
}
MailMessage mailMessage = new MailMessage(
fromAddress, toAddress, subject, body, true);
mailMessage.setBCC(addressList);
_mailService.sendEmail(mailMessage);
There could be several reasons behind this, some not even code related.
I see you are using this code for a newsletter, which suggests you are using a smtp service that is meant for this.
It could be that your server is in fact sending the email, with success, but the smtp server is simply blocking, rejecting or marking to resend later. Moreover, that server might be configured to not send an error message, or sending an error message in the form of a successful delivery, but the data contains the error.
I would start checking you mail server configuration, and the accounts permissions, then its logs.
Also, you might consider using plugins for mass mail delivery, like this one: https://www.e-systems.tech/blog/-/blogs/connecting-liferay-to-mailgun
Few things you can do to debug this problem:
Make sure you are deploying the intended code on HOST machine. (Silly suggestion, but many times this is the problem.)
Try to set following package's Log level to ALL/DEBUG to see if it shows any problem in logs.com.liferay.mail.service

Getting "Client was not authenticated to send anonymous mail during MAIL FROM" error from Exchange SMTP using Rust lettre library

I am writing a Rust application that will send email through an Exchange server with SMTP functionality enabled. According to Microsoft's webpage, the settings that are required are:
Server address smtp.office365.com
Port 587
StartTLS Enabled
Credentials for mail account login
These are corroborated by the POP/IMAP settings of the webmail service.
Here is my code (with some censoring):
extern crate lettre;
use self::lettre::email::EmailBuilder;
use self::lettre::transport::smtp::{SecurityLevel, SmtpTransportBuilder, SUBMISSION_PORT};
use self::lettre::transport::smtp::authentication::Mechanism;
use self::lettre::transport::EmailTransport;
pub fn send_mail() {
let email = EmailBuilder::new()
.from("my email")
.to("destination email")
.body("testing")
.subject("testing")
.build()
.unwrap();
// Connect to SMTP server
let mut transport = SmtpTransportBuilder::new(("smtp.office365.com", SUBMISSION_PORT))
.expect("Failed to create email transport")
.encrypt()
.smtp_utf8(true)
.credentials("my email", "my password")
.authentication_mechanism(Mechanism::Login)
.build();
println!("Mail transport built");
println!("{:?}", transport.send(email.clone()));
}
When I compile and run the code,it gives me this error:
Err(Permanent(Response { code: Code { severity:
PermanentNegativeCompletion, category: Unspecified3, detail: 0 },
message: ["5.7.57 SMTP; Client was not authenticated to send anonymous
mail during MAIL FROM [SYXPR01CA0106.ausprd01.prod.outlook.com]"] }))
Why is this happening?
The closest I've come in my research is an issue on GitHub in relation to the lettre library not supporting the Login authentication mechanism (which Office 365 uses); however, the codebase was updated to support Login and I am using the master branch directly from GitHub so theoretically my application should support the Login mechanism.
Edit: Forgot to mention that I attempted an EHLO to the server, but it returned a (Client:(Connection closed)) error.
I used telnet and openssl to try connecting directly to my SMTP server, where I found that AUTH LOGIN requires 3 commands; one to send the AUTH LOGIN code, one to send the username and another to send the password. I found that the lettre library implements all its AUTH commands as single commands, so this wasn't working with the server. I downloaded the source code for the library, changed the send function to do the three separate commands, recompiled my code and everything worked fine :)
My addition to the lettre code:
if (accepted_mechanisms[0] == Mechanism::Login) &&
(accepted_mechanisms.capacity() == 1) {
try_smtp!(self.client.command("AUTH LOGIN"), self);
try_smtp!(self.client.command(base64::encode_config(
&username.as_bytes(),
base64::STANDARD).as_str()), self);
try_smtp!(self.client.command(base64::encode_config(
&password.as_bytes(),
base64::STANDARD).as_str()), self);

Fiddler Error Connecting to HTTPS Applications !SecureClientPipeDirect failed

Fiddler Error Connecting to HTTPS Applications
Fiddler Log:
!SecureClientPipeDirect failed: Authentication failed because the remote party has closed the transport stream. on pipe to (CN=services.bigpond.com, O=DO_NOT_TRUST_BC, OU=Created by http://www.fiddler2.com)
I have followed other posts but no answers
The typical explanation for this message, as documented in many places, is that the client application has not been configured to trust Fiddler's root certificate. As such, the client closes the connection to Fiddler when it sees the untrusted certificate.
http://fiddler2.com/documentation/Configure-Fiddler/Tasks/TrustFiddlerRootCert
In Kestrel I'm using an SSL cert.
I 'downgraded' the TLS protocol in order to get this to work.
This is not something you'd do in production - but in production you shouldn't be using kestrel. I'm not saying this is the best overall config, but this is mainly to show the SslProtocols option.
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 5000); // http:localhost:5000
options.Listen(IPAddress.Any, 44300, listenOptions =>
{
// https://dotnetthoughts.net/enable-http2-on-kestrel/
//listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
listenOptions.UseHttps(#"S:\WORK\SSL\example.com.pfx", "cert-password", httpsOptions =>
{
httpsOptions.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
});
});
})
.UseStartup<Startup>();

Sending a mail with Sendgrid from a Grails 2.0 application on Heroku

I'm trying to send emails from my Grails 2.0 app via Sendgrid on Heroku but I can't find the right configuration. I keep getting "Connection refused" exceptions:
java.net.ConnectException: Connection refused
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:546)
at java.net.Socket.connect(Socket.java:495)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:233)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:189)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1359)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412)
at javax.mail.Service.connect(Service.java:288)
at grails.plugin.mail.MailMessageBuilder.sendMessage(MailMessageBuilder.groovy:102)
at grails.plugin.mail.MailService.sendMail(MailService.groovy:39)
at MailGrailsPlugin$_configureSendMail_closure6.doCall(MailGrailsPlugin.groovy:149)
The latest configuration I tried is the following:
grails {
mail {
host = "smtp.sendgrid.net"
port = 587
username = System.env.SENDGRID_USERNAME
password = System.env.SENDGRID_PASSWORD
props = [
"mail.smtp.protocol":"smtps",
"mail.smtp.channel":"plain",
"mail.smtp.auth":"true",
"mail.debug":"true"
]
}
}
It looks like you might have a firewall or ISP blocking port 587. Try this: http://support.sendgrid.com/entries/131119-help-smtp-port-25-is-being-blocked
Elmer Thomas, Developer Evangelist at SendGrid.com
Actually, the problem came from my Grails configuration. For some reason, my mail config was reset at some point and what I had in Config.groovy was not used. So the app tried to send emails via localhost and that didn't work. I found a workaround to this problem but I don't understand yet why it works.

Tomcat as Clients communicating with multiple separated Servers via SSL

Here is the scenario:
I have multiple application servers running locally for now (should be running in different host) --> each is listening on different port (at localhost).
I have a single client application running on Tomcat.
When startup Tomcat, login with different user's details with connect to different (above) servers remotely.
My problem is:
First, I startup Tomcat and logged in as userA, it then connected successfully to serverA(localhost:1000).
Then I logged out.
Logged in again as userB, it did NOT connect to serverB(localhost:1001) as expected; instead, it gave exception
"javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown"
However, if I restart Tomcat, and login as userB first, it then connects successfully to serverB.
Does anyone know what the problem is?
I really appreciate any suggestion :)
Code for client Tomcat:
SetupClientKeystore();
SetupServerKeystore();
SSLContext context = SetupSSLContext();
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(hostname, portNo);
GZIPOutputStream gZipOut = new GZIPOutputStream(socket.getOutputStream()); // no trust certificate found throws here
Code for serverA and B:
setupClientKeyStore();
setupServerKeystore();
setupSSLContext();
server = new ServerSocket(portNo);
SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory();
serverSocket = (SSLServerSocket) socketFactory.createServerSocket(portNo);
serverSocket.setNeedClientAuth(true);
while ( true )
{
Socket client = serverSocket.accept();
inStream = client.getInputStream();
BufferedInputStream bufferedIn = new BufferedInputStream(inStream); //unknown_certificate throws here
//do something here.....
}
"javax.net.ssl.SSLHandshakeException: Received fatal alert:
certificate_unknown"
This usually indicates that the server's certificate is not trusted.
Could it be that when you log-in as userA you load the trusted certificate of serverA and connect, and then when you try to connect to serverB you try to authenticate serverB using the certificate of ServerA (loaded when you logged in as userA)?
As a result the SSL handshake fails.
So when you restart and login as userB the appropriate certificate (i.e. of ServerB) is loaded and the connection is succesfull?
You have no code in your post but if you do it as I say, this explains the exception.