#!/usr/bin/env python

"""
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

# 导入所需的枚举类型
from lib.core.enums import CONTENT_TYPE
from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import POST_HINT

# 导入各种数据库别名和设置
from lib.core.settings import ACCESS_ALIASES
from lib.core.settings import ALTIBASE_ALIASES
from lib.core.settings import BLANK
from lib.core.settings import CACHE_ALIASES
from lib.core.settings import CRATEDB_ALIASES
from lib.core.settings import CUBRID_ALIASES
from lib.core.settings import DB2_ALIASES
from lib.core.settings import DERBY_ALIASES
from lib.core.settings import EXTREMEDB_ALIASES
from lib.core.settings import FIREBIRD_ALIASES
from lib.core.settings import FRONTBASE_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import INFORMIX_ALIASES
from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import MCKOI_ALIASES
from lib.core.settings import MIMERSQL_ALIASES
from lib.core.settings import MONETDB_ALIASES
from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import NULL
from lib.core.settings import ORACLE_ALIASES
from lib.core.settings import PGSQL_ALIASES
from lib.core.settings import PRESTO_ALIASES
from lib.core.settings import RAIMA_ALIASES
from lib.core.settings import SQLITE_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES
from lib.core.settings import VIRTUOSO_ALIASES
from lib.core.settings import CLICKHOUSE_ALIASES

# Firebird数据库的数据类型映射字典
FIREBIRD_TYPES = {
    261: "BLOB",        # 二进制大对象
    14: "CHAR",         # 定长字符串
    40: "CSTRING",      # C风格字符串
    11: "D_FLOAT",      # 双精度浮点数
    27: "DOUBLE",       # 双精度数
    10: "FLOAT",        # 浮点数
    16: "INT64",        # 64位整数
    8: "INTEGER",       # 整数
    9: "QUAD",          # 四字节整数
    7: "SMALLINT",      # 小整数
    12: "DATE",         # 日期
    13: "TIME",         # 时间
    35: "TIMESTAMP",    # 时间戳
    37: "VARCHAR",      # 变长字符串
}

# Informix数据库的数据类型映射字典
INFORMIX_TYPES = {
    0: "CHAR",          # 定长字符串
    1: "SMALLINT",      # 小整数
    2: "INTEGER",       # 整数
    3: "FLOAT",         # 浮点数
    4: "SMALLFLOAT",    # 小浮点数
    5: "DECIMAL",       # 十进制数
    6: "SERIAL",        # 序列号
    7: "DATE",          # 日期
    8: "MONEY",         # 货币类型
    9: "NULL",          # 空值
    10: "DATETIME",     # 日期时间
    11: "BYTE",         # 字节
    12: "TEXT",         # 文本
    13: "VARCHAR",      # 变长字符串
    14: "INTERVAL",     # 时间间隔
    15: "NCHAR",        # Unicode字符
    16: "NVARCHAR",     # Unicode变长字符
    17: "INT8",         # 8字节整数
    18: "SERIAL8",      # 8字节序列号
    19: "SET",          # 集合
    20: "MULTISET",     # 多重集
    21: "LIST",         # 列表
    22: "ROW (unnamed)", # 未命名行
    23: "COLLECTION",   # 集合
    40: "Variable-length opaque type", # 变长不透明类型
    41: "Fixed-length opaque type",    # 定长不透明类型
    43: "LVARCHAR",     # 长变长字符串
    45: "BOOLEAN",      # 布尔值
    52: "BIGINT",       # 大整数
    53: "BIGSERIAL",    # 大序列号
    2061: "IDSSECURITYLABEL", # 安全标签
    4118: "ROW (named)", # 命名行
}

# Sybase数据库的数据类型映射字典
SYBASE_TYPES = {
    14: "floatn",       # 可空浮点数
    8: "float",         # 浮点数
    15: "datetimn",     # 可空日期时间
    12: "datetime",     # 日期时间
    23: "real",         # 实数
    28: "numericn",     # 可空数值
    10: "numeric",      # 数值
    27: "decimaln",     # 可空十进制数
    26: "decimal",      # 十进制数
    17: "moneyn",       # 可空货币
    11: "money",        # 货币
    21: "smallmoney",   # 小额货币
    22: "smalldatetime", # 小日期时间
    13: "intn",         # 可空整数
    7: "int",           # 整数
    6: "smallint",      # 小整数
    5: "tinyint",       # 微整数
    16: "bit",          # 位
    2: "varchar",       # 变长字符串
    18: "sysname",      # 系统名称
    25: "nvarchar",     # Unicode变长字符
    1: "char",          # 定长字符串
    24: "nchar",        # Unicode字符
    4: "varbinary",     # 变长二进制
    80: "timestamp",    # 时间戳
    3: "binary",        # 二进制
    19: "text",         # 文本
    20: "image",        # 图像
}

# Altibase数据库的数据类型映射字典
ALTIBASE_TYPES = {
    1: "CHAR",          # 定长字符串
    12: "VARCHAR",      # 变长字符串
    -8: "NCHAR",        # Unicode字符
    -9: "NVARCHAR",     # Unicode变长字符
    2: "NUMERIC",       # 数值
    6: "FLOAT",         # 浮点数
    8: "DOUBLE",        # 双精度数
    7: "REAL",          # 实数
    -5: "BIGINT",       # 大整数
    4: "INTEGER",       # 整数
    5: "SMALLINT",      # 小整数
    9: "DATE",          # 日期
    30: "BLOB",         # 二进制大对象
    40: "CLOB",         # 字符大对象
    20001: "BYTE",      # 字节
    20002: "NIBBLE",    # 半字节
    -7: "BIT",          # 位
    -100: "VARBIT",     # 变长位串
    10003: "GEOMETRY",  # 几何数据
}

# MySQL数据库的权限映射字典
MYSQL_PRIVS = {
    1: "select_priv",   # 查询权限
    2: "insert_priv",   # 插入权限
    3: "update_priv",   # 更新权限
    4: "delete_priv",   # 删除权限
    5: "create_priv",   # 创建权限
    6: "drop_priv",     # 删除权限
    7: "reload_priv",   # 重载权限
    8: "shutdown_priv", # 关闭权限
    9: "process_priv",  # 进程权限
    10: "file_priv",    # 文件权限
    11: "grant_priv",   # 授权权限
    12: "references_priv", # 引用权限
    13: "index_priv",   # 索引权限
    14: "alter_priv",   # 修改权限
    15: "show_db_priv", # 显示数据库权限
    16: "super_priv",   # 超级权限
    17: "create_tmp_table_priv", # 创建临时表权限
    18: "lock_tables_priv", # 锁表权限
    19: "execute_priv", # 执行权限
    20: "repl_slave_priv", # 复制从权限
    21: "repl_client_priv", # 复制客户端权限
    22: "create_view_priv", # 创建视图权限
    23: "show_view_priv", # 显示视图权限
    24: "create_routine_priv", # 创建例程权限
    25: "alter_routine_priv", # 修改例程权限
    26: "create_user_priv", # 创建用户权限
}

# PostgreSQL数据库的权限映射字典
PGSQL_PRIVS = {
    1: "createdb",      # 创建数据库权限
    2: "super",         # 超级用户权限
    3: "catupd",        # 更新系统目录权限
}

# Firebird数据库的权限映射字典
FIREBIRD_PRIVS = {
    "S": "SELECT",      # 查询权限
    "I": "INSERT",      # 插入权限
    "U": "UPDATE",      # 更新权限
    "D": "DELETE",      # 删除权限
    "R": "REFERENCE",   # 引用权限
    "X": "EXECUTE",     # 执行权限
    "A": "ALL",         # 所有权限
    "M": "MEMBER",      # 成员权限
    "T": "DECRYPT",     # 解密权限
    "E": "ENCRYPT",     # 加密权限
    "B": "SUBSCRIBE",   # 订阅权限
}

# Informix数据库的权限映射字典
INFORMIX_PRIVS = {
    "D": "DBA (all privileges)", # 数据库管理员(所有权限)
    "R": "RESOURCE (create UDRs, UDTs, permanent tables and indexes)", # 资源权限(创建用户定义例程、类型、永久表和索引)
    "C": "CONNECT (work with existing tables)", # 连接权限(使用现有表)
    "G": "ROLE",        # 角色
    "U": "DEFAULT (implicit connection)", # 默认权限(隐式连接)
}

# DB2数据库的权限映射字典
DB2_PRIVS = {
    1: "CONTROLAUTH",   # 控制权限
    2: "ALTERAUTH",     # 修改权限
    3: "DELETEAUTH",    # 删除权限
    4: "INDEXAUTH",     # 索引权限
    5: "INSERTAUTH",    # 插入权限
    6: "REFAUTH",       # 引用权限
    7: "SELECTAUTH",    # 查询权限
    8: "UPDATEAUTH",    # 更新权限
}

# 转储数据时的替换规则
DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}

# 数据库管理系统(DBMS)字典,包含每个数据库系统的别名、Python驱动、项目URL和SQLAlchemy方言
DBMS_DICT = {
    DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"),
    DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/PyMySQL/PyMySQL", "mysql"),
    DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"),
    DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"),
    DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/3/library/sqlite3.html", "sqlite"),
    DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"),
    DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
    DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
    DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"),
    DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
    DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & https://github.com/jpype-project/jpype", None),
    DBMS.H2: (H2_ALIASES, None, None, None),
    DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
    DBMS.MONETDB: (MONETDB_ALIASES, "pymonetdb", "https://github.com/gijzelaerr/pymonetdb", "monetdb"),
    DBMS.DERBY: (DERBY_ALIASES, "pydrda", "https://github.com/nakagami/pydrda/", None),
    DBMS.VERTICA: (VERTICA_ALIASES, "vertica-python", "https://github.com/vertica/vertica-python", "vertica+vertica_python"),
    DBMS.MCKOI: (MCKOI_ALIASES, None, None, None),
    DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
    DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
    DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
    DBMS.CLICKHOUSE: (CLICKHOUSE_ALIASES, "clickhouse_connect", "https://github.com/ClickHouse/clickhouse-connect", None),
    DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"),
    DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None),
    DBMS.CACHE: (CACHE_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & https://github.com/jpype-project/jpype", None),
    DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
    DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
    DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
    DBMS.VIRTUOSO: (VIRTUOSO_ALIASES, None, None, None),
}

# 不同数据库系统的虚拟表(用于在没有实际表时执行查询)
FROM_DUMMY_TABLE = {
    DBMS.ORACLE: " FROM DUAL",
    DBMS.ACCESS: " FROM MSysAccessObjects",
    DBMS.FIREBIRD: " FROM RDB$DATABASE",
    DBMS.MAXDB: " FROM VERSIONS",
    DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
    DBMS.HSQLDB: " FROM INFORMATION_SCHEMA.SYSTEM_USERS",
    DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
    DBMS.DERBY: " FROM SYSIBM.SYSDUMMY1",
    DBMS.MIMERSQL: " FROM SYSTEM.ONEROW",
    DBMS.FRONTBASE: " FROM INFORMATION_SCHEMA.IO_STATISTICS"
}

# 不同数据库系统的NULL值评估函数
HEURISTIC_NULL_EVAL = {
    DBMS.ACCESS: "CVAR(NULL)",
    DBMS.MAXDB: "ALPHA(NULL)",
    DBMS.MSSQL: "DIFFERENCE(NULL,NULL)",
    DBMS.MYSQL: "QUARTER(NULL XOR NULL)",
    DBMS.ORACLE: "INSTR2(NULL,NULL)",
    DBMS.PGSQL: "QUOTE_IDENT(NULL)",
    DBMS.SQLITE: "UNLIKELY(NULL)",
    DBMS.H2: "STRINGTOUTF8(NULL)",
    DBMS.MONETDB: "CODE(NULL)",
    DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
    DBMS.VERTICA: "BITSTRING_TO_BINARY(NULL)",
    DBMS.MCKOI: "TONUMBER(NULL)",
    DBMS.PRESTO: "FROM_HEX(NULL)",
    DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
    DBMS.MIMERSQL: "ASCII_CHAR(256)",
    DBMS.CRATEDB: "MD5(NULL~NULL)",  # 注意: NULL~NULL也在H2和Ignite上进行评估
    DBMS.CUBRID: "(NULL SETEQ NULL)",
    DBMS.CACHE: "%SQLUPPER NULL",
    DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
    DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))",
    DBMS.VIRTUOSO: "__MAX_NOTNULL(NULL)",
    DBMS.CLICKHOUSE: "halfMD5(NULL) IS NULL",
}

# SQL语句类型分类
SQL_STATEMENTS = {
    "SQL SELECT statement": (  # SQL查询语句
        "select ",
        "show ",
        " top ",
        " distinct ",
        " from ",
        " from dual",
        " where ",
        " group by ",
        " order by ",
        " having ",
        " limit ",
        " offset ",
        " union all ",
        " rownum as ",
        "(case ",
    ),

    "SQL data definition": (  # SQL数据定义语句
        "create ",
        "declare ",
        "drop ",
        "truncate ",
        "alter ",
    ),

    "SQL data manipulation": (  # SQL数据操作语句
        "bulk ",
        "insert ",
        "update ",
        "delete ",
        "merge ",
        "load ",
    ),

    "SQL data control": (  # SQL数据控制语句
        "grant ",
        "revoke ",
    ),

    "SQL data execution": (  # SQL数据执行语句
        "exec ",
        "execute ",
        "values ",
        "call ",
    ),

    "SQL transaction": (  # SQL事务语句
        "start transaction ",
        "begin work ",
        "begin transaction ",
        "commit ",
        "rollback ",
    ),

    "SQL administration": (  # SQL管理语句
        "set ",
    ),
}

# POST请求提示的内容类型
POST_HINT_CONTENT_TYPES = {
    POST_HINT.JSON: "application/json",
    POST_HINT.JSON_LIKE: "application/json",
    POST_HINT.MULTIPART: "multipart/form-data",
    POST_HINT.SOAP: "application/soap+xml",
    POST_HINT.XML: "application/xml",
    POST_HINT.ARRAY_LIKE: "application/x-www-form-urlencoded; charset=utf-8",
}

# 过时的选项及其替代建议
OBSOLETE_OPTIONS = {
    "--replicate": "use '--dump-format=SQLITE' instead",
    "--no-unescape": "use '--no-escape' instead",
    "--binary": "use '--binary-fields' instead",
    "--auth-private": "use '--auth-file' instead",
    "--ignore-401": "use '--ignore-code' instead",
    "--second-order": "use '--second-url' instead",
    "--purge-output": "use '--purge' instead",
    "--sqlmap-shell": "use '--shell' instead",
    "--check-payload": None,
    "--check-waf": None,
    "--pickled-options": "use '--api -c ...' instead",
    "--identify-waf": "functionality being done automatically",
}

# 已弃用的选项
DEPRECATED_OPTIONS = {
}

# 转储数据预处理规则
DUMP_DATA_PREPROCESS = {
    DBMS.ORACLE: {"XMLTYPE": "(%s).getStringVal()"},  # 参考: https://www.tibcommunity.com/docs/DOC-3643
    DBMS.MSSQL: {"IMAGE": "CONVERT(VARBINARY(MAX),%s)"},
}

# 默认文档根目录
DEFAULT_DOC_ROOTS = {
    OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
    OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www")  # 参考: https://wiki.apache.org/httpd/DistrosDefaultLayout
}

# 部分运行内容类型
PART_RUN_CONTENT_TYPES = {
    "checkDbms": CONTENT_TYPE.TECHNIQUES,           # 检查数据库类型
    "getFingerprint": CONTENT_TYPE.DBMS_FINGERPRINT, # 获取数据库指纹
    "getBanner": CONTENT_TYPE.BANNER,               # 获取横幅信息
    "getCurrentUser": CONTENT_TYPE.CURRENT_USER,    # 获取当前用户
    "getCurrentDb": CONTENT_TYPE.CURRENT_DB,        # 获取当前数据库
    "getHostname": CONTENT_TYPE.HOSTNAME,           # 获取主机名
    "isDba": CONTENT_TYPE.IS_DBA,                  # 是否为DBA
    "getUsers": CONTENT_TYPE.USERS,                # 获取用户列表
    "getPasswordHashes": CONTENT_TYPE.PASSWORDS,    # 获取密码哈希
    "getPrivileges": CONTENT_TYPE.PRIVILEGES,      # 获取权限
    "getRoles": CONTENT_TYPE.ROLES,                # 获取角色
    "getDbs": CONTENT_TYPE.DBS,                    # 获取数据库列表
    "getTables": CONTENT_TYPE.TABLES,              # 获取表列表
    "getColumns": CONTENT_TYPE.COLUMNS,            # 获取列列表
    "getSchema": CONTENT_TYPE.SCHEMA,              # 获取架构
    "getCount": CONTENT_TYPE.COUNT,                # 获取计数
    "dumpTable": CONTENT_TYPE.DUMP_TABLE,          # 转储表
    "search": CONTENT_TYPE.SEARCH,                 # 搜索
    "sqlQuery": CONTENT_TYPE.SQL_QUERY,            # SQL查询
    "tableExists": CONTENT_TYPE.COMMON_TABLES,     # 表是否存在
    "columnExists": CONTENT_TYPE.COMMON_COLUMNS,   # 列是否存在
    "readFile": CONTENT_TYPE.FILE_READ,            # 读取文件
    "writeFile": CONTENT_TYPE.FILE_WRITE,          # 写入文件
    "osCmd": CONTENT_TYPE.OS_CMD,                  # 操作系统命令
    "regRead": CONTENT_TYPE.REG_READ               # 注册表读取
}

# HTML实体编码对照表
HTML_ENTITIES = {
    "quot": 34,     # 双引号
    "amp": 38,      # &符号
    "apos": 39,     # 单引号
    "lt": 60,       # 小于号
    "gt": 62,       # 大于号
    "nbsp": 160,    # 不间断空格
    "iexcl": 161,   # 倒感叹号
    "cent": 162,    # 分币符号
    "pound": 163,   # 英镑符号
    "curren": 164,  # 货币符号
    "yen": 165,     # 日元符号
    # ... (其余HTML实体编码省略,与原文相同)
}
