import cyrus-sasl-2.1.23
[cyrus-sasl.git] / java / Test / jimtest.java
1
2 import java.net.*;
3 import java.io.*;
4 import java.util.Hashtable;
5 import CyrusSasl.*;
6
7 class jimtest
8 {
9     private static PrintWriter os=null;
10     private static InputStreamReader ir=null;
11     private static Socket s=null;
12     private static BufferedReader br=null;
13
14   static void send(String str)
15   {
16       os.print(str+"\r\n");
17       os.flush();
18     
19   }
20
21     static boolean connect(String servername, int port)
22     {
23         try
24             {
25                 s=new Socket(servername,port);
26             } catch (UnknownHostException e){
27                 System.out.println("invalid host");
28                 return false;
29             } catch (IOException e) {
30                 System.out.println("invalid host");
31                 return false;
32             }
33
34         try {
35             os=new PrintWriter(s.getOutputStream());
36             ir=new InputStreamReader(s.getInputStream());
37             br=new BufferedReader(ir);                  
38
39         } catch (IOException e) {
40             System.out.println("IO no work");   
41             return false;      
42         }
43
44                 
45         System.out.println("connected...");
46
47         return true;                                            
48     }
49
50     static String[] parsecapabilities(String line)
51     {
52         String[] ret = new String[100];
53         int size = 0;
54         String tmp;
55         int pos = 0;
56
57         while (pos < line.length() )
58         {
59             char c;
60             tmp = "";
61
62             do {
63                 c = line.charAt(pos);
64                 tmp+=c;
65                 pos++;
66             } while ((c!=' ') && (pos < line.length()));
67             
68             if (tmp.startsWith("AUTH=")==true)
69             {
70                 ret[size++] = tmp.substring(5);
71             }
72         }
73         
74         return ret;
75     }
76
77     static String[] askcapabilities()
78     {
79         String line;
80         String mechs[];
81         
82         try {
83             
84             send(". CAPABILITY");
85             
86             do {
87                 line = br.readLine();
88             } while (line.startsWith("* CAPABILITY")==false);
89             
90             mechs = parsecapabilities(line);
91
92             do {
93                 line = br.readLine();
94             } while (line.startsWith(".")==false);
95
96         } catch (IOException e) {
97             System.out.println("IO no work");   
98             return null;      
99         }
100         
101         return mechs;
102     }
103
104     static SaslClient start_sasl(String[] mechs, String remoteserver, String localaddr, int minssf, int maxssf)
105     {
106         SaslClient conn;
107         Hashtable props = new Hashtable();
108         props.put("javax.security.sasl.encryption.minimum",String.valueOf(minssf));
109         props.put("javax.security.sasl.encryption.maximum",String.valueOf(maxssf));
110         props.put("javax.security.sasl.ip.local",localaddr);
111         props.put("javax.security.sasl.ip.remote",remoteserver);
112
113         Handler cbh = new Handler();
114
115         try {
116             conn = Sasl.createSaslClient(mechs,
117                                          "tmartin",
118                                          "imap",
119                                          remoteserver,
120                                          props,
121                                          cbh);
122
123             if (conn == null) {
124                 System.out.println("conn is null");
125             }
126             
127             if (conn.hasInitialResponse()) {
128                 /* xxx */
129             }
130
131             send(". AUTHENTICATE "+conn.getMechanismName());
132
133             do {
134
135                 String line = br.readLine();
136
137                 if (line.startsWith("+ ")==true) {
138
139                     line = line.substring(2);
140
141                     byte[] in = SaslUtils.decode64(line);
142
143                     byte[] out = conn.evaluateChallenge(in);
144
145                     String outline = SaslUtils.encode64(out);
146
147                     send(outline);
148
149                 } else if (line.startsWith(". OK")==true) {
150                     System.out.println("S: " + line);
151
152                     if (conn.isComplete()==false) {
153                         System.out.println("Something funny going on here...");
154                         System.exit(1);
155                     }
156                     return conn;
157                 } else {
158                     System.out.println("S: "+ line);
159                     /* authentication failed */
160                     return null;
161                 } 
162
163             } while (true);
164             
165         } catch (SaslException e) {
166             System.out.println("SASL exception\n");
167         } catch (IOException e) {
168             System.out.println("IO exception\n");
169         }
170
171         return null;
172     }
173
174     static void be_interactive(SaslClient conn)
175     {
176         try {
177             InputStream saslin = conn.getInputStream(s.getInputStream());
178             OutputStream saslout = conn.getOutputStream(s.getOutputStream());
179             int len;
180             byte[] arr;
181
182             while (true)
183              {
184                  if ((len = System.in.available())>0) {
185
186                      /* read from keyboard */
187                      arr = new byte[len+1];
188                      System.in.read(arr,0,len);
189
190                      if (arr[len-1]=='\n') {
191                          arr[len-1]= (byte) '\r';
192                          arr[len]= (byte) '\n';
193                      }
194                      
195                      /* write out to stream */               
196                      saslout.write(arr);
197                      saslout.flush();
198
199                  } else if ((len = saslin.available())>0) {
200
201                      /* read from socket */
202                      arr = new byte[len];
203                      saslin.read(arr);
204
205                      System.out.print(new String(arr));
206
207                  } else {
208                      /* sleep */
209                  }
210              }
211
212         } catch (SaslException e) {
213
214         } catch (IOException e) {
215
216         }
217
218         
219     }
220
221     static void usage()
222     {
223         System.out.println("Usage:");
224         System.out.println("jimtest [-k minssf] [-l maxssf] [-m mech] [-p port] server");
225         System.exit(1);
226     }
227
228     public static void main (String args[])
229     {
230         String[] mechs;
231         SaslClient conn;
232
233         String arg;
234         int i = 0;
235         int minssf = 0;
236         int maxssf = 9999;
237         String onemech = null;
238         int port = 143;
239
240         while ((i < (args.length-1) ) && (args[i].startsWith("-"))) {
241             arg = args[i++];
242                     
243             // use this type of check for arguments that require arguments
244             if (arg.equals("-k")) {
245                 if (i < args.length)
246                     minssf = Integer.parseInt(args[i++]);
247                 else {
248                     System.err.println("-k requires a number");
249                     usage();
250                 }
251             } else if (arg.equals("-l")) {
252                 if (i < args.length)
253                     maxssf = Integer.parseInt(args[i++]);
254                 else {
255                     System.err.println("-l requires a number");
256                     usage();
257                 }
258             } else if (arg.equals("-m")) {
259                 if (i < args.length)
260                     onemech = args[i++];
261                 else {
262                     System.err.println("-m requires parameter");
263                     usage();
264                 }
265             } else if (arg.equals("-p")) {
266                 if (i < args.length)
267                     port = Integer.parseInt(args[i++]);
268                 else {
269                     System.err.println("-p requires a number");
270                     usage();
271                 }
272             } else {
273                 usage();
274             }
275         }
276
277         if (i != args.length-1) usage();
278
279         String servername = args[i];
280
281         if (connect(servername,port)==false) {
282             System.out.println("Unable to connect to host: "+servername);
283             System.exit(1);
284         }
285
286         mechs = askcapabilities();
287
288         if (onemech!=null) {
289             mechs = new String[1];
290             mechs[0]=onemech;
291         }
292
293         conn = start_sasl(mechs,servername, s.getLocalAddress().getHostName(), minssf,maxssf);
294
295         if (conn == null) {
296             System.out.println("Authentication failed");
297             System.exit(1);
298         }
299
300         be_interactive(conn);
301     }
302
303
304 }