2009-11-06 12 views
5

Napisałem małą niestandardową aplikację serwera WWW w języku C działającym pod kontrolą systemu Linux. Kiedy aplikacja otrzymuje żądanie, wywołuje fork() i obsługuje żądanie w oddzielnym procesie, który jest chrootowany do określonego katalogu zawierającego pliki, które chcę udostępnić.odpowiednik fork/chroot dla aplikacji serwera Windows

Chcę przenieść aplikację do systemu Windows, ale ani fork(), ani chroot() nie są dostępne na tej platformie i nie ma żadnych bezpośrednich odpowiedników. Czy możesz wskazać mi prosty (najlepiej napisany) przykład kodu, który zapewni tę funkcjonalność w systemie Windows? Moje C nie jest aż tak dobre, więc im prostsze, tym lepiej.

+0

Odpowiedzi do tej pory wskazują, że nie ma prostego alternatywą fork(), jestem zadowolony rozważyć użycie oddzielnego wątki, a nie rozwidlają nowy proces, ale nadal chciałbym podać przykład kodu. Istnieje wiele serwerów sieciowych działających pod Windows (np. Apache), które muszą adresować zarówno części fork(), jak i chroot() tego problemu, zaakceptowałyby krótkie podsumowanie podejścia, które jest zwykle podejmowane i łączy się z odpowiednimi częściami źródła Apache (lub innego). – codebox

+0

Biorąc pod uwagę twój komentarz, sugeruję, aby nie opierać swojego kodu na źródle próbnym Cygwin, ale zamiast tego użyć biblioteki Apache Portable Runtime, aby zająć się szczegółami. –

+0

Też myślę, że powinieneś pójść z jakąś biblioteką. Zobacz także: http://www.gnu.org/software/libmicrohttpd/ - Biblioteka serwerów HTTP obsługująca systemy Windows i Unix. Służy do osadzania funkcjonalności serwera internetowego w twoim programie. http://abyss.sourceforge.net/ - serwer WWW dla wygrywa/unix Ponadto można zapomnieć o wątkach i procesach oraz użyć niezablokowującego IO. W ten sposób potrzebujesz tylko jednego procesu, zamiast tego śledzisz połączenia na liście lub tablicy. Przykład: http://www.cubicsky.com/files/shinyhttpd-0.1.3-src.tar.gz –

Odpowiedz

9

Po pierwsze, odpowiednik Windowsa chroot to RUNAS, który jest documented here. Jeśli potrzebujesz tego z programu, studiowanie this C++ source code powinno pomóc ci zrozumieć, jak używać Windows API. Nie jest to dokładnie to samo, co w przypadku Windowsa ludowego, aby utworzyć coś takiego jak więzienie w chroot, tworząc użytkownika z bardzo ograniczonymi uprawnieniami i nadającego tylko uprawnienia odczytu dla użytkownika w folderze aplikacji, i zapisując uprawnienia do jednego folderu dla danych.

Prawdopodobnie nie chcesz dokładnie emulować fork() w systemie Windows, ponieważ nie brzmi tak, jakbyś musiał posunąć się tak daleko. Aby zrozumieć interfejs API systemu Windows służący do tworzenia procesów i ich różnicę od fork(), należy sprawdzić: Mr. Peabody Explains fork(). Rzeczywisty bieżący kod źródłowy dla Cygwin's fork implementation pokazuje aktualny stan techniki.

Dokumentacja Microsoft dla CreateProcess() i CreateThread() to miejsce, w którym można znaleźć więcej informacji na temat różnic między nimi.

I na koniec, jeśli nie chcesz poznać wszystkich drobnych szczegółów platformy, po prostu napisz przenośne programy działające pod Windows i Unix, dlaczego nie po prostu użyć samego siebie. Here are some docs on process creation with some sample code, w C, aby utworzyć nowy proces.

+1

To nie jest 'chroot()', 'chroot' zmienia twój katalog główny, a nie który użytkownik jest zidentyfikowany jako – Hasturkun

+4

Masz rację, to nie jest chroot(), ponieważ Windows nie ma chroot(), ale RUNAS.EXE jest tym co Użytkownicy Windowsa używają do stworzenia czegoś podobnego do więzienia chroot UNIX. –

+3

RUNAS nie jest podobny do więzienia chroot. –

3

Nie ma czegoś takiego jak fork() w systemie Windows. Musisz zadzwonić pod numer CreateProcess() - to rozpocznie oddzielny proces (w większości odpowiadający wywoływaniu fork(), a następnie natychmiast exec() dla procesu spawnu) i przekazuje mu parametry w jakiś sposób. Ponieważ wydaje się, że masz wszystkie dane do przetworzenia w dedykowanym katalogu, możesz użyć parametru lpCurrentDirectory z CreateProcess() - wystarczy podać ścieżkę do katalogu, z której wcześniej korzystałeś z chroot().

+1

Zauważ, że 'lpCurrentDirectory' odpowiada chdir(), nie chroot(). –

+0

Dzięki, ale nie jest to dokładnie to, czego potrzebuję - głównym powodem używania chroot jest bezpieczeństwo (powstrzymuje kogoś używającego ../ .. w adresie URL żądania, aby uzyskać dostęp do plików w innym miejscu systemu plików) i ustawienie katalogu bieżącego nie zapewniają to. Mam również wiele wartości w pamięci, które są wymagane przez rozwidlony proces, afaik jedynym sposobem przekazania ich przez exec będzie argumentacja linii poleceń, i nie chcę tam iść ... – codebox

+2

Cóż, znowu nie ma czegoś takiego jak fork(), które powieliłoby proces w systemie Windows. W każdym razie musiałbyś użyć jakiejś formy IPC, więc być może przejście w linii poleceń lub przez plik tymczasowy jest najprostszym sposobem. Jeśli chodzi o chroot(), możesz wykonać następujące czynności: utwórz oddzielne konto do uruchamiania procesów roboczych, które nie mają żadnych uprawnień z wyjątkiem folderu tymczasowego i uruchom proces roboczy na tym koncie. – sharptooth

0

Używanie fork/chroot nie jest po prostu sposobem wykonywania czynności w systemie Windows. Jeśli martwisz się bezpieczeństwem w podprocesach, być może chcesz użyć jakiejś formy wirtualizacji lub piaskownicy. Przekazywanie złożonych informacji do podprocesu może odbywać się za pomocą jakiejś formy rozwiązania RPC.

To brzmi dla mnie tak, jakbyś zaprojektował swoją aplikację w sposób uniksowy, a teraz chcesz uruchomić w systemie Windows bez konieczności zmiany czegokolwiek. W takim przypadku możesz rozważyć użycie Cygwin, ale nie jestem pewien, czy/jak Cygwin emuluje chroot.

+1

Tak, cygwin ma chroot. –

2

Najprostszym sposobem na to jest użycie Cygwin, bezpłatnej warstwy emulacji Unix dla Windows. Pobierz i zainstaluj kompletne środowisko programistyczne. (Wybierz w instalatorze.) Jeśli masz szczęście, będziesz w stanie skompilować swój program bez zmian.

Oczywiście są wady i niektórzy mogą uznać to za "oszustwo", ale poprosiliście o najprostsze rozwiązanie.

+1

Rozumiem, że więzienie chrstrów w Cygwin nie jest doskonałe. Zadanie skompilowane przez non cygwin może się zepsuć. –

+0

Sanjaya, prawdopodobnie masz rację, ale do większości celów powinno działać. –

0

Rozważmy SUA (aka Windows Services for Unix). Ma prawie wszystko, czego potrzebujesz do przenoszenia aplikacji.

man chroot(interix)

1

bez użycia ramy zgodności (Interix, Cygwin, ...) szukasz w użyciu paradygmat Windows tego typu rzeczy.

widelec/vfork jest tania operacja na UNIX-ów, dlatego jest on wykorzystywany często w porównaniu do wielowątkowości. odpowiednik systemu Windows - CreateProcess() - jest dla porównania kosztowną operacją iz tego powodu powinieneś spojrzeć na użycie wątków zamiast, tworząc je z CreateThread(). Istnieje wiele przykładowego kodu dla CreateThread().

Pod względem chroot(), Windows nie ma tego pojęcia. Są tam biblioteki, które twierdzą, że mogą emulować to, czego potrzebujesz. Jednak to zależy od tego, dlaczego chcesz chroot w pierwszej kolejności.

Czytanie komentarzy, jeśli jest to po prostu zatrzymanie osób wchodzących na drzewo z ../../../../ (itp.), Chroot wykona zadanie, ale nie będzie podstawą do analizowania danych wejściowych i upewnienia się, że jest to normalne: np. wielu rodziców zostało określonych, zablokuj użytkownika w znanym katalogu głównym. Apache prawie na pewno robi to jak nigdy nie miałem do tworzenia środowiska chroot() dla Apache do pracy ...

Powiązane problemy