@ -49,6 +49,21 @@ const char *Flags[] = {
SSL_CTX * SSLContext = 0 ;
void
free_message ( message_t * msg )
{
message_t * tmp ;
while ( msg )
{
tmp = msg ;
msg = msg - > next ;
if ( tmp - > file )
free ( tmp - > file ) ;
free ( tmp ) ;
}
}
/* this gets called when a certificate is to be verified */
static int
verify_cert ( SSL * ssl )
@ -100,7 +115,6 @@ verify_cert (SSL * ssl)
puts ( " \n *** Fine, but don't say I didn't warn you! \n " ) ;
}
return ret ;
}
static int
@ -304,15 +318,6 @@ parse_fetch (imap_t * imap, list_t * list)
}
}
#if 0
if ( uid = = 221 )
{
int loop = 1 ;
while ( loop ) ;
}
# endif
cur = calloc ( 1 , sizeof ( message_t ) ) ;
cur - > next = imap - > msgs ;
imap - > msgs = cur ;
@ -485,24 +490,61 @@ imap_exec (imap_t * imap, const char *fmt, ...)
* mailbox .
*/
imap_t *
imap_open ( config_t * box , unsigned int minuid )
imap_open ( config_t * box , unsigned int minuid , imap_t * imap )
{
int ret ;
imap_t * imap ;
int s ;
struct sockaddr_in sin ;
struct hostent * he ;
char * ns_prefix = " " ;
int reuse = 0 ;
# if HAVE_LIBSSL
int use_ssl = 0 ;
# endif
if ( imap )
{
/* determine whether or not we can reuse the existing session */
if ( strcmp ( box - > host , imap - > box - > host ) | |
strcmp ( box - > user , imap - > box - > user ) | |
box - > port ! = imap - > box - > port
# if HAVE_LIBSSL
/* initialize SSL */
if ( init_ssl ( box ) )
return 0 ;
/* ensure that security requirements are met */
| | ( box - > require_ssl ^ imap - > box - > require_ssl )
| | ( box - > require_cram ^ imap - > box - > require_cram )
# endif
)
{
/* can't reuse */
imap_close ( imap ) ;
imap = 0 ;
}
else
{
reuse = 1 ;
/* reset mailbox-specific state info */
imap - > recent = 0 ;
imap - > deleted = 0 ;
imap - > count = 0 ;
imap - > maxuid = 0 ;
free_message ( imap - > msgs ) ;
imap - > msgs = 0 ;
}
}
if ( ! imap )
{
imap = calloc ( 1 , sizeof ( imap_t ) ) ;
imap - > sock = calloc ( 1 , sizeof ( Socket_t ) ) ;
imap - > buf = calloc ( 1 , sizeof ( buffer_t ) ) ;
imap - > buf - > sock = imap - > sock ;
}
imap - > box = box ;
imap - > minuid = minuid ;
if ( ! reuse )
{
/* open connection to IMAP server */
memset ( & sin , 0 , sizeof ( sin ) ) ;
@ -533,30 +575,38 @@ imap_open (config_t * box, unsigned int minuid)
}
puts ( " ok " ) ;
imap = calloc ( 1 , sizeof ( imap_t ) ) ;
imap - > sock = calloc ( 1 , sizeof ( Socket_t ) ) ;
imap - > sock - > fd = s ;
imap - > buf = calloc ( 1 , sizeof ( buffer_t ) ) ;
imap - > buf - > sock = imap - > sock ;
imap - > box = box ;
imap - > minuid = minuid ;
}
do
{
/* if we are reusing the existing connection, we can skip the
* authentication steps .
*/
if ( ! reuse )
{
# if HAVE_LIBSSL
if ( ! box - > use_imaps )
{
/* let's see what this puppy can do... */
ret = imap_exec ( imap , " CAPABILITY " ) ;
if ( ( ret = imap_exec ( imap , " CAPABILITY " ) ) )
break ;
/* always try to select SSL support if available */
if ( imap - > have_starttls & & ! imap_exec ( imap , " STARTTLS " ) )
if ( imap - > have_starttls )
{
if ( ( ret = imap_exec ( imap , " STARTTLS " ) ) )
break ;
use_ssl = 1 ;
}
if ( ! use_ssl )
{
if ( box - > require_ssl )
{
puts ( " Error, SSL support not available " ) ;
return 0 ;
ret = - 1 ;
break ;
}
else
puts ( " Warning, SSL support not available " ) ;
@ -567,28 +617,36 @@ imap_open (config_t * box, unsigned int minuid)
if ( use_ssl )
{
/* initialize SSL */
if ( init_ssl ( box ) )
return 0 ;
imap - > sock - > ssl = SSL_new ( SSLContext ) ;
SSL_set_fd ( imap - > sock - > ssl , imap - > sock - > fd ) ;
ret = SSL_connect ( imap - > sock - > ssl ) ;
if ( ret < = 0 )
{
ret = SSL_get_error ( imap - > sock - > ssl , ret ) ;
printf ( " Error, SSL_connect: %s \n " , ERR_error_string ( ret , 0 ) ) ;
return 0 ;
printf ( " Error, SSL_connect: %s \n " ,
ERR_error_string ( ret , 0 ) ) ;
ret = - 1 ;
break ;
}
/* verify the server certificate */
if ( verify_cert ( imap - > sock - > ssl ) )
return 0 ;
if ( ( ret = verify_cert ( imap - > sock - > ssl ) ) )
break ;
imap - > sock - > use_ssl = 1 ;
puts ( " SSL support enabled " ) ;
if ( box - > use_imaps )
ret = imap_exec ( imap , " CAPABILITY " ) ;
if ( ( ret = imap_exec ( imap , " CAPABILITY " ) ) )
break ;
}
# else
ret = imap_exec ( imap , " CAPABILITY " ) ;
if ( ( ret = imap_exec ( imap , " CAPABILITY " ) ) )
break ;
# endif
puts ( " Logging in... " ) ;
@ -597,7 +655,15 @@ imap_open (config_t * box, unsigned int minuid)
{
puts ( " Authenticating with CRAM-MD5 " ) ;
imap - > cram = 1 ;
ret = imap_exec ( imap , " AUTHENTICATE CRAM-MD5 " ) ;
if ( ( ret = imap_exec ( imap , " AUTHENTICATE CRAM-MD5 " ) ) )
break ;
}
else if ( imap - > box - > require_cram )
{
puts
( " Error, CRAM-MD5 authentication is not supported by server " ) ;
ret = - 1 ;
break ;
}
else
# endif
@ -605,41 +671,46 @@ imap_open (config_t * box, unsigned int minuid)
# if HAVE_LIBSSL
if ( ! use_ssl )
# endif
puts ( " *** Warning *** Password is being sent in the clear " ) ;
ret = imap_exec ( imap , " LOGIN \" %s \" \" %s \" " , box - > user , box - > pass ) ;
puts
( " *** Warning *** Password is being sent in the clear " ) ;
if (
( ret =
imap_exec ( imap , " LOGIN \" %s \" \" %s \" " , box - > user ,
box - > pass ) ) )
break ;
}
/* get NAMESPACE info */
if ( ! ret & & box - > use_namespace & & imap - > have_namespace & &
! imap_exec ( imap , " NAMESPACE " ) )
if ( box - > use_namespace & & imap - > have_namespace )
{
if ( ( ret = imap_exec ( imap , " NAMESPACE " ) ) )
break ;
}
} /* !reuse */
/* XXX for now assume personal namespace */
if ( is_list ( imap - > ns_personal ) & &
if ( imap - > box - > use_namespace & & i s_list ( imap - > ns_personal ) & &
is_list ( imap - > ns_personal - > child ) & &
is_atom ( imap - > ns_personal - > child - > child ) )
{
ns_prefix = imap - > ns_personal - > child - > child - > val ;
}
}
if ( ! ret )
{
fputs ( " Selecting mailbox... " , stdout ) ;
fflush ( stdout ) ;
ret = imap_exec ( imap , " SELECT %s%s " , ns_prefix , box - > box ) ;
if ( ! ret )
if ( ( ret = imap_exec ( imap , " SELECT %s%s " , ns_prefix , box - > box ) ) )
break ;
printf ( " %d messages, %d recent \n " , imap - > count , imap - > recent ) ;
}
if ( ! ret )
{
puts ( " Reading IMAP mailbox index " ) ;
if ( imap - > count > 0 )
{
ret = imap_exec ( imap , " UID FETCH %d:* (FLAGS RFC822.SIZE) " ,
imap - > minuid ) ;
if ( ( ret = imap_exec ( imap , " UID FETCH %d:* (FLAGS RFC822.SIZE) " ,
imap - > minuid ) ) )
break ;
}
}
while ( 0 ) ;
if ( ret )
{
@ -658,6 +729,12 @@ imap_close (imap_t * imap)
{
puts ( " Closing IMAP connection " ) ;
imap_exec ( imap , " LOGOUT " ) ;
close ( imap - > sock - > fd ) ;
free ( imap - > sock ) ;
free ( imap - > buf ) ;
free_message ( imap - > msgs ) ;
memset ( imap , 0xff , sizeof ( imap_t ) ) ;
free ( imap ) ;
}
/* write a buffer stripping all \r bytes */