C program¿¡ Shadow¸¦ Áö¿øÇϵµ·Ï µ¡ºÙÀÌ´Â °ÍÀº ½ÇÁ¦ÀûÀ¸·Î ¸Å¿ì °£´ÜÇÏ´Ù. ´ÜÁö
¹®Á¦´Â /etc/shadow
file¿¡ Á¢±ÙÇϱâ À§Çؼ´Â programÀÌ root(¶Ç´Â SUID
root)·Î ½ÇÇàµÇ¾î¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.
ÀÌ °ÍÀº Ä¿´Ù¶õ ¹®Á¦ Çϳª¸¦ ¿ì¸®¿¡°Ô °¿äÇÑ´Ù: SUID programÀ» ¸¸µé ¶§, ¸Å¿ì Á¶½É½º·´°Ô programmingÇÏ´Â ½À°üÀÌ µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, programÀÌ shell Å»Ãâ±â´ÉÀ» °¡Áö°í ÀÖ°í ÀÌ programÀÌ SUID root¶ó¸é, ÀÌ ±â´ÉÀÌ root ±ÇÇÑÀ» Á־ ¾ÈµÈ´Ù.
password¸¦ °Ë»çÇØ ÇÒ ¼ö ÀÖÁö¸¸ ´Ù¸¥ °æ¿ì´Â root±ÇÇÑÀ¸·Î ½ÇÇàÇÒ ÇÊ¿ä°¡ ¾ø´Â
program¿¡ shadow Áö¿ø ±â´ÉÀ» µ¡ºÙÀÓÀ¸·Î½á, SUID programº¸´Ù ÈξÀ ¾ÈÀüÇÑ
programÀ» ¸¸µé ¼ö ÀÖ°Ô ÇÑ´Ù. xlock
programÀÌ ±× ÇÑ ¿¹ÀÌ´Ù.
¾Æ·¡ ¿¹¿¡¼, pppd-1.2.1d
´Â ÀÌ¹Ì SUID root·Î ½ÇÇàÇÏ°í ÀÖÀ¸¹Ç·Î,
shadow Áö¿ø ±â´ÉÀ» µ¡ºÙÀÌ´Â °ÍÀº programÀÌ ´õ Ãë¾àÇÏ°Ô ¸¸µéÁö ¾ÊÀ» °ÍÀÌ´Ù.
header fileµéÀº /usr/include/shadow
¿¡ ÀÖ´Ù.
¶ÇÇÑ, /usr/include/shadow.h
µµ ÀÖ´Ù. ±×·¯³ª, ÀÌ°ÍÀº
/usr/include/shadow/shadow.h
¿¡ ´ëÇÑ symbolic linkÀÏ °ÍÀÌ´Ù.
shadow Áö¿ø ±â´ÉÀ» Ãß°¡Çϱâ À§ÇØ, header fileÀ» ³ÖÀÚ:
#include <shadow/shadow.h> #include <shadow/pwauth.h>
shadow code¸¦ »óȲ¿¡ µû¶ó compileÇϵµ·Ï compiler directive(Áö½ÃÀÚ)¸¦ ¾²´Â °ÍÀº Á¾Àº ¹æ¹ýÀÌ´Ù (¾Æ·¡ ¿¹¿¡¼ º¸µµ·Ï).
Shadow SuiteÀ» ¼³Ä¡ÇÒ ¶§, libshadow.a
file˼
/usr/lib
¿¡ ³õÀδÙ.
shadow Áö¿ø±â´ÉÀ» program¿¡ ³ÖÀ»·Á¸é, linker¿¡°Ô libshadow.a
¸¦
°°ÀÌ linkÇϵµ·Ï Áö½ÃÇØÁÖ¾î¾ß ÇÑ´Ù.
´ÙÀ½Ã³·³:
gcc program.c -o program -lshadow
¾î·µç, ¾Æ·¡ ¿¹¿¡¼ º¸´Ù½ÃÇÇ, ´ëºÎºÐ °Å´ëÇÑ programµéÀº Makefile
À»
»ç¿ëÇÏ°í, ¿ì¸®°¡ °íÄ¥ LIBS=...
¶ó´Â º¯¼ö¸¦ ´ë°³ ¾´´Ù.
libshadow.a
library´Â /etc/shadow
file·ÎºÎÅÍ ¾ò´Â Á¤º¸¸¦
spwd
¶ó´Â ±¸Á¶Ã¼¿¡ ´ã´Â´Ù. spwd
±¸Á¶Ã¼¿¡ ´ëÇÑ Á¤ÀÇ´Â
/usr/include/shadow/shadow.h
file¿¡ ÀÖ´Ù:
struct spwd { char *sp_namp; /* »ç¿ëÀÚ À̸§ */ char *sp_pwdp; /* encryptµÈ password */ sptime sp_lstchg; /* ÃÖ±Ù data ¼öÁ¤ÀÏ */ sptime sp_min; /* ¼öÁ¤ÀÛ¾÷°£ÀÇ ÃÖ¼Ò ³¯Â¥(°á±¹ Çѹø ¼öÁ¤ÇÑ ´ÙÀ½ ¾ðÁ¦ ¼öÁ¤ÀÌ °¡´ÉÇÑ°¡¿¡ ´ëÇÑ ´ë´ä) */ sptime sp_max; /* ¼öÁ¤ÀÛ¾÷°£ÀÇ ÃÖ´ë ³¯Â¥(password À¯È¿±â°£) */ sptime sp_warn; /* password°¡ ¹«È¿°¡ µÇ±â Àü °æ°íÇÏ´Â ±â°£ */ sptime sp_inact; /* password°¡ ¹«È¿µÈ µÚ, °èÁ¤ÀÌ »ç¿ëºÒ´ÉÀÌ µÉ ¶§±îÁöÀÇ ±â°£. */ sptime sp_expire; /* ³¯Â¥(°èÁ¤»ç¿ëºÒ´É - 1/1/70) */ unsigned long sp_flag; /* ³ªÁßÀ» À§ÇØ ºñ¿öµÒ */ };
Shadow Suite´Â sp_pwdp
field¿¡ encodeµÈ passwd¿Í ÇÔ²² ´Ù¸¥ °É
³ÖÀ» ¼ö ÀÖ´Ù. password field´Â ´ÙÀ½Ã³·³ µÉ ¼ö ÀÖ´Ù:
username:Npge08pfz4wuk;@/sbin/extra:9479:0:10000::::
ÀÌ´Â password¿¡ µ¡ºÙ¿©, /sbin/extra
programÀÌ ´õ ½ÉÈµÈ ÀÎÁõÀ» À§ÇØ
È£ÃâµÈ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. È£ÃâµÇ´Â programÀº username, È£ÃâÀÌÀ¯¸¦ ¾Ë·ÁÁÖ´Â
switch¸¦ ¹ÞÀ» ¼ö ÀÖ¾î¾ß µÉ °ÍÀÌ´Ù. ÀÚ¼¼ÇÑ °É ¾Ë°í ½Í´Ù¸é,
/usr/include/shadow/pwauth.h
¿Í pwauth.c
¸¦ º¸±â ¹Ù¶õ´Ù.
ÀÌ°ÍÀÌ ÀǵµÇÏ´Â ¹Ù´Â -µÎ¹ø »ç¿ëÀÚ È®ÀÎÇÏ´Â µ¥ »ç¿ëÇÒ ¼öµµ ÀÖ´Â- ´Ù¸¥
ÇöÁ¸ÇÏ´Â(actual) »ç¿ëÀÚ È®ÀÎ ¹æ¹ýÀ» ¼öÇàÇÒ ¼ö ÀÖµµ·Ï pwauth
±â´ÉÀ»
¾²´Â °ÍÀÌ´Ù.
Shadow SuiteÀÇ ÀúÀÚ´Â ÇöÁ¸ÇÏ´Â ´ëºÎºÐÀÇ programµéÀÌ ÀÌ ±â´ÉÀ» ¾²°í ÀÖÁö ¾ÊÀ½Àº ÁöÀûÇϸé¼, Shadow Suite Â÷±â version¿¡´Â »ç¶óÁö°Å³ª, ¹Ù²ð °ÍÀ̶ó°í ÇÑ´Ù.
shadow.h
file˼ libshadow.a
library¿¡ ÀÖ´Â ÇÔ¼öµéÀÇ
±âº»ÇüÀ» Æ÷ÇÔÇÏ°í ÀÖ´Ù:
extern void setspent __P ((void)); extern void endspent __P ((void)); extern struct spwd *sgetspent __P ((__const char *__string)); extern struct spwd *fgetspent __P ((FILE *__fp)); extern struct spwd *getspent __P ((void)); extern struct spwd *getspnam __P ((__const char *__name)); extern int putspent __P ((__const struct spwd *__sp, FILE *__fp));
¿¹Á¦¿¡¼ ¾µ ÇÔ¼ö´Â: getspnam
- spwd
±¸Á¶Ã¼¿¡¼ »ç¿ëÀÚ À̸§À»
°¡Á®¿À´Â ÇÔ¼ö - ÀÌ´Ù.
ÀÌ°ÍÀº shadow Áö¿ø±â´ÉÀÌ ÇÊ¿äÇÏÁö¸¸ ±âº»¼³Á¤À¸·Î µÇ¾î ÀÖÁö ¾ÊÀº program¿¡ ±×°ÍÀ» Ãß°¡ÇÏ´Â ¿¹Á¦ÀÌ´Ù.
º» ¿¹Á¦·Î, PAPÀ̳ª CHAP´ë½Å /etc/passwd
file¿¡ ÀÖ´Â
»ç¿ëÀÚÀ̸§°ú password¸¦ »ç¿ëÇÏ¿© PAP ÀÎÁõÀ» ¼öÇàÇÏ´Â mode¸¦ Áö´Ñ,
Point-to-Point Protocol Server (pppd-1.2.1d)¸¦ µé°í ÀÖ´Ù.
pppdÀÇ ÀÌ·± ±â´ÉÀº ±×¸® ÀÚÁÖ ¾²ÀÌ°í ÀÖÁö ¾Ê´Ù. ±×·¯³ª Shadow Suite°¡
¼³Ä¡µÇ¸é ÀÌ ±â´ÉÀº ¸ø ¾²°Ô µÉ °ÍÀÌ´Ù. ¿Ö³ÄÇϸé password´Â ´õ ÀÌ»ó
/etc/passwd
¿¡ ÀÖÁö ¾Ê±â ¶§¹®ÀÌ´Ù.
ppad-1.2.1d
¿¡¼ »ç¿ëÀÚ ÀÎÁõÇÏ´Â code´Â
/usr/src/pppd-1.2.1d/pppd/auth.c
file¿¡ ÀÖ´Ù.
´ÙÀ½ code´Â #include
Áö½ÃÀÚ°¡ À§Ä¡ÇÏ´Â fileÀÇ ÀºÎºÐ¿¡ µ¡´î ÇÊ¿ä°¡
ÀÖ´Ù. ¿ì¸®´Â Á¶°ÇÁö½ÃÀÚ(conditional directive)·Î #include
¸¦ µÑ·¯½Õ´Ù
(Ưº°È÷ shadow Áö¿ø±â´ÉÀ» ³Ö¾î compileÇÒ ¶§¸¸ Æ÷ÇÔÇϵµ·Ï)
#ifdef HAS_SHADOW #include <shadow.h> #include <shadow/pwauth.h> #endif
´ÙÀ½Àº ½ÇÁ¦ code¸¦ °íÄ¡´Â ÀÏÀÌ´Ù. ¾ÆÁ÷µµ auth.c
fileÀ» °íÄ¡°í ÀÖ´Ù.
°íÄ¡±â ÀüÀÇ auth.c
´Â:
/* * login - Check the user name and password against the system * password database, and login the user if OK. * * returns: * UPAP_AUTHNAK: Login failed. * UPAP_AUTHACK: Login succeeded. * In either case, msg points to an appropriate message. */ static int login(user, passwd, msg, msglen) char *user; char *passwd; char **msg; int *msglen; { struct passwd *pw; char *epasswd; char *tty; if ((pw = getpwnam(user)) == NULL) { return (UPAP_AUTHNAK); } /* * XXX If no passwd, let them login without one. */ if (pw->pw_passwd == '\0') { return (UPAP_AUTHACK); } epasswd = crypt(passwd, pw->pw_passwd); if (strcmp(epasswd, pw->pw_passwd)) { return (UPAP_AUTHNAK); } syslog(LOG_INFO, "user %s logged in", user); /* * Write a wtmp entry for this user. */ tty = strrchr(devname, '/'); if (tty == NULL) tty = devname; else tty++; logwtmp(tty, user, ""); /* Add wtmp login entry */ logged_in = TRUE; return (UPAP_AUTHACK); }
»ç¿ëÀÚ password´Â pw->pw_passwd
¿¡ À§Ä¡ÇÑ´Ù. µû¶ó¼ ÇÒ ÀÏÀº
getspnam
ÇÔ¼ö¸¦ Ãß°¡ÇÏ´Â °ÍÀÌ ÀüºÎ´Ù. ÀÌ ÇÔ¼ö´Â
spwd->sp_pwdp
¿¡ password¸¦ ÇÒ´çÇÑ´Ù.
¿ì¸®´Â ´Ù¸¥ ÇöÁ¸ÇÏ´Â(actual) »ç¿ëÀÚ È®ÀÎ ÀÛ¾÷À» ¼öÇàÇϵµ·Ï pwauth
ÇÔ¼ö¸¦ ³ÖÀ» °ÍÀÌ´Ù. ÀÌ´Â shadow file¿¡ ¼³Á¤µÇ¾î ÀÖÀ¸¸é ÀÚµ¿ÀûÀ¸·Î µÎ¹ø°
ÀÎÁõÀ» ¼öÇàÇÑ´Ù.
shadow¸¦ Áö¿øÇϵµ·Ï °íÄ£ auth.c
´Â:
/* * login - Check the user name and password against the system * password database, and login the user if OK. * * This function has been modified to support the Linux Shadow Password * Suite if USE_SHADOW is defined. * * returns: * UPAP_AUTHNAK: Login failed. * UPAP_AUTHACK: Login succeeded. * In either case, msg points to an appropriate message. */ static int login(user, passwd, msg, msglen) char *user; char *passwd; char **msg; int *msglen; { struct passwd *pw; char *epasswd; char *tty; #ifdef USE_SHADOW struct spwd *spwd; struct spwd *getspnam(); #endif if ((pw = getpwnam(user)) == NULL) { return (UPAP_AUTHNAK); } #ifdef USE_SHADOW spwd = getspnam(user); if (spwd) pw->pw_passwd = spwd->sp-pwdp; #endif /* * XXX If no passwd, let NOT them login without one. */ if (pw->pw_passwd == '\0') { return (UPAP_AUTHNAK); } #ifdef HAS_SHADOW if ((pw->pw_passwd && pw->pw_passwd[0] == '@' && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL)) || !valid (passwd, pw)) { return (UPAP_AUTHNAK); } #else epasswd = crypt(passwd, pw->pw_passwd); if (strcmp(epasswd, pw->pw_passwd)) { return (UPAP_AUTHNAK); } #endif syslog(LOG_INFO, "user %s logged in", user); /* * Write a wtmp entry for this user. */ tty = strrchr(devname, '/'); if (tty == NULL) tty = devname; else tty++; logwtmp(tty, user, ""); /* Add wtmp login entry */ logged_in = TRUE; return (UPAP_AUTHACK); }
ÁÖÀÇÇؼ º¸¸é ¿ì¸®°¡ ÇÑ ´Ù¸¥ º¯È¸¦ º¼ ¼ö ÀÖÀ» °ÍÀÌ´Ù. /etc/passwd
file¿¡ password°¡ ¾ø´Ù¸é, ¿ø versionÀº UPAP_AUTHACK
¸¦ µ¹·ÁÁÖ°í
Á¢¼ÓÀ» Çã¿ëÇß´Ù. ÀÌ°Ç ¾È ÁÁ´Ù. ¿Ö³ÄÇϸé, ÀÌ login±â´ÉÀÇ ÀϹÝÀûÀÎ
¿ëµµ´Â PPP process¿¡ Á¢±ÙÇÑ ´ÙÀ½, PAP¿¡ ÀÇÇØ Áö¿øµÇ´Â »ç¿ëÀÚ À̸§°ú password¸¦
/etc/passwd
¿¡ ÀÖ´Â »ç¿ëÀÚ À̸§°ú /etc/shadow
¿¡ ÀÖ´Â
password¿Í ¸Â´ÂÁö Á¡°ËÇϵµ·Ï Çã¿ëÇÏ´Â, ÇÑ °èÁ¤À» »ç¿ëÇÏ´Â °ÍÀ̱⠶§¹®ÀÌ´Ù.
µû¶ó¼, ¿ø versionÀÌ »ç¿ëÀÚ(ƯÈ÷, ppp
)¸¦ À§ÇØ shellÀ» ½ÇÇà½ÃÅ°µµ·Ï
¼³Á¤Çß´Ù¸é, ´©±¸µçÁö ±×µéÀÇ PAP¸¦ »ç¿ëÀÚÀ̸§À» ppp
, password¸¦ null·Î
ÇÔÀ¸·Î½á ppp ¿¬°áÀ» ȹµæÇÒ ¼ö ÀÖ¾ú´Ù.
¿ì¸®´Â ÀÌ°ÍÀ» password°¡ ¾ø´Ù¸é UPAP_AUTHACK
´ë½Å
UPAP_AUTHNAK
¸¦ µÇµ¹·ÁÁÖµµ·Ï °íÃÆ´Ù.
Èï¹Ì·Ó°Ôµµ pppd-2.2.0
·Î °°Àº ¹®Á¦¸¦ Áö´Ï°í ÀÖ´Ù.
´ÙÀ½Àº µÎ°¡Áö ÀÏÀÌ ÀϾ ¼ö ÀÖµµ·Ï MakefileÀ» °íÁö´Â °ÍÀÌ´Ù:
USE_SHADOW
°¡ ¼±¾ðµÇ¾î ÀÖ¾î¾ß ÇÏ°í, libshadow.a
°¡ linkµÇµµ·Ï
ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù.
Makefile¿¡¼´Â:
LIBS = -lshadow
±×¸®°í³ª¼ ´ÙÀ½ ÁÙÀ»:
COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t
¿¡¼:
COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t -DUSE_SHADOW
·Î ¹Ù²Û´Ù.
ÀÌÁ¦ ¸¸µé¾î¼ ¼³Ä¡Ç϶ó.