Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/lib/core/update.py
2989 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
import glob
9
import os
10
import re
11
import shutil
12
import subprocess
13
import time
14
import zipfile
15
16
from lib.core.common import dataToStdout
17
from lib.core.common import extractRegexResult
18
from lib.core.common import getLatestRevision
19
from lib.core.common import getSafeExString
20
from lib.core.common import openFile
21
from lib.core.common import pollProcess
22
from lib.core.common import readInput
23
from lib.core.convert import getText
24
from lib.core.data import conf
25
from lib.core.data import logger
26
from lib.core.data import paths
27
from lib.core.revision import getRevisionNumber
28
from lib.core.settings import GIT_REPOSITORY
29
from lib.core.settings import IS_WIN
30
from lib.core.settings import VERSION
31
from lib.core.settings import TYPE
32
from lib.core.settings import ZIPBALL_PAGE
33
from thirdparty.six.moves import urllib as _urllib
34
35
def update():
36
if not conf.updateAll:
37
return
38
39
success = False
40
41
if TYPE == "pip":
42
infoMsg = "updating sqlmap to the latest stable version from the "
43
infoMsg += "PyPI repository"
44
logger.info(infoMsg)
45
46
debugMsg = "sqlmap will try to update itself using 'pip' command"
47
logger.debug(debugMsg)
48
49
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
50
51
output = ""
52
try:
53
process = subprocess.Popen("pip install -U sqlmap", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
54
pollProcess(process, True)
55
output, _ = process.communicate()
56
success = not process.returncode
57
except Exception as ex:
58
success = False
59
output = getSafeExString(ex)
60
finally:
61
output = getText(output)
62
63
if success:
64
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)))
65
else:
66
logger.error("update could not be completed ('%s')" % re.sub(r"[^a-z0-9:/\\]+", " ", output).strip())
67
68
elif not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
69
warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
70
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
71
logger.warning(warnMsg)
72
73
if VERSION == getLatestRevision():
74
logger.info("already at the latest revision '%s'" % (getRevisionNumber() or VERSION))
75
return
76
77
message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
78
if readInput(message, default='N', boolean=True):
79
directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)
80
81
try:
82
open(os.path.join(directory, "sqlmap.py"), "w+b")
83
except Exception as ex:
84
errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex))
85
logger.error(errMsg)
86
else:
87
attrs = os.stat(os.path.join(directory, "sqlmap.py")).st_mode
88
for wildcard in ('*', ".*"):
89
for _ in glob.glob(os.path.join(directory, wildcard)):
90
try:
91
if os.path.isdir(_):
92
shutil.rmtree(_)
93
else:
94
os.remove(_)
95
except:
96
pass
97
98
if glob.glob(os.path.join(directory, '*')):
99
errMsg = "unable to clear the content of directory '%s'" % directory
100
logger.error(errMsg)
101
else:
102
try:
103
archive = _urllib.request.urlretrieve(ZIPBALL_PAGE)[0]
104
105
with zipfile.ZipFile(archive) as f:
106
for info in f.infolist():
107
info.filename = re.sub(r"\Asqlmap[^/]+", "", info.filename)
108
if info.filename:
109
f.extract(info, directory)
110
111
filepath = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
112
if os.path.isfile(filepath):
113
with openFile(filepath, "rb") as f:
114
version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
115
logger.info("updated to the latest version '%s#dev'" % version)
116
success = True
117
except Exception as ex:
118
logger.error("update could not be completed ('%s')" % getSafeExString(ex))
119
else:
120
if not success:
121
logger.error("update could not be completed")
122
else:
123
try:
124
os.chmod(os.path.join(directory, "sqlmap.py"), attrs)
125
except OSError:
126
logger.warning("could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py"))
127
128
else:
129
infoMsg = "updating sqlmap to the latest development revision from the "
130
infoMsg += "GitHub repository"
131
logger.info(infoMsg)
132
133
debugMsg = "sqlmap will try to update itself using 'git' command"
134
logger.debug(debugMsg)
135
136
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
137
138
output = ""
139
try:
140
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
141
pollProcess(process, True)
142
output, _ = process.communicate()
143
success = not process.returncode
144
except Exception as ex:
145
success = False
146
output = getSafeExString(ex)
147
finally:
148
output = getText(output)
149
150
if success:
151
logger.info("%s the latest revision '%s'" % ("already at" if "Already" in output else "updated to", getRevisionNumber()))
152
else:
153
if "Not a git repository" in output:
154
errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "
155
errMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
156
logger.error(errMsg)
157
else:
158
logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", output).strip())
159
160
if not success:
161
if IS_WIN:
162
infoMsg = "for Windows platform it's recommended "
163
infoMsg += "to use a GitHub for Windows client for updating "
164
infoMsg += "purposes (https://desktop.github.com/) or just "
165
infoMsg += "download the latest snapshot from "
166
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
167
else:
168
infoMsg = "for Linux platform it's recommended "
169
infoMsg += "to install a standard 'git' package (e.g.: 'apt install git')"
170
171
logger.info(infoMsg)
172
173