* More license declarations
[citadel.git] / citadel / modules / managesieve / serv_managesieve.c
index 065702fa1ef8631d03533092f731e68e5e3862bd..8904ea1cfff53b34eae3f4882ff21d95a3177446 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * This module is an managesieve implementation for the Citadel system.
@@ -7,6 +7,22 @@
  * http://tools.ietf.org/html/draft-martin-managesieve-06
  * as this draft expires with this writing, you might need to search for
  * the new one.
+ *
+ * Copyright (c) 2007-2009 by the citadel.org team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "sysdep.h"
 
 
 #include "ctdl_module.h"
-
-
-
-#ifdef HAVE_LIBSIEVE
-
 #include "serv_sieve.h"
 
 
@@ -95,12 +106,13 @@ enum {     /** Command states for login authentication */
        mgsve_plain
 };
 
-#define MGSVE          CC->MGSVE
+#define MGSVE          ((struct citmgsve *)CC->session_specific_data)
 
 /*****************************************************************************/
 /*                      MANAGESIEVE Server                                   */
 /*****************************************************************************/
 
+
 void sieve_outbuf_append(char *str)
 {
         size_t newlen = strlen(str)+1;
@@ -124,7 +136,7 @@ void sieve_outbuf_append(char *str)
  */
 void cmd_mgsve_caps(void)
 { 
-       cprintf("\"IMPLEMENTATION\" \"CITADEL Sieve v6.84\"\r\n" /* TODO: put citversion here. */
+       cprintf("\"IMPLEMENTATION\" \"CITADEL Sieve " PACKAGE_VERSION "\"\r\n" 
                "\"SASL\" \"PLAIN\"\r\n" /*DIGEST-MD5 GSSAPI  SASL sucks.*/
 #ifdef HAVE_OPENSSL
 /* if TLS is already there, should we say that again? */
@@ -142,9 +154,9 @@ void managesieve_greeting(void) {
 
        strcpy(CC->cs_clientname, "Managesieve session");
 
-       CC->internal_pgm = 1;
+       CC->internal_pgm = 0;
        CC->cs_flags |= CS_STEALTH;
-       MGSVE = malloc(sizeof(struct citmgsve));
+       CC->session_specific_data = malloc(sizeof(struct citmgsve));
        memset(MGSVE, 0, sizeof(struct citmgsve));
        cmd_mgsve_caps();
 }
@@ -213,15 +225,24 @@ void cmd_mgsve_auth(int num_parms, char **parms, struct sdm_userdata *u)
        {
                char auth[SIZ];
                int retval;
-               char *message = ReadString(GetSizeToken(parms[2]), parms[0]);
+               char *message;
+               char *username;
+
+               message = NULL;
+               memset (auth, 0, SIZ);
+               if (parms[2][0] == '{')
+                       message = ReadString(GetSizeToken(parms[2]), parms[0]);
                
                if (message != NULL) {/**< do we have tokenized login? */
                        retval = CtdlDecodeBase64(auth, MGSVE->transmitted_message, SIZ);
                }
                else 
                        retval = CtdlDecodeBase64(auth, parms[2], SIZ);
-
-               if (login_ok == CtdlLoginExistingUser(NULL, auth))
+               username = auth;
+               if ((*username == '\0') && (*(username + 1) != '\0'))
+                       username ++;
+               
+               if (login_ok == CtdlLoginExistingUser(NULL, username))
                {
                        char *pass;
                        pass = &(auth[strlen(auth)+1]);
@@ -236,7 +257,6 @@ void cmd_mgsve_auth(int num_parms, char **parms, struct sdm_userdata *u)
                        }
                }
        }
-       
        cprintf("NO \"Authentication Failure.\"\r\n");/* we just support auth plain. */
        CC->kill_me = 1;
 }
@@ -260,7 +280,7 @@ void cmd_mgsve_starttls(void)
 void cmd_mgsve_logout(struct sdm_userdata *u)
 {
        cprintf("OK\r\n");
-       lprintf(CTDL_NOTICE, "MgSve bye.");
+       CtdlLogPrintf(CTDL_NOTICE, "MgSve bye.");
        CC->kill_me = 1;
 }
 
@@ -509,11 +529,11 @@ void managesieve_command_loop(void) {
                length = strlen(parms[0]);
        }
        if (length < 1) {
-               lprintf(CTDL_CRIT, "Client disconnected: ending session.\n");
+               CtdlLogPrintf(CTDL_CRIT, "Client disconnected: ending session.\n");
                CC->kill_me = 1;
                return;
        }
-       lprintf(CTDL_INFO, "MANAGESIEVE: %s\n", cmdbuf);
+       CtdlLogPrintf(CTDL_INFO, "MANAGESIEVE: %s\n", cmdbuf);
        if ((length>= 12) && (!strncasecmp(parms[0], "AUTHENTICATE", 12))){
                cmd_mgsve_auth(num_parms, parms, &u);
        }
@@ -530,7 +550,7 @@ void managesieve_command_loop(void) {
                cmd_mgsve_caps();
        } 
        /** these commands need to be authenticated. throw it out if it tries. */
-       else if (!CtdlAccessCheck(ac_logged_in))
+       else if (CC->logged_in != 0)
        {
                msiv_load(&u);
                if ((length>= 9) && (!strncasecmp(parms[0], "HAVESPACE", 9))){
@@ -557,35 +577,43 @@ void managesieve_command_loop(void) {
                msiv_store(&u, changes_made);
        }
        else {
-               cprintf("No\r\n");
-               lprintf(CTDL_INFO, "illegal Managesieve command: %s", parms[0]);
+               cprintf("No Invalid access or command.\r\n");
+               CtdlLogPrintf(CTDL_INFO, "illegal Managesieve command: %s", parms[0]);
                CC->kill_me = 1;
        }
 
 
 }
 
+/*
+ * This cleanup function blows away the temporary memory and files used by
+ * the server.
+ */
+void managesieve_cleanup_function(void) {
 
-#endif /* HAVE_LIBSIEVE */
-const char* CitadelServiceManageSieve = "ManageSieve";
-CTDL_MODULE_INIT(managesieve)
-{
-
-#ifdef HAVE_LIBSIEVE
-
-       CtdlRegisterServiceHook(config.c_managesieve_port,      /* MGSVE */
-                               NULL,
-                               managesieve_greeting,
-                               managesieve_command_loop,
-                               NULL, 
-                               CitadelServiceManageSieve);
+       /* Don't do this stuff if this is not a managesieve session! */
+       if (CC->h_command_function != managesieve_command_loop) return;
 
-#else  /* HAVE_LIBSIEVE */
+       CtdlLogPrintf(CTDL_DEBUG, "Performing managesieve cleanup hook\n");
+       free(MGSVE);
+}
 
-       lprintf(CTDL_INFO, "This server is missing libsieve.  Managesieve protocol is disabled..\n");
 
-#endif /* HAVE_LIBSIEVE */
 
+const char* CitadelServiceManageSieve = "ManageSieve";
+CTDL_MODULE_INIT(managesieve)
+{
+       if (!threading)
+       {
+               CtdlRegisterServiceHook(config.c_managesieve_port,
+                                       NULL,
+                                       managesieve_greeting,
+                                       managesieve_command_loop,
+                                       NULL, 
+                                       CitadelServiceManageSieve);
+               CtdlRegisterSessionHook(managesieve_cleanup_function, EVT_STOP);
+       }
+       
        /* return our Subversion id for the Log */
        return "$Id$";
 }