<EditTextPreference
android:key="pref_authname"
android:summary="Username for SASL Authentication"
- android:title="Nickname"
+ android:title="Authname"
android:defaultValue="" />
<EditTextPreference
android:key="pref_password"
}
Os.debug("Client: connected");
+ if (this.usesasl)
+ this.raw("CAP REQ :sasl");
this.raw("USER "+this.username+" "+this.hostname+" "+this.server+" :"+this.nickname);
this.raw("NICK "+this.nickname);
Os.debug("> " + line);
Message msg = new Message(line);
this.process(msg);
+ if (this.usesasl)
+ this.dosasl(msg);
return msg;
} catch (SocketException e) {
this.ready = false;
this.raw("PING " + msg.msg);
}
}
+
+ private void dosasl(Message msg)
+ {
+ switch (msg.type) {
+ case CAP:
+ if (msg.msg.equals("sasl") && msg.arg.equals("ACK")) {
+ Os.debug("Client: sasl - starting auth");
+ this.raw("AUTHENTICATE PLAIN");
+ } else {
+ Os.debug("Client: sasl - Server does not support sasl");
+ }
+ break;
+ case AUTH:
+ if (msg.arg.equals("+")) {
+ Os.debug("Client: sasl - performin authentication");
+ this.raw("AUTHENTICATE " + Os.base64(
+ this.authname + "\0" +
+ this.authname + "\0" +
+ this.password));
+ } else {
+ Os.debug("Client: sasl - unexpected authenticate response");
+ }
+ break;
+ case AUTHOK:
+ Os.debug("Client: SASL Auth Successful");
+ this.raw("CAP END");
+ break;
+ case AUTHFAIL:
+ Os.debug("Client: SASL Auth Failed");
+ this.raw("CAP END");
+ break;
+ }
+ }
}
private ScrollView lscroll;
private ScrollView dscroll;
+ /* Private helper methods */
+ private void notice(String text)
+ {
+ this.log.append("*** " + text + "\n");
+ }
+
/* Private handler methods */
private void onRegister(Object obj)
{
break;
case TOPIC:
if (!msg.txt.equals(this.topic))
- this.log.append("** Topic for " + msg.arg + ": " + msg.txt + " **\n");
+ this.notice("Topic for " + msg.arg + ": " + msg.txt);
this.topic = msg.txt;
break;
case NAMES:
if (!msg.txt.equals(this.names))
- this.log.append("** Users in " + msg.arg + ": " + msg.txt + " **\n");
+ this.notice("Users in " + msg.arg + ": " + msg.txt);
this.names = msg.txt;
break;
+ case ERROR:
+ this.notice("Error: " + msg.txt);
+ break;
+ case AUTHOK:
+ this.notice("Authentication succeeded: " + msg.txt);
+ break;
+ case AUTHFAIL:
+ this.notice("Authentication failed: " + msg.txt);
+ break;
}
this.lscroll.smoothScrollTo(0, this.log.getBottom());
}
private void onNotify(String text)
{
Os.debug("Main: onNotify - " + text);
- this.log.append("** " + text + " **\n");
+ this.notice(text);
this.toast.setText(text);
this.toast.show();
}
PRIVMSG,
TOPIC,
NAMES,
+ ERROR,
+ CAP,
+ AUTH,
+ AUTHOK,
+ AUTHFAIL,
};
/* Constnats */
- private final String reMsg = "(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+)[= ]+)?(([^: ]+) +)?(:(.*))";
+ private final String reMsg = "(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+)[= ]+)?(([^: ]+) *)?(:(.*))?";
private final String reFrom = "([^! ]+)!.*";
private final String reTo = "(([^ :,]*)[:,] *)?(.*)";
this.txt = notnull(mrTo.group(3));
// Parse commands names
- if (this.cmd.equals("PRIVMSG")) this.type = Type.PRIVMSG;
- if (this.cmd.equals("332")) this.type = Type.TOPIC;
- if (this.cmd.equals("353")) this.type = Type.NAMES;
+ if (this.cmd.equals("PRIVMSG")) this.type = Type.PRIVMSG;
+ else if (this.cmd.equals("332")) this.type = Type.TOPIC;
+ else if (this.cmd.equals("353")) this.type = Type.NAMES;
+ else if (this.cmd.equals("ERROR")) this.type = Type.ERROR;
+ else if (this.cmd.equals("CAP")) this.type = Type.CAP;
+ else if (this.cmd.equals("AUTHENTICATE")) this.type = Type.AUTH;
+ else if (this.cmd.equals("903")) this.type = Type.AUTHOK;
+ else if (this.cmd.equals("904")) this.type = Type.AUTHFAIL;
+ else if (this.cmd.equals("905")) this.type = Type.AUTHFAIL;
+ else if (this.cmd.equals("906")) this.type = Type.AUTHFAIL;
+ else if (this.cmd.equals("907")) this.type = Type.AUTHFAIL;
}
public void debug()
package org.pileus.spades;
import android.util.Log;
+import android.util.Base64;
public class Os
{
{
Log.d("Spades", txt);
}
+
+ /* Utilities */
+ public static String base64(String txt)
+ {
+ return Base64.encodeToString(txt.getBytes(), 0);
+ }
}