Use the UUID API to generate and validate UUIDs for res_calendar_exchange.
[asterisk/asterisk.git] / res / res_calendar_exchange.c
index 05a4263..dda4414 100644 (file)
  */
 
 /*! \file
- * \brief Resource for handling iCalnedar calendars
+ * \brief Resource for handling MS Exchange calendars
  */
 
 /*** MODULEINFO
        <depend>neon</depend>
        <depend>ical</depend>
        <depend>iksemel</depend>
+       <support_level>core</support_level>
 ***/
+
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include <libical/ical.h>
-#include <neon/ne_session.h>
-#include <neon/ne_uri.h>
-#include <neon/ne_request.h>
-#include <neon/ne_auth.h>
+#include <ne_session.h>
+#include <ne_uri.h>
+#include <ne_request.h>
+#include <ne_auth.h>
+#include <ne_redirect.h>
 #include <iksemel.h>
 
 #include "asterisk/module.h"
@@ -41,6 +44,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/lock.h"
 #include "asterisk/config.h"
 #include "asterisk/astobj2.h"
+#include "asterisk/uuid.h"
 
 static void *exchangecal_load_calendar(void *data);
 static void *unref_exchangecal(void *obj);
@@ -212,11 +216,6 @@ static int parse_cdata(void *data, char *value, size_t len)
        return IKS_OK;
 }
 
-static int cb_true(void *user_data, void *arg, int flags)
-{
-       return CMP_MATCH;
-}
-
 static void exchangecal_destructor(void *obj)
 {
        struct exchangecal_pvt *pvt = obj;
@@ -227,7 +226,7 @@ static void exchangecal_destructor(void *obj)
        }
        ast_string_field_free_memory(pvt);
 
-       ao2_callback(pvt->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, cb_true, NULL);
+       ao2_callback(pvt->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
 
        ao2_ref(pvt->events, -1);
 }
@@ -243,36 +242,30 @@ static void *unref_exchangecal(void *obj)
 /* It is very important to use the return value of this function as a realloc could occur */
 static struct ast_str *generate_exchange_uuid(struct ast_str *uid)
 {
-       unsigned short val[8];
-       int x;
+       char buffer[AST_UUID_STR_LEN];
+       struct ast_uuid *uuid = ast_uuid_generate();
 
-       for (x = 0; x < 8; x++) {
-               val[x] = ast_random();
+       if (!uuid) {
+               return NULL;
        }
-       ast_str_set(&uid, 0, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]);
+
+       ast_str_set(&uid, 0, "%s", ast_uuid_to_str(uuid, buffer, AST_UUID_STR_LEN));
+
+       ast_free(uuid);
 
        return uid;
 }
 
 static int is_valid_uuid(struct ast_str *uid)
 {
-       int i;
+       struct ast_uuid *uuid = ast_str_to_uuid(ast_str_buffer(uid));
 
-       if (ast_str_strlen(uid) != 36) {
-               return 0;
+       if (uuid) {
+               ast_free(uuid);
+               return 1;
        }
 
-       for (i = 0; i < ast_str_strlen(uid); i++) {
-               if (i == 8 || i == 13 || i == 18 || i == 23) {
-                       if (ast_str_buffer(uid)[i] != '-') {
-                               return 0;
-                       }
-               } else if (!((ast_str_buffer(uid)[i] > 47 && ast_str_buffer(uid)[i] < 58) || (ast_str_buffer(uid)[i] > 96 && ast_str_buffer(uid)[i] < 103))) {
-                       return 0;
-               }
-       }
-
-       return 1;
+       return 0;
 }
 
 static struct ast_str *xml_encode_str(struct ast_str *dst, const char *src)
@@ -407,6 +400,7 @@ static struct ast_str *exchangecal_request(struct exchangecal_pvt *pvt, const ch
        ne_add_request_header(req, "Content-type", "text/xml");
 
        ret = ne_request_dispatch(req);
+       ne_request_destroy(req);
 
        if (ret != NE_OK || !ast_str_strlen(response)) {
                ast_log(LOG_WARNING, "Unknown response to CalDAV calendar %s, request %s to %s: %s\n", pvt->owner->name, method, pvt->url, ne_get_error(pvt->session));
@@ -434,9 +428,8 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
                return -1;
        }
        if (!(body = ast_str_create(512)) ||
-               !(subdir = ast_str_create(32)) ||
-               !(response = ast_str_create(512))) {
-               ast_log(LOG_ERROR, "Could not allocate memory for request and response!\n");
+               !(subdir = ast_str_create(32))) {
+               ast_log(LOG_ERROR, "Could not allocate memory for request!\n");
                goto write_cleanup;
        }
 
@@ -506,9 +499,10 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
        ast_verb(0, "\n\n%s\n\n", ast_str_buffer(body));
        ast_str_set(&subdir, 0, "/Calendar/%s.eml", ast_str_buffer(uid));
 
-       response = exchangecal_request(event->owner->tech_pvt, "PROPPATCH", body, subdir);
+       if ((response = exchangecal_request(event->owner->tech_pvt, "PROPPATCH", body, subdir))) {
+               ret = 0;
+       }
 
-       ret = 0;
 write_cleanup:
        if (uid) {
                ast_free(uid);
@@ -698,8 +692,9 @@ static void *exchangecal_load_calendar(void *void_data)
        }
 
        pvt->session = ne_session_create(pvt->uri.scheme, pvt->uri.host, pvt->uri.port);
+       ne_redirect_register(pvt->session);
        ne_set_server_auth(pvt->session, auth_credentials, pvt);
-       if (!strncasecmp(pvt->uri.scheme, "https", sizeof(pvt->uri.scheme))) {
+       if (!strcasecmp(pvt->uri.scheme, "https")) {
                ne_ssl_trust_default_ca(pvt->session);
        }
 
@@ -758,7 +753,8 @@ static int unload_module(void)
        return 0;
 }
 
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk MS Exchange Calendar Integration",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Asterisk MS Exchange Calendar Integration",
                .load = load_module,
                .unload = unload_module,
+               .load_pri = AST_MODPRI_DEVSTATE_PLUGIN,
        );