mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 20:51:31 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
626b310e7e | ||
|
|
76a2e658b5 | ||
|
|
9c1879b08d | ||
|
|
ae1bd2136a | ||
|
|
305d79846f | ||
|
|
acd9831917 | ||
|
|
8430d6ba96 | ||
|
|
162bafa77d | ||
|
|
1ce9c8ab94 | ||
|
|
bfe03ef95a | ||
|
|
27c4e8d29a | ||
|
|
d42187ac47 | ||
|
|
93a8828dab | ||
|
|
d38d734e6d | ||
|
|
f94ab0f650 | ||
|
|
585a13d89b |
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
|
[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
|
||||||
|
|
||||||
sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z nich danych, a nawet pozwalających na dostęp do systemu plików o uruchamianie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia.
|
sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z niej danych, a nawet pozwalających na dostęp do systemu plików oraz wykonywanie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia.
|
||||||
|
|
||||||
Zrzuty ekranowe
|
Zrzuty ekranu
|
||||||
----
|
----
|
||||||
|
|
||||||

|

|
||||||
@@ -33,18 +33,18 @@ Aby uzyskać listę wszystkich funkcji i parametrów użyj polecenia:
|
|||||||
|
|
||||||
python sqlmap.py -hh
|
python sqlmap.py -hh
|
||||||
|
|
||||||
Przykładowy wynik działania dostępny jest [tutaj](https://asciinema.org/a/46601).
|
Przykładowy wynik działania można znaleźć [tutaj](https://asciinema.org/a/46601).
|
||||||
Aby uzyskać listę wszystkich dostępnych funkcji, parametrów i opisów ich działania wraz z przykładami użycia sqlmap proponujemy odwiedzić [instrukcję użytkowania](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
|
Aby uzyskać listę wszystkich dostępnych funkcji, parametrów oraz opisów ich działania wraz z przykładami użycia sqlmap zalecamy odwiedzić [instrukcję użytkowania](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
|
||||||
|
|
||||||
Odnośniki
|
Odnośniki
|
||||||
----
|
----
|
||||||
|
|
||||||
* Strona projektu: https://sqlmap.org
|
* Strona projektu: https://sqlmap.org
|
||||||
* Pobieranie: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
* Pobieranie: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) lub [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
||||||
* RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
* RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||||
* Raportowanie błędów: https://github.com/sqlmapproject/sqlmap/issues
|
* Zgłaszanie błędów: https://github.com/sqlmapproject/sqlmap/issues
|
||||||
* Instrukcja użytkowania: https://github.com/sqlmapproject/sqlmap/wiki
|
* Instrukcja użytkowania: https://github.com/sqlmapproject/sqlmap/wiki
|
||||||
* Często zadawane pytania (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
* Często zadawane pytania (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||||
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
|
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
|
||||||
* Dema: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
|
* Dema: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
|
||||||
* Zrzuty ekranowe: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
* Zrzuty ekranu: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ chmod +x .git/hooks/pre-commit
|
|||||||
|
|
||||||
PROJECT="../../"
|
PROJECT="../../"
|
||||||
SETTINGS="../../lib/core/settings.py"
|
SETTINGS="../../lib/core/settings.py"
|
||||||
|
DIGEST="../../sha256sums.txt"
|
||||||
|
|
||||||
declare -x SCRIPTPATH="${0}"
|
declare -x SCRIPTPATH="${0}"
|
||||||
|
|
||||||
PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT
|
PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT
|
||||||
SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
|
SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
|
||||||
|
DIGEST_FULLPATH=${SCRIPTPATH%/*}/$DIGEST
|
||||||
|
|
||||||
git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0
|
git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0
|
||||||
|
|
||||||
@@ -35,3 +37,5 @@ then
|
|||||||
fi
|
fi
|
||||||
git add "$SETTINGS_FULLPATH"
|
git add "$SETTINGS_FULLPATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
cd $PROJECT_FULLPATH && git ls-files | sort | uniq | grep -v sha256 | xargs sha256sum > $DIGEST_FULLPATH
|
||||||
|
|||||||
@@ -880,7 +880,7 @@ def getManualDirectories():
|
|||||||
def getAutoDirectories():
|
def getAutoDirectories():
|
||||||
"""
|
"""
|
||||||
>>> pushValue(kb.absFilePaths)
|
>>> pushValue(kb.absFilePaths)
|
||||||
>>> kb.absFilePaths = ["C:\\inetpub\\wwwroot\\index.asp", "/var/www/html"]
|
>>> kb.absFilePaths = [r"C:\\inetpub\\wwwroot\\index.asp", "/var/www/html"]
|
||||||
>>> getAutoDirectories()
|
>>> getAutoDirectories()
|
||||||
['C:/inetpub/wwwroot', '/var/www/html']
|
['C:/inetpub/wwwroot', '/var/www/html']
|
||||||
>>> kb.absFilePaths = popValue()
|
>>> kb.absFilePaths = popValue()
|
||||||
@@ -2308,7 +2308,7 @@ def ntToPosixSlashes(filepath):
|
|||||||
Replaces all occurrences of NT backslashes in provided
|
Replaces all occurrences of NT backslashes in provided
|
||||||
filepath with Posix slashes
|
filepath with Posix slashes
|
||||||
|
|
||||||
>>> ntToPosixSlashes('C:\\Windows')
|
>>> ntToPosixSlashes(r'C:\\Windows')
|
||||||
'C:/Windows'
|
'C:/Windows'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -4273,6 +4273,9 @@ def safeSQLIdentificatorNaming(name, isTable=False):
|
|||||||
|
|
||||||
retVal = name
|
retVal = name
|
||||||
|
|
||||||
|
if conf.unsafeNaming:
|
||||||
|
return retVal
|
||||||
|
|
||||||
if isinstance(name, six.string_types):
|
if isinstance(name, six.string_types):
|
||||||
retVal = getUnicode(name)
|
retVal = getUnicode(name)
|
||||||
_ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE)
|
_ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import threading
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from thirdparty.odict import OrderedDict
|
from thirdparty.odict import OrderedDict
|
||||||
@@ -142,6 +143,7 @@ class LRUDict(object):
|
|||||||
def __init__(self, capacity):
|
def __init__(self, capacity):
|
||||||
self.capacity = capacity
|
self.capacity = capacity
|
||||||
self.cache = OrderedDict()
|
self.cache = OrderedDict()
|
||||||
|
self.__lock = threading.Lock()
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.cache)
|
return len(self.cache)
|
||||||
@@ -158,11 +160,12 @@ class LRUDict(object):
|
|||||||
return self.__getitem__(key)
|
return self.__getitem__(key)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
try:
|
with self.__lock:
|
||||||
self.cache.pop(key)
|
try:
|
||||||
except KeyError:
|
self.cache.pop(key)
|
||||||
if len(self.cache) >= self.capacity:
|
except KeyError:
|
||||||
self.cache.popitem(last=False)
|
if len(self.cache) >= self.capacity:
|
||||||
|
self.cache.popitem(last=False)
|
||||||
self.cache[key] = value
|
self.cache[key] = value
|
||||||
|
|
||||||
def set(self, key, value):
|
def set(self, key, value):
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ optDict = {
|
|||||||
"testFilter": "string",
|
"testFilter": "string",
|
||||||
"testSkip": "string",
|
"testSkip": "string",
|
||||||
"timeLimit": "float",
|
"timeLimit": "float",
|
||||||
|
"unsafeNaming": "boolean",
|
||||||
"webRoot": "string",
|
"webRoot": "string",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from thirdparty import six
|
|||||||
from thirdparty.six import unichr as _unichr
|
from thirdparty.six import unichr as _unichr
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.7.1.0"
|
VERSION = "1.8.3.0"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
@@ -333,7 +333,7 @@ REFERER_ALIASES = ("ref", "referer", "referrer")
|
|||||||
HOST_ALIASES = ("host",)
|
HOST_ALIASES = ("host",)
|
||||||
|
|
||||||
# DBMSes with upper case identifiers
|
# DBMSes with upper case identifiers
|
||||||
UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.H2, DBMS.DERBY, DBMS.ALTIBASE))
|
UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.H2, DBMS.HSQLDB, DBMS.DERBY, DBMS.ALTIBASE))
|
||||||
|
|
||||||
# Default schemas to use (when unable to enumerate)
|
# Default schemas to use (when unable to enumerate)
|
||||||
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
||||||
|
|||||||
@@ -226,7 +226,8 @@ def _setRequestParams():
|
|||||||
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
|
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
|
||||||
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
|
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
|
||||||
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
|
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
|
||||||
conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"']?(?P<name>[^\"'\r\n]+)[\"']?).+?)((%s)+--)" % ("\r\n" if "\r\n" in conf.data else '\n'), functools.partial(process, repl=r"\g<1>%s\g<4>" % kb.customInjectionMark), conf.data)
|
conf.data = re.sub(r"(?si)(Content-Disposition:[^\n]+\s+name=\"(?P<name>[^\"]+)\"(?:[^f|^b]|f(?!ilename=)|b(?!oundary=))*?)((%s)--)" % ("\r\n" if "\r\n" in conf.data else '\n'),
|
||||||
|
functools.partial(process, repl=r"\g<1>%s\g<3>" % kb.customInjectionMark), conf.data)
|
||||||
|
|
||||||
if not kb.postHint:
|
if not kb.postHint:
|
||||||
if kb.customInjectionMark in conf.data: # later processed
|
if kb.customInjectionMark in conf.data: # later processed
|
||||||
|
|||||||
@@ -739,6 +739,9 @@ def cmdLineParser(argv=None):
|
|||||||
general.add_argument("--time-limit", dest="timeLimit", type=float,
|
general.add_argument("--time-limit", dest="timeLimit", type=float,
|
||||||
help="Run with a time limit in seconds (e.g. 3600)")
|
help="Run with a time limit in seconds (e.g. 3600)")
|
||||||
|
|
||||||
|
general.add_argument("--unsafe-naming", dest="unsafeNaming", action="store_true",
|
||||||
|
help="Disable escaping of DBMS identifiers (e.g. \"user\")")
|
||||||
|
|
||||||
general.add_argument("--web-root", dest="webRoot",
|
general.add_argument("--web-root", dest="webRoot",
|
||||||
help="Web server document root directory (e.g. \"/var/www\")")
|
help="Web server document root directory (e.g. \"/var/www\")")
|
||||||
|
|
||||||
|
|||||||
@@ -680,7 +680,7 @@ def version(token=None):
|
|||||||
logger.debug("Fetched version (%s)" % ("admin" if is_admin(token) else request.remote_addr))
|
logger.debug("Fetched version (%s)" % ("admin" if is_admin(token) else request.remote_addr))
|
||||||
return jsonize({"success": True, "version": VERSION_STRING.split('/')[-1]})
|
return jsonize({"success": True, "version": VERSION_STRING.split('/')[-1]})
|
||||||
|
|
||||||
def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=RESTAPI_DEFAULT_ADAPTER, username=None, password=None):
|
def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=RESTAPI_DEFAULT_ADAPTER, username=None, password=None, database=None):
|
||||||
"""
|
"""
|
||||||
REST-JSON API server
|
REST-JSON API server
|
||||||
"""
|
"""
|
||||||
@@ -689,8 +689,11 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
|
|||||||
DataStore.username = username
|
DataStore.username = username
|
||||||
DataStore.password = password
|
DataStore.password = password
|
||||||
|
|
||||||
_, Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)
|
if not database:
|
||||||
os.close(_)
|
_, Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)
|
||||||
|
os.close(_)
|
||||||
|
else:
|
||||||
|
Database.filepath = database
|
||||||
|
|
||||||
if port == 0: # random
|
if port == 0: # random
|
||||||
with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ class Custom(object):
|
|||||||
query = _input("sql-shell> ")
|
query = _input("sql-shell> ")
|
||||||
query = getUnicode(query, encoding=sys.stdin.encoding)
|
query = getUnicode(query, encoding=sys.stdin.encoding)
|
||||||
query = query.strip("; ")
|
query = query.strip("; ")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print()
|
||||||
|
errMsg = "invalid user input"
|
||||||
|
logger.error(errMsg)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print()
|
print()
|
||||||
errMsg = "user aborted"
|
errMsg = "user aborted"
|
||||||
|
|||||||
@@ -829,6 +829,9 @@ testSkip =
|
|||||||
# Run with a time limit in seconds (e.g. 3600).
|
# Run with a time limit in seconds (e.g. 3600).
|
||||||
timeLimit =
|
timeLimit =
|
||||||
|
|
||||||
|
# Disable escaping of DBMS identifiers (e.g. "user").
|
||||||
|
unsafeNaming = False
|
||||||
|
|
||||||
# Web server document root directory (e.g. "/var/www").
|
# Web server document root directory (e.g. "/var/www").
|
||||||
webRoot =
|
webRoot =
|
||||||
|
|
||||||
|
|||||||
66
sqlmapapi.py
66
sqlmapapi.py
@@ -12,13 +12,55 @@ sys.dont_write_bytecode = True
|
|||||||
__import__("lib.utils.versioncheck") # this has to be the first non-standard import
|
__import__("lib.utils.versioncheck") # this has to be the first non-standard import
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import optparse
|
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
warnings.filterwarnings(action="ignore", category=UserWarning)
|
warnings.filterwarnings(action="ignore", category=UserWarning)
|
||||||
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
|
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from optparse import OptionGroup
|
||||||
|
from optparse import OptionParser as ArgumentParser
|
||||||
|
|
||||||
|
ArgumentParser.add_argument = ArgumentParser.add_option
|
||||||
|
|
||||||
|
def _add_argument(self, *args, **kwargs):
|
||||||
|
return self.add_option(*args, **kwargs)
|
||||||
|
|
||||||
|
OptionGroup.add_argument = _add_argument
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
finally:
|
||||||
|
def get_actions(instance):
|
||||||
|
for attr in ("option_list", "_group_actions", "_actions"):
|
||||||
|
if hasattr(instance, attr):
|
||||||
|
return getattr(instance, attr)
|
||||||
|
|
||||||
|
def get_groups(parser):
|
||||||
|
return getattr(parser, "option_groups", None) or getattr(parser, "_action_groups")
|
||||||
|
|
||||||
|
def get_all_options(parser):
|
||||||
|
retVal = set()
|
||||||
|
|
||||||
|
for option in get_actions(parser):
|
||||||
|
if hasattr(option, "option_strings"):
|
||||||
|
retVal.update(option.option_strings)
|
||||||
|
else:
|
||||||
|
retVal.update(option._long_opts)
|
||||||
|
retVal.update(option._short_opts)
|
||||||
|
|
||||||
|
for group in get_groups(parser):
|
||||||
|
for option in get_actions(group):
|
||||||
|
if hasattr(option, "option_strings"):
|
||||||
|
retVal.update(option.option_strings)
|
||||||
|
else:
|
||||||
|
retVal.update(option._long_opts)
|
||||||
|
retVal.update(option._short_opts)
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
from lib.core.common import setPaths
|
from lib.core.common import setPaths
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
@@ -52,19 +94,21 @@ def main():
|
|||||||
setPaths(modulePath())
|
setPaths(modulePath())
|
||||||
|
|
||||||
# Parse command line options
|
# Parse command line options
|
||||||
apiparser = optparse.OptionParser()
|
apiparser = ArgumentParser()
|
||||||
apiparser.add_option("-s", "--server", help="Run as a REST-JSON API server", action="store_true")
|
apiparser.add_argument("-s", "--server", help="Run as a REST-JSON API server", action="store_true")
|
||||||
apiparser.add_option("-c", "--client", help="Run as a REST-JSON API client", action="store_true")
|
apiparser.add_argument("-c", "--client", help="Run as a REST-JSON API client", action="store_true")
|
||||||
apiparser.add_option("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS, action="store")
|
apiparser.add_argument("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS)
|
||||||
apiparser.add_option("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type="int", action="store")
|
apiparser.add_argument("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type=int)
|
||||||
apiparser.add_option("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER, action="store")
|
apiparser.add_argument("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER)
|
||||||
apiparser.add_option("--username", help="Basic authentication username (optional)", action="store")
|
apiparser.add_argument("--database", help="Set IPC database filepath (optional)")
|
||||||
apiparser.add_option("--password", help="Basic authentication password (optional)", action="store")
|
apiparser.add_argument("--username", help="Basic authentication username (optional)")
|
||||||
(args, _) = apiparser.parse_args()
|
apiparser.add_argument("--password", help="Basic authentication password (optional)")
|
||||||
|
(args, _) = apiparser.parse_known_args() if hasattr(apiparser, "parse_known_args") else apiparser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
# Start the client or the server
|
# Start the client or the server
|
||||||
if args.server:
|
if args.server:
|
||||||
server(args.host, args.port, adapter=args.adapter, username=args.username, password=args.password)
|
server(args.host, args.port, adapter=args.adapter, username=args.username, password=args.password, database=args.database)
|
||||||
elif args.client:
|
elif args.client:
|
||||||
client(args.host, args.port, username=args.username, password=args.password)
|
client(args.host, args.port, username=args.username, password=args.password)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user