2019-05-08 12:47:52 +02:00
|
|
|
#!/usr/bin/env python
|
2008-10-15 15:38:22 +00:00
|
|
|
|
|
|
|
|
"""
|
2026-01-01 19:12:07 +01:00
|
|
|
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
|
2017-10-11 14:50:46 +02:00
|
|
|
See the file 'LICENSE' for copying permission
|
2008-10-15 15:38:22 +00:00
|
|
|
"""
|
|
|
|
|
|
2018-03-14 13:36:10 +01:00
|
|
|
import glob
|
2012-07-03 22:13:01 +02:00
|
|
|
import os
|
2008-10-15 15:38:22 +00:00
|
|
|
import re
|
2018-03-14 13:36:10 +01:00
|
|
|
import shutil
|
2016-12-19 23:47:39 +01:00
|
|
|
import subprocess
|
2010-01-18 14:59:24 +00:00
|
|
|
import time
|
2018-03-14 13:36:10 +01:00
|
|
|
import zipfile
|
2008-10-15 15:38:22 +00:00
|
|
|
|
2010-01-18 14:05:23 +00:00
|
|
|
from lib.core.common import dataToStdout
|
2020-11-27 12:57:16 +01:00
|
|
|
from lib.core.common import extractRegexResult
|
2018-07-11 19:30:14 +02:00
|
|
|
from lib.core.common import getLatestRevision
|
2019-06-04 14:44:06 +02:00
|
|
|
from lib.core.common import getSafeExString
|
2019-05-13 11:51:47 +02:00
|
|
|
from lib.core.common import openFile
|
2013-01-09 16:04:23 +00:00
|
|
|
from lib.core.common import pollProcess
|
2018-03-14 13:36:10 +01:00
|
|
|
from lib.core.common import readInput
|
2019-05-27 13:09:13 +02:00
|
|
|
from lib.core.convert import getText
|
2008-10-15 15:38:22 +00:00
|
|
|
from lib.core.data import conf
|
|
|
|
|
from lib.core.data import logger
|
|
|
|
|
from lib.core.data import paths
|
2012-07-26 00:02:38 +02:00
|
|
|
from lib.core.revision import getRevisionNumber
|
2012-07-08 19:24:25 +02:00
|
|
|
from lib.core.settings import GIT_REPOSITORY
|
2011-03-18 16:35:30 +00:00
|
|
|
from lib.core.settings import IS_WIN
|
2018-07-11 19:30:14 +02:00
|
|
|
from lib.core.settings import VERSION
|
2020-11-27 12:57:16 +01:00
|
|
|
from lib.core.settings import TYPE
|
2018-03-14 13:36:10 +01:00
|
|
|
from lib.core.settings import ZIPBALL_PAGE
|
2019-05-02 23:51:54 +02:00
|
|
|
from thirdparty.six.moves import urllib as _urllib
|
2008-10-15 15:38:22 +00:00
|
|
|
|
2011-01-31 11:38:00 +00:00
|
|
|
def update():
|
2012-07-02 00:00:46 +01:00
|
|
|
if not conf.updateAll:
|
|
|
|
|
return
|
|
|
|
|
|
2012-07-03 22:13:01 +02:00
|
|
|
success = False
|
2010-01-18 14:59:24 +00:00
|
|
|
|
2020-11-27 12:57:16 +01:00
|
|
|
if TYPE == "pip":
|
|
|
|
|
infoMsg = "updating sqlmap to the latest stable version from the "
|
|
|
|
|
infoMsg += "PyPI repository"
|
|
|
|
|
logger.info(infoMsg)
|
|
|
|
|
|
|
|
|
|
debugMsg = "sqlmap will try to update itself using 'pip' command"
|
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
|
|
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
|
|
|
|
|
|
|
|
|
|
output = ""
|
|
|
|
|
try:
|
|
|
|
|
process = subprocess.Popen("pip install -U sqlmap", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
|
|
|
|
|
pollProcess(process, True)
|
|
|
|
|
output, _ = process.communicate()
|
|
|
|
|
success = not process.returncode
|
|
|
|
|
except Exception as ex:
|
|
|
|
|
success = False
|
|
|
|
|
output = getSafeExString(ex)
|
|
|
|
|
finally:
|
|
|
|
|
output = getText(output)
|
|
|
|
|
|
|
|
|
|
if success:
|
|
|
|
|
logger.info("%s the latest revision '%s'" % ("already at" if "already up-to-date" in output else "updated to", extractRegexResult(r"\binstalled sqlmap-(?P<result>\d+\.\d+\.\d+)", output) or extractRegexResult(r"\((?P<result>\d+\.\d+\.\d+)\)", output)))
|
|
|
|
|
else:
|
|
|
|
|
logger.error("update could not be completed ('%s')" % re.sub(r"[^a-z0-9:/\\]+", " ", output).strip())
|
|
|
|
|
|
|
|
|
|
elif not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
|
2018-03-14 13:36:10 +01:00
|
|
|
warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
|
|
|
|
|
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
|
2022-06-22 12:04:34 +02:00
|
|
|
logger.warning(warnMsg)
|
2018-03-14 13:36:10 +01:00
|
|
|
|
2018-07-11 19:30:14 +02:00
|
|
|
if VERSION == getLatestRevision():
|
2023-04-05 09:33:17 +02:00
|
|
|
logger.info("already at the latest revision '%s'" % (getRevisionNumber() or VERSION))
|
2018-07-11 19:30:14 +02:00
|
|
|
return
|
|
|
|
|
|
2018-03-15 11:07:14 +01:00
|
|
|
message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
|
|
|
|
|
if readInput(message, default='N', boolean=True):
|
2018-03-14 13:36:10 +01:00
|
|
|
directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
open(os.path.join(directory, "sqlmap.py"), "w+b")
|
2019-01-22 00:40:48 +01:00
|
|
|
except Exception as ex:
|
2018-03-14 13:36:10 +01:00
|
|
|
errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex))
|
|
|
|
|
logger.error(errMsg)
|
|
|
|
|
else:
|
2018-06-01 11:23:41 +02:00
|
|
|
attrs = os.stat(os.path.join(directory, "sqlmap.py")).st_mode
|
2018-03-14 13:36:10 +01:00
|
|
|
for wildcard in ('*', ".*"):
|
|
|
|
|
for _ in glob.glob(os.path.join(directory, wildcard)):
|
|
|
|
|
try:
|
|
|
|
|
if os.path.isdir(_):
|
|
|
|
|
shutil.rmtree(_)
|
|
|
|
|
else:
|
|
|
|
|
os.remove(_)
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
if glob.glob(os.path.join(directory, '*')):
|
|
|
|
|
errMsg = "unable to clear the content of directory '%s'" % directory
|
|
|
|
|
logger.error(errMsg)
|
|
|
|
|
else:
|
|
|
|
|
try:
|
2019-05-02 23:51:54 +02:00
|
|
|
archive = _urllib.request.urlretrieve(ZIPBALL_PAGE)[0]
|
2018-03-14 13:36:10 +01:00
|
|
|
|
|
|
|
|
with zipfile.ZipFile(archive) as f:
|
|
|
|
|
for info in f.infolist():
|
|
|
|
|
info.filename = re.sub(r"\Asqlmap[^/]+", "", info.filename)
|
|
|
|
|
if info.filename:
|
|
|
|
|
f.extract(info, directory)
|
|
|
|
|
|
|
|
|
|
filepath = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
|
|
|
|
|
if os.path.isfile(filepath):
|
2025-11-06 11:41:35 +01:00
|
|
|
with openFile(filepath, "r") as f:
|
2018-03-14 13:36:10 +01:00
|
|
|
version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
|
|
|
|
|
logger.info("updated to the latest version '%s#dev'" % version)
|
|
|
|
|
success = True
|
2019-01-22 00:40:48 +01:00
|
|
|
except Exception as ex:
|
2018-03-14 13:36:10 +01:00
|
|
|
logger.error("update could not be completed ('%s')" % getSafeExString(ex))
|
|
|
|
|
else:
|
|
|
|
|
if not success:
|
|
|
|
|
logger.error("update could not be completed")
|
2018-06-01 11:23:41 +02:00
|
|
|
else:
|
2018-06-09 22:59:08 +02:00
|
|
|
try:
|
|
|
|
|
os.chmod(os.path.join(directory, "sqlmap.py"), attrs)
|
|
|
|
|
except OSError:
|
|
|
|
|
logger.warning("could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py"))
|
2020-11-27 12:57:16 +01:00
|
|
|
|
2012-07-03 22:13:01 +02:00
|
|
|
else:
|
2018-01-21 11:49:50 +01:00
|
|
|
infoMsg = "updating sqlmap to the latest development revision from the "
|
2012-07-03 22:13:01 +02:00
|
|
|
infoMsg += "GitHub repository"
|
|
|
|
|
logger.info(infoMsg)
|
2010-01-18 14:59:24 +00:00
|
|
|
|
2012-07-03 22:13:01 +02:00
|
|
|
debugMsg = "sqlmap will try to update itself using 'git' command"
|
|
|
|
|
logger.debug(debugMsg)
|
2011-03-18 16:26:39 +00:00
|
|
|
|
2019-01-29 14:59:31 +01:00
|
|
|
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
|
2015-10-16 23:59:39 +02:00
|
|
|
|
2019-08-27 13:41:30 +02:00
|
|
|
output = ""
|
2015-10-16 23:59:39 +02:00
|
|
|
try:
|
2019-05-19 07:44:32 +02:00
|
|
|
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
|
2015-10-16 23:59:39 +02:00
|
|
|
pollProcess(process, True)
|
2019-05-13 11:08:25 +02:00
|
|
|
output, _ = process.communicate()
|
2015-10-16 23:59:39 +02:00
|
|
|
success = not process.returncode
|
2019-05-19 07:44:32 +02:00
|
|
|
except Exception as ex:
|
2015-10-16 23:59:39 +02:00
|
|
|
success = False
|
2019-05-13 11:08:25 +02:00
|
|
|
output = getSafeExString(ex)
|
|
|
|
|
finally:
|
|
|
|
|
output = getText(output)
|
2011-01-31 22:51:14 +00:00
|
|
|
|
2012-07-03 22:13:01 +02:00
|
|
|
if success:
|
2019-05-13 11:08:25 +02:00
|
|
|
logger.info("%s the latest revision '%s'" % ("already at" if "Already" in output else "updated to", getRevisionNumber()))
|
2012-07-03 22:13:01 +02:00
|
|
|
else:
|
2019-05-13 11:08:25 +02:00
|
|
|
if "Not a git repository" in output:
|
2015-10-14 16:11:11 +02:00
|
|
|
errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
|
2018-03-13 10:37:13 +01:00
|
|
|
errMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
|
2015-10-14 16:11:11 +02:00
|
|
|
logger.error(errMsg)
|
|
|
|
|
else:
|
2019-05-13 11:08:25 +02:00
|
|
|
logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", output).strip())
|
2012-07-03 16:49:34 +02:00
|
|
|
|
2012-07-03 22:13:01 +02:00
|
|
|
if not success:
|
2012-07-03 16:49:34 +02:00
|
|
|
if IS_WIN:
|
|
|
|
|
infoMsg = "for Windows platform it's recommended "
|
|
|
|
|
infoMsg += "to use a GitHub for Windows client for updating "
|
2021-02-08 22:42:08 +01:00
|
|
|
infoMsg += "purposes (https://desktop.github.com/) or just "
|
2012-07-04 20:28:18 +02:00
|
|
|
infoMsg += "download the latest snapshot from "
|
2026-01-05 00:35:13 +05:30
|
|
|
infoMsg += "https://github.com/sqlmapproject/sqlmap/releases"
|
2012-07-03 16:49:34 +02:00
|
|
|
else:
|
2018-03-14 13:36:10 +01:00
|
|
|
infoMsg = "for Linux platform it's recommended "
|
2021-07-19 13:58:54 +02:00
|
|
|
infoMsg += "to install a standard 'git' package (e.g.: 'apt install git')"
|
2011-04-12 14:25:17 +00:00
|
|
|
|
2012-07-03 16:34:11 +02:00
|
|
|
logger.info(infoMsg)
|