2013-01-31 23 views
1

我正尝试使用asmack(Android Gingerbread)连接到Google Talk。我已经设置了connectionConfig.setTruststoreType("BKS") - 所以我解决了证书问题。现在失败在XMPPConnection.proceedTLSReceived()函数中,这是在服务器发送'begin'进行'starttls'请求之后调用的。(a)Smack:尝试使用XMPP登录时TLS套接字已关闭

该函数应该初始化TSL套接字。它失败,出现异常“java.net.SocketException:套接字关闭”。

// Verify certificate presented by the server 
context.init(kms, 
    new javax.net.ssl.TrustManager[]{new ServerTrustManager(getServiceName(), config)}, 
    //new javax.net.ssl.TrustManager[]{new OpenTrustManager()}, 
    new java.security.SecureRandom()); 
Socket plain = socket; 
// Secure the plain connection 
socket = context.getSocketFactory().createSocket(plain, plain.getInetAddress().getHostName(), plain.getPort(), false); 
socket.setSoTimeout(0); ////// THIS LINE THROWS THE EXCEPTION 

任何线索?

插座被描述为:在插座 SSL套接字[ADDR = talk.google.com/173.194.70.125,端口= 5222,将localPort = 34840]

它无法在模拟器上,并在我的银河S I9000。

回答

1

事实证明,SSL连接有一个超时问题。我的应用程序花了很多时间来生成SSL套接字(通过普通套接字),而另一方却放弃了......这或者是一个关键问题(但我没有收到任何验证错误)。

我决心在这个问题:移动到API 15级

  1. - 使用AndroidCSStore,而不是BKS(我用API 10)。
  2. 使用getAuthToken获取密码 - 它实际上是一个令牌,但后来​​在连接时用作密码。
  3. 我没有空余时间去真正解决问题的根本。它现在可以工作,而这一切都很重要。

我在下面发布了我的代码。 SASLXOAuth2机制已完成。但是来自Main的代码是有条不紊的,并不完整。我从本网站的其他答案中撕下了一些代码片段,我事先为我的诽谤道歉。

Main.java - 启动asmack

// Init asmack, and register new mechanisms. 
asmack = SmackAndroid.init(ctx); 

SASLAuthentication.registerSASLMechanism("X-OAUTH2", SASLXOAuth2Mechanism.class); 
SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0); 

ConnectionConfiguration connectionConfig = 
    new ConnectionConfiguration (getHost(), getPort(), getService()); 
connectionConfig.setSASLAuthenticationEnabled(true); 
connectionConfig.setSecurityMode(true); 
connectionConfig.setRosterLoadedAtLogin(true); 
connectionConfig.setReconnectionAllowed(true); 
connectionConfig.setSendPresence(false); 
//connectionConfig.setCompressionEnabled(true); 

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
     connectionConfig.setTruststoreType("AndroidCAStore"); 
     connectionConfig.setTruststorePassword(null); 
     connectionConfig.setTruststorePath(null); 
} /*else { 
     connectionConfig.setTruststoreType("BKS"); 
     String path = System.getProperty("javax.net.ssl.trustStore"); 
     if (path == null) 
      path = System.getProperty("java.home") + File.separator + "etc" 
       + File.separator + "security" + File.separator 
       + "cacerts.bks"; 
     connectionConfig.setTruststorePath(path); 
     connectionConfig.setTruststorePassword("changeit"); 
//} */ 

XMPPConnection con = new XMPPConnection(connectionConfig); 

SASLXOAuth2Mechanism.java - 在XOAuth2机制

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

import org.jivesoftware.smack.SASLAuthentication; 
import org.jivesoftware.smack.XMPPException; 
import org.jivesoftware.smack.packet.Packet; 
import org.jivesoftware.smack.sasl.SASLMechanism; 
import org.jivesoftware.smack.util.Base64; 

import de.measite.smack.Sasl; 

public class SASLXOAuth2Mechanism extends SASLMechanism 
{ 
    static final String AUTHENTICATOR_URL = "http://www.google.com/talk/protocol/auth"; 
    protected String authenticationText = null; 
    static final String TAG = "SASLXOAuth2Mechanism"; 

    public SASLXOAuth2Mechanism(SASLAuthentication saslAuthentication) { 
     super(saslAuthentication); 
    } 

    @Override 
    protected String getName() 
    { 
     return "X-OAUTH2"; 
    } 

    @Override 
    public void authenticate(String username, String host, String password) throws IOException, XMPPException { 
     this.password = password; 
     this.authenticationId = username; 

     StringBuilder credentials = new StringBuilder(); 
     credentials.append("\0"); 
     credentials.append(username); 
     credentials.append("\0"); 
     credentials.append(password); 
     authenticationText = Base64.encodeBytes(credentials.toString().getBytes("UTF-8"), Base64.DONT_BREAK_LINES); 

     String[] mechanisms = { "PLAIN" }; 
     Map<String,String> props = new HashMap<String,String>(); 
     sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this); 
     authenticate(); 
    } 

    protected void authenticate() throws IOException, XMPPException { 
     // Send the authentication to the server 
     getSASLAuthentication().send(new XOAuth2AuthMechanism(getName(), authenticationText)); 
    } 

    /** 
    * Initiating SASL authentication by select a mechanism. 
    */ 
    public class XOAuth2AuthMechanism extends Packet { 
     final private String name; 
     final private String authenticationText; 

     public XOAuth2AuthMechanism(String name, String authenticationText) { 
      super(); 
      this.name = name; 
      this.authenticationText = authenticationText; 
     } 

     public String toXML() { 
      StringBuilder stanza = new StringBuilder(); 
      stanza.append("<auth mechanism=\"").append(name); 
      stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" auth:service=\"oauth2\" xmlns:auth=\"").append(AUTHENTICATOR_URL); 
      stanza.append("\">"); 
      if (authenticationText != null) { 
       stanza.append(authenticationText); 
      } 
      stanza.append("</auth>"); 
      return stanza.toString(); 
     } 
    } 
} 
相关问题