LCOV - code coverage report
Current view: top level - src/infrastructure - auth_transfer.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.3 % 75 67
Test Date: 2026-04-20 19:54:22 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-3.0-or-later */
       2              : /* Copyright 2026 Peter Csaszar */
       3              : 
       4              : /**
       5              :  * @file auth_transfer.c
       6              :  * @brief P10-04 — auth.exportAuthorization + auth.importAuthorization.
       7              :  */
       8              : 
       9              : #include "auth_transfer.h"
      10              : 
      11              : #include "tl_serial.h"
      12              : #include "tl_registry.h"
      13              : #include "logger.h"
      14              : #include "raii.h"
      15              : 
      16              : #include <stdlib.h>
      17              : #include <string.h>
      18              : 
      19              : /* TL constructor IDs (not yet in tl_registry). */
      20              : #define CRC_auth_exportAuthorization   0xe5bfffcdu
      21              : #define CRC_auth_exportedAuthorization 0xb434e2b8u
      22              : #define CRC_auth_importAuthorization   0xa57a7dadu
      23              : #define CRC_auth_authorization         0x2ea2c0d4u
      24              : #define CRC_auth_authorizationSignUpRequired 0x44747e9au
      25              : 
      26              : #define RESP_BUF_SIZE 65536
      27              : 
      28              : /* ---- export ---- */
      29              : 
      30           13 : int auth_transfer_export(const ApiConfig *cfg,
      31              :                           MtProtoSession *home_s, Transport *home_t,
      32              :                           int target_dc_id,
      33              :                           AuthExported *out,
      34              :                           RpcError *err) {
      35           13 :     if (!cfg || !home_s || !home_t || !out) return -1;
      36           12 :     if (err) { err->error_code = 0; err->error_msg[0] = '\0';
      37            9 :                err->migrate_dc = -1; err->flood_wait_secs = 0; }
      38           12 :     memset(out, 0, sizeof(*out));
      39              : 
      40              :     uint8_t query[64];
      41           12 :     TlWriter w; tl_writer_init(&w);
      42           12 :     tl_write_uint32(&w, CRC_auth_exportAuthorization);
      43           12 :     tl_write_int32 (&w, target_dc_id);
      44           12 :     if (w.len > sizeof(query)) { tl_writer_free(&w); return -1; }
      45           12 :     memcpy(query, w.data, w.len);
      46           12 :     size_t qlen = w.len;
      47           12 :     tl_writer_free(&w);
      48              : 
      49           12 :     RAII_STRING uint8_t *resp = (uint8_t *)malloc(RESP_BUF_SIZE);
      50           12 :     if (!resp) return -1;
      51           12 :     size_t resp_len = 0;
      52           12 :     if (api_call(cfg, home_s, home_t, query, qlen,
      53              :                  resp, RESP_BUF_SIZE, &resp_len) != 0) {
      54            0 :         logger_log(LOG_ERROR, "auth_transfer_export: api_call failed");
      55            0 :         return -1;
      56              :     }
      57           12 :     if (resp_len < 4) return -1;
      58              : 
      59              :     uint32_t top;
      60           12 :     memcpy(&top, resp, 4);
      61           12 :     if (top == TL_rpc_error) {
      62            1 :         RpcError perr; rpc_parse_error(resp, resp_len, &perr);
      63            1 :         if (err) *err = perr;
      64            1 :         logger_log(LOG_ERROR, "auth_transfer_export: RPC %d: %s",
      65              :                    perr.error_code, perr.error_msg);
      66            1 :         return -1;
      67              :     }
      68           11 :     if (top != CRC_auth_exportedAuthorization) {
      69            0 :         logger_log(LOG_ERROR,
      70              :                    "auth_transfer_export: unexpected top 0x%08x", top);
      71            0 :         return -1;
      72              :     }
      73              : 
      74           11 :     TlReader r = tl_reader_init(resp, resp_len);
      75           11 :     tl_read_uint32(&r);                           /* constructor */
      76           11 :     out->id = tl_read_int64(&r);
      77              : 
      78           11 :     size_t bl = 0;
      79           22 :     RAII_STRING uint8_t *bytes = tl_read_bytes(&r, &bl);
      80           11 :     if (!bytes || bl == 0 || bl > AUTH_TRANSFER_BYTES_MAX) {
      81            2 :         logger_log(LOG_ERROR,
      82              :                    "auth_transfer_export: bytes len %zu out of range", bl);
      83            2 :         return -1;
      84              :     }
      85            9 :     memcpy(out->bytes, bytes, bl);
      86            9 :     out->bytes_len = bl;
      87            9 :     logger_log(LOG_INFO,
      88              :                "auth_transfer_export: exported to DC%d (id=%lld, %zu bytes)",
      89            9 :                target_dc_id, (long long)out->id, bl);
      90            9 :     return 0;
      91              : }
      92              : 
      93              : /* ---- import ---- */
      94              : 
      95            9 : int auth_transfer_import(const ApiConfig *cfg,
      96              :                           MtProtoSession *s, Transport *t,
      97              :                           const AuthExported *in,
      98              :                           RpcError *err) {
      99            9 :     if (!cfg || !s || !t || !in) return -1;
     100            8 :     if (in->bytes_len == 0 || in->bytes_len > AUTH_TRANSFER_BYTES_MAX)
     101            1 :         return -1;
     102            7 :     if (err) { err->error_code = 0; err->error_msg[0] = '\0';
     103            6 :                err->migrate_dc = -1; err->flood_wait_secs = 0; }
     104              : 
     105            7 :     TlWriter w; tl_writer_init(&w);
     106            7 :     tl_write_uint32(&w, CRC_auth_importAuthorization);
     107            7 :     tl_write_int64 (&w, in->id);
     108            7 :     tl_write_bytes (&w, in->bytes, in->bytes_len);
     109              : 
     110            7 :     RAII_STRING uint8_t *query = (uint8_t *)malloc(w.len);
     111            7 :     if (!query) { tl_writer_free(&w); return -1; }
     112            7 :     memcpy(query, w.data, w.len);
     113            7 :     size_t qlen = w.len;
     114            7 :     tl_writer_free(&w);
     115              : 
     116            7 :     RAII_STRING uint8_t *resp = (uint8_t *)malloc(RESP_BUF_SIZE);
     117            7 :     if (!resp) return -1;
     118            7 :     size_t resp_len = 0;
     119            7 :     if (api_call(cfg, s, t, query, qlen,
     120              :                  resp, RESP_BUF_SIZE, &resp_len) != 0) {
     121            0 :         logger_log(LOG_ERROR, "auth_transfer_import: api_call failed");
     122            0 :         return -1;
     123              :     }
     124            7 :     if (resp_len < 4) return -1;
     125              : 
     126              :     uint32_t top;
     127            7 :     memcpy(&top, resp, 4);
     128            7 :     if (top == TL_rpc_error) {
     129            2 :         RpcError perr; rpc_parse_error(resp, resp_len, &perr);
     130            2 :         if (err) *err = perr;
     131            2 :         logger_log(LOG_ERROR, "auth_transfer_import: RPC %d: %s",
     132              :                    perr.error_code, perr.error_msg);
     133            2 :         return -1;
     134              :     }
     135            5 :     if (top != CRC_auth_authorization
     136            2 :         && top != CRC_auth_authorizationSignUpRequired) {
     137            0 :         logger_log(LOG_ERROR,
     138              :                    "auth_transfer_import: unexpected top 0x%08x", top);
     139            0 :         return -1;
     140              :     }
     141            5 :     logger_log(LOG_INFO, "auth_transfer_import: foreign DC now authorized");
     142            5 :     return 0;
     143              : }
        

Generated by: LCOV version 2.0-1