@@ -33,7 +33,7 @@ namespace ActiveUp.Net.Mail
3333#endif
3434 public class Imap4Client : System . Net . Sockets . TcpClient
3535 {
36-
36+
3737 #region Constructors
3838
3939 public Imap4Client ( )
@@ -407,29 +407,39 @@ internal void OnNewMessageReceived(ActiveUp.Net.Mail.NewMessageReceivedEventArgs
407407
408408 #region Private utility methods
409409
410- private string _CramMd5 ( string username , string password )
410+ protected string _CramMd5 ( string username , string password )
411411 {
412412 this . OnAuthenticating ( new ActiveUp . Net . Mail . AuthenticatingEventArgs ( username , password ) ) ;
413413 string stamp = System . DateTime . Now . ToString ( "yyMMddhhmmss" + System . DateTime . Now . Millisecond . ToString ( ) ) ;
414414 byte [ ] data = System . Convert . FromBase64String ( this . Command ( stamp + " authenticate cram-md5" , stamp ) . Split ( ' ' ) [ 1 ] . Trim ( new char [ ] { '\r ' , '\n ' } ) ) ;
415415 string digest = System . Text . Encoding . ASCII . GetString ( data , 0 , data . Length ) ;
416416 string response = this . Command ( System . Convert . ToBase64String ( System . Text . Encoding . ASCII . GetBytes ( username + " " + ActiveUp . Net . Mail . Crypto . HMACMD5Digest ( password , digest ) ) ) , stamp ) ;
417417 this . OnAuthenticated ( new ActiveUp . Net . Mail . AuthenticatedEventArgs ( username , password , response ) ) ;
418- this . Mailboxes = this . GetMailboxes ( "" , "%" ) ;
419- this . AllMailboxes = this . GetMailboxes ( "" , "*" ) ;
418+ this . LoadMailboxes ( ) ;
420419 return response ;
421420 }
422421
423- private string _Login ( string username , string password )
422+ protected string _Login ( string username , string password )
424423 {
425424 this . OnAuthenticating ( new ActiveUp . Net . Mail . AuthenticatingEventArgs ( username , password ) ) ;
426425 string stamp = System . DateTime . Now . ToString ( "yyMMddhhmmss" + System . DateTime . Now . Millisecond . ToString ( ) ) ;
427426 this . Command ( "authenticate login" ) ;
428427 this . Command ( System . Convert . ToBase64String ( System . Text . Encoding . ASCII . GetBytes ( username ) ) , stamp ) ;
429428 string response = this . Command ( System . Convert . ToBase64String ( System . Text . Encoding . ASCII . GetBytes ( password ) ) , stamp ) ;
430429 this . OnAuthenticated ( new ActiveUp . Net . Mail . AuthenticatedEventArgs ( username , password , response ) ) ;
431- this . Mailboxes = this . GetMailboxes ( "" , "%" ) ;
432- this . AllMailboxes = this . GetMailboxes ( "" , "*" ) ;
430+ this . LoadMailboxes ( ) ;
431+ return response ;
432+ }
433+
434+ protected string _Plain ( string username , string password )
435+ {
436+ this . OnAuthenticating ( new ActiveUp . Net . Mail . AuthenticatingEventArgs ( username , password ) ) ;
437+ string stamp = System . DateTime . Now . ToString ( "yyMMddhhmmss" + System . DateTime . Now . Millisecond . ToString ( ) ) ;
438+ this . Command ( "authenticate plain" , stamp ) ;
439+ string response = this . Command ( System . Convert . ToBase64String ( System . Text . Encoding . UTF8 . GetBytes ( '\0 ' + username + '\0 ' + password ) ) , "" , stamp ) ;
440+ // needs to use UTF8 encoding instead of ASCII at least for password chars. _Login might need to use UTF8 as well
441+ this . OnAuthenticated ( new ActiveUp . Net . Mail . AuthenticatedEventArgs ( username , password , response ) ) ;
442+ this . LoadMailboxes ( ) ;
433443 return response ;
434444 }
435445
@@ -486,13 +496,13 @@ private string renderSafeParam(string commandParam)
486496 return sb . ToString ( ) ;
487497 }
488498
489- private void receiveResponseData ( Stream stream )
499+ private void receiveResponseData ( Stream stream )
490500 {
491501 byte [ ] readBuffer = new byte [ this . Client . ReceiveBufferSize ] ;
492502 int readbytes = 0 ;
493503
494504 readbytes = this . GetStream ( ) . Read ( readBuffer , 0 , readBuffer . Length ) ;
495- while ( readbytes > 0 )
505+ while ( readbytes > 0 )
496506 {
497507 stream . Write ( readBuffer , 0 , readbytes ) ;
498508 readbytes = 0 ;
@@ -910,8 +920,7 @@ public string Login(string username, string password)
910920 this . OnAuthenticating ( new ActiveUp . Net . Mail . AuthenticatingEventArgs ( username , password , this . host ) ) ;
911921 string response = this . Command ( "login " + username + " " + password ) ;
912922 this . OnAuthenticated ( new ActiveUp . Net . Mail . AuthenticatedEventArgs ( username , password , this . host , response ) ) ;
913- this . Mailboxes = this . GetMailboxes ( "" , "%" ) ;
914- this . AllMailboxes = this . GetMailboxes ( "" , "*" ) ;
923+ this . LoadMailboxes ( ) ;
915924 return response ;
916925 }
917926 public IAsyncResult BeginLogin ( string username , string password , AsyncCallback callback )
@@ -979,6 +988,8 @@ public string Authenticate(string username, string password, ActiveUp.Net.Mail.S
979988 return this . _CramMd5 ( username , password ) ;
980989 case ActiveUp . Net . Mail . SaslMechanism . Login :
981990 return this . _Login ( username , password ) ;
991+ case ActiveUp . Net . Mail . SaslMechanism . Plain :
992+ return this . _Plain ( username , password ) ;
982993 }
983994 return string . Empty ;
984995 }
@@ -1047,11 +1058,13 @@ public void StopIdle()
10471058 #region Command sending, receiving and stream access
10481059
10491060 //Binary result
1050- public byte [ ] CommandBinary ( string command , CommandOptions options = null ) {
1061+ public byte [ ] CommandBinary ( string command , CommandOptions options = null )
1062+ {
10511063 return this . CommandBinary ( command , System . DateTime . Now . ToString ( "yyMMddhhmmss" + System . DateTime . Now . Millisecond . ToString ( ) ) , options ) ;
10521064 }
10531065
1054- public byte [ ] CommandBinary ( string command , string stamp , CommandOptions options = null ) {
1066+ public byte [ ] CommandBinary ( string command , string stamp , CommandOptions options = null )
1067+ {
10551068 if ( options == null )
10561069 options = new CommandOptions ( ) ;
10571070
@@ -1074,9 +1087,12 @@ public byte[] CommandBinary(string command, string stamp, CommandOptions options
10741087 // Complement the Atif changes. Use the flag for !PocketPC config for avoid build errors.
10751088
10761089#if ! PocketPC
1077- if ( this . _sslStream != null ) {
1090+ if ( this . _sslStream != null )
1091+ {
10781092 this . _sslStream . Write ( System . Text . Encoding . ASCII . GetBytes ( stamp + ( ( stamp . Length > 0 ) ? " " : "" ) + command + "\r \n \r \n " ) , 0 , stamp . Length + ( ( stamp . Length > 0 ) ? 1 : 0 ) + command . Length + 2 ) ;
1079- } else {
1093+ }
1094+ else
1095+ {
10801096 base . GetStream ( ) . Write ( System . Text . Encoding . ASCII . GetBytes ( stamp + ( ( stamp . Length > 0 ) ? " " : "" ) + command + "\r \n \r \n " ) , 0 , stamp . Length + ( ( stamp . Length > 0 ) ? 1 : 0 ) + command . Length + 2 ) ;
10811097 }
10821098#else
@@ -1094,9 +1110,12 @@ public byte[] CommandBinary(string command, string stamp, CommandOptions options
10941110 string partResponse = "" ;
10951111 string lastLine = "" ;
10961112 string lastLineOfPartResponse = "" ;
1097- using ( StreamReader sr = new StreamReader ( new MemoryStream ( ) ) ) {
1098- while ( true ) {
1099- if ( sr . EndOfStream ) {
1113+ using ( StreamReader sr = new StreamReader ( new MemoryStream ( ) ) )
1114+ {
1115+ while ( true )
1116+ {
1117+ if ( sr . EndOfStream )
1118+ {
11001119 long streamPos = sr . BaseStream . Position ;
11011120 receiveResponseData ( sr . BaseStream ) ;
11021121 sr . BaseStream . Seek ( streamPos , SeekOrigin . Begin ) ;
@@ -1114,28 +1133,38 @@ public byte[] CommandBinary(string command, string stamp, CommandOptions options
11141133 pos = 0 ;
11151134 lastLineOfPartResponse = partResponse . Substring ( pos ) ;
11161135
1117- if ( commandAsUpper . StartsWith ( "LIST" ) == true ) {
1118- if ( lastLineOfPartResponse . StartsWith ( stamp ) || ( lastLineOfPartResponse . StartsWith ( "+ " ) && options . IsPlusCmdAllowed ) ) {
1136+ if ( commandAsUpper . StartsWith ( "LIST" ) == true )
1137+ {
1138+ if ( lastLineOfPartResponse . StartsWith ( stamp ) || ( lastLineOfPartResponse . StartsWith ( "+ " ) && options . IsPlusCmdAllowed ) )
1139+ {
11191140 lastLine = lastLineOfPartResponse ;
11201141 break ;
11211142 }
1122- } else if ( commandAsUpper . StartsWith ( "DONE" ) == true ) {
1143+ }
1144+ else if ( commandAsUpper . StartsWith ( "DONE" ) == true )
1145+ {
11231146 lastLine = lastLineOfPartResponse ;
11241147 stamp = lastLine . Split ( ' ' ) [ 0 ] ;
11251148 break ;
1126- } else if ( lastLineOfPartResponse != null ) {
1149+ }
1150+ else if ( lastLineOfPartResponse != null )
1151+ {
11271152 //Had to remove + check - this was failing when the email contained a line with +
11281153 //Please add comments as to why here, and reimplement differently
1129- if ( lastLineOfPartResponse . StartsWith ( stamp ) || lastLineOfPartResponse . ToLower ( ) . StartsWith ( "* " + command . Split ( ' ' ) [ 0 ] . ToLower ( ) ) || ( lastLineOfPartResponse . StartsWith ( "+ " ) && options . IsPlusCmdAllowed ) ) {
1154+ if ( lastLineOfPartResponse . StartsWith ( stamp ) || lastLineOfPartResponse . ToLower ( ) . StartsWith ( "* " + command . Split ( ' ' ) [ 0 ] . ToLower ( ) ) || ( ( lastLineOfPartResponse . StartsWith ( "+ " ) || lastLineOfPartResponse . StartsWith ( "+\r \n " ) ) && options . IsPlusCmdAllowed ) )
1155+ {
11301156 lastLine = lastLineOfPartResponse ;
11311157 break ;
1132- } else {
1158+ }
1159+ else
1160+ {
11331161 if ( buffer . Length > 100 )
11341162 lastLineOfPartResponse = buffer . ToString ( ) . Substring ( buffer . Length - 100 ) . Replace ( "\r \n " , "" ) ;
11351163 else
11361164 lastLineOfPartResponse = buffer . ToString ( ) . Replace ( "\r \n " , "" ) ;
11371165 int stampPos = lastLineOfPartResponse . IndexOf ( stamp + " OK" ) ;
1138- if ( stampPos > 0 ) {
1166+ if ( stampPos > 0 )
1167+ {
11391168 lastLine = lastLineOfPartResponse . Substring ( stampPos ) ;
11401169 break ;
11411170 }
@@ -1148,7 +1177,8 @@ public byte[] CommandBinary(string command, string stamp, CommandOptions options
11481177 sr . BaseStream . Seek ( 0 , SeekOrigin . Begin ) ;
11491178 sr . BaseStream . Read ( bufferBytes , 0 , bufferBytes . Length ) ;
11501179
1151- if ( ! sr . CurrentEncoding . Equals ( Encoding . UTF8 ) ) {
1180+ if ( ! sr . CurrentEncoding . Equals ( Encoding . UTF8 ) )
1181+ {
11521182 var utf8Bytes = Encoding . Convert ( sr . CurrentEncoding , Encoding . UTF8 , sr . CurrentEncoding . GetBytes ( bufferString ) ) ;
11531183 bufferString = Encoding . UTF8 . GetString ( utf8Bytes ) ;
11541184 }
@@ -1157,7 +1187,7 @@ public byte[] CommandBinary(string command, string stamp, CommandOptions options
11571187 this . OnTcpRead ( new ActiveUp . Net . Mail . TcpReadEventArgs ( bufferString ) ) ;
11581188 else
11591189 this . OnTcpRead ( new ActiveUp . Net . Mail . TcpReadEventArgs ( "long data" ) ) ;
1160- if ( lastLine . StartsWith ( stamp + " OK" ) || lastLine . ToLower ( ) . StartsWith ( "* " + command . Split ( ' ' ) [ 0 ] . ToLower ( ) ) || lastLine . StartsWith ( "+ " ) )
1190+ if ( lastLine . StartsWith ( stamp + " OK" ) || lastLine . ToLower ( ) . StartsWith ( "* " + command . Split ( ' ' ) [ 0 ] . ToLower ( ) ) || lastLine . StartsWith ( "+ " ) || lastLine . StartsWith ( "+ \r \n " ) )
11611191 return bufferBytes ;
11621192 else
11631193 throw new ActiveUp . Net . Mail . Imap4Exception ( "Command \" " + command + "\" failed" , bufferBytes ) ;
@@ -1216,15 +1246,16 @@ public byte[] CommandBinary(string command, string stamp, string checkStamp, Com
12161246 this . OnTcpRead ( new ActiveUp . Net . Mail . TcpReadEventArgs ( buffer . ToString ( ) ) ) ;
12171247 else
12181248 this . OnTcpRead ( new ActiveUp . Net . Mail . TcpReadEventArgs ( "long data" ) ) ;
1219- if ( lastline . StartsWith ( checkStamp + " OK" ) || temp . ToLower ( ) . StartsWith ( "* " + command . Split ( ' ' ) [ 0 ] . ToLower ( ) ) || temp . StartsWith ( "+ " ) )
1249+ if ( lastline . StartsWith ( checkStamp + " OK" ) || temp . ToLower ( ) . StartsWith ( "* " + command . Split ( ' ' ) [ 0 ] . ToLower ( ) ) || temp . StartsWith ( "+ " ) || temp . StartsWith ( "+ \r \n " ) )
12201250 return bufferBytes ;
12211251 else
12221252 throw new ActiveUp . Net . Mail . Imap4Exception ( "Command \" " + command + "\" failed" , bufferBytes ) ;
12231253 }
12241254 }
12251255
12261256 //With Encoding parameter
1227- public string Command ( string command , string stamp , Encoding encoding , CommandOptions options = null ) {
1257+ public string Command ( string command , string stamp , Encoding encoding , CommandOptions options = null )
1258+ {
12281259 return encoding . GetString ( this . CommandBinary ( command , stamp , options ) ) ;
12291260 }
12301261
0 commit comments