Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

beebox / crossover   deb

Repository URL to install this package:

Version: 18.5.0-1 

/ opt / cxoffice / lib / python / demoutils.py

# (c) Copyright 2009-2012, 2015. CodeWeavers, Inc.

import os
import stat

import cxlog
import distversion

import urllib2
import cxobjc
import binascii
import tempfile
import proxyinfo

import cxutils
import cxconfig

# for localization
from cxutils import cxgettext as _


class DemoUtils(cxobjc.Proxy):
    pass

@cxobjc.method(DemoUtils, 'demoStatusForLicenseFile_andSig_')
def demo_status(licenseFile, sigFile):
    """Checks the demo-status of the install. Returns a 5-tuple.
       The first item is a simple boolean:  True if we're in demo
       mode, False if we aren't. The second item is a string which
       will describe the account used to register the demo, if any.
       The third entry is the expiration date of the license.
       Fourth entry:  License ID
       Fifth entry:  True if this license has been revoked
    """

    keyFile = os.path.join(cxutils.CX_ROOT, "share/crossover/data", "tie.pub")

    if not (os.path.exists(licenseFile) and os.path.exists(sigFile)):
        cxlog.log("Unable to locate license %s and/or signature %s.\n" % (licenseFile, sigFile))
        return (True, None, None, None, False)

    if not signatureIsValid(licenseFile, sigFile, keyFile):
        cxlog.log("Signature %s for file %s is invalid.\n" % (sigFile, licenseFile))
        return (True, None, None, None, False)

    licenseData = cxconfig.get(licenseFile)
    username = licenseData[distversion.DEMO_SKU].get('customer')
    expiration = licenseData[distversion.DEMO_SKU].get('expires')
    licenseID = licenseData["license"].get('id')

    if not expiration or not username or not licenseID:
        # The license file is there, but there's no entry for this product.
        return (True, None, None, None, False)

    import c4profilesmanager
    if licenseID in c4profilesmanager.C4ProfilesSet.get_revoked_licenses():
        return (True, username, expiration, licenseID, True)

    builddate = distversion.DATE
    expirationdate = expiration

    if builddate > expirationdate:
        return (True, username, expiration, licenseID, False)
    return (False, username, expiration, licenseID, False)


@cxobjc.method(DemoUtils, 'canRegisterWithLicenseDir_')
def can_register_as_current_user(licenseDir):
    """ Returns True if we have current permission to register. Return
        False if we need to authenticate as root before registering.
    """
    licenseFile = os.path.join(licenseDir, "license.txt")
    sigFile = os.path.join(licenseDir, "license.sig")

    if os.path.exists(licenseFile):
        if not os.access(licenseFile, os.W_OK):
            return False

    if os.path.exists(sigFile):
        if not os.access(sigFile, os.W_OK):
            return False

    if os.path.exists(licenseDir):
        return os.access(licenseDir, os.W_OK)

    parentDir = os.path.dirname(licenseDir)
    return os.access(parentDir, os.W_OK)

@cxobjc.method(DemoUtils, 'serialRegistrationURL')
def serial_reg_url():
    return "https://www.codeweavers.com/bin/serial"

@cxobjc.method(DemoUtils, 'licenseUrlForLogin_andPassword_')
def reg_license_url(login, password):
    # Get an md5 of the password.
    md5hasher = cxutils.md5_hasher()
    md5hasher.update(password)
    mdPassword = md5hasher.hexdigest()

    URL = "HTTPS://www.codeweavers.com/bin/register/%s;%s;lic;%s;md5;0;bom" % (login, mdPassword, distversion.DEMO_EXTREP)
    return URL

def json_format_start():
    # Python 2.6 and higher have a json library, but we still
    # target earlier versions, and it's trivial to encode
    return "{"

def json_format(key, value):
    return "\"%s\":\"%s\"," % (key, value)

def json_format_end(key, value):
    return "\"%s\":\"%s\"}" % (key, value)

@cxobjc.method(DemoUtils, 'createAccountRequestBodyForEmail_name_andPassword_withSerialCode_')
def create_account_request_body_for_email_name_password_with_serial_code(email, name, password, serial):
    # create json request asking the server to create a new account
    request = json_format_start()
    request += json_format("ver", "1")
    request += json_format("cxver", distversion.CX_VERSION)
    request += json_format("name", name)
    request += json_format("email", email)
    request += json_format("password", password)
    request += json_format("sub", "0")
    request += json_format_end("serial", serial)
    return request

@cxobjc.method(DemoUtils, 'checkSerialCodeRegistrationResponse_')
def checkSerialCodeRegistrationResponse(responseBuffer):
    if responseBuffer.find("OK", 0, 16) != -1:
        errorString = None
    elif responseBuffer.find("UNKNOWNSERIAL", 0, 16) != -1:
        errorString = _("CrossOver does not recognize this activation code.\n\nBe sure you have entered the activation code correctly.\n\n") + lastResort()
    elif responseBuffer.find("WRONGPASSWORD", 0, 16) != -1:
        errorString = _("An account already exists for the email address which you have entered, but you have not provided the correct password.\n\nIf you already have an account with codeweavers.com, please enter the current password for your account.") + " " + lastResort()
    elif responseBuffer.find("BADEMAIL", 0, 16) != -1:
        errorString = _("The email address you have entered is not in a valid format. Please enter a valid email address.\n\n") + lastResort()
    elif responseBuffer.find("SERIALREGISTERED", 0, 16) != -1:
        errorString = _("The activation code you have entered has already been registered, and cannot be used again.") + " " + lastResortErroneous()
    elif responseBuffer.find("EXPIRED", 0, 16) != -1:
        errorString = _("The activation code you have entered has expired and can no longer be used.") + " " + lastResortErroneous()
    elif responseBuffer.find("ERROR", 0, 16) != -1:
        errorString = _("The server has encountered an unknown error trying to create your account or register your activation code.\n\n") + lastResort() + "\n"
    else:
        errorString = _("CrossOver has received an unrecognized response from the server while trying to create your account and register your activation code.\n\n") + lastResort() + "\n"

    return errorString

@cxobjc.method(DemoUtils, 'splitLicenseAndSigFromBuffer_')
def splitLicenseAndSigFromBuffer(licenseBuffer_data):
    licenseBuffer = str(licenseBuffer_data).decode("utf_8")
    [openLicenseFD, licenseTempFile] = tempfile.mkstemp(prefix="license.txt")
    os.chmod(licenseTempFile,
             stat.S_IRUSR | stat.S_IWUSR |
             stat.S_IRGRP |
             stat.S_IROTH)
    openLicense = os.fdopen(openLicenseFD, "w")

    [openSigFD, sigTempFile] = tempfile.mkstemp(prefix="license.sig")
    os.chmod(sigTempFile,
             stat.S_IRUSR | stat.S_IWUSR |
             stat.S_IRGRP |
             stat.S_IROTH)
    openSig = os.fdopen(openSigFD, "w")

    rVals = (licenseTempFile, sigTempFile)

    sigannounce = "<!-- Signature"
    inSig = False

    # Split the downloaded file into license and signature, and write them out.
    for l in licenseBuffer.split(os.linesep):
        if sigannounce in l:
            inSig = True

        if inSig:
            # We have a signature embedded in an XML comment.
            # Strip out the commenty bits.
            strippedline = l.replace(sigannounce, "")
            strippedline = strippedline.replace("-->", "")
            strippedline = strippedline.rstrip()
            splitline = strippedline.split("= ")
            if len(splitline) > 1:
                hexline = splitline[1].strip()
            else:
                hexline = strippedline.strip()

            openSig.write(binascii.unhexlify(hexline))
        else:
            openLicense.write(l)
            openLicense.write("\n")

    openLicense.close()
    openSig.close()

    if not inSig:
        cxlog.log("The license file we downloaded has no signature, so is probably broken.")
        os.remove(rVals[0])
        os.remove(rVals[1])

        return (None, None)
    return rVals

@cxobjc.method(DemoUtils, 'lastResort')
def lastResort():
    lastResortStr = _("If this problem persists, contact CodeWeavers sales support at sales@codeweavers.com.")
    return lastResortStr

def lastResortErroneous():
    lastResortStr = _("If you believe this is in error, contact CodeWeavers sales support at sales@codeweavers.com.")
    return lastResortStr

@cxobjc.method(DemoUtils, 'checkLicenseDownload_')
def checkLicenseDownload(licenseBuffer_data):
    licenseBuffer = str(licenseBuffer_data).decode("utf_8")
    errorString = None
    if licenseBuffer.find("FILE NOT FOUND", 0, 16) != -1:
        errorString = _("Unable to locate a key for %(product)s.\n\n") % {'product': distversion.PRODUCT_NAME}
        errorString += lastResort()
    elif licenseBuffer.find("USER EXPIRED", 0, 16) != -1:
        errorString = _("Your support period has expired. You are no longer entitled to product upgrades.\n\nVisit store.codeweavers.com to extend your support contract. If you believe this is in error, contact CodeWeavers sales support at sales@codeweavers.com.")
    elif licenseBuffer.find("USER NOT FOUND", 0, 16) != -1 or licenseBuffer.find("BAD PASSWORD", 0, 256) != -1:
        errorString = _("Unable to validate your username and password.\n\nVisit store.codeweavers.com to make sure you have a valid login, and try again.\n\n") + lastResort()
    elif licenseBuffer.find("ERROR", 0, 16) != -1:
        errorString = _("An unknown error occurred while downloading your license file.\n\n") + lastResort()

    return errorString

def create_acct_apply_scode(login, password, username, serialcode):
    errorString = None

    request_body = create_account_request_body_for_email_name_password_with_serial_code(login, username, password, serialcode)
    URL = serial_reg_url()

    try:
        proxyinfo.install_default_opener()
        # Note: this is duplicated from cxurlget.py
        # demoutils is used during registration, and
        # even something like a module import can
        # break registration in hard-to-predict ways.
        # So, atm, I'm just going to duplicate this.
        user_agent = 'Mozilla/5.0 (like Gecko) CrossOver'
        header = {'User-Agent': user_agent}

        request = urllib2.Request(URL, request_body, header)

        response = urllib2.urlopen(request)
        responseBuffer = response.read()
    except urllib2.URLError:
        # Errors in communication with the server
        errorString = _("Registration failed")
        errorString += "\n\n" + lastResort()
        cxlog.warn("registration failed: %s" % errorString)


    if errorString is None:
        # Errors returned by the server
        errorString = checkSerialCodeRegistrationResponse(responseBuffer)

    return errorString

def download_and_split_license_file(login, password):
    """ Attempt to download a license file and drop it into the appropriate dir.
        Returns licensefile, sigfile, errorstring where filename will be None
        if the download failed. Otherwise licensefile and sigfile are temporary
        files; it is the caller's responsibility to test, move, and/or delete
        them.
    """

    errorString = None
    licenseFile = None
    sigFile = None

    URL = reg_license_url(login, password)
    try:
        proxyinfo.install_default_opener()
        licenseFileLike = urllib2.urlopen(URL)
        licenseBuffer = licenseFileLike.read()
    except urllib2.URLError:
        errorString = _("Download failed.\n\n") + lastResort()

    if errorString is None:
        errorString = checkLicenseDownload(licenseBuffer)

    if errorString is None:
        (licenseFile, sigFile) = splitLicenseAndSigFromBuffer(licenseBuffer)
        if not licenseFile or not sigFile:
            errorString = _("The licence file download is corrupt.\n\n") + lastResort()
            licenseFile = None
            sigFile = None

    return licenseFile, sigFile, errorString


def signatureIsValid(fileName, sigFileName, keyFileName):
    args = ("openssl", "dgst", "-sha1", "-verify", keyFileName, "-signature", sigFileName, fileName)
    retcode, _out, _err = cxutils.run(args, stdout=cxutils.NULL, stderr=cxutils.NULL)
    return retcode == 0