From 6e569701b3083ec7bd8158b77d5b104162f7178f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 20 Nov 2014 18:50:33 +0100 Subject: [PATCH] Add support for SASL X-OAUTH2 --- .../smack/SmackInitialization.java | 2 + .../smack/sasl/core/SASLXOauth2Mechanism.java | 99 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java index 9fe0e0023..d047edda5 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java @@ -34,6 +34,7 @@ import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.provider.BindIQProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.provider.RosterPacketProvider; +import org.jivesoftware.smack.sasl.core.SASLXOauth2Mechanism; import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism; import org.jivesoftware.smack.util.FileUtils; import org.xmlpull.v1.XmlPullParser; @@ -137,6 +138,7 @@ public final class SmackInitialization { } SASLAuthentication.registerSASLMechanism(new SCRAMSHA1Mechanism()); + SASLAuthentication.registerSASLMechanism(new SASLXOauth2Mechanism()); ProviderManager.addIQProvider(RosterPacket.ELEMENT, RosterPacket.NAMESPACE, RosterPacketProvider.INSTANCE); ProviderManager.addIQProvider(Bind.ELEMENT, Bind.NAMESPACE, new BindIQProvider()); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java new file mode 100644 index 000000000..d8e04800a --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/SASLXOauth2Mechanism.java @@ -0,0 +1,99 @@ +/** + * + * Copyright 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.sasl.core; + +import javax.security.auth.callback.CallbackHandler; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.sasl.SASLMechanism; +import org.jivesoftware.smack.util.stringencoder.Base64; + +/** + * The SASL X-OAUTH2 mechanism as described in https://developers.google + * .com/talk/jep_extensions/oauth + *

+ * The given password will be used as OAUTH token. + *

+ *

+ * Note that X-OAUTH2 is experimental in Smack. This is because Google defined, besides being a bad practice, custom + * attributes to the 'auth' stanze, as can be seen here + *

+ * + *
+ * {@code
+ * 
+ * }
+ * 
+ * + * from https://developers.google.com/cloud-print/docs/rawxmpp and here + * + *
+ * {@code
+ * 
+ * base64("\0" + user_name + "\0" + oauth_token)
+ * 
+ * }
+ * 
+ * + * from https://developers.google.com/talk/jep_extensions/oauth + *

+ * Those attribute extensions are currently not supported by Smack, and it's unclear how it affects authorization and + * how widely they are used. + *

+ */ +public class SASLXOauth2Mechanism extends SASLMechanism { + + public static final String NAME = "X-OAUTH2"; + + @Override + protected void authenticateInternal(CallbackHandler cbh) throws SmackException { + throw new UnsupportedOperationException("CallbackHandler not (yet) supported"); + } + + @Override + protected byte[] getAuthenticationText() throws SmackException { + // base64("\0" + user_name + "\0" + oauth_token) + return Base64.decode('\u0000' + authenticationId + '\u0000' + password); + } + + @Override + public String getName() { + return NAME; + } + + @Override + public int getPriority() { + // Same priority as SASL PLAIN + return 410; + } + + @Override + public SASLXOauth2Mechanism newInstance() { + return new SASLXOauth2Mechanism(); + } + + @Override + public void checkIfSuccessfulOrThrow() throws SmackException { + // No check performed + } +}