KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > ristretto > pop3 > POP3Protocol


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Ristretto Mail API.
15  *
16  * The Initial Developers of the Original Code are
17  * Timo Stich and Frederik Dietz.
18  * Portions created by the Initial Developers are Copyright (C) 2004
19  * All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */

36 package org.columba.ristretto.pop3;
37
38 import java.io.IOException JavaDoc;
39 import java.io.InputStream JavaDoc;
40 import java.io.OutputStream JavaDoc;
41 import java.net.Socket JavaDoc;
42 import java.nio.ByteBuffer JavaDoc;
43 import java.security.MessageDigest JavaDoc;
44 import java.security.NoSuchAlgorithmException JavaDoc;
45 import java.util.LinkedList JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47 import java.util.regex.Matcher JavaDoc;
48 import java.util.regex.Pattern JavaDoc;
49
50 import javax.net.ssl.SSLException;
51 import javax.net.ssl.SSLSocket;
52
53 import org.columba.ristretto.auth.AuthenticationException;
54 import org.columba.ristretto.auth.AuthenticationFactory;
55 import org.columba.ristretto.auth.AuthenticationMechanism;
56 import org.columba.ristretto.auth.AuthenticationServer;
57 import org.columba.ristretto.auth.NoSuchAuthenticationException;
58 import org.columba.ristretto.coder.Base64;
59 import org.columba.ristretto.concurrency.Mutex;
60 import org.columba.ristretto.config.RistrettoConfig;
61 import org.columba.ristretto.io.Source;
62 import org.columba.ristretto.log.LogInputStream;
63 import org.columba.ristretto.log.LogOutputStream;
64 import org.columba.ristretto.log.RistrettoLogger;
65 import org.columba.ristretto.parser.ParserException;
66 import org.columba.ristretto.pop3.parser.ScanListParser;
67 import org.columba.ristretto.pop3.parser.UIDListParser;
68 import org.columba.ristretto.ssl.RistrettoSSLSocketFactory;
69
70 /**
71  * Implementation of the client side POP3 Protocol.
72  *
73  * @author Timo Stich <tstich@users.sourceforge.net>
74  */

75 public class POP3Protocol implements AuthenticationServer {
76
77     /** JDK 1.4+ logging framework logger, used for logging. */
78     private static final Logger JavaDoc LOG = Logger.getLogger("org.columba.ristretto.pop3.protocol");
79
80
81     /**
82      * The default port of POP3 is 110.
83      */

84     public static final int DEFAULT_PORT = 110;
85     /**
86      * The default port of POP3S is 995.
87      */

88     public static final int DEFAULT_SSL_PORT = 995;
89
90     /**
91      * @deprecated Use NOT_CONNECTED instead
92      */

93     public static final int CONNECTION_CLOSED = 0;
94
95     /**
96      * Protcol state.
97      */

98     public static final int NOT_CONNECTED = 0;
99     /**
100      * Protcol state.
101      */

102     public static final int AUTHORIZATION = 1;
103     /**
104      * Protcol state.
105      */

106     public static final int TRANSACTION = 2;
107
108     private static final Pattern JavaDoc timestampPattern =
109         Pattern.compile("(<[^>]*>)");
110
111     private static final Pattern JavaDoc linePattern = Pattern.compile("(([^\r\n]+)\r?\n?)");
112
113     private static final Pattern JavaDoc statPattern = Pattern.compile("(\\d+) (\\d+)");
114     
115
116     // Attributes for ProgressObservable & Cancelable
117
private String JavaDoc servername;
118     private int port;
119     private Socket JavaDoc socket;
120     private POP3InputStream in;
121     private OutputStream JavaDoc out;
122     private int state;
123
124     private String JavaDoc timestamp;
125
126     private Mutex mutex;
127     
128     /**
129      * Constructs the POP3Protocol.
130      *
131      * @param servername the server to connect to
132      * @param port the port to connect to
133      */

134     public POP3Protocol(String JavaDoc servername, int port) {
135         this.port = port;
136         this.servername = servername;
137
138         mutex = new Mutex();
139         
140         state = NOT_CONNECTED;
141     }
142
143     /**
144      * Constructs the POP3Protocol.
145      *
146      * @param servername the server to connect to
147      */

148     public POP3Protocol(String JavaDoc servername) {
149         this(servername, DEFAULT_PORT);
150     }
151
152     /**
153      * Opens a connection to the POP3 server.
154      *
155      * @throws IOException
156      * @throws POP3Exception
157      */

158     public void openPort() throws IOException JavaDoc, POP3Exception {
159         socket = new Socket JavaDoc(servername, port);
160
161         socket.setSoTimeout(RistrettoConfig.getInstance().getTimeout());
162         
163         createStreams();
164
165         POP3Response response = in.readSingleLineResponse();
166
167         // try to find a timestamp
168
Matcher JavaDoc matcher = timestampPattern.matcher(response.getMessage());
169         if (matcher.find()) {
170             timestamp = matcher.group(1);
171         }
172         
173         if( response.isOK() ) {
174             state = AUTHORIZATION;
175         }
176     }
177     
178     /**
179      * Opens a connection to the POP3 server using a SSL socket.
180      * This is also known as the POPs protocol.
181      *
182      * @throws IOException
183      * @throws SSLException
184      * @throws POP3Exception
185      */

186     public void openSSLPort() throws IOException JavaDoc, SSLException, POP3Exception {
187         socket = RistrettoSSLSocketFactory.getInstance().createSocket(servername,
188                 port);
189         socket.setSoTimeout(RistrettoConfig.getInstance().getTimeout());
190
191         // handshake (which cyper algorithms are used?)
192
((SSLSocket) socket).startHandshake();
193         
194         createStreams();
195         
196         POP3Response response = in.readSingleLineResponse();
197
198         // try to find a timestamp
199
Matcher JavaDoc matcher = timestampPattern.matcher(response.getMessage());
200         if (matcher.find()) {
201             timestamp = matcher.group(1);
202         }
203         
204         if( response.isOK() ) {
205             state = AUTHORIZATION;
206         }
207     }
208     
209     /**
210      * Switches to a SSL Socket using the TLS extension.
211      *
212      * @throws IOException
213      * @throws SSLException
214      * @throws POP3Exception
215      */

216     public void startTLS() throws IOException JavaDoc, SSLException, POP3Exception {
217         sendCommand("STLS", null);
218         
219         POP3Response response = readSingleLineResponse();
220         if( response.isERR() ) throw new CommandNotSupportedException("STLS");
221         
222         socket = RistrettoSSLSocketFactory.getInstance().createSocket(socket, servername, port, true);
223         
224         // handshake (which cyper algorithms are used?)
225
((SSLSocket) socket).startHandshake();
226         
227         createStreams();
228     }
229
230     protected void sendCommand(String JavaDoc command, String JavaDoc[] parameters)
231         throws IOException JavaDoc {
232         try {
233             // write the command
234
out.write(command.getBytes());
235
236             // write optional parameters
237
if (parameters != null) {
238                 for (int i = 0; i < parameters.length; i++) {
239                     out.write(' ');
240                     out.write(parameters[i].getBytes());
241                 }
242             }
243             
244             // write CRLF
245
out.write('\r');
246             out.write('\n');
247
248             // flush the stream
249
out.flush();
250         } catch (IOException JavaDoc e) {
251             state = NOT_CONNECTED;
252             throw e;
253         }
254     }
255     
256     protected POP3Response readSingleLineResponse() throws IOException JavaDoc, POP3Exception {
257         try {
258             return in.readSingleLineResponse();
259         } catch (IOException JavaDoc e) {
260             // Connection was closed
261
state = NOT_CONNECTED;
262             throw e;
263         }
264     }
265
266     protected POP3Response readMultiLineResponse() throws IOException JavaDoc, POP3Exception {
267         try {
268             return in.readMultiLineResponse();
269         } catch (IOException JavaDoc e) {
270             // Connection was closed
271
state = NOT_CONNECTED;
272             throw e;
273         }
274     }
275
276
277     private void checkState(int state) throws POP3Exception {
278         if( this.state != state ) {
279             throw new POP3Exception("Wrong state: Should be "+ state + "but is in " + this.state);
280         }
281     }
282
283     
284     /**
285      * Checks if the POP3 server supports APOP authentication.
286      *
287      * @see #apop(String, char[])
288      *
289      * @return true if the server supports APOP
290      * @throws POP3Exception
291      */

292     public boolean isApopSupported() throws POP3Exception {
293         checkState(AUTHORIZATION);
294
295         return( timestamp != null);
296     }
297     
298     /**
299      * Sends the APOP authentication command.
300      *
301      * @param user username
302      * @param secret the shared secret (e.g. the password)
303      * @throws IOException
304      * @throws POP3Exception
305      */

306     public void apop(String JavaDoc user, char[] secret)
307         throws IOException JavaDoc, POP3Exception {
308         if (timestamp == null) {
309             throw new CommandNotSupportedException("No timestamp from server - APOP not possible");
310         }
311         try {
312             MessageDigest JavaDoc md = MessageDigest.getInstance("MD5");
313             md.update(timestamp.getBytes());
314             if (secret == null)
315                 secret = new char[0];
316             byte[] digest = md.digest(new String JavaDoc(secret).getBytes("ISO-8859-1"));
317             
318             mutex.lock();
319             sendCommand("APOP", new String JavaDoc[] { user, digestToString(digest)});
320             
321             POP3Response response = readSingleLineResponse();
322             if (!response.isOK()) {
323                 throw new POP3Exception(response);
324             }
325             state = TRANSACTION;
326         } catch (NoSuchAlgorithmException JavaDoc e) {
327             throw new POP3Exception("Installed JRE doesn't support MD5 - APOP not possible");
328         } finally {
329             mutex.release();
330         }
331     }
332     
333     /**
334      * Authenticates a user. This is done with the Authentication
335      * mechanisms provided by the @link{org.columba.ristretto.auth.AuthenticationFactory}.
336      *
337      *
338      * @param algorithm the algorithm used to authenticate the user (e.g. PLAIN, DIGEST-MD5)
339      * @param user the user name
340      * @param password the password
341      * @throws IOException
342      * @throws POP3Exception
343      * @throws AuthenticationException
344      */

345     public void auth(String JavaDoc algorithm, String JavaDoc user, char[] password) throws IOException JavaDoc, POP3Exception, AuthenticationException {
346         
347         mutex.lock();
348         try {
349             AuthenticationMechanism auth = AuthenticationFactory.getInstance().getAuthentication(algorithm);
350             sendCommand("AUTH", new String JavaDoc[] { algorithm } );
351             
352             auth.authenticate(this, user, password);
353         } catch (NoSuchAuthenticationException e) {
354             throw new POP3Exception( e );
355         } catch (AuthenticationException e) {
356             throw e;
357         } finally {
358             mutex.release();
359         }
360         
361         POP3Response response = readSingleLineResponse();
362         mutex.release();
363         
364         if (!response.isOK()) {
365             throw new POP3Exception(response);
366         }
367         state = TRANSACTION;
368     }
369     /**
370      *
371      * Helper method for APOP authentication
372      *
373      * @param digest
374      * @return the digest String
375      */

376     private String JavaDoc digestToString(byte[] digest) {
377         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
378         for (int i = 0; i < 16; ++i) {
379             if ((digest[i] & 0xFF) < 0x10) {
380                 sb.append("0");
381             }
382             sb.append(Integer.toHexString(digest[i] & 0xFF));
383         }
384         return sb.toString();
385     }
386
387     
388     /**
389      * Authenticates a user with the simple USER PASS commands.
390      *
391      * @param usr the username
392      * @param pass the password
393      * @throws IOException
394      * @throws POP3Exception
395      */

396     public void userPass(String JavaDoc usr, char[] pass) throws IOException JavaDoc, POP3Exception {
397         POP3Response response;
398         mutex.lock();
399         sendCommand("USER", new String JavaDoc[] { usr });
400         try {
401             response = readSingleLineResponse();
402         
403             if (response.isOK()) {
404                 sendCommand("PASS", new String JavaDoc[] { new String JavaDoc(pass) });
405             
406                 response = readSingleLineResponse();
407             }
408         }
409         
410         
411         finally {
412             mutex.release();
413         }
414         
415         if (!response.isOK()) {
416             throw new POP3Exception(response);
417         }
418
419         state = TRANSACTION;
420     }
421
422     /**
423      * Sends the STAT command to get the status of the mailbox.
424      *
425      * @return Array of number of messages and total size.
426      * @throws IOException
427      * @throws POP3Exception
428      */

429     public int[] stat() throws IOException JavaDoc, POP3Exception {
430         checkState(TRANSACTION);
431         POP3Response response;
432
433         mutex.lock();
434         sendCommand("STAT", null);
435         try {
436             response = readSingleLineResponse();
437         } finally {
438             mutex.release();
439         }
440         
441         if (response.isOK()) {
442             Matcher JavaDoc matcher = statPattern.matcher(response.getMessage());
443             if( matcher.find() ) {
444                 return new int[] { Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)) };
445             }
446         }
447
448         throw new POP3Exception(response);
449     }
450
451     /**
452      * Sends the LIST command to get informations about the mails in the mailbox.
453      *
454      * @return ScanList entries whith the information about index and size of the mails in the mailbox.
455      * @throws IOException
456      * @throws POP3Exception
457      */

458     public ScanListEntry[] list() throws IOException JavaDoc, POP3Exception {
459         checkState(TRANSACTION);
460         POP3Response response;
461         LinkedList JavaDoc list = new LinkedList JavaDoc();
462         
463         mutex.lock();
464         sendCommand("LIST", null);
465         try {
466             response = readMultiLineResponse();
467         } finally {
468             mutex.release();
469         }
470         
471         if( response.isOK() ) {
472             Source source = response.getData();
473             Matcher JavaDoc matcher = linePattern.matcher(source);
474
475             while( matcher.find()) {
476                 try {
477                     list.add(ScanListParser.parse(matcher.group(1)));
478                 } catch (ParserException e) {
479                     // This line couldn't be parsed
480
// throw no exception but simply drop it
481
LOG.severe(e.getMessage());
482                 }
483             }
484             
485         }
486         
487         return (ScanListEntry[]) list.toArray(new ScanListEntry[] {});
488     }
489     
490     
491     /**
492      * Sends the LIST command with a index of a mail as parameter.
493      *
494      * @param messageindex the index of the mail in the mailbox
495      * @return the index and size of the mail.
496      * @throws IOException
497      * @throws POP3Exception
498      */

499     public ScanListEntry list(int messageindex) throws IOException JavaDoc, POP3Exception {
500         checkState(TRANSACTION);
501         POP3Response response;
502         
503         sendCommand("LIST", new String JavaDoc[] {Integer.toString(messageindex)});
504         response = readSingleLineResponse();
505         if( response.isOK() ) {
506             try {
507                 return ScanListParser.parse( response.getMessage() );
508             } catch (ParserException e) {
509                 throw new POP3Exception( e.getMessage() );
510             }
511         }
512         
513         throw new POP3Exception(response);
514     }
515
516     /**
517      * Asynchronously download the message from the
518      * server. This means the call to the method
519      * returns instantly while the message is downloaded
520      * by the POP3DownloadThread.
521      *
522      * @param messageindex
523      * @return the message
524      * @throws IOException
525      * @throws POP3Exception
526      */

527     public InputStream JavaDoc retr(int messageindex) throws IOException JavaDoc, POP3Exception {
528         checkState(TRANSACTION);
529         
530         ScanListEntry info = list( messageindex );
531         
532         return retr( messageindex, info.getSize());
533     }
534     
535     
536         
537     /**
538      * Asynchronously download the message from the
539      * server. This means the call to the method
540      * returns instantly while the message is downloaded
541      * by the POP3DownloadThread.
542      *
543      * @param messageindex
544      * @param size
545      * @return the message
546      * @throws IOException
547      * @throws POP3Exception
548      */

549     public InputStream JavaDoc retr(int messageindex, int size) throws IOException JavaDoc, POP3Exception {
550         checkState(TRANSACTION);
551         POP3Response response;
552         
553         mutex.lock();
554         sendCommand("RETR", new String JavaDoc[] {Integer.toString(messageindex)});
555         response = readSingleLineResponse();
556         if( response.isERR() ) {
557             throw new POP3Exception( response );
558         }
559         
560         return in.asyncDownload(size, mutex);
561     }
562     
563     
564     /**
565      * Synchronously download the message from the
566      * server. This means the call to the method
567      * blocks until the complete message is downloaded
568      * from the server.
569      *
570      * @param messageindex
571      * @param size
572      * @return the message
573      * @throws IOException
574      * @throws POP3Exception
575      */

576     public InputStream JavaDoc sretr(int messageindex, int size) throws IOException JavaDoc, POP3Exception {
577         checkState(TRANSACTION);
578         POP3Response response;
579         
580         
581         sendCommand("RETR", new String JavaDoc[] {Integer.toString(messageindex)});
582         response = readSingleLineResponse();
583         if( response.isERR() ) {
584             throw new POP3Exception( response );
585         }
586         
587         return in.syncDownload(size); //no mutex usage
588
}
589     
590     
591     
592     /**
593      * Delete the message from the server.
594      *
595      * @param messageindex
596      * @return <code>true</code> if the command succeeded
597      * @throws IOException
598      * @throws POP3Exception
599      */

600     public boolean dele(int messageindex) throws IOException JavaDoc, POP3Exception {
601         checkState(TRANSACTION);
602         POP3Response response;
603         
604         try {
605             mutex.lock();
606             
607             sendCommand("DELE", new String JavaDoc[] {Integer.toString(messageindex)});
608             response = readSingleLineResponse();
609         } finally {
610             mutex.release();
611         }
612         
613         return response.isOK();
614     }
615     
616     /**
617      * Send a NOOP command.
618      *
619      * @throws IOException
620      * @throws POP3Exception
621      */

622     public void noop() throws IOException JavaDoc, POP3Exception {
623         checkState(TRANSACTION);
624         POP3Response response;
625         
626         try {
627             mutex.lock();
628             
629             sendCommand("NOOP", null );
630             response = readSingleLineResponse();
631         } finally {
632             mutex.release();
633         }
634     
635         
636         if( !response.isOK() ) throw new POP3Exception( response);
637     }
638     
639     /**
640      * Send a RSET command to the server.
641      *
642      * @throws IOException
643      * @throws POP3Exception
644      */

645     public void rset() throws IOException JavaDoc, POP3Exception {
646         checkState(TRANSACTION);
647         POP3Response response;
648         
649         try {
650             mutex.lock();
651             
652             sendCommand("RSET", null );
653             response = readSingleLineResponse();
654         } finally {
655             mutex.release();
656         }
657         
658         
659         if( !response.isOK() ) throw new POP3Exception( response);
660     }
661     
662     /**
663      * Quit the connection to the server.
664      *
665      * @throws IOException
666      * @throws POP3Exception
667      */

668     public void quit() throws IOException JavaDoc, POP3Exception {
669         try {
670             mutex.lock();
671             sendCommand("QUIT", null );
672         } finally {
673             mutex.release();
674             socket.close();
675         
676             in = null;
677             out = null;
678             socket = null;
679         
680             state = NOT_CONNECTED;
681
682         }
683     }
684
685     /**
686      * Send the TOP command to get the fist n lines
687      * of the message. Not supported by every server.
688      *
689      *
690      * @param messageindex
691      * @param numberOfLines
692      * @return the top of the message
693      * @throws IOException
694      * @throws POP3Exception
695      */

696     public Source top(int messageindex, int numberOfLines) throws IOException JavaDoc, POP3Exception {
697         checkState(TRANSACTION);
698         POP3Response response;
699         try {
700             mutex.lock();
701             sendCommand("TOP", new String JavaDoc[] {Integer.toString(messageindex), Integer.toString(numberOfLines)});
702             response = readMultiLineResponse();
703
704         } finally {
705             mutex.release();
706         }
707         
708         return response.getData();
709     }
710
711     /**
712      * Fetch the UID of the messages.
713      *
714      * @param messageindex
715      * @return the UidListEntry
716      * @throws IOException
717      * @throws POP3Exception
718      */

719     public UidListEntry uidl(int messageindex) throws IOException JavaDoc, POP3Exception {
720         checkState(TRANSACTION);
721         POP3Response response;
722         
723         try {
724             mutex.lock();
725             sendCommand("UIDL", new String JavaDoc[] {Integer.toString(messageindex) } );
726             response = readSingleLineResponse();
727         } finally {
728             mutex.release();
729         }
730     
731         
732         if( response.isOK() ) {
733             try {
734                 return UIDListParser.parse( response.getMessage() );
735             } catch (ParserException e) {
736                 throw new POP3Exception( e.getMessage() );
737             }
738         }
739         
740         throw new POP3Exception(response);
741     }
742     
743     /**
744      * Fetch the UIDs of all messages.
745      *
746      * @return the UidListEntries
747      * @throws IOException
748      * @throws POP3Exception
749      */

750     public UidListEntry[] uidl() throws IOException JavaDoc, POP3Exception {
751         checkState(TRANSACTION);
752         POP3Response response;
753         LinkedList JavaDoc list = new LinkedList JavaDoc();
754         
755         try {
756             mutex.lock();
757             sendCommand("UIDL", null);
758             response = readMultiLineResponse();
759         } finally {
760             mutex.release();
761         }
762         
763         if( response.isOK() ) {
764             Source source = response.getData();
765             Matcher JavaDoc matcher = linePattern.matcher(source);
766
767             while( matcher.find()) {
768                 try {
769                     list.add(UIDListParser.parse(matcher.group(1)));
770                 } catch (ParserException e) {
771                     // This line couldn't be parsed
772
LOG.severe(e.getMessage());
773                 }
774             }
775             
776         } else throw new CommandNotSupportedException("UIDL");
777         
778         return (UidListEntry[]) list.toArray(new UidListEntry[] {});
779     }
780
781     /**
782      * Get the capabilities of the server.
783      *
784      * @return the capablities
785      * @throws IOException
786      * @throws POP3Exception
787      */

788     public String JavaDoc[] capa() throws IOException JavaDoc, POP3Exception {
789         POP3Response response;
790         LinkedList JavaDoc list = new LinkedList JavaDoc();
791         
792         try {
793             mutex.lock();
794             sendCommand("CAPA", null);
795             response = readMultiLineResponse();
796         } finally {
797             mutex.release();
798         }
799         
800         if( response.isOK() ) {
801             Source source = response.getData();
802             Matcher JavaDoc matcher = linePattern.matcher(source);
803
804             while( matcher.find()) {
805                 list.add(matcher.group(2));
806             }
807             
808         } else {
809             throw new CommandNotSupportedException("CAPA");
810         }
811         
812         return (String JavaDoc[]) list.toArray(new String JavaDoc[] {});
813     }
814     
815     
816
817     /**
818      * @see org.columba.ristretto.auth.AuthenticationServer#authSend(byte[])
819      */

820     public void authSend(byte[] call) throws IOException JavaDoc {
821         out.write(Base64.encode(ByteBuffer.wrap(call), false).toString()
822                 .getBytes("Us-ASCII"));
823         out.write('\r');
824         out.write('\n');
825         out.flush();
826     }
827
828     /**
829      * @see org.columba.ristretto.auth.AuthenticationServer#authReceive()
830      */

831     public byte[] authReceive() throws AuthenticationException, IOException JavaDoc {
832         try {
833                 POP3Response response = in.readSingleLineResponse();
834                 if(response.isOK()) {
835                     if( response.getMessage() != null) {
836                         return Base64.decodeToArray(response.getMessage());
837                     } else {
838                         return new byte[0];
839                     }
840                 }
841                 throw new AuthenticationException(new POP3Exception(response));
842             } catch (POP3Exception e) {
843                 throw new AuthenticationException( e );
844             }
845     }
846
847     /**
848      * @return the actual state
849      */

850     public int getState() {
851         return state;
852     }
853     
854     private void createStreams() throws IOException JavaDoc {
855         if( RistrettoLogger.logStream != null ) {
856             in =
857                 new POP3InputStream( new LogInputStream(
858                         socket.getInputStream(),RistrettoLogger.logStream ));
859             out = new LogOutputStream( socket.getOutputStream(),RistrettoLogger.logStream) ;
860         } else {
861             in =
862                 new POP3InputStream(
863                         socket.getInputStream());
864             out = socket.getOutputStream();
865             
866         }
867     }
868     /**
869      * @see org.columba.ristretto.auth.AuthenticationServer#getHostName()
870      */

871     public String JavaDoc getHostName() {
872         return servername;
873     }
874     
875     /**
876      * @see org.columba.ristretto.auth.AuthenticationServer#getService()
877      */

878     public String JavaDoc getService() {
879         return "pop3";
880     }
881     
882     /**
883      * Drops the connection.
884      *
885      * @throws IOException
886      *
887      */

888     public void dropConnection() throws IOException JavaDoc {
889         if (state != NOT_CONNECTED) {
890             state = NOT_CONNECTED;
891
892             socket.close();
893             in = null;
894             out = null;
895             socket = null;
896             
897             mutex.release();
898         }
899     }
900     
901 }
902
Popular Tags