use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class IncomingFileTransfer method negotiateStream.
private InputStream negotiateStream() throws SmackException, XMPPErrorException, InterruptedException {
setStatus(Status.negotiating_transfer);
final StreamNegotiator streamNegotiator = negotiator.selectStreamNegotiator(recieveRequest);
setStatus(Status.negotiating_stream);
FutureTask<InputStream> streamNegotiatorTask = new FutureTask<InputStream>(new Callable<InputStream>() {
@Override
public InputStream call() throws Exception {
return streamNegotiator.createIncomingStream(recieveRequest.getStreamInitiation());
}
});
streamNegotiatorTask.run();
InputStream inputStream;
try {
inputStream = streamNegotiatorTask.get(15, TimeUnit.SECONDS);
} catch (ExecutionException e) {
final Throwable cause = e.getCause();
if (cause instanceof XMPPErrorException) {
throw (XMPPErrorException) cause;
}
if (cause instanceof InterruptedException) {
throw (InterruptedException) cause;
}
if (cause instanceof NoResponseException) {
throw (NoResponseException) cause;
}
if (cause instanceof SmackException) {
throw (SmackException) cause;
}
throw new SmackException("Error in execution", e);
} catch (TimeoutException e) {
throw new SmackException("Request timed out", e);
} finally {
streamNegotiatorTask.cancel(true);
}
setStatus(Status.negotiated);
return inputStream;
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class ScramMechanism method evaluateChallenge.
@Override
protected byte[] evaluateChallenge(byte[] challenge) throws SmackException {
String challengeString;
try {
// TODO: Where is it specified that this is an UTF-8 encoded string?
challengeString = new String(challenge, StringUtils.UTF8);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
switch(state) {
case AUTH_TEXT_SENT:
final String serverFirstMessage = challengeString;
Map<Character, String> attributes = parseAttributes(challengeString);
// Handle server random ASCII (nonce)
String rvalue = attributes.get('r');
if (rvalue == null) {
throw new SmackException("Server random ASCII is null");
}
if (rvalue.length() <= clientRandomAscii.length()) {
throw new SmackException("Server random ASCII is shorter then client random ASCII");
}
String receivedClientRandomAscii = rvalue.substring(0, clientRandomAscii.length());
if (!receivedClientRandomAscii.equals(clientRandomAscii)) {
throw new SmackException("Received client random ASCII does not match client random ASCII");
}
// Handle iterations
int iterations;
String iterationsString = attributes.get('i');
if (iterationsString == null) {
throw new SmackException("Iterations attribute not set");
}
try {
iterations = Integer.parseInt(iterationsString);
} catch (NumberFormatException e) {
throw new SmackException("Exception parsing iterations", e);
}
// Handle salt
String salt = attributes.get('s');
if (salt == null) {
throw new SmackException("SALT not send");
}
// Parsing and error checking is done, we can now begin to calculate the values
// First the client-final-message-without-proof
String channelBinding = "c=" + Base64.encodeToString(getCBindInput());
String clientFinalMessageWithoutProof = channelBinding + ",r=" + rvalue;
// AuthMessage := client-first-message-bare + "," + server-first-message + "," +
// client-final-message-without-proof
byte[] authMessage = toBytes(clientFirstMessageBare + ',' + serverFirstMessage + ',' + clientFinalMessageWithoutProof);
// RFC 5802 § 5.1 "Note that a client implementation MAY cache ClientKey&ServerKey … for later reauthentication …
// as it is likely that the server is going to advertise the same salt value upon reauthentication."
// Note that we also mangle the mechanism's name into the cache key, since the cache is used by multiple
// mechanisms.
final String cacheKey = password + ',' + salt + ',' + getName();
byte[] serverKey, clientKey;
Keys keys = CACHE.lookup(cacheKey);
if (keys == null) {
// SaltedPassword := Hi(Normalize(password), salt, i)
byte[] saltedPassword = hi(saslPrep(password), Base64.decode(salt), iterations);
// ServerKey := HMAC(SaltedPassword, "Server Key")
serverKey = hmac(saltedPassword, SERVER_KEY_BYTES);
// ClientKey := HMAC(SaltedPassword, "Client Key")
clientKey = hmac(saltedPassword, CLIENT_KEY_BYTES);
keys = new Keys(clientKey, serverKey);
CACHE.put(cacheKey, keys);
} else {
serverKey = keys.serverKey;
clientKey = keys.clientKey;
}
// ServerSignature := HMAC(ServerKey, AuthMessage)
serverSignature = hmac(serverKey, authMessage);
// StoredKey := H(ClientKey)
byte[] storedKey = SHA1.bytes(clientKey);
// ClientSignature := HMAC(StoredKey, AuthMessage)
byte[] clientSignature = hmac(storedKey, authMessage);
// ClientProof := ClientKey XOR ClientSignature
byte[] clientProof = new byte[clientKey.length];
for (int i = 0; i < clientProof.length; i++) {
clientProof[i] = (byte) (clientKey[i] ^ clientSignature[i]);
}
String clientFinalMessage = clientFinalMessageWithoutProof + ",p=" + Base64.encodeToString(clientProof);
state = State.RESPONSE_SENT;
return toBytes(clientFinalMessage);
case RESPONSE_SENT:
String clientCalculatedServerFinalMessage = "v=" + Base64.encodeToString(serverSignature);
if (!clientCalculatedServerFinalMessage.equals(challengeString)) {
throw new SmackException("Server final message does not match calculated one");
}
state = State.VALID_SERVER_RESPONSE;
break;
default:
throw new SmackException("Invalid state");
}
return null;
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class SASLJavaXMechanism method authenticateInternal.
@Override
protected void authenticateInternal() throws SmackException {
String[] mechanisms = { getName() };
Map<String, String> props = getSaslProps();
String authzid = null;
if (authorizationId != null) {
authzid = authorizationId.toString();
}
try {
sc = Sasl.createSaslClient(mechanisms, authzid, "xmpp", getServerName().toString(), props, new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
NameCallback ncb = (NameCallback) callbacks[i];
ncb.setName(authenticationId);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback) callbacks[i];
pcb.setPassword(password.toCharArray());
} else if (callbacks[i] instanceof RealmCallback) {
RealmCallback rcb = (RealmCallback) callbacks[i];
// Retrieve the REALM from the challenge response that
// the server returned when the client initiated the
// authentication exchange. If this value is not null or
// empty, *this value* has to be sent back to the server
// in the client's response to the server's challenge
String text = rcb.getDefaultText();
// The SASL client (sc) created in smack uses
// rcb.getText when creating the negotiatedRealm to send
// it back to the server. Make sure that this value
// matches the server's realm
rcb.setText(text);
} else if (callbacks[i] instanceof RealmChoiceCallback) {
// unused, prevents UnsupportedCallbackException
// RealmChoiceCallback rccb =
// (RealmChoiceCallback)callbacks[i];
} else {
throw new UnsupportedCallbackException(callbacks[i]);
}
}
}
});
} catch (SaslException e) {
throw new SmackException(e);
}
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class JingleTransportProvider method parse.
/**
* Parse a iq/jingle/transport element.
*
* @param parser the structure to parse
* @return a transport element.
* @throws IOException
* @throws XmlPullParserException
* @throws SmackException
*/
@Override
public JingleTransport parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException {
boolean done = false;
JingleTransport trans = getInstance();
while (!done) {
int eventType = parser.next();
String name = parser.getName();
if (eventType == XmlPullParser.START_TAG) {
if (name.equals(JingleTransportCandidate.NODENAME)) {
JingleTransportCandidate jtc = parseCandidate(parser);
if (jtc != null)
trans.addCandidate(jtc);
} else {
throw new SmackException("Unknown tag \"" + name + "\" in transport element.");
}
} else if (eventType == XmlPullParser.END_TAG) {
if (name.equals(JingleTransport.NODENAME)) {
done = true;
}
}
}
return trans;
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class MultipleRecipientManager method reply.
/**
* Sends a reply to a previously received stanza(/packet) that was sent to multiple recipients. Before
* attempting to send the reply message some checkings are performed. If any of those checkings
* fail then an XMPPException is going to be thrown with the specific error detail.
*
* @param connection the connection to use to send the reply.
* @param original the previously received stanza(/packet) that was sent to multiple recipients.
* @param reply the new message to send as a reply.
* @throws SmackException
* @throws XMPPErrorException
* @throws InterruptedException
*/
public static void reply(XMPPConnection connection, Message original, Message reply) throws SmackException, XMPPErrorException, InterruptedException {
MultipleRecipientInfo info = getMultipleRecipientInfo(original);
if (info == null) {
throw new SmackException("Original message does not contain multiple recipient info");
}
if (info.shouldNotReply()) {
throw new SmackException("Original message should not be replied");
}
if (info.getReplyRoom() != null) {
throw new SmackException("Reply should be sent through a room");
}
// Any <thread/> element from the initial message MUST be copied into the reply.
if (original.getThread() != null) {
reply.setThread(original.getThread());
}
MultipleAddresses.Address replyAddress = info.getReplyAddress();
if (replyAddress != null && replyAddress.getJid() != null) {
// Send reply to the reply_to address
reply.setTo(replyAddress.getJid());
connection.sendStanza(reply);
} else {
// Send reply to multiple recipients
List<Jid> to = new ArrayList<>(info.getTOAddresses().size());
List<Jid> cc = new ArrayList<>(info.getCCAddresses().size());
for (MultipleAddresses.Address jid : info.getTOAddresses()) {
to.add(jid.getJid());
}
for (MultipleAddresses.Address jid : info.getCCAddresses()) {
cc.add(jid.getJid());
}
// Add original sender as a 'to' address (if not already present)
if (!to.contains(original.getFrom()) && !cc.contains(original.getFrom())) {
to.add(original.getFrom());
}
// Remove the sender from the TO/CC list (try with bare JID too)
EntityFullJid from = connection.getUser();
if (!to.remove(from) && !cc.remove(from)) {
EntityBareJid bareJID = from.asEntityBareJid();
to.remove(bareJID);
cc.remove(bareJID);
}
send(connection, reply, to, cc, null, null, null, false);
}
}
Aggregations