شروع به کار با Sandboxed API، شروع به کار با Sandboxed API

در این صفحه، نحوه ایجاد کتابخانه سندباکس C/C++ خود را با Sandboxed API (SAPI) خواهید آموخت. از آن به عنوان راهنما در کنار مثال ها و مستندات کد موجود در فایل های هدر استفاده کنید.

ایجاد وابستگی

وابستگی های زیر باید روی سیستم نصب شوند:

  • هسته لینوکس با پشتیبانی از UTS، IPC، کاربر، PID و فضای نام شبکه
  • هدرهای API فضای کاربران لینوکس
  • برای کامپایل کد خود: GCC 6 (نسخه 7 یا بالاتر ترجیح داده می شود) یا Clang 7 (یا بالاتر)
  • برای تولید خودکار فایل‌های هدر: Clang Python Bindings
  • پایتون 3.5 یا بالاتر
  • Bazel نسخه 2.2.0 یا CMake نسخه 3.12 یا بالاتر.
    • فقط CMake: GNU Make یا نسخه ای از هدرهای کتابخانه libcap و یک ابزار ساخت مانند Ninja (توصیه می شود).

با استفاده از بازل

Bazel سیستم ساخت توصیه شده است و ساده ترین سیستم برای ادغام با آن است.

مستندات ما از کامپایلر Clang استفاده می کند. اگر به یک زنجیره ابزار خاص نیاز دارید (مثلاً کامپایلر، پیوند دهنده و غیره)، برای اطلاعات در مورد نحوه تغییر زنجیره ابزار کامپایلر پیش فرض، به مستندات Bazel مراجعه کنید.

Debian 10 (Buster)

برای نصب وابستگی های ساخت:

echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
  sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \
  python3-pip libclang-dev
pip3 install clang

جنتو

گزینه های هسته مورد نیاز:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

برای نصب وابستگی های ساخت:

emerge dev-util/bazel dev-python/typing dev-python/clang-python

با استفاده از CMake

CMake یک سیستم متا بیلد منبع باز محبوب است که فایل های پروژه را برای ابزارهای ساخت مانند Ninja یا Make تولید می کند.

Debian 10 (Buster)

برای نصب وابستگی های ساخت:

sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \
  python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang

جنتو

گزینه های هسته مورد نیاز:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

برای نصب وابستگی های ساخت:

emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python

فرآیند توسعه

برای سندباکس یک کتابخانه C/C++، باید دو مورد را برای پروژه خود آماده کنید:

ممکن است با zlib از نمونه های Sandbox2 در اینجا آشنایی داشته باشید که یک برنامه کامل ( zpipe.c ) sandbox شده است. در مراحل زیر، نحوه استفاده از SAPI برای جعبه شنود کتابخانه zlib و استفاده از کتابخانه Sandboxed را یاد خواهید گرفت.

1. تصمیم بگیرید که کدام توابع مورد نیاز است

اگر به کد میزبان zlib ( main_zlib.cc ) نگاه کنید، می بینید که عملکرد ابزار خواندن داده ها از stdin و استفاده از تابع deflate() zlib برای فشرده سازی داده ها تا زمانی که یک نشانگر EOF خوانده شود است. در کل، این برنامه از سه تابع از zlib استفاده می کند:

  • deflateInit_() : برای مقداردهی اولیه برای فشرده سازی
  • deflate() : برای انجام عملیات فشرده سازی بر روی قطعه داده
  • deflateEnd() : برای پایان دادن به فشرده سازی و آزادسازی ساختارهای داده تخصیص یافته به صورت پویا

در یک مثال واقعی، کتابخانه C/C++ را بررسی کرده و تصمیم می گیرید که کدام توابع مورد نیاز است. یک استراتژی ممکن این است که با کد میزبان شروع کنید و از کتابخانه بدون جعبه ایمنی استفاده کنید. سپس، در مرحله دوم، می‌توانید کتابخانه Sandboxed را ایجاد کنید و کد میزبان را برای استفاده از فراخوانی تابع sandbox شده تطبیق دهید.

2. قانون ساخت sapi_library را بنویسید

بعد از اینکه سه تابع zlib مورد نیاز از کتابخانه zlib sandbox شده را شناسایی کردید، می توانید قانون ساخت را در فایل BUILD تعریف کنید. اسناد مربوط به قانون ساخت sapi_library را می توانید در صفحه قوانین ساخت پیدا کنید.

قطعه کد زیر تعریف sapi_library را برای مثال zlib SAPI نشان می دهد. با استفاده از ویژگی lib ، به Bazel دستور داده می شود که در فایل WORKSPACE کتابخانه zlib را جستجو کند.

sapi_library(
    name = "zlib-sapi",
    srcs = [],
    hdrs = [],
    functions = [
        "deflateInit_",
        "deflate",
        "deflateEnd",
    ],
    lib = "@net_zlib//:zlib",
    lib_name = "Zlib",
    namespace = "sapi::zlib",
)

نتیجه این است که کتابخانه zlib sandbox شده تولید می شود. خروجی شی SAPI است که می تواند در کد میزبان گنجانده شود و برای برقراری ارتباط با کتابخانه sandboxed از طریق تماس های RPC استفاده شود. سیاست Sandbox استفاده شده در این مثال، خط مشی پیش فرض است.

3. کد میزبان را بنویسید یا تغییر دهید

اکنون زمان آن است که کتابخانه SAPI تولید شده را در کد میزبان ادغام کنیم.

Sandbox را ایجاد کنید

استفاده از sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create()); برای ایجاد یک شی جعبه شنی

استفاده از sapi::zlib::ZlibApi api(&sandbox); برای نمونه سازی SAPI Object و در نتیجه در دسترس قرار دادن توابع sandboxed برای استفاده.

از انواع SAPI استفاده کنید

انواع SAPI انواع خاصی در قالب کلاس های C++ هستند که SAPI ارائه می دهد زیرا گاهی اوقات نوع C معمولی کار نمی کنند.

اولین استفاده از نوع SAPI را می توان در اعلان strm مشاهده کرد، جایی که یک ساختار SAPI استفاده می شود: sapi::v::Struct<sapi::zlib::z_stream> strm;

نوع قالب ( sapi::zlib::z_stream ) نمونه خوبی از کدهایی است که به طور خودکار توسط قانون ساخت تولید می شود.

برای جزئیات بیشتر به صفحه متغیرها نگاه کنید.

برقراری تماس های API

برای برقراری تماس با defalteInit_ ، deflate یا deflateEnd ، از شیء SAPI استفاده کنید. اگر تصمیم دارید از رویکرد "تغییر" استفاده کنید، باید مطمئن شوید که پارامترهای تابع با مقادیر مورد انتظار مطابقت دارند.

نمونه ای از هر یک از تماس های مثال zlib :

  • api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
        version.PtrBefore(), sizeof(sapi::zlib::z_stream));
  • api.deflate(strm.PtrBoth(), flush);
  • api.deflateEnd(strm.PtrBoth()).IgnoreError();

استفاده از تراکنش های SAPI

SAPI کد میزبان را از کتابخانه Sandboxed جدا می کند و به تماس گیرنده این امکان را می دهد که درخواست های پردازش داده مشکل ساز را راه اندازی مجدد یا لغو کند. SAPI Transaction یک قدم جلوتر می رود و به طور خودکار فرآیندهای شکست خورده را تکرار می کند.

برای جزئیات بیشتر به صفحه معاملات SAPI نگاهی بیندازید.

مثال ها

در زیر نمونه ها می توانید چند کتابخانه را پیدا کنید که قبلاً توسط تیم SAPI تهیه شده است.

،

در این صفحه، نحوه ایجاد کتابخانه سندباکس C/C++ خود را با Sandboxed API (SAPI) خواهید آموخت. از آن به عنوان راهنما در کنار مثال ها و مستندات کد موجود در فایل های هدر استفاده کنید.

ایجاد وابستگی

وابستگی های زیر باید روی سیستم نصب شوند:

  • هسته لینوکس با پشتیبانی از UTS، IPC، کاربر، PID و فضای نام شبکه
  • هدرهای API فضای کاربران لینوکس
  • برای کامپایل کد خود: GCC 6 (نسخه 7 یا بالاتر ترجیح داده می شود) یا Clang 7 (یا بالاتر)
  • برای تولید خودکار فایل‌های هدر: Clang Python Bindings
  • پایتون 3.5 یا بالاتر
  • Bazel نسخه 2.2.0 یا CMake نسخه 3.12 یا بالاتر.
    • فقط CMake: GNU Make یا نسخه ای از هدرهای کتابخانه libcap و یک ابزار ساخت مانند Ninja (توصیه می شود).

با استفاده از بازل

Bazel سیستم ساخت توصیه شده است و ساده ترین سیستم برای ادغام با آن است.

مستندات ما از کامپایلر Clang استفاده می کند. اگر به یک زنجیره ابزار خاص نیاز دارید (مثلاً کامپایلر، پیوند دهنده و غیره)، برای اطلاعات در مورد نحوه تغییر زنجیره ابزار کامپایلر پیش فرض، به مستندات Bazel مراجعه کنید.

Debian 10 (Buster)

برای نصب وابستگی های ساخت:

echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
  sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \
  python3-pip libclang-dev
pip3 install clang

جنتو

گزینه های هسته مورد نیاز:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

برای نصب وابستگی های ساخت:

emerge dev-util/bazel dev-python/typing dev-python/clang-python

با استفاده از CMake

CMake یک سیستم متا بیلد منبع باز محبوب است که فایل های پروژه را برای ابزارهای ساخت مانند Ninja یا Make تولید می کند.

Debian 10 (Buster)

برای نصب وابستگی های ساخت:

sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \
  python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang

جنتو

گزینه های هسته مورد نیاز:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

برای نصب وابستگی های ساخت:

emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python

فرآیند توسعه

برای سندباکس یک کتابخانه C/C++، باید دو مورد را برای پروژه خود آماده کنید:

ممکن است با zlib از نمونه های Sandbox2 در اینجا آشنایی داشته باشید که یک برنامه کامل ( zpipe.c ) sandbox شده است. در مراحل زیر، نحوه استفاده از SAPI برای جعبه شنود کتابخانه zlib و استفاده از کتابخانه Sandboxed را یاد خواهید گرفت.

1. تصمیم بگیرید که کدام توابع مورد نیاز است

اگر به کد میزبان zlib ( main_zlib.cc ) نگاه کنید، می بینید که عملکرد ابزار خواندن داده ها از stdin و استفاده از تابع deflate() zlib برای فشرده سازی داده ها تا زمانی که یک نشانگر EOF خوانده شود است. در کل، این برنامه از سه تابع از zlib استفاده می کند:

  • deflateInit_() : برای مقداردهی اولیه برای فشرده سازی
  • deflate() : برای انجام عملیات فشرده سازی بر روی قطعه داده
  • deflateEnd() : برای پایان دادن به فشرده سازی و آزادسازی ساختارهای داده تخصیص یافته به صورت پویا

در یک مثال واقعی، کتابخانه C/C++ را بررسی کرده و تصمیم می گیرید که کدام توابع مورد نیاز است. یک استراتژی ممکن این است که با کد میزبان شروع کنید و از کتابخانه بدون جعبه ایمنی استفاده کنید. سپس، در مرحله دوم، می‌توانید کتابخانه Sandboxed را ایجاد کنید و کد میزبان را برای استفاده از فراخوانی تابع sandbox شده تطبیق دهید.

2. قانون ساخت sapi_library را بنویسید

بعد از اینکه سه تابع zlib مورد نیاز از کتابخانه zlib sandbox شده را شناسایی کردید، می توانید قانون ساخت را در فایل BUILD تعریف کنید. اسناد مربوط به قانون ساخت sapi_library را می توانید در صفحه قوانین ساخت پیدا کنید.

قطعه کد زیر تعریف sapi_library را برای مثال zlib SAPI نشان می دهد. با استفاده از ویژگی lib ، به Bazel دستور داده می شود که در فایل WORKSPACE کتابخانه zlib را جستجو کند.

sapi_library(
    name = "zlib-sapi",
    srcs = [],
    hdrs = [],
    functions = [
        "deflateInit_",
        "deflate",
        "deflateEnd",
    ],
    lib = "@net_zlib//:zlib",
    lib_name = "Zlib",
    namespace = "sapi::zlib",
)

نتیجه این است که کتابخانه zlib sandbox شده تولید می شود. خروجی شی SAPI است که می تواند در کد میزبان گنجانده شود و برای برقراری ارتباط با کتابخانه sandboxed از طریق تماس های RPC استفاده شود. سیاست Sandbox استفاده شده در این مثال، خط مشی پیش فرض است.

3. کد میزبان را بنویسید یا تغییر دهید

اکنون زمان آن است که کتابخانه SAPI تولید شده را در کد میزبان ادغام کنیم.

Sandbox را ایجاد کنید

استفاده از sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create()); برای ایجاد یک شی جعبه شنی

استفاده از sapi::zlib::ZlibApi api(&sandbox); برای نمونه سازی SAPI Object و در نتیجه در دسترس قرار دادن توابع sandboxed برای استفاده.

از انواع SAPI استفاده کنید

انواع SAPI انواع خاصی در قالب کلاس های C++ هستند که SAPI ارائه می دهد زیرا گاهی اوقات نوع C معمولی کار نمی کنند.

اولین استفاده از نوع SAPI را می توان در اعلان strm مشاهده کرد، جایی که یک ساختار SAPI استفاده می شود: sapi::v::Struct<sapi::zlib::z_stream> strm;

نوع قالب ( sapi::zlib::z_stream ) نمونه خوبی از کدهایی است که به طور خودکار توسط قانون ساخت تولید می شود.

برای جزئیات بیشتر به صفحه متغیرها نگاه کنید.

برقراری تماس های API

برای برقراری تماس با defalteInit_ ، deflate یا deflateEnd ، از شیء SAPI استفاده کنید. اگر تصمیم دارید از رویکرد "تغییر" استفاده کنید، باید مطمئن شوید که پارامترهای تابع با مقادیر مورد انتظار مطابقت دارند.

نمونه ای از هر یک از تماس های مثال zlib :

  • api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
        version.PtrBefore(), sizeof(sapi::zlib::z_stream));
  • api.deflate(strm.PtrBoth(), flush);
  • api.deflateEnd(strm.PtrBoth()).IgnoreError();

استفاده از تراکنش های SAPI

SAPI کد میزبان را از کتابخانه Sandboxed جدا می کند و به تماس گیرنده این امکان را می دهد که درخواست های پردازش داده مشکل ساز را راه اندازی مجدد یا لغو کند. SAPI Transaction یک قدم جلوتر می رود و به طور خودکار فرآیندهای شکست خورده را تکرار می کند.

برای جزئیات بیشتر به صفحه معاملات SAPI نگاهی بیندازید.

مثال ها

در زیر نمونه ها می توانید چند کتابخانه را پیدا کنید که قبلاً توسط تیم SAPI تهیه شده است.