Путь к домашней директории для сохранения файлов (C++)

Модератор: Модераторы разделов

Nauro
Сообщения: 8
ОС: Xubuntu 8.10

Путь к домашней директории для сохранения файлов

Сообщение Nauro »

Возникла такая вот заковыка: надо сделать сохранение конфига в файлике, чтобы при следующем запуске подцепить его. Подумал, что лучше всего сохранить куда-то типа /home/nauro/.abc/ но вот он зависит от имени юзера, т.е. на другой системе работать не будет... Можно ли путь к домашнему каталогу как-то определить?
Спасибо сказали:
Аватара пользователя
CycaHuH
Сообщения: 85
ОС: FreeBSD; Archlinux; Calculate

Re: Путь к домашней директории для сохранения файлов

Сообщение CycaHuH »

getenv("HOME");
Спасибо сказали:
Аватара пользователя
kosmonaFFFt
Сообщения: 183
ОС: win 7, Kubuntu 10.10

Re: Путь к домашней директории для сохранения файлов

Сообщение kosmonaFFFt »

Или юзать тильду, теоретически должно работать...
Т. е. ~ = /home/username для текущего юзера.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Путь к домашней директории для сохранения файлов

Сообщение RasenHerz »

kosmonaFFFt писал(а):
14.01.2009 19:59
Или юзать тильду, теоретически должно работать...
Т. е. ~ = /home/username для текущего юзера.

getenv() надежней ;)
собственно по сабжу:

Код: Выделить всё

#include<iostream>
#include <cstdio>
#include <string.h>

using namespace std;

int main(int argc ,char *argv[]){
    char text[128];
    FILE *name;
    name = popen("whoami", "r");
    fgets(text, 128, name);
    pclose(name);
    char home_dir[255] = {'/', 'h', 'o', 'm', 'e', '/', 0 };
    strcpy(home_dir+6,text);
    cout << "Home directory is: " << home_dir << endl;
    return 0;
}
Спасибо сказали:
Аватара пользователя
Cra3y
Сообщения: 80
ОС: Debian

Re: Путь к домашней директории для сохранения файлов

Сообщение Cra3y »

Код: Выделить всё

#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static inline char* get_home() {
        return getpwuid(getuid())->pw_dir;
}

int main(int argc, char** argv) {
        puts(get_home());
        return 0;
}
HP G62 (AMD Phenom II x3 1.8GHz 4GB DDR3 Ram) / Debian 8 amd64
Спасибо сказали:
Nauro
Сообщения: 8
ОС: Xubuntu 8.10

Re: Путь к домашней директории для сохранения файлов

Сообщение Nauro »

Спасибо за помощь. Разобрался.

P.S. Тильда была первым интуитивным рывком, но, увы, неудачным.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Путь к домашней директории для сохранения файлов

Сообщение watashiwa_daredeska »

kosmonaFFFt писал(а):
14.01.2009 19:59
Или юзать тильду, теоретически должно работать...
Не должно. Тильда раскрывается шеллом, а не libc или ядром. getenv("HOME") -- правильный вариант, потому что общепринятый.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Путь к домашней директории для сохранения файлов

Сообщение RasenHerz »

watashiwa_daredeska писал(а):
16.01.2009 20:26
Не должно. Тильда раскрывается шеллом, а не libc или ядром. getenv("HOME") -- правильный вариант, потому что общепринятый.

а еще кроме того, что он общепринятый - он еще и теоретически уязвимый.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Путь к домашней директории для сохранения файлов

Сообщение watashiwa_daredeska »

RasenHerz писал(а):
16.01.2009 21:48
а еще кроме того, что он общепринятый - он еще и теоретически уязвимый.
А можно пример уязвимости?
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Путь к домашней директории для сохранения файлов

Сообщение RasenHerz »

нет времени и желания что-то расписывать. почитайте лучше книгу Джон Эриксон "Хакинг. Искусство эксплойта" там для начинающих, все очень подробно расписано (и про переполнение в куче и bss, форматные строки). читайте.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Путь к домашней директории для сохранения файлов

Сообщение watashiwa_daredeska »

RasenHerz писал(а):
20.01.2009 21:35
для начинающих, все очень подробно расписано (и про переполнение в куче и bss, форматные строки). читайте.
Где в getenv("HOME") может произойти переполнение кучи или bss, где здесь форматные строки? Начинающим рекомендуется, в первую очередь, думать, что и каким местом куда применимо. Вот это чудовище куда страшнее getenv во всех смыслах, а этот вариант ведет себя не так, как принято в большинстве случаев, нарушая Rule of Least Surprise, хотя и имеет право на жизнь в некоторых случаях, но не для поиска конфигов.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Путь к домашней директории для сохранения файлов

Сообщение RasenHerz »

watashiwa_daredeska писал(а):
21.01.2009 01:42
Где в getenv("HOME") может произойти переполнение кучи или bss, где здесь форматные строки? Начинающим рекомендуется, в первую очередь, думать, что и каким местом куда применимо. Вот это чудовище куда страшнее getenv во всех смыслах, а этот вариант ведет себя не так, как принято в большинстве случаев, нарушая Rule of Least Surprise, хотя и имеет право на жизнь в некоторых случаях, но не для поиска конфигов.

почему вы все так усложняете? ваш пост похож на параноидальный бред.
во-первых, я сказал теоретически уязвимый, во-вторых, я не говорил что в этом коде присутствуют такие уязвимости как переполнение, доступ к поизвольному адресу памяти, в-третьих, ваш интерес к уязвимостям вызвал с моей стороны вполне объяснимое желание помочь, а именно указать книгу, в которой вы можете почерпнуть все необходимые знания; в-четвертых, хотите уязвимость? получайте:

Код: Выделить всё

#include <stdio.h>
#include <stdlib.h>

int main ()
{
  char home_path[255];
  strcpy(home_path, getenv("PATH"));
  return 0;
}

К чему все это? А к тому, что доверять внешним данным нельзя, в данном случае - необходимо проверить возвращенную функцией строку на правильность.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Путь к домашней директории для сохранения файлов

Сообщение watashiwa_daredeska »

RasenHerz писал(а):
21.01.2009 02:03
ваш пост похож на параноидальный бред.
Я как раз не боюсь getenv, ибо знаю чем он грозит, а чем нет. А вот "параноидальный бред" по поводу уязвимостей несу тут совсем не я ;)

RasenHerz писал(а):
21.01.2009 02:03
во-первых, я сказал теоретически уязвимый
Хорошо: Где в getenv("HOME") может теоретически произойти переполнение кучи или bss, где здесь теоретически форматные строки?

RasenHerz писал(а):
21.01.2009 02:03
в-третьих, ваш интерес к уязвимостям вызвал с моей стороны вполне объяснимое желание помочь, а именно указать книгу, в которой вы можете почерпнуть все необходимые знания
Меня интересовали уязвимости конкретно getenv("HOME"), а не вообще. Вообще-то, я более-менее знаком с различными видами уязвимостей, как разработчик конечно, а не как эксперт по безопасности. Так что можете общаться на нормальном уровне, не подразумевая в собеседнике девятиклассника ;)

RasenHerz писал(а):
21.01.2009 02:03
в-четвертых, хотите уязвимость? получайте
Ну и причем тут getenv? Скажите еще, что параметры командной строки теоретически уязвимы. По той же самой причине. И строки char* вообще.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Путь к домашней директории для сохранения файлов

Сообщение RasenHerz »

по-моему, мы друг друга совсем не поняли - я не против использования getenv, а за то чтобы его использовали с умом! грош цена программе, не проверяющей входные данные. давайте проведем "мысленный" эксперимент: представим что есть некая гипотетическая программа, которая должна принять принять от пользователя некоторые данные(в нашем случае значение переменной среды окружения $HOME) и потом соответствующим образом обработать.
пусть будет сильно упрощенный код, который выполняет данные действия:

Код: Выделить всё

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    char *home_dir = getenv("HOME");
    char home[255];
    strcpy(home, home_dir);
    printf("%s\n", home_dir);
    return 0;
}
}

скомпилируем программу и запустим ее:

negativ@negativ-pc

negativ@negativ-pc:~$ g++ -O2 -o prog main.cpp negativ@negativ-pc:~$ ./prog /home/negativ

хорошо, похоже все и в правду работает... Поробуем "позапускать" ее еще:

negativ@negativ-pc

negativ@negativ-pc:~$ HOME=/ ./prog / negativ@negativ-pc:~$ HOME=blah-blah ./prog blah-blah

А вот это уже интересно - контроля со стороны ОС или libc за значением $HOME нет. хорошо... идем дальше:

negativ@negativ-pc

negativ@negativ-pc:~$ HOME=/ ./prog negativ@negativ-pc:~$ HOME=`perl -e 'print "\x41" x 320;'` ./prog AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA Ошибка сегментирования

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

P.S. если спросите, почему я постоянно копирую в char[], то ответ предельно прост - адрес, возвращаемый функцией getenv() для каждой определенной переменной всегда одинаков, т.е. возможна модификация значения $HOME, чтобы избежать даже "случайной" модификации лучше скопировать в буффер. вот пример доказывающий это:

Код: Выделить всё

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    char *home_dir = getenv("HOME");
    char home[255];
    strcpy(home, home_dir);
    printf("%s\n", home_dir);
    home_dir[0] = 'B';
    home_dir = (char*)0x00;
    home_dir = getenv("HOME");
    strcpy(home, home_dir);
    printf("%s\n", home);
    return 0;
}

вывод:

negativ@negativ-pc

negativ@negativ-pc:~$ !HO HOME=`perl -e 'print "\x41" x 320;'` ./prog AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAA BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAA Ошибка сегментирования


P.P.S никакой паранои =)
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Путь к домашней директории для сохранения файлов

Сообщение watashiwa_daredeska »

RasenHerz писал(а):
21.01.2009 04:53
по-моему, мы друг друга совсем не поняли - я не против использования getenv, а за то чтобы его использовали с умом!
по-моему, мы друг друга совсем не поняли - я не против использования getenvаргументов командной строки, а за то чтобы их использовали с умом! (и далее по тексту с заменой s/getenv("HOME")/argv[1]/)

Вопросы:
  • Назовите что-нибудь, что можно использовать без ума. ;)
  • Кто научил вас матерному слову strcpy?
  • Почему наличие матерного strcpy в программе влияет на уязвимость getenv?
  • Почему наличие матерного strcpy в программе не влияет на уязвимость прочих char*?
  • При чем тут вообще getenv?
getenv опасна не более, чем любые другие char*, поэтому никаких особых замечаний по этому поводу не требуется.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Путь к домашней директории для сохранения файлов

Сообщение RasenHerz »

Ответы:

- Много чего, но пользы от этого...
- Для меня это довольно удобная вещь когда мне надо к в одну строку добавить другую:

Код: Выделить всё

char usr_str[RESP_MLEN] = {'U', 'S', 'E', 'R', ' ', 0};
/* ......................................... */
strcpy(usr_str+5, usr); // usr - проверенная строка

использовать здесь, к примеру, тот же memcpy(ну или strnсpy) я считаю не удобным. Есть варианты удобнее?

- Влияет так же как фаза луны влияет на то, соберется ли моя программа =)
- Влияет! Если при работе с памятью не знать границ, в прямом смысле этого слова, будет очень худо.
- Я сделал замечание, что getenv() без должного внимания может послужить дырой в безопасности программы. К самой реализации функции претензий у меня нет, а вот к ее неаккуратному использованию - определенно есть. Уж извините, но на мой взгляд, самой большой опасностью для безопасности программы являются пользовательские данные. И как заметил один мой знакомый, программа требующая интерактивности уязвима всегда =)
Спасибо сказали: