diff --git a/.gitignore b/.gitignore index 70da36f0..68d34212 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ nosetests.xml # Qt creator *.autosave + +# Licence keys +keys diff --git a/gns3/licence.py b/gns3/licence.py new file mode 100644 index 00000000..0188a675 --- /dev/null +++ b/gns3/licence.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 GNS3 Technologies Inc. +# +# 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, see . + +import rsa +import sys +import os +import base64 + +PUB_KEY = b"""-----BEGIN RSA PUBLIC KEY----- +MIICCgKCAgEAiE4Zgzge3Cg6EUfct7vnzcmXkIvsy6g/QkfEeKSz3Cd+L7kxVZGE +weOXySrSSrRBoF1i2JhL2KkqZTY31972deviL+fv+TgE5RueyERFey3fw7+oN/RW +i8UIUvRqHjwocCuJq5yUiOv+AdGKG3TNeYXvx4Xvnrr4AJnJRThDfqd0nr8QAXRn +/Ifx4MKivL8RDyqHoVlHvHeyJmtaZIzsYthsK3FU2XED6d6xwbga3t2cb4+DfJa3 +rBtWnoIXHiRdZZUtl34dGiiyxKL2yco+Dpd5pUvw6F7+n77SnSwN+F0ZzrrgUMHA +vBHBnF4WB6mjRFxbO+B/H1OxnXcjwxgYWLCbkrhQogqyfdkmacppWLOH9OyzGUkY +r7qITLCWSAHuIqXmQF4VAqCPYwEK7o6ndebFk1jaAAPGIw52AA1YOSXJ6jpKiO7f +5gXT3xRfv4kW1Fp6le0hp0Laz6VGbOv44vauxk516v5MI+CUL3u5TOmGWM53u1OG +qq6SfL+5Cu0/4L+SUaJ7nzN+PgWx6BEd0LRzEVQcmRPA4zHbhJ7ebBbYOul9RFyW +8D7yy7mUQZwVQDcuaB6l2pu0BfZppb+Uf81h0nRQIrHt7BRBiyaGojQIHsw8CrqP +3fsnHUvqtNLipC26FSTW4wlPIEktsWU8TABgjbuS45+zFTI141/J77ECAwEAAQ== +-----END RSA PUBLIC KEY-----""" + +import logging +log = logging.getLogger(__name__) + + +def checkLicence(): + """ + Return true if the user as correctly installed the licence file + """ + if sys.platform.startswith("darwin"): + appname = "gns3.net" + else: + appname = "GNS3" + + filename = "licence.txt" + + if sys.platform.startswith("win"): + # On windows, the user specific configuration file location is %APPDATA%/GNS3/gns3_gui.conf + appdata = os.path.expandvars("%APPDATA%") + licence_file = os.path.join(appdata, appname, filename) + + else: + # On UNIX-like platforms, the user specific configuration file location is /etc/xdg/GNS3/gns3_gui.conf + home = os.path.expanduser("~") + licence_file = os.path.join(home, ".config", appname, filename) + + return check_licence_file(licence_file) + + +def check_licence_file(licence_file): + if os.path.exists(licence_file): + with open(licence_file) as f: + email = f.readline().strip() + key = f.readline().strip() + pubkey = rsa.PublicKey.load_pkcs1(PUB_KEY) + try: + rsa.verify(email.encode("utf-8"), base64.b64decode(key), pubkey) + log.info("Found a valid licence file. Thanks for your support") + return True + except rsa.pkcs1.VerificationError: + log.error("Invalid licence file.") + return False + return False diff --git a/gns3/main_window.py b/gns3/main_window.py index 33fc7e21..23254751 100644 --- a/gns3/main_window.py +++ b/gns3/main_window.py @@ -66,6 +66,7 @@ from .cloud.exceptions import KeyPairExists from .project import Project from .http_client import HTTPClient from .progress import Progress +from .licence import checkLicence log = logging.getLogger(__name__) @@ -110,7 +111,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.loading_cloud_project = False self._uiNewsDockWidget = None - if not self._settings["hide_news_dock_widget"]: + if not checkLicence(): try: from .news_dock_widget import NewsDockWidget self._uiNewsDockWidget = NewsDockWidget(self) diff --git a/requirements.txt b/requirements.txt index 5f6d58aa..22f13c26 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ apache-libcloud==0.16.0 paramiko==1.15.1 requests==2.4.3 raven==5.2.0 +rsa==3.1.4 diff --git a/scripts/licence_generator.py b/scripts/licence_generator.py new file mode 100644 index 00000000..4a040885 --- /dev/null +++ b/scripts/licence_generator.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 GNS3 Technologies Inc. +# +# 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, see . + +""" +This script generate a licence key for an user. +You need the GNS 3 private key if you want to use +this key with the public GNS 3 distribution. +""" + +import rsa +import argparse +import base64 +from gns3.licence import check_licence_file + +BITS = 4096 + + +def generate(): + """Generate licence key pair""" + print("Generate licence it can be slow") + (pubkey, privkey) = rsa.newkeys(BITS) + with open("keys/private.pem", "w+") as f: + f.write(privkey.save_pkcs1()) + with open("keys/pub.pem", "w+") as f: + f.write(pubkey.save_pkcs1()) + +# generate() + + +parser = argparse.ArgumentParser(description="Generate licences files") +parser.add_argument("--private", dest="private", + action="store", + required=True, + help="The private key") +parser.add_argument("--out", dest="out", + action="store", + required=True, + help="The output file") +parser.add_argument("--email", dest="email", + action="store", + required=True, + help="The user email") + +args = parser.parse_args() + +with open(args.private, "rb") as privatefile: + keydata = privatefile.read() + privkey = rsa.PrivateKey.load_pkcs1(keydata) + +signature = rsa.sign(args.email.encode("utf-8"), privkey, "SHA-512") +with open(args.out, "wb+") as f: + f.write(args.email.encode("utf-8")) + f.write(b"\n") + f.write(base64.b64encode(signature)) + f.write(b"\n") + +print("Check licence: {}".format(check_licence_file(args.out))) diff --git a/setup.py b/setup.py index 5966baad..b075a2ab 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,8 @@ setup( "requests>=2.4.3", "paramiko>=1.15.1", "gns3-converter>=1.2.3", - "raven>=5.2.0" + "raven>=5.2.0", + "rsa>=3.1.4" ], entry_points={ "gui_scripts": [