Wrong host sending SMTP - java

I'm trying to send a mail using javax.mail. This is my code:
Properties props = new Properties();
props.setProperty("mail.smtp.host", host);
props.setProperty("mail.smtp.port", port);
props.setProperty("mail.user", user);
props.setProperty("mail.password", password);
Session session = Session.getDefaultInstance(props);
But I get this error:
javax.mail.MessagingException: Could not connect to SMTP host: smtp.wrong.server.com, port: 25;
The funny thing is that "smtp.wrong.server.com" isn't the value that I'm passing as host.
It is like Session.getDefaultInstance(props) is returning an already created session with the wrong host name.
There isn't any other place inside my EAR where javax.mail is used (at least not in my code, maybe inside a third party dependecy?).
This behaviour only happens, of course, in PRO environment. The same EAR deployed in DEV and TEST env works fine.
Any help would be appreciated

The problem was with Session.getDefaultInstance. I should use Session.getInstance
From javadoc:
getDefaultInstance
(...)the default session is potentially available to all code executing in the same Java virtual machine(...)Subsequent calls return the Session object that was created by the first call, and ignore the passed Properties object. Use the getInstance method to get a new Session object every time the method is called.

It seams your are not using the correct key for your proerties. see Javadoc for javax.mail.Session
It is expected that the client supplies values for the properties
listed in Appendix A of the JavaMail spec (particularly
mail.store.protocol, mail.transport.protocol, mail.host, mail.user,
and mail.from) as the defaults are unlikely to work in all cases.

Related

JavaMail IMAP not using specified properties

I'm seeing an issue where when connected to a mailbox using IMAP the infinite timeout default is causing an issue. I am having an issue getting Java Mail to recgonise IMAP properties. I verified IMAP did not seem to be using the properties by setting things like port number to the value 1, which should not work.
This is the code snippit:
Properties props = new Properties()
props.put("mail.imap.port", "1");
props.put("mail.imap.timeout", "1");
props.put("mail.imaps.connectiontimeout", "1");
Session session = Session.getInstance(props, null);
Store store = session.getStore("imaps");
store.connect(***,***,***);
If anyone knows where the problem is arising from that would great, all help is appreciated.
I believe you should be using props.setProperty(key, value) instead of using props.put(key, value). The documentation here: http://docs.oracle.com/javase/tutorial/essential/environment/properties.html warns you not to use hashTable methods
You're using the "imaps" protocol but setting properties for the "imap" protocol. Change your property names to "mail.imaps.*".

Session timeout during connecting Hotmail account with Java mail API

For connecting with hotmail account through java mail API , I m setting these properties
pop3Props.setProperty("mail.pop3.ssl.enable", "true");
pop3Props.setProperty("mail.pop3s.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3s.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3s.port", "995");
pop3Props.setProperty("mail.pop3s.socketFactory.port", "995");
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3s.port", "995");
Session session = Session.getInstance(pop3Props, null);
Store store = session.getStore("pop3s");
store.connect(host, 995, username, password);
I am able to login into my hotmail account and do other operations(send/receive) but
after some time (I think) session time out happens i.e not able to connect with hotmail
server.
Later sometime onward again it is working fine ( i m able to connect with hotmail
server).
And I checked in my code that whenever I open a new connection , I m closing it also.
Please help .
Are you leaving the connection open for long periods of time without doing anything?
Are you opening and closing the connection frequently over short periods of time?
Servers have lots of ways of preventing you from "abusing" their resources. You may be running into one of them.
Or, maybe you have an unreliable network connection?
See the JavaMail FAQ for debugging tips; the debug output might provide more clues as to why it's failing.
Also see the list of common mistakes; you can simplify your code.

Must issue a STARTTLS command first when trying to send a SimpleMailMessage in Grails

I try to send a message in a grails application. I use Java code with this problem tho, here is my code
SimpleMailMessage message_ref = new SimpleMailMessage();
JavaMailSenderImpl sender_ref = new JavaMailSenderImpl();
sender_ref.setHost("smtp.gmail.com")
sender_ref.setUsername("testAccount#googlemail.com")
sender_ref.setPassword("topsecret")
message_ref.setTo("testRecipient#gmx.de")
message_ref.setSubject("Hello there")
message_ref.setText("How are you")
sender_ref.send(message_ref)
I'm getting the following exception:
SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first
I found a similar problem here on stackoverflow here
Must issue a STARTTLS command first. Sending email with Java and Google Apps
but it didn't help me cause he used an different approach.
Can somebody tell me what's wrong? I'm expecting the error is not in the code but in some configuration file and this is where my knowledge edges.
Quoting from the Grails mail plugin docs:
grails {
mail {
host = "smtp.gmail.com"
port = 465
username = "youracount#gmail.com"
password = "yourpassword"
props = ["mail.smtp.auth":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
} }
I can't help you much, but your problem is basically that you need to use SSL to communicate with the server. Google does not allow plain-text communication for a lot of good reasons. I don't know much about grails, but I assume it has some sort of ssl-support. If it does not, you're probably better off doing it in javax.mail.
StartTLS is just a text-command you send to the smtp-server to explicitly start secure communications.
Properties properties = new Properties();
properties.put("mail.smtp.host", smtpHost);
properties.put("mail.smtp.port", smtpPort);
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.user", userName);
properties.put("mail.password", password);

How to enable connection pooling over LDAP SSL?

Okay, so I'm moving my application over from non-SSL to SSL connections to my LDAP server. When running the application in non-SSL, connection pooling is working fine. However when I switch to SSL connection pools no longer work.
While researching here I realized that I never set the "com.sun.jndi.ldap.connect.pool.protocol" property to "plain ssl" since defaultly it is set to plain. I thought this was the problem.
When I implemented the change to include "plain ssl", it did not fix the problem and connection pools were still not being used.
Is there some other setting that I am missing?
Relevant code:
Hashtable LDAPEnvironment = new Hashtable();
LDAPEnvironment.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION);
LDAPEnvironment.put(Context.SECURITY_PRINCIPAL, SECURITY_PRINCIPAL);
LDAPEnvironment.put(Context.SECURITY_CREDENTIALS, SECURITY_CREDENTIALS);
LDAPEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
LDAPEnvironment.put(Context.PROVIDER_URL, PROVIDER_URL );
LDAPEnvironment.put(Context.SECURITY_AUTHENTICATION, "simple");
LDAPEnvironment.put("java.naming.ldap.version", versionOfLDAP );
if (ldapProtocol != null && ldapProtocol.equalsIgnoreCase("SSL")){
LDAPEnvironment.put(Context.SECURITY_PROTOCOL,"ssl");
LDAPEnvironment.put("com.sun.jndi.ldap.connect.pool.protocol","plain ssl");
}
LDAPEnvironment.put("com.sun.jndi.ldap.connect.pool", "true");
I have found the problem. The documentation specifically states that the those properties are system properties and not environment properties. I was setting these as environment properties. :-)
If you scroll down a little, at the link you provided (scroll to "How Connections are Pooled"), you'll see the explanation to how the pooling works.
When you request a pooled connection, you will get one only if ALL the specified properties are identical. And that's a long list of properties...
I your case this is:
connection controls
host name, port number as specified in the "java.naming.provider.url" property, referral, or URL supplied to the initial context
java.naming.security.protocol property
java.naming.ldap.version property
java.naming.security.principal property
java.naming.security.credentials property
If you always use the same constants when request a connection from the connection pool, I think you should get the same pooled connection. That is, if you set the com.sun.jndi.ldap.connect.pool.* properties properly - but I didn't see that in the code you provided.
If you did set the com.sun.jndi.ldap.connect.pool.* properties to sensible values, try setting com.sun.jndi.ldap.connect.pool.debug to fine. This will help you debug.
Another option is to use a framework, or a provider that supports connection pooling. Note that the pooling provided to you by Java is rather limited. I used Spring-Ldap in the past, and it has very good support.
Hope this helps.

Send to MQ from java always uses default installed mqm userid for IBM MQ version 6.0

Our code runs in weblogic and we MQ 6.0. No matter if I use the default createQueueConnection() or createQueueConnection("myuserid","mypassword") it always seems to use userid mqm. See code below.
When I connect from version 6.0 to an older mq installion 5 it seems to throw the following error javax.jms.JMSSecurityException: MQJMS2013: invalid security authentication supplied for MQQueueManager using the default createQueueConnection() unless I send a blank userid/password as in createQueueConnection("","")
How can I get myuserid to be send instead ?
Hashtable properties = new Hashtable(2);
properties.put(Context.PROVIDER_URL,context);
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
InitialContext ctx = new InitialContext(properties);
QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("QCF");
QueueConnection qc = qcf.createQueueConnection();
javax.jms.Queue q = (javax.jms.Queue) ctx.lookup("MYQUEUE");
QueueSession qs = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
TextMessage tm = qs.createTextMessage();
tm.setText(outString);
QueueSender sender = qs.createSender(q);
sender.send(tm);
sender.close();
qs.close();
qc.close();
If you are setting the ID in the createQueueConnection, rest assured, it is being presented to the queue manager. The problem you are seeing is that the SVRCONN channel definition on the QMgr has the value MCAUSER('mqm') hard coded. This overrides any value presented by the client app.
A couple of things to note here.
Although you can send the ID and password, WMQ accepts these at face value. The fields exist to make the credentials available for a channel exit that can validate them. Without such an exit the channel just runs as whatever ID the app claims to be and the password is ignored.
For the reason stated above, I always tell people not to trust the credentials presented unless they have such an exit. The administrator must code the appropriate value into the MCAUSER.
The administrative ID ('mqm' on UNIX flavors) is NOT the appropriate value. It confers administrative authority to anyone connecting on that channel.
For a LOT more on this topic and pointers to the WMQ security presentation and WMQ Security Lab guide from IMPACT, please see this SO question.

Categories

Resources