<commit_before>/*
 * xenapi_driver.c: Xen API driver.
 * Copyright (C) 2009, 2010 Citrix Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <libxml/uri.h>
#include <curl/curl.h>
#include <xen/api/xen_all.h>
#include "internal.h"
#include "domain_conf.h"
#include "virterror_internal.h"
#include "datatypes.h"
#include "authhelper.h"
#include "util.h"
#include "uuid.h"
#include "memory.h"
#include "buf.h"
#include "xenapi_driver.h"
#include "xenapi_driver_private.h"
#include "xenapi_utils.h"


/*
 * getCapsObject
 *
 * Build the capabilities of the hypervisor
 * Return virCapsPtr on success or NULL on failure
 */
static virCapsPtr
getCapsObject (void)
{
    virCapsPtr caps = virCapabilitiesNew("x86_64", 0, 0);
    if (!caps) {
        virReportOOMError();
        return NULL;
    }
    virCapsGuestPtr guest1 = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 0, "", "", 0, NULL);
    if (!guest1)
        goto error_cleanup;
    virCapsGuestDomainPtr domain1 = virCapabilitiesAddGuestDomain(guest1, "xen", "", "", 0, NULL);
    if (!domain1)
        goto error_cleanup;
    virCapsGuestPtr guest2 = virCapabilitiesAddGuest(caps, "xen", "x86_64", 0, "", "", 0, NULL);
    if (!guest2)
        goto error_cleanup;
    virCapsGuestDomainPtr domain2 = virCapabilitiesAddGuestDomain(guest2, "xen", "", "", 0, NULL);
    if (!domain2)
        goto error_cleanup;

    return caps;

  error_cleanup:
    virCapabilitiesFree(caps);
    return NULL;
}

/*
 * XenapiOpen
 *
 * Authenticates and creates a session with the server
 * Return VIR_DRV_OPEN_SUCCESS on success, else VIR_DRV_OPEN_ERROR
 */
static virDrvOpenStatus
xenapiOpen (virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
{
    char *username = NULL;
    char *password = NULL;
    struct _xenapiPrivate *privP = NULL;

    if (conn->uri == NULL || conn->uri->scheme == NULL ||
        STRCASENEQ(conn->uri->scheme, "XenAPI")) {
        return VIR_DRV_OPEN_DECLINED;
    }

    if (conn->uri->server == NULL) {
        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                  "Server name not in URI");
        goto error;
    }

    if (auth == NULL) {
        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                  "Authentication Credentials not found");
        goto error;
    }

    if (conn->uri->user != NULL) {
        username = strdup(conn->uri->user);

        if (username == NULL) {
            virReportOOMError();
            goto error;
        }
    } else {
        username = virRequestUsername(auth, NULL, conn->uri->server);

        if (username == NULL) {
            xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                      "Username request failed");
            goto error;
        }
    }

    password = virRequestPassword(auth, username, conn->uri->server);

    if (password == NULL) {
        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                  "Password request failed");
        goto error;
    }

    if (VIR_ALLOC(privP) < 0) {
        virReportOOMError();
        goto error;
    }

    if (virAsprintf(&privP->url, "https://%s", conn->uri->server) < 0) {
        virReportOOMError();
        goto error;
    }

    if (xenapiUtil_ParseQuery(conn, conn->uri, &privP->noVerify) < 0)
        goto error;

    if (!(privP->caps = getCapsObject())) {
        xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR,
                                  "Capabilities not found");
        goto error;
    }

    xmlInitParser();
    xmlKeepBlanksDefault(0);
    xen_init();
    curl_global_init(CURL_GLOBAL_ALL);

    privP->session = xen_session_login_with_password(call_func, privP, username,
                                                     password, xen_api_latest_version);

    if (privP->session != NULL && privP->session->ok) {
        conn->privateData = privP;

        VIR_FREE(username);
        VIR_FREE(password);

        return VIR_DRV_OPEN_SUCCESS;
    }

    xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED, "");

  error:
    VIR_FREE(username);
    VIR_FREE(password);

    if (privP != NULL) {
        if (privP->session != NULL)
            xenSessionFree(privP->session);

        VIR_FREE(privP);
    }

    return VIR_DRV_OPEN_ERROR;
}

/*
 * xenapiClose:
 *
 * Returns 0 on successful session logout
 *<commit_msg>xenapi: Don't leak url and caps in case of error<commit_after>/*
 * xenapi_driver.c: Xen API driver.
 * Copyright (C) 2009, 2010 Citrix Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <libxml/uri.h>
#include <curl/curl.h>
#include <xen/api/xen_all.h>
#include "internal.h"
#include "domain_conf.h"
#include "virterror_internal.h"
#include "datatypes.h"
#include "authhelper.h"
#include "util.h"
#include "uuid.h"
#include "memory.h"
#include "buf.h"
#include "xenapi_driver.h"
#include "xenapi_driver_private.h"
#include "xenapi_utils.h"


/*
 * getCapsObject
 *
 * Build the capabilities of the hypervisor
 * Return virCapsPtr on success or NULL on failure
 */
static virCapsPtr
getCapsObject (void)
{
    virCapsPtr caps = virCapabilitiesNew("x86_64", 0, 0);
    if (!caps) {
        virReportOOMError();
        return NULL;
    }
    virCapsGuestPtr guest1 = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 0, "", "", 0, NULL);
    if (!guest1)
        goto error_cleanup;
    virCapsGuestDomainPtr domain1 = virCapabilitiesAddGuestDomain(guest1, "xen", "", "", 0, NULL);
    if (!domain1)
        goto error_cleanup;
    virCapsGuestPtr guest2 = virCapabilitiesAddGuest(caps, "xen", "x86_64", 0, "", "", 0, NULL);
    if (!guest2)
        goto error_cleanup;
    virCapsGuestDomainPtr domain2 = virCapabilitiesAddGuestDomain(guest2, "xen", "", "", 0, NULL);
    if (!domain2)
        goto error_cleanup;

    return caps;

  error_cleanup:
    virCapabilitiesFree(caps);
    return NULL;
}

/*
 * XenapiOpen
 *
 * Authenticates and creates a session with the server
 * Return VIR_DRV_OPEN_SUCCESS on success, else VIR_DRV_OPEN_ERROR
 */
static virDrvOpenStatus
xenapiOpen (virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
{
    char *username = NULL;
    char *password = NULL;
    struct _xenapiPrivate *privP = NULL;

    if (conn->uri == NULL || conn->uri->scheme == NULL ||
        STRCASENEQ(conn->uri->scheme, "XenAPI")) {
        return VIR_DRV_OPEN_DECLINED;
    }

    if (conn->uri->server == NULL) {
        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                  "Server name not in URI");
        goto error;
    }

    if (auth == NULL) {
        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                  "Authentication Credentials not found");
        goto error;
    }

    if (conn->uri->user != NULL) {
        username = strdup(conn->uri->user);

        if (username == NULL) {
            virReportOOMError();
            goto error;
        }
    } else {
        username = virRequestUsername(auth, NULL, conn->uri->server);

        if (username == NULL) {
            xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                      "Username request failed");
            goto error;
        }
    }

    password = virRequestPassword(auth, username, conn->uri->server);

    if (password == NULL) {
        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
                                  "Password request failed");
        goto error;
    }

    if (VIR_ALLOC(privP) < 0) {
        virReportOOMError();
        goto error;
    }

    if (virAsprintf(&privP->url, "https://%s", conn->uri->server) < 0) {
        virReportOOMError();
        goto error;
    }

    if (xenapiUtil_ParseQuery(conn, conn->uri, &privP->noVerify) < 0)
        goto error;

    if (!(privP->caps = getCapsObject())) {
        xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR,
                                  "Capabilities not found");
        goto error;
    }

    xmlInitParser();
    xmlKeepBlanksDefault(0);
    xen_init();
    curl_global_init(CURL_GLOBAL_ALL);

    privP->session = xen_session_login_with_password(call_func, privP, username,
                                                     password, xen_api_latest_version);

    if (privP->session != NULL && privP->session->ok) {
        conn->privateData = privP;

        VIR_FREE(username);
        VIR_FREE(password);

        return VIR_DRV_OPEN_SUCCESS;
    }

    xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED, "");

  error:
    VIR_FREE(username);
    VIR_FREE(password);

    if (privP != NULL) {
        virCapabilitiesFree(privP->caps);

        if (privP->session != NULL)
            xenSessionFree(privP->session);

        VIR_FREE(privP->url);
        VIR_FREE(privP);
    }

    return VIR_DRV_OPEN_ERROR;
}

/*
 * xenapiClose:
 *
 * Returns 0 on successful session logout
 *
{'fraction_non_alphanumeric': 0.1113645001900418, 'fraction_numerical': 0.01121246674268339, 'mean_word_length': 2.6659700452803903, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 81, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4763910', 'n_tokens_mistral': 3416, 'n_tokens_neox': 3263, 'n_words': 865}