import java.net.*;
import java.io.*;
import java.util.Hashtable;
import CyrusSasl.*;
class jimtest
{
private static PrintWriter os=null;
private static InputStreamReader ir=null;
private static Socket s=null;
private static BufferedReader br=null;
static void send(String str)
{
os.print(str+"\r\n");
os.flush();
}
static boolean connect(String servername, int port)
{
try
{
s=new Socket(servername,port);
} catch (UnknownHostException e){
System.out.println("invalid host");
return false;
} catch (IOException e) {
System.out.println("invalid host");
return false;
}
try {
os=new PrintWriter(s.getOutputStream());
ir=new InputStreamReader(s.getInputStream());
br=new BufferedReader(ir);
} catch (IOException e) {
System.out.println("IO no work");
return false;
}
System.out.println("connected...");
return true;
}
static String[] parsecapabilities(String line)
{
String[] ret = new String[100];
int size = 0;
String tmp;
int pos = 0;
while (pos < line.length() )
{
char c;
tmp = "";
do {
c = line.charAt(pos);
tmp+=c;
pos++;
} while ((c!=' ') && (pos < line.length()));
if (tmp.startsWith("AUTH=")==true)
{
ret[size++] = tmp.substring(5);
}
}
return ret;
}
static String[] askcapabilities()
{
String line;
String mechs[];
try {
send(". CAPABILITY");
do {
line = br.readLine();
} while (line.startsWith("* CAPABILITY")==false);
mechs = parsecapabilities(line);
do {
line = br.readLine();
} while (line.startsWith(".")==false);
} catch (IOException e) {
System.out.println("IO no work");
return null;
}
return mechs;
}
static SaslClient start_sasl(String[] mechs, String remoteserver, String localaddr, int minssf, int maxssf)
{
SaslClient conn;
Hashtable props = new Hashtable();
props.put("javax.security.sasl.encryption.minimum",String.valueOf(minssf));
props.put("javax.security.sasl.encryption.maximum",String.valueOf(maxssf));
props.put("javax.security.sasl.ip.local",localaddr);
props.put("javax.security.sasl.ip.remote",remoteserver);
Handler cbh = new Handler();
try {
conn = Sasl.createSaslClient(mechs,
"tmartin",
"imap",
remoteserver,
props,
cbh);
if (conn == null) {
System.out.println("conn is null");
}
if (conn.hasInitialResponse()) {
}
send(". AUTHENTICATE "+conn.getMechanismName());
do {
String line = br.readLine();
if (line.startsWith("+ ")==true) {
line = line.substring(2);
byte[] in = SaslUtils.decode64(line);
byte[] out = conn.evaluateChallenge(in);
String outline = SaslUtils.encode64(out);
send(outline);
} else if (line.startsWith(". OK")==true) {
System.out.println("S: " + line);
if (conn.isComplete()==false) {
System.out.println("Something funny going on here...");
System.exit(1);
}
return conn;
} else {
System.out.println("S: "+ line);
return null;
}
} while (true);
} catch (SaslException e) {
System.out.println("SASL exception\n");
} catch (IOException e) {
System.out.println("IO exception\n");
}
return null;
}
static void be_interactive(SaslClient conn)
{
try {
InputStream saslin = conn.getInputStream(s.getInputStream());
OutputStream saslout = conn.getOutputStream(s.getOutputStream());
int len;
byte[] arr;
while (true)
{
if ((len = System.in.available())>0) {
arr = new byte[len+1];
System.in.read(arr,0,len);
if (arr[len-1]=='\n') {
arr[len-1]= (byte) '\r';
arr[len]= (byte) '\n';
}
saslout.write(arr);
saslout.flush();
} else if ((len = saslin.available())>0) {
arr = new byte[len];
saslin.read(arr);
System.out.print(new String(arr));
} else {
}
}
} catch (SaslException e) {
} catch (IOException e) {
}
}
static void usage()
{
System.out.println("Usage:");
System.out.println("jimtest [-k minssf] [-l maxssf] [-m mech] [-p port] server");
System.exit(1);
}
public static void main (String args[])
{
String[] mechs;
SaslClient conn;
String arg;
int i = 0;
int minssf = 0;
int maxssf = 9999;
String onemech = null;
int port = 143;
while ((i < (args.length-1) ) && (args[i].startsWith("-"))) {
arg = args[i++];
if (arg.equals("-k")) {
if (i < args.length)
minssf = Integer.parseInt(args[i++]);
else {
System.err.println("-k requires a number");
usage();
}
} else if (arg.equals("-l")) {
if (i < args.length)
maxssf = Integer.parseInt(args[i++]);
else {
System.err.println("-l requires a number");
usage();
}
} else if (arg.equals("-m")) {
if (i < args.length)
onemech = args[i++];
else {
System.err.println("-m requires parameter");
usage();
}
} else if (arg.equals("-p")) {
if (i < args.length)
port = Integer.parseInt(args[i++]);
else {
System.err.println("-p requires a number");
usage();
}
} else {
usage();
}
}
if (i != args.length-1) usage();
String servername = args[i];
if (connect(servername,port)==false) {
System.out.println("Unable to connect to host: "+servername);
System.exit(1);
}
mechs = askcapabilities();
if (onemech!=null) {
mechs = new String[1];
mechs[0]=onemech;
}
conn = start_sasl(mechs,servername, s.getLocalAddress().getHostName(), minssf,maxssf);
if (conn == null) {
System.out.println("Authentication failed");
System.exit(1);
}
be_interactive(conn);
}
}