Защита рецептов: SQL DEPO/SPECTRE/QUIK вынесен в пакет fsql под garble
Реализация варианта B из аудита защиты знаний. Прямой garble всего bj-server ломает html/template (он обращается к полям структур по имени, garble их переименовывает). Решение — селективная обфускация: GOGARBLE обфусцирует ТОЛЬКО пакет с секретами, шаблоны и обработчики не затрагиваются. 95 SQL-запросов к DEPO/SPECTRE/QUIK и трансферным таблицам FTV_M2M вынесены из lkgateway в отдельный пакет internal/lkgateway/fsql как переменные (именно var, не const: const компилятор вставил бы обратно в необфусцируемый пакет, и шифрование бы не сработало — проверено). Сами обработчики, типы и параметры sql.Named остались на месте; пакет держит только строки запросов. build-release.sh собирает bj-server с `GOGARBLE=.../fsql garble -literals` (нужен отдельный SDK go1.26 — модуль-кэшный тулчейн garble не подходит); если garble/go1.26 не найдены — обычная сборка с предупреждением. Проверено на реальном garble-бинаре (запускается, /admin и страницы на структурах работают): рецепт чтения чужих систем из бинаря исчез — OD_RESTS 13→0, OD_WIRING 5→0, OD_TURNS 1→0, OD_BALANCES 3→0, D_B_CONTRACTS 1→0, OD_CLIENTS_PORTS 10→0, DepoLimits/MoneyLimits →0. Остаток FTV_M2M — упоминания имён таблиц в операторских embed-шаблонах и логах, не сам рецепт. Стенд собран обычной сборкой (без garble) — трассировки остаются читаемыми. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/lkgateway/fsql"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -54,9 +55,7 @@ func depoClientIDs(ctx context.Context, s FancyMSSQLSettings, contract string) (
|
||||
defer conn.Close()
|
||||
cctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
||||
defer cancel()
|
||||
rows, err := conn.QueryContext(cctx, `SELECT DISTINCT c.ID, ISNULL(c.NUMBER,''), ISNULL(c.FACE,0)
|
||||
FROM OD_CLIENTS c JOIN OD_CLIENTS_PORTS p ON p.CLIENT = c.ID
|
||||
WHERE p.PORT_NUM = @p1 OR p.PORT_NUM LIKE @p2`, contract, likeEscape(contract)+" %")
|
||||
rows, err := conn.QueryContext(cctx, fsql.Hist01, contract, likeEscape(contract)+" %")
|
||||
if err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
@@ -137,32 +136,7 @@ func lkOperations(ctx context.Context, s FancyMSSQLSettings, contract, from, to
|
||||
}
|
||||
fromT, toT := parseRange(from, to)
|
||||
// Три вида операций в одном списке: зачисление, списание, перевод между счетами.
|
||||
q := fmt.Sprintf(`SELECT TOP %d * FROM (
|
||||
SELECT d.R_DATE AS RD, d.PROC_DATE AS PD, ISNULL(d.NUM,'') AS NUM, d.STATE AS ST, N'зачисление' AS KIND,
|
||||
z.DEPO AS ACC, ISNULL(v.ISIN,'') AS ISIN, ISNULL(v.NAME,'') AS SEC, CAST(ISNULL(z.AMOUNT,0) AS float) AS QTY,
|
||||
LTRIM(RTRIM(ISNULL(z.COMMENT,'') + ' ' + ISNULL(z.REJECT_REASON,''))) AS NOTE
|
||||
FROM U_OP_INV_ZACH z JOIN OD_DOCS d ON d.ID = z.DOC LEFT JOIN OD_VALUES v ON v.ID = z.SHARE
|
||||
WHERE z.DEPO IN (%s)
|
||||
UNION ALL
|
||||
SELECT d.R_DATE, d.PROC_DATE, ISNULL(d.NUM,''), d.STATE, N'списание',
|
||||
p.DEPO, ISNULL(v.ISIN,''), ISNULL(v.NAME,''), -CAST(ISNULL(p.AMOUNT,0) AS float),
|
||||
LTRIM(RTRIM(ISNULL(p.COMMENT,'') + ' ' + ISNULL(p.REJECT_REASON,'')))
|
||||
FROM U_OP_INV_SPIS p JOIN OD_DOCS d ON d.ID = p.DOC LEFT JOIN OD_VALUES v ON v.ID = p.SHARE
|
||||
WHERE p.DEPO IN (%s)
|
||||
UNION ALL
|
||||
SELECT d.R_DATE, d.PROC_DATE, ISNULL(d.NUM,''), d.STATE, N'перевод: списание',
|
||||
t.D_DEPO, ISNULL(v.ISIN,''), ISNULL(v.NAME,''), -CAST(ISNULL(t.AMOUNT,0) AS float),
|
||||
LTRIM(RTRIM(ISNULL(t.COMMENT,'') + ' ' + ISNULL(t.REJECT_REASON,'')))
|
||||
FROM U_OP_INV_PEREVOD t JOIN OD_DOCS d ON d.ID = t.DOC LEFT JOIN OD_VALUES v ON v.ID = t.SHARE
|
||||
WHERE t.D_DEPO IN (%s)
|
||||
UNION ALL
|
||||
SELECT d.R_DATE, d.PROC_DATE, ISNULL(d.NUM,''), d.STATE, N'перевод: зачисление',
|
||||
t.K_DEPO, ISNULL(v.ISIN,''), ISNULL(v.NAME,''), CAST(ISNULL(t.AMOUNT,0) AS float),
|
||||
LTRIM(RTRIM(ISNULL(t.COMMENT,'') + ' ' + ISNULL(t.REJECT_REASON,'')))
|
||||
FROM U_OP_INV_PEREVOD t JOIN OD_DOCS d ON d.ID = t.DOC LEFT JOIN OD_VALUES v ON v.ID = t.SHARE
|
||||
WHERE t.K_DEPO IN (%s)) x
|
||||
WHERE x.RD >= @p1 AND x.RD < DATEADD(day, 1, @p2)
|
||||
ORDER BY x.RD DESC, x.NUM DESC`, limit, inClause(ids), inClause(ids), inClause(ids), inClause(ids))
|
||||
q := fmt.Sprintf(fsql.Hist02, limit, inClause(ids), inClause(ids), inClause(ids), inClause(ids))
|
||||
rows, err := conn.QueryContext(cctx, q, fromT, toT)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -226,17 +200,7 @@ func lkIncome(ctx context.Context, s FancyMSSQLSettings, contract, from, to stri
|
||||
cctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
fromT, toT := parseRange(from, to)
|
||||
q := fmt.Sprintf(`SELECT TOP 200 h.P_DATE, h.INCOME_KIND, ISNULL(v.ISIN,''), ISNULL(v.NAME,''),
|
||||
CAST(ISNULL(l.AMOUNT,0) AS float), CAST(ISNULL(l.SUMMA_TOTAL,0) AS float),
|
||||
CAST(ISNULL(l.TAX_HOLDED,0) AS float), CAST(ISNULL(l.TOTAL_TO_PAY,0) AS float),
|
||||
ISNULL(l.STATUS,''), ISNULL(l.DEPO,0)
|
||||
FROM U_OP_INF_INCOME_DOL l
|
||||
JOIN OD_DOLS o ON o.ID = l.DOL
|
||||
JOIN U_OP_INF_INCOME h ON h.DOC = o.DOC
|
||||
LEFT JOIN OD_VALUES v ON v.ID = h.SHARE
|
||||
WHERE (l.DEPO IN (%s) OR l.INCOME_FACE = @p3)
|
||||
AND h.P_DATE >= @p1 AND h.P_DATE < DATEADD(day, 1, @p2)
|
||||
ORDER BY h.P_DATE DESC`, inClause(ids))
|
||||
q := fmt.Sprintf(fsql.Hist03, inClause(ids))
|
||||
rows, err := conn.QueryContext(cctx, q, fromT, toT, face)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@@ -266,8 +230,7 @@ func lkIncome(ctx context.Context, s FancyMSSQLSettings, contract, from, to stri
|
||||
}
|
||||
// Удержанный налог по лицу за период — по журналу НДФЛ депозитария.
|
||||
if face > 0 {
|
||||
_ = conn.QueryRowContext(cctx, `SELECT CAST(ISNULL(SUM(CAST(SUMMA AS float)),0) AS float) FROM OD_NDFL
|
||||
WHERE FACE = @p1 AND R_DATE >= @p2 AND R_DATE < DATEADD(day, 1, @p3)`,
|
||||
_ = conn.QueryRowContext(cctx, fsql.Hist04,
|
||||
sql.Named("p1", face), sql.Named("p2", fromT), sql.Named("p3", toT)).Scan(&taxTotal)
|
||||
}
|
||||
return rowsOut, taxTotal, nil
|
||||
|
||||
Reference in New Issue
Block a user