📄 localoutgoingserversession.java
字号:
connection.getTLSStreamHandler().getInputStream());
in.setFlushMode(JZlib.Z_PARTIAL_FLUSH);
xpp.setInput(new InputStreamReader(in, CHARSET));
// Skip the opening stream sent by the server
for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;)
{
eventType = xpp.next();
}
// Get new stream features
features = reader.parseDocument().getRootElement();
if (features == null || features.element("mechanisms") == null) {
Log.debug("LocalOutgoingServerSession: OS - Error, EXTERNAL SASL was not offered by " + hostname);
return null;
}
}
else {
Log.debug("LocalOutgoingServerSession: OS - Stream compression was rejected by " + hostname);
}
}
else {
Log.debug(
"LocalOutgoingServerSession: OS - Stream compression found but zlib method is not supported by" +
hostname);
}
}
else {
Log.debug("LocalOutgoingServerSession: OS - Stream compression not supoprted by " + hostname);
}
}
Iterator it = features.element("mechanisms").elementIterator();
while (it.hasNext()) {
Element mechanism = (Element) it.next();
if ("EXTERNAL".equals(mechanism.getTextTrim())) {
Log.debug("LocalOutgoingServerSession: OS - Starting EXTERNAL SASL with " + hostname);
if (doExternalAuthentication(domain, connection, reader)) {
Log.debug("LocalOutgoingServerSession: OS - EXTERNAL SASL with " + hostname + " was successful");
// SASL was successful so initiate a new stream
connection.deliverRawText(openingStream.toString());
// Reset the parser
xpp.resetInput();
// Skip the opening stream sent by the server
for (int eventType = xpp.getEventType();
eventType != XmlPullParser.START_TAG;) {
eventType = xpp.next();
}
// SASL authentication was successful so create new
// OutgoingServerSession
String id = xpp.getAttributeValue("", "id");
StreamID streamID = new BasicStreamIDFactory().createStreamID(id);
LocalOutgoingServerSession session = new LocalOutgoingServerSession(domain,
connection, new OutgoingServerSocketReader(reader), streamID);
connection.init(session);
// Set the hostname as the address of the session
session.setAddress(new JID(null, hostname, null));
// Set that the session was created using TLS+SASL (no server dialback)
session.usingServerDialback = false;
return session;
}
else {
Log.debug("LocalOutgoingServerSession: OS - Error, EXTERNAL SASL authentication with " + hostname +
" failed");
return null;
}
}
}
Log.debug("LocalOutgoingServerSession: OS - Error, EXTERNAL SASL was not offered by " + hostname);
}
else {
Log.debug("LocalOutgoingServerSession: OS - Error, no SASL mechanisms were offered by " + hostname);
}
}
else {
Log.debug("LocalOutgoingServerSession: OS - Error, <proceed> was not received");
}
return null;
}
private static boolean doExternalAuthentication(String domain, SocketConnection connection,
XMPPPacketReader reader) throws DocumentException, IOException, XmlPullParserException {
StringBuilder sb = new StringBuilder();
sb.append("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"EXTERNAL\">");
sb.append(StringUtils.encodeBase64(domain));
sb.append("</auth>");
connection.deliverRawText(sb.toString());
Element response = reader.parseDocument().getRootElement();
return response != null && "success".equals(response.getName());
}
public LocalOutgoingServerSession(String serverName, Connection connection,
OutgoingServerSocketReader socketReader, StreamID streamID) {
super(serverName, connection, streamID);
this.socketReader = socketReader;
socketReader.setSession(this);
}
boolean canProcess(Packet packet) {
String senderDomain = packet.getFrom().getDomain();
if (!getAuthenticatedDomains().contains(senderDomain)) {
synchronized (senderDomain.intern()) {
if (!getAuthenticatedDomains().contains(senderDomain) &&
!authenticateSubdomain(senderDomain, packet.getTo().getDomain())) {
// Return error since sender domain was not validated by remote server
returnErrorToSender(packet);
return false;
}
}
}
return true;
}
void deliver(Packet packet) throws UnauthorizedException {
if (conn != null && !conn.isClosed()) {
conn.deliver(packet);
}
}
public boolean authenticateSubdomain(String domain, String hostname) {
if (!usingServerDialback) {
// Using SASL so just assume that the domain was validated
// (note: this may not be correct)
addAuthenticatedDomain(domain);
addHostname(hostname);
return true;
}
ServerDialback method = new ServerDialback(getConnection(), domain);
if (method.authenticateDomain(socketReader, domain, hostname, getStreamID().getID())) {
// Add the validated domain as an authenticated domain
addAuthenticatedDomain(domain);
addHostname(hostname);
return true;
}
return false;
}
private void returnErrorToSender(Packet packet) {
RoutingTable routingTable = XMPPServer.getInstance().getRoutingTable();
try {
if (packet instanceof IQ) {
IQ reply = new IQ();
reply.setID(packet.getID());
reply.setTo(packet.getFrom());
reply.setFrom(packet.getTo());
reply.setChildElement(((IQ) packet).getChildElement().createCopy());
reply.setError(PacketError.Condition.remote_server_not_found);
routingTable.routePacket(reply.getTo(), reply, true);
}
else if (packet instanceof Presence) {
Presence reply = new Presence();
reply.setID(packet.getID());
reply.setTo(packet.getFrom());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.remote_server_not_found);
routingTable.routePacket(reply.getTo(), reply, true);
}
else if (packet instanceof Message) {
Message reply = new Message();
reply.setID(packet.getID());
reply.setTo(packet.getFrom());
reply.setFrom(packet.getTo());
reply.setType(((Message)packet).getType());
reply.setThread(((Message)packet).getThread());
reply.setError(PacketError.Condition.remote_server_not_found);
routingTable.routePacket(reply.getTo(), reply, true);
}
}
catch (Exception e) {
Log.warn("Error returning error to sender. Original packet: " + packet, e);
}
}
public Collection<String> getAuthenticatedDomains() {
return Collections.unmodifiableCollection(authenticatedDomains);
}
public void addAuthenticatedDomain(String domain) {
authenticatedDomains.add(domain);
}
public Collection<String> getHostnames() {
synchronized (hostnames) {
return Collections.unmodifiableCollection(hostnames);
}
}
public void addHostname(String hostname) {
synchronized (hostnames) {
hostnames.add(hostname);
}
// Add a new route for this new session
XMPPServer.getInstance().getRoutingTable().addServerRoute(new JID(null, hostname, null, true), this);
}
public String getAvailableStreamFeatures() {
// Nothing special to add
return null;
}
public boolean isUsingServerDialback() {
return usingServerDialback;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -