KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SnowMailClient > MailEngine > SecurePopConnection


1 package SnowMailClient.MailEngine;
2
3
4 import SnowMailClient.crypto.*;
5 import SnowMailClient.utils.*;
6 import snow.utils.gui.*;
7 import snow.crypto.*;
8 import snow.concurrent.*;
9 import SnowMailClient.model.*;
10 import SnowMailClient.model.accounts.*;
11 import SnowMailClient.Language.Language;
12
13
14 import java.io.*;
15 import java.net.*;
16 import javax.net.ssl.*;
17
18 import java.util.Vector JavaDoc;
19 import java.util.Date JavaDoc;
20 import java.util.LinkedHashMap JavaDoc;
21 import java.util.concurrent.*;
22
23 /**
24  * basic POP3 reader + snowraver SPAS autentication + crypto
25  * and also a non secure standard mode.
26  * manages the connection to a mail account
27  */

28 public final class SecurePopConnection
29 {
30   final private MailAccount mailAccount;
31   final private AccountLog accountLog;
32   final private String JavaDoc username;
33   final private String JavaDoc password;
34
35   private Socket connection;
36   private boolean secure;
37
38   private OutputStreamWriter out = null;
39   private BufferedReader in = null;
40   private byte[] pass = null;
41
42   /** at the beginning, encrypt is false, it is turned on after a successful SPAS
43      login on snowserver */

44   private boolean encryptNow = false;
45
46   // access to ADUR, STOP, GELO commands
47
private boolean adminPrivileges = false;
48
49   private final static boolean debug = false;
50
51   // store the message UIDL's (used to identify a message rather than the message number)
52
// this database is updated at connection update (each login)
53
private final LinkedHashMap JavaDoc<String JavaDoc, Integer JavaDoc> messageUIDLs = new LinkedHashMap JavaDoc<String JavaDoc, Integer JavaDoc>();
54
55   private boolean sslMode = false;
56
57
58
59   /** initialize a new session
60    * handshake with SPAS if secure mode or USER/PASS of the last century of primitive hello world programmers
61    * parameters are taken from the mailAccount settings.
62    *
63    * it also directly test for new message, retriving all the UIDL's
64    */

65   public SecurePopConnection(MailAccount mailAccount) throws Exception JavaDoc
66   {
67       this.mailAccount = mailAccount;
68
69       this.accountLog = mailAccount.getAccountLog();
70       this.username = mailAccount.getAccountUserName();
71       this.password = mailAccount.getAccountPassword();
72       this.secure = mailAccount.isSnowraverAccount();//securePasswordProtocolSnowRaver;
73
this.sslMode = mailAccount.useSSLPOP();
74
75
76       if(sslMode)
77       {
78         try
79         {
80            accountLog.appendComment("\n"
81              +Language.translate("Opening new connection to SSL POP Server %1 on port %2",mailAccount.getPop(),""+mailAccount.getSSLPopPort()));
82            accountLog.appendComment("=========== "+(new Date JavaDoc())+" ==========");
83            connection = SSLConnection.createSSLConnection(mailAccount.getPop(), mailAccount.getSSLPopPort());
84         }
85         catch(Exception JavaDoc e)
86         {
87            //e.printStackTrace();
88
accountLog.appendError(Language.translate("Error")+":"+e.getMessage());
89            throw e;
90         }
91
92       }
93       else
94       {
95         // normal mode, NO ssl
96
try
97         {
98            accountLog.appendComment("\n"
99              +Language.translate("Opening new connection to POP Server %1 on port %2",mailAccount.getPop(),""+mailAccount.getPopPort()));
100            connection = new Socket(mailAccount.getPop(), mailAccount.getPopPort());
101            connection.setSoTimeout(1000*60);
102            accountLog.appendComment("=========== "+(new Date JavaDoc())+" ==========");
103         }
104         catch(Exception JavaDoc e)
105         {
106            accountLog.appendError(Language.translate("Error")+": "+e.getMessage());
107            throw new Exception JavaDoc(Language.translate("Cannot connect to %",mailAccount.getPop()));
108         }
109       }
110
111       out = new OutputStreamWriter(connection.getOutputStream()); //, "utf-8");
112
in = new BufferedReader( new InputStreamReader(connection.getInputStream())); // , "utf-8"));
113

114       //greetings
115
String JavaDoc line = readOneLineFromServer();
116       if(!line.toLowerCase().startsWith("+ok"))
117          throw new Exception JavaDoc(Language.translate("Bad POP3 Greetings, awaiting +OK*, reveived")+" "+line);
118
119       // read timestamp
120
String JavaDoc timestamp = null;
121       int pos = line.indexOf("<");
122       if(pos !=- 1)
123       {
124         timestamp = line.substring(pos).trim();
125         // secure case, verify that this stamp is not trivial... ###
126
if(secure)
127         {
128            if(timestamp.length()<3)
129              throw new Exception JavaDoc("Too short timestamp, security leak because replay attack possible ? "+timestamp);
130         }
131       }
132       else
133       {
134         if(secure)
135         {
136            throw new Exception JavaDoc("No timestamp in the greeting, secure mode not possible..., \nwaiting +OK* <xxxx.xxxx>, received "+line);
137         }
138       }
139
140       if(secure)
141       {
142          String JavaDoc secPass = Utilities.hashPassword(timestamp+Utilities.hashPassword(password));
143          String JavaDoc secUser = Utilities.hashPassword(username);
144
145          sendOneLineToServer("SPAS "+secUser+" "+secPass);
146          line = readOneLineFromServer();
147          if(!line.toLowerCase().startsWith("+ok"))
148          {
149             throw new BadPasswordException("Secure SPAS failled,\n"+line);
150          }
151
152          adminPrivileges = line.endsWith("admin");
153
154          // from now, everything is encrypted with the password hash that is our shared
155
// secret with the server.
156
byte[] hash = Utilities.hashPassword(password).getBytes();
157          pass = new byte[16];
158          System.arraycopy(hash, 0, pass, 0,16);
159          encryptNow = true;
160       }
161       else
162       {
163          // no security mode, send password and username as text over the net !
164
logUsingAuthentication();
165       }
166
167       retrieveMessagesUIDL();
168   }
169
170
171   /** explain what the status is
172   */

173   public String JavaDoc getConnectionStatusExplanation()
174   {
175      StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
176      sb.append(Language.translate("POP Connection status")+":");
177      sb.append("\n Connected to " +connection.getInetAddress()
178           +", port "+connection.getPort()+", local port="+connection.getLocalPort());
179      if(this.sslMode)
180      {
181        sb.append("\n +++ SSL mode is active.");
182        if(this.connection instanceof SSLSocket)
183        {
184          SSLSocket sconnection = (SSLSocket) connection;
185          SSLSession sSLSession = sconnection.getSession();
186          if(sSLSession!=null)
187          {
188            String JavaDoc cipherSuite = sSLSession.getCipherSuite();
189            String JavaDoc proto = sSLSession.getProtocol();
190            sb.append("\n Protocol="+proto+", Cipher suite="+cipherSuite);
191          }
192        }
193        else
194        {
195           sb.append("\nERROR: socket is not instance of SSLSocket");
196        }
197      }
198      else
199      {
200        sb.append("\n --- SSL mode is NOT active.");
201      }
202
203      if(encryptNow)
204      {
205        sb.append("\n +++ Snow encryption is active.");
206      }
207      else
208      {
209        sb.append("\n --- Snow encryption not active.");
210      }
211
212      return sb.toString();
213   }
214
215
216   final private Vector JavaDoc<String JavaDoc> authenticationTypes = new Vector JavaDoc<String JavaDoc>();
217
218   private synchronized void logUsingAuthentication() throws Exception JavaDoc
219   {
220       sendOneLineToServer("AUTH");
221       String JavaDoc line = readOneLineFromServer();
222       if(!line.toLowerCase().startsWith("+ok"))
223       {
224          accountLog.appendError("Cannot authenticate using AUTH, try old unsecure method");
225          logUsingUserAndPass();
226          //throw new Exception("USER error : "+line);
227
// [Sept 2005]: was missing !
228
return;
229       }
230       // normally receive a list of supported auth mechanisms
231
line = readOneLineFromServer().trim();
232       boolean cancrammd5 = false;
233       while(!line.equals("."))
234       {
235           if( line.toLowerCase().indexOf("cram-md5")!=-1) cancrammd5 = true;
236           authenticationTypes.addElement(line);
237           line = readOneLineFromServer().trim();
238       }
239
240       if(cancrammd5)
241       {
242           sendOneLineToServer("AUTH CRAM-MD5");
243           line = readOneLineFromServer();
244           if(!line.toLowerCase().startsWith("+ "))
245           {
246              throw new Exception JavaDoc("Sent >AUTH CRAM-MD5, awaiting '+ code'\nreceived: "+line);
247           }
248           String JavaDoc stamp = new String JavaDoc(Utilities.decodeBase64(line.substring(2).trim()));
249           String JavaDoc rep = Utilities.HMAC_KEYED_CRAM_MD5(password.getBytes(), stamp.getBytes(),username);
250           sendOneLineToServer(rep);
251           line = readOneLineFromServer();
252           if(!line.toLowerCase().startsWith("+ok"))
253           {
254              throw new Exception JavaDoc("AUTH failed, received: "+line);
255           }
256           // OK, we are authenticated !
257
}
258       else
259       {
260           logUsingUserAndPass();
261       }
262   }
263
264   /** unsecure !!!
265   */

266   private synchronized void logUsingUserAndPass() throws Exception JavaDoc
267   {
268
269         sendOneLineToServer("USER "+username);
270         String JavaDoc line = readOneLineFromServer();
271         if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("USER error : "+line);
272
273         if(!this.mailAccount.getAllowUnsecurePasswordProtocols())
274         {
275           throw new Exception JavaDoc(
276              Language.translate("Stopped authentication process for %\r\nbecause the unsecure protocol USER / PASS was requested.",
277                     this.mailAccount.getAddress()));
278         }
279
280         sendOneLineToServer("PASS "+password);
281         //accountLog.append("################# NOT SECURE MODE #################");
282

283         line = readOneLineFromServer();
284         if(!line.toLowerCase().startsWith("+ok")) throw new BadPasswordException("PASS error : "+line);
285   }
286
287
288
289   /** does this account have special admin privileges.
290      + used to turn on the associated admin menu items
291   */

292   public boolean hasAdminPrivileges() {return adminPrivileges;}
293
294
295   /** send the public key on the server
296   */

297   public synchronized void publishPublicKey(String JavaDoc address, String JavaDoc publickey) throws Exception JavaDoc
298   {
299       sendOneLineToServer("CHPK "+address+" "+ publickey);
300       String JavaDoc line = readOneLineFromServer();
301       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("CHPK error : "+line);
302   }
303
304
305   /** special command to change this account password
306    */

307   public synchronized void changePassword(String JavaDoc newHash) throws Exception JavaDoc
308   {
309       sendOneLineToServer("CPAS "+ newHash);
310       String JavaDoc line = readOneLineFromServer();
311       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("CPAS error : "+line);
312   }
313
314
315   /** special command to add a new user
316    */

317   public synchronized void addNewUser(String JavaDoc name, String JavaDoc hash) throws Exception JavaDoc
318   {
319       if(!adminPrivileges) throw new Exception JavaDoc(
320         Language.translate("Requires administrator privileges"));
321       sendOneLineToServer("ADUR "+ name+" "+hash);
322       String JavaDoc line = readOneLineFromServer();
323       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("ADUR error : "+line);
324   }
325
326   /** special command to set a user's password
327    */

328   public synchronized void setUserPassword(String JavaDoc name, String JavaDoc hash) throws Exception JavaDoc
329   {
330       if(!adminPrivileges) throw new Exception JavaDoc(Language.translate("Requires administrator privileges"));
331       sendOneLineToServer("SUPA "+ name+" "+hash);
332       String JavaDoc line = readOneLineFromServer();
333       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("SUPA error : "+line);
334   }
335
336   /** special command, add a new forbidden address
337    */

338   public synchronized void addNewForbiddenFrom(String JavaDoc forbidden) throws Exception JavaDoc
339   {
340       sendOneLineToServer("ADFO "+ forbidden);
341       String JavaDoc line = readOneLineFromServer();
342       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("ADFO error : "+line);
343   }
344
345   /** special command, remove the forbidden address
346    */

347   public synchronized void removeForbiddenFrom(String JavaDoc forbidden) throws Exception JavaDoc
348   {
349       sendOneLineToServer("REFO "+ forbidden);
350       String JavaDoc line = readOneLineFromServer();
351       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("REFO error : "+line);
352   }
353
354
355   public synchronized Vector JavaDoc getForbiddenList() throws Exception JavaDoc
356   {
357       sendOneLineToServer("GEFO");
358       String JavaDoc line = readOneLineFromServer();
359       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("GEFO error : "+line);
360       Vector JavaDoc<String JavaDoc> addresses = new Vector JavaDoc<String JavaDoc>();
361       while(true)
362       {
363          line = readOneLineFromServer();
364          if(line==null || line.equals(".")) break;
365          addresses.addElement(line);
366       }
367       return addresses;
368   }
369
370
371   /** special command
372    */

373   public synchronized void getServerLogFile(AccountLog log) throws Exception JavaDoc
374   {
375       if(!adminPrivileges) throw new Exception JavaDoc(Language.translate("Requires administrator privileges"));
376       sendOneLineToServer("GELO") ;
377       String JavaDoc line = readOneLineFromServer();
378       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("GELO error : "+line);
379
380       while(true)
381       {
382         line = readOneLineFromServer();
383         if( line==null || line.equals(".")) break;
384         log.appendLine(line);
385       }
386   }
387
388
389   /** @return a message list in the format
390          mess number "space" size in bytes
391   */

392   public synchronized String JavaDoc[] getMessagesLIST_() throws Exception JavaDoc
393   {
394       sendOneLineToServer("LIST");
395       String JavaDoc line = readOneLineFromServer();
396       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("STAT error : "+line);
397
398       Vector JavaDoc<String JavaDoc> ident = new Vector JavaDoc<String JavaDoc>();
399       while(true)
400       {
401          line = readOneLineFromServer();
402          if(line==null || line.equals(".")) break;
403          ident.addElement(line);
404       }
405       return ident.toArray(new String JavaDoc[ident.size()]);
406   }
407
408
409   /** @return the sizes in bytes
410   */

411   public synchronized int[] getSizes_from_MessagesLIST(String JavaDoc[] list) throws Exception JavaDoc
412   {
413      int[] sizes = new int[list.length];
414      for(int i=0; i<list.length; i++)
415      {
416         String JavaDoc nn = list[i].trim();
417         int pos = nn.lastIndexOf(" ");
418         try
419         {
420           nn = nn.substring(pos+1);
421           sizes[i] = Integer.parseInt(nn);
422         }
423         catch(NumberFormatException JavaDoc e)
424         {
425           System.out.println("Cannot parse a number from "+nn);
426         }
427      }
428      return sizes;
429   }
430
431   /** @return all the messages UIDL's
432   */

433   public synchronized String JavaDoc[] getMessagesUIDLs() throws Exception JavaDoc
434   {
435      String JavaDoc[] uidls = new String JavaDoc[messageUIDLs.size()];
436      return messageUIDLs.keySet().toArray(uidls);
437   }
438
439
440   /** put the uidl's in the hashtable messageUIDLs
441       with following syntax :
442         key = UIDL (String), object = message number (Integer)
443
444       this index must be rebuild at each login in the mailserver
445   */

446   private synchronized void retrieveMessagesUIDL() throws Exception JavaDoc
447   {
448       messageUIDLs.clear();
449
450       sendOneLineToServer("UIDL");
451       String JavaDoc line = readOneLineFromServer();
452       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("UIDL error : "+line);
453
454       while(true)
455       {
456          line = readOneLineFromServer();
457          if(line==null || line.equals(".")) break;
458          int pos = line.indexOf(" ");
459          if(pos==-1) throw new Exception JavaDoc("Bad UIDL line : "+line);
460          String JavaDoc number = line.substring(0,pos);
461          String JavaDoc ident = line.substring(pos+1);
462          messageUIDLs.put(ident, new Integer JavaDoc(number));
463       }
464
465       //System.out.println("Message uidls for "+this.username+" = "+messageUIDLs);
466
}
467
468
469   /** @return {n, totalSize in bytes}
470   */

471   public synchronized int[] getNumberOfMessages() throws Exception JavaDoc
472   {
473       sendOneLineToServer("STAT");
474       String JavaDoc line = readOneLineFromServer();
475       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("STAT error : "+line);
476
477       // read number of messages
478
String JavaDoc nStr = line.substring(4); // "7 2334" 7 messages, total of 2334 chars
479
int numberOfMessages = 0;
480       int pos = nStr.indexOf(" ");
481       int size = 0;
482       if(pos!=-1)
483       {
484          try
485          {
486             numberOfMessages = Integer.parseInt( nStr.substring(0,pos) );
487          }
488          catch(NumberFormatException JavaDoc e)
489          {
490             throw new Exception JavaDoc("ERROR Cannot read the number of messages in '"+nStr.substring(0,pos)+"'");
491          }
492
493          try
494          {
495             size = Integer.parseInt(nStr.substring(pos+1) );
496          }
497          catch(NumberFormatException JavaDoc e)
498          {
499             // not fatal, this is just used for progress
500
size = numberOfMessages*2000;
501          }
502       }
503       return new int[]{numberOfMessages, size};
504   }
505
506
507   public synchronized void deleteMessage(String JavaDoc uidl) throws Exception JavaDoc
508   {
509      deleteMessage(getMessageNumberFromUIDL(uidl));
510      // no exception => remove the UIDL from the list
511
this.messageUIDLs.remove(uidl);
512   }
513
514   /**
515   */

516   private synchronized void deleteMessage(int number) throws Exception JavaDoc
517   {
518       sendOneLineToServer( "DELE "+number );
519       String JavaDoc line = readOneLineFromServer();
520       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("DELE error : "+line);
521   }
522
523
524   public synchronized void sendFile(byte[] bytes, String JavaDoc name) throws Exception JavaDoc
525   {
526       sendOneLineToServer( "SEFI "+name);
527       String JavaDoc line = readOneLineFromServer();
528       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("SEFI error : "+line);
529
530       OutputStream os = connection.getOutputStream();
531       DataOutputStream dos = new DataOutputStream(os);
532       dos.writeInt(bytes.length);
533
534       ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
535
536       byte[] buf = new byte[256];
537       int read = 0;
538       while((read=bis.read(buf))!=-1)
539       {
540          dos.write(buf,0,read);
541       }
542       dos.flush();
543   }
544
545
546   public synchronized void deleteFile(String JavaDoc name) throws Exception JavaDoc
547   {
548       sendOneLineToServer( "DEFI "+name);
549       String JavaDoc line = readOneLineFromServer();
550       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("DEFI error : "+line);
551   }
552
553
554   public synchronized boolean hasFile(String JavaDoc name) throws Exception JavaDoc
555   {
556       sendOneLineToServer( "HAFI "+name);
557       String JavaDoc line = readOneLineFromServer();
558       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("HAFI error : "+line);
559       String JavaDoc rep = line.substring(3).trim().toLowerCase();
560       if(rep.equals("yes")) return true;
561       return false;
562   }
563
564
565   public synchronized byte[] getFile(String JavaDoc name) throws Exception JavaDoc
566   {
567       sendOneLineToServer( "GEFI "+name);
568       String JavaDoc line = readOneLineFromServer();
569       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("GEFI error : "+line);
570
571       InputStream is = connection.getInputStream();
572       DataInputStream dis = new DataInputStream(is);
573       int size = dis.readInt();
574
575       byte[] bytes = new byte[size];
576       dis.readFully(bytes);
577       return bytes;
578   }
579
580
581
582   /** this return the message number (session dependent) from the UIDL (robust)
583   */

584   private synchronized int getMessageNumberFromUIDL(String JavaDoc uidl) throws Exception JavaDoc
585   {
586      if(!messageUIDLs.containsKey(uidl))
587      {
588         throw new Exception JavaDoc("Message uidl='"+uidl+"' not found on server");
589         // try to get the number direct ???
590
}
591      return messageUIDLs.get(uidl);
592   }
593
594
595   /** @return the first lines of the message.
596       @param len = 0 => only the header
597   */

598   public synchronized String JavaDoc getMessageTop(String JavaDoc ident, int len) throws Exception JavaDoc
599   {
600      return getMessageTop(
601         getMessageNumberFromUIDL(ident), len);
602   }
603
604   /** not robust, the message number is not a ggod identifier,
605      it may have changed. Use getMessageTop(String ident, int len) instead
606   */

607   private synchronized String JavaDoc getMessageTop(int number, int len) throws Exception JavaDoc
608   {
609       StringBuffer JavaDoc message = new StringBuffer JavaDoc();
610       sendOneLineToServer( "TOP "+number+" "+len );
611       String JavaDoc line = readOneLineFromServer();
612       if(!line.toLowerCase().startsWith("+ok"))
613       {
614         throw new Exception JavaDoc("TOP error : "+line);
615       }
616
617       while(true)
618       {
619          line = readOneLineFromServer();
620          if(line==null || line.equals(".")) break;
621          message.append(line);
622          message.append("\r\n");
623       }
624       return message.toString().trim();
625   }
626
627   /** @param counter can be null, it is used to monitor the number of bytes read
628   */

629   public synchronized String JavaDoc getMessage(String JavaDoc UIDL, Interrupter interrupter, Counter counter) throws Exception JavaDoc
630   {
631      return getMessage(getMessageNumberFromUIDL(UIDL), interrupter, counter);
632   }
633
634   /** @param progress can be null
635   */

636   private synchronized String JavaDoc getMessage(int number, final Interrupter interrupter, Counter counter) throws Exception JavaDoc
637   {
638       StringBuffer JavaDoc message = new StringBuffer JavaDoc();
639       sendOneLineToServer( "RETR " + number );
640
641       String JavaDoc line = readOneLineFromServer();
642       if(!line.toLowerCase().startsWith("+ok")) throw new Exception JavaDoc("RETR error : "+line);
643
644       int readTotal = 0;
645       long lastTime = 0;
646       int incr = 0;
647
648       while(true)
649       {
650          if(interrupter!=null && interrupter.shouldStopEvaluation())
651          {
652            // important: close the connection, otherwise, we will hang the line !
653
// or the mailbox on server side!
654
try
655            {
656              in.close();
657            } catch(Exception JavaDoc e) {}
658            throw new ManualInterruptedException(Language.translate("The message reception was cancelled by the user"));
659          }
660
661          line = readOneLineFromServer();
662          if(line==null || line.equals(".")) break;
663          message.append(line);
664          message.append("\r\n");
665          readTotal += line.length();
666          incr += line.length();
667
668          long time = System.currentTimeMillis();
669          if(counter!=null && (time-lastTime) > 200)
670          {
671            lastTime = time;
672            counter.increment(incr);
673            incr=0;
674          }
675       }
676
677       if(counter!=null)
678       {
679          counter.increment(incr);
680       }
681
682       return message.toString();
683   }
684
685
686   /** after this, one have to reconnect...
687       sends a QUIT to the server
688       close the socket connection
689    */

690   public synchronized void terminateSession() throws Exception JavaDoc
691   {
692       //System.out.println("Terminate session "+username);
693
//new Throwable().printStackTrace();
694

695       sendOneLineToServer("QUIT");
696       //read dummy line
697
String JavaDoc dummyIgnoredLine = readOneLineFromServer();
698       // ## it returns -ERR if not all messages were deleted
699
messageUIDLs.clear();
700
701       try
702       {
703         this.connection.close();
704       }
705       catch(Exception JavaDoc e)
706       {
707         e.printStackTrace();
708       }
709   }
710
711
712   /** @return true if the line is alive, to determine if yes,
713    * make a NOOP ping
714    */

715   public synchronized boolean isAlive()
716   {
717      try
718      {
719          sendOneLineToServer( "NOOP" );
720          String JavaDoc line = readOneLineFromServer();
721          if(!line.toLowerCase().startsWith("+ok")) return false;
722      }
723      catch(Exception JavaDoc e)
724      {
725          return false;
726      }
727      return true;
728   }
729
730
731   /**
732    * use encryption when activated (after secure logon)
733    */

734   private synchronized void sendOneLineToServer(String JavaDoc _line) throws Exception JavaDoc
735   {
736     String JavaDoc line = _line;
737
738     accountLog.appendSendLine(line, encryptNow);
739
740     if(encryptNow)
741     {
742       line = Utilities.encryptSingleLineBlowfishFormat64(_line, pass);
743     }
744     out.write(line+"\r\n");
745     out.flush();
746   }
747
748
749
750   /**
751    * use encryption when activated (after secure logon)
752    */

753   private synchronized String JavaDoc readOneLineFromServer() throws Exception JavaDoc
754   {
755     String JavaDoc line = in.readLine();
756     if (line==null) return null; // connection broken or terminated...
757

758     if(encryptNow)
759     {
760       if(line.length() ==0) throw new Exception JavaDoc("Zero length line received");
761       line = Utilities.decryptSingleLineBlowfishFormat64(line, pass);
762     }
763
764     accountLog.appendReadLine(line, encryptNow);
765     return line;
766   }
767
768
769 }
Popular Tags