Надежно стирающийся пароль в памяти (Python)

Похоже, вы создаете какую-то мини-тестовую среду с использованием препроцессора c.

1112 Есть предостережение для тел; для препроцессора C фигурные скобки и квадратные скобки являются просто токенами. Выражения в скобках распознаются (то есть, скобки совпадают), а запятые распознаются как разделители. Так, например, этот вызов макроса:

test(dosomething, { int a = add(1, 1); assert(a == 2); })

... имеет два аргумента, несмотря на наличие двух запятых (потому что вторая запятая «обнята» в наборе в скобках), но это немного вводит в заблуждение. Этот вызов:

test(dosomething, { enum { red, green, blue }; assert(red+1==green); })

... имеет четыре аргумента: 1: dosomething, 2: { enum { red, 3: green и 4: blue }; assert(red+1==green); }. Если вы собираетесь это сделать, вы, вероятно, захотите охватить такие случаи, как это ... есть базовые стратегии: (а) обнять тело в скобках (вы можете развернуть его в расширении) или (б) использовать макросы с переменным числом аргументов.

Их нужно повторить. blockquote>

Похоже на работу для x-macros (ниже я буду использовать параметризованный макрокоманду x-macros). [ 1115]

Но более того, я хотел бы передать обратный вызов для асинхронных функций, чтобы сказать, что они завершены, например: blockquote>

... вы не можете добавить аргумент в середине, но фигурные скобки не должны быть частью этого (они все равно не помогают, так как препроцессор их игнорирует). Так что для вышеизложенного мы, вероятно, хотим выбрать вариант объятия. В результате ваши вызовы выглядят так:

test(dosomething, (int a=add(1,1); assert(a==2);), done)

Однако, поскольку мы вырываем фигурные скобки, мы можем поместить их в произвольные места в нашем расширении и делать произвольные вещи между ними. Так как я предполагаю, что вы хотите, чтобы происходила та же асинхронная вещь, мы могли бы просто поместить эту вещь в расширение, которое генерирует определение, а не аргумент.

Вот примерно то, на что это было бы похоже, используя параметризованную макро-версию x-макроса и применяя асинхронное расширение (используя семафоры, чтобы продемонстрировать, насколько это может быть произвольно):

#define APPLY_TEST_MACROS(macro) \
    macro(test_add, (int a=add(1,1); assert(a==2);  )) \
    macro(test_sub, (int a=sub(5,2); assert(a==3);  )) \
    macro(test_mul, (int a=mul(3,4); assert(a==12); ))

#define UNWRAP(...) __VA_ARGS__
#define MAKE_ASYNC_SEM(NAME_, BODY_) \
   void NAME_() { \
      sem_wait(&test_sem_ctl); print(#NAME_); sem_post(&test_sem_ctl); \
      UNWRAP BODY_ \
      sem_wait(&test_sem_ctl); \
      if (0==--tests_remaining) sem_post(&test_sem_done); \
      sem_post(&test_sem_ctl); \
   }
#define COUNT_TESTS(NAME_, BODY_) +1
sem_t test_sem_ctl;
sem_t test_sem_done;
void init_semaphores() {
   sem_init(&test_sem_ctl, 0, 1);
   sem_init(&test_sem_done, 0, 0);
}
// iterate over tests to count them
unsigned int tests_remaining = APPLY_TEST_MACROS(COUNT_TESTS);
// define the tests
APPLY_TEST_MACROS(MAKE_ASYNC_SEM)

.. и так далее (я останавливаюсь здесь, потому что идея состоит в том, чтобы передать идею, а не кодировать ее для вас). Макет x-macro позволяет вам выполнять итерации в препроцессоре, так что вы можете сделать что-то вроде порождения потока за тест; вы могли бы также просто использовать этот же подход для построения массива тестовых функций, если, скажем, вы хотите передать свои тесты в пул потоков.

44
задан Community 23 May 2017 в 12:33
поделиться

5 ответов

Python не имеет того низко уровня управления памятью. Примите его и идите дальше. Лучшее, которое можно сделать, к del password после вызова mail.login так, чтобы никакие ссылки на объект строки пароля не оставались. Любое решение, которое подразумевает мочь сделать больше, чем это, только дает Вам ложное чувство защищенности.

Строковые объекты Python неизменны; нет никакого прямого способа изменить содержание строки после того, как она будет создана. Даже если Вы смогли так или иначе перезаписать содержание строки, упомянутой password (который технически возможен с глупыми приемами ctypes), все еще были бы другие копии пароля, которые были созданы в различных строковых операциях:

  • getpass модулем, когда это снимает изоляцию с запаздывающей новой строки введенного пароля
  • imaplib модулем, когда это заключает пароль в кавычки и затем создает полную команду IMAP перед выдаванием его к сокету

Необходимо было бы так или иначе получить ссылки на все те строки и перезаписать их память также.

41
ответ дан Miles 26 November 2019 в 22:15
поделиться

Если Вам не нужен почтовый объект сохраниться, после того как Вы сделаны с ним, я думаю, что Ваш лучший выбор состоит в том, чтобы выполнить почтовую работу в подпроцессе (см. модуль подпроцесса.) Тот путь, когда подпроцесс умирает, поэтому идет Ваш пароль.

6
ответ дан zdan 26 November 2019 в 22:15
поделиться

Сохраните пароль в списке, и если Вы просто устанавливаете список в NULL, память массива, сохраненного в списке, автоматически освобождена.

-4
ответ дан AlbertoPL 26 November 2019 в 22:15
поделиться

Править: удаленный плохой совет...

Можно также использовать массивы как пример Java, если Вам нравится, но просто перезапись его должна быть достаточно.

http://docs.python.org/library/array.html

-4
ответ дан Trey Stout 26 November 2019 в 22:15
поделиться

На самом деле есть способ безопасного стирания строк в Python; используйте функцию memset C согласно Отметьте данные как конфиденциальные в python

Отредактировано для добавления, спустя много времени после того, как сообщение было сделано: вот более глубокое погружение в интернирование строк . Есть некоторые обстоятельства (в основном связанные с непостоянными строками), когда интернирование не происходит, что делает очистку строкового значения несколько более явной на основе GC CPython подсчета ссылок. (Хотя это еще не «чистка» / «дезинфекция».)

19
ответ дан 26 November 2019 в 22:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: