[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Homeverzeichnis in /etc/passwd als relativer Pfad
[Thread Prev] | [Thread Next]
- Subject: Re: Homeverzeichnis in /etc/passwd als relativer Pfad
- From: Raphael Eiselstein <rabe@xxxxxxxxx>
- Date: Sat, 27 Oct 2012 03:01:33 +0200
- To: uugrn@xxxxxxxxxxxxxxx
Hallo Markus, On Thu, Oct 25, 2012 at 11:09:42PM -0200, Markus Demleitner wrote: > > Eine Option waere, den Zugriff auf die Datei /etc/passwd zu maskieren, > > d.h. ein fopen("/etc/passwd") transparent fuer den jeweiligen Prozess > > tatsaechlich umzuleiten auf $DIR/conf/etc/passwd, also eine Art > > Mapping-Datei / Alias-Datei, die von zB glibc oder aber im Kernel > > Anwendung findet. > Uh. Du bist sicher, dass du nicht lieber einen winzigen Patch in die > ssh-Quellen reinfummeln willst? Nein, will ich nicht. Ich will das Verhalten ja nur fuer einen bestimmten Benutzer veraendern. > Ich gebe zu, an ssh rumfummeln ist > immer etwas aufregend, aber eigentlich sieht der Kram recht harmlos > aus (ssh.c, einfach nach _PATH_SSH_USER_CONFFILE suchen; in 5.5p1 ist > das in der Gegend von Zeile 650). Aber ein Check auf ein Configfile > macht dann eigentlich nicht viel was anderes als der Wrapper oben, > der auch noch gleich den Vorteil hat, dass man ihn statt ssh dann > lieber ssh-spezial nennen kann, so dass die Leute sehen, dass da > Magie passiert. Ich habe mir heute mal ne Stunde Zeit genommen und in den Sourcen von openssh-portable rumgesucht. Ich habe in glob.c Code gefunden, der eigentlich das tun sollte, was ich erwarten wuerde: ~ resolven nach getenv("HOME"). --------------------------------------------------------------------------- static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { ... #if 0 if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { #endif if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { if ((pwd = getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; ... } --------------------------------------------------------------------------- In getpwuid(3) steht entsprechend auch, dass man das so tun *sollte* The pw_dir field contains the name of the iniâ?? tial working directory of the user. Login proâ?? grams use the value of this field to initialize the HOME environment variable for the login shell. An application that wants to determine its user's home directory should inspect the value of HOME (rather than the value getpâ?? wuid(getuid())->pw_dir) since this allows the user to modify their notion of "the home direcâ?? tory" during a login session. To determine the (initial) home directory of another user, it is necessary to use getpwnam("username")->pw_dir or similar. Es scheint, dass ssh(1) die diversen(!) Konstanten in der Form "~/.ssh/..." nicht ueber HOME evaluiert sondern ueber offensichtlich ueber getpwuid(getuid())->pw_dir). Obiger Code ist aus /openbsd-compat/glob.c, die Funktionen haengen so zusammen: glob() --> glob0() --> globtilde() Also habe ich den Code nach "glob(" gegreppt: /work/usr/ports/security/openssh-portable/work/openssh-5.8p2]# find . -type f -name "*.c" -exec grep -l "glob(" {} + ./openbsd-compat/glob.c ./sftp.c ./sftp-glob.c Der globbing-Code wird scheinbar nur fuer sftp verwendet, scheinbar nicht fuer ssh(1). Zugriff auf "pw_dir" (das ist der Name des Feldes aus /etc/passwd, in dem das Homeverzeichnis steht) wird an sehr vielen Stellen verwendet: find . -type f -name "*.c" -exec grep -l "pw_dir" {} + ./monitor.c ./auth.c ./ssh-rand-helper.c ./ssh-add.c ./ssh-keygen.c ./auth-rhosts.c ./misc.c ./openbsd-compat/glob.c ./session.c ./monitor_wrap.c ./ssh.c Zum Beispiel hier in ssh.c: main(...) { ... /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { logit("You don't exist, go away!"); exit(255); } /* Take a copy of the returned structure. */ pw = pwcopy(pw); ... /* * Read per-user configuration file. Ignore the system wide * config * file if the user specifies a config file on the command line. */ if (config != NULL) { if (!read_config_file(config, host, &options, 0)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) (void)read_config_file(buf, host, &options, 1); ... } Oder kurz: * pw = getpwuid(...) * pw->pw_dir Hier wird also in ssh.c gezielt nur die Information benutzt, die aus getpwuid() kommt (also das Homeverzeichnis anhand von /etc/passwd) Ich kann sowas fuer sshd(8) nachvollziehen, weil da macht es Sinn *NICHT* $HOME zu verwenden oder wenn der Benutzer root-Rechte hat. Aber wenn ein normaler Benutzer ssh(1) verwendet, dann sollte ihm gestattet sein, ueber Anderung von HOME=/some/where/ auf andere Dateien zu verweisen, die er ohnehin lokal verwenden oder ueberschreiben koennte. Ich verstehe also den Sicherheitsgewinn nicht, wieso nicht HOME verwendet wird. Fazit: SSH ist ein ziemliches Biest! [mapping fuer fopen()] > LD_PRELOAD; zumindest auf glibc-Systemen muesstest du in ld.so(8) was > finden. Das Zeug ist fuer alles moegliche gut (ich erinnere mich Nachdem ich etwas vom Code gelesen und oberflaechlich verstanden habe, wuerde ich nur fuer den Aufgruf von ssh(1) die Funktion getpwuid() ueberladen, sodass getpwuid() mir etwas liefert, was ich ueber eine Umgebungsvariable steuern kann, zB HOME_OVERRIDE=/opt/foo/bla/conf/ wuerde (falls gesetzt) den Wert ersetzen, den getpwuid() sonst aus /etc/passwd ziehen wuerde, sodass ssh(1) dann nicht HOME sondern effektiv HOME_OVERRIDE bekommt. Das ist sicher die Hardcore-Variante, waere aber gegenueber dem restlichen System und Standardverhalten minimalinvasiv anwendbar, da es nur on-demand per LD_PRELOAD verwendet wird. Vermutlich koennte man sich den erforderlichen Code per copy-paste aus den openssh-Quellen zusammenbauen. Ich hab schlichtweg aber keine Ahnung wie man C entwickelt sodass es das oben beschriebene (HOME_OVERRIDE nehmen falls gesetzt) tut. Haette den Vorteil, dass man das fuer alles verwenden koennte, was aehnlich garstig ist wie openssh. Aktuell lebe ich mit dem Hack, dass ich in /etc/passwd als Homeverzeichnis "./conf" eingetragen habe, was dann abhaengig vom aktuellen Pfad verwendet wird. Gruss Raphael -- Raphael Eiselstein <rabe@xxxxxxxxx> http://rabe.uugrn.org/ xmpp:freibyter@xxxxxx | https://www.xing.com/profile/Raphael_Eiselstein GnuPG: E7B2 1D66 3AF2 EDC7 9828 6D7A 9CDA 3E7B 10CA 9F2D .........|.........|.........|.........|.........|.........|.........|.. -- UUGRN e.V. http://www.uugrn.org/ http://mailman.uugrn.org/mailman/listinfo/uugrn Wiki: https://wiki.uugrn.org/UUGRN:Mailingliste Archiv: http://lists.uugrn.org/