Thư điện tử

Thư điện tử, hay email (từ chữ electronic mail), đôi khi được dịch không chính xác là điện thư, là một hệ thống chuyển nhận thư từ qua các mạng máy tính. Email là một phương tiện thông tin rất nhanh. Một mẫu thông tin (thư từ) có thể được gửi đi ở dạng mã hoá hay dạng thông thường và được chuyển qua các mạng máy tính đặc biệt là mạng Internet. Nó có thể chuyển mẫu thông tin từ một máy nguồn tới một hay rất nhiều máy nhận trong cùng lúc. Ngày nay, email chẳng những có thể truyền gửi được chữ, nó còn có thể truyền được các dạng thông tin khác như hình ảnh, âm thanh, phim, và đặc biệt các phần mềm thư điện tử kiểu mới còn có thể hiển thị các email dạng sống động tương thích với kiểu tệpHTML.

pdf71 trang | Chia sẻ: tlsuongmuoi | Lượt xem: 1986 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Thư điện tử, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ng truyeàn phaûi bò ñöùt) vaø bò treo ñöôøng truyeàn khi cuoäc goïi ñaõ hoaøn thaønh. Pppd daemon baét ñaàu xaùc laäp caùc thoâng soá keát noái vôùi heä thoáng töø xa baèng caùch chuyeån ñoåi ñòa chæ IP, vaø xaùc laäp caùc giaù trò keát noái döïa treân thoâng tin truyeàn. Khi ñaõ hoaøn taát, pppd seõ xaùc laäp lôùp network cho Linux kernel cuûa chuùng ta duøng PPP link baèng caùch thieát laäp giao tieáp thaønh “/dev/pppd0” (neáu ñaây laø PPP link ñaàu tieân active treân maùy). Neáu chuùng ta muoán chuyeån ñoåi caùc thieát laäp maëc nhieân cuûa pppd daemon, chuùng ta coù theå thöïc hieän ñieàu naøy thoâng qua caùc option töø doøng leänh LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 32 hoaëc file ñieàu khieån. Söû duïng caùc file thì toát hôn neáu chuùng ta muoán chuyeån ñoåi thoâng soá cho moãi laàn thöïc hieän keát noái duøng PPP. Tröôùc khi thöïc hieän doøng leänh, pppd seõ xem xeùt taát caû caùc file option coù theå coù. File “/etc/ppp/options” thöôøng duøng ñeå chöùa caùc giaù trò maëc nhieân. Ví duï: # /etc/ppp/options: globabl definitions domain merlin.com auth # force authentication usehostname # use local hostname for authentication lock # use file locking UUCP-style domain ñöôïc thieát laäp vôùi töø khoùa domain theo sau vôùi teân domain ñaày ñuû. Hai doøng keá tieáp (auth vaø usehostname) duøng vôùi quaù trình authentication cuûa PPP, traùnh vieäc söû duïng vaø truy xuaát khoâng mong muoán. Chuùng ta seõ xem xeùt quaù trình authentication trong phaàn sau. Töø khoùa lock noùi pppd khoùa file theo kieåu UUCP ñeå traùnh söï xung ñoät giöõa caùc thieát bò. Locking neân duøng vôùi taát caû caùc heä thoáng PPP ñeå traùnh loãi xaûy ra. 4. KIEÅÅM TRA LOÃÃI Pppd daemon seõ phaûn hoài taát caû caùc warning vaø error tôùi syslog moät caùch uyeån chuyeån. Neáu chuùng ta coù vaán ñeà gì trong keát noái PPP, chuùng ta coù theå kieåm tra syslog ñeå tìm loãi. Syslog seõ chöùa taát caû caùc warning vaø error, tröø khi muïc nhaäp trong “/etc/syslog.conf” ñöôïc taùi ñònh höôùng laïi ñeå chuyeån sang file khaùc. Ñeå löu nhöõng message töø pppd vaø chat, theâm doøng sau vaøo file “/etc/syslog.conf”: daemon.* /tmp/ppp-log Muïc naøy noùi syslog löu taát caû caùc message töø daemon tôùi file “/tmp/ppp-log”. 5. PPP AUTHENTICATION Giao thöùc PPP raát phuø cho vieäc giao tieáp thoâng qua moñem, nhöng coù moät vaán ñeà chuû yeáu laø: coù nhöõng loã hoång raát lôùn veà tính an toaøn. Neáu caáu hình khoâng chính xaùc duø laø raát nhoû thì baát kyø ai cuõng coù theå vaøo trong heä thoáng thoâng qua ñöôøng line ppp, hoaëc söû duïng line ppp ñeå ñi ra heä thoáng khaùc. Ñeå traùnh tình traïng naøy, cô cheá authentiction ñaõ ñöôïc söû duïng. PPP söû duïng hai cô cheá authentiction laø :Password Authentication Protocol (PAP) vaø Challenge Handshake Authentication Protocol (CHAP). PAP gioáng nhö moät thuû tuïc ñeà login. Khi moät maùy naøo ñoù göûi ñi thoâng tin login vaø password tôùi maùy khaùc, beân maùy nhaän seõ kieåm tra thoâng tin baèng cô sôû döõ lieäu maø noù coù, vôùi tính ñôn giaûn cuûa noù neân noù coù moät vaán ñeà ñoù caàn chuù yù laø baát kyø ai cuõng coù theå maéc reõ nhaùnh vaøo ñöôøng daây ñieän thoaïi cuûa mình ñeå laáy thoâng tin password truyeàn treân ñöôøng daây. Ñeå giaûi quyeát vaán ñeà naøy chuùng ta duøng cô cheá CHAP vaø ñaây laø daïng ñöôïc duøng nhieàu trong kieåu noái PPP. CHAP cho pheùp moät maùy (maùy A) göûi moät chuoãi baát kyø tôùi moät maùy khaùc cuøng vôùi teân hostname cuûa noù. Beân nhaän (maùy B) söû duïng hostname naøy ñeå tìm ra reply ñuùng, toå hôïp chuùng vôùi chuoãi kyù töï LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 33 ban ñaàu, maõ hoùa chuùng roài göûi laïi cho maùy A cuøng vôùi teân hostname cuûa noù. Maùy A seõ th75c hieän cuõng caùc thao taùc nhö maùy B ñoái vôùi chuoãi kyù töï noù ñaõ göûi ñi luùc ñaàu, neáu hai reply gioáng nhau vieäc authentication chaám döùt. CHAP khoâng thöïc hieän vieäc Authentication vaøo luùc khôûi ñoäng, maø vaøo baát kyø luùc naøo trong suaát quaù trình keát noái. Khi hai maùy keát noái vôùi nhau, chuùng seõ khoâng thöïc hieän vieäc authentication neáu khoâng coù chæ ñònh. Neáu cô cheá authentication ñöôïc active, ñaàu tieân,moät maùy seõ söû duïng CHAP, neáu maùy kia khoâng hoã trôï CHAP, thì noù seõ söû duïng PAP. Neáu caû hai cô cheá ñeàu khoâng ñöôïc hoã trôï, vieäc keát noái seõ bò ñoùng laïi. Taát caû nhöõng thoâng tin caàn thieát cho PAP vaø CHAP ñöôïc ñaët trong hai file: /etc/ppp/cap-serects vaø /etc/ppp/ppp-serects. Khi authentication ñöôïc active, maùy A seõ kieåm tra maùy B thoâng qua caùc file naøy vaø söû dung CHAP tröôùc. Neáu chuùng ta söû duïng authentication cho moïi cuoäc keát noái, thí chuùng ta taïo ra caùc file chap-serects vaø pap-serects. Neáu chuùng ta ñaët caáu hình cho caû chap-serects vaø pap-serecs vaø xaùc ñònh option trong /etc/ppp/option thì khoâng maùy naøo maø khoâng coù authentication coù theå connect vaøo maùy mình. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 34 PHAÀÀN III HIEÄÄN THÖÏÏC CHÖÔNG TRÌNH SHAREMAIL DDDD CHÖÔNG I : CHÖÔNG TRÌNH POP3 CLIENT CHÖÔNG II : CHÖÔNG TRÌNH DELIVER CHÖÔNG III : CHÖÔNG TRÌNH SMTP CLIENT CHÖÔNG IV : CHÖÔNG TRÌNH SMTP SERVER. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 35 CHÖÔNG I: CHÖÔNG TRÌNH POP3 CLIENT. Pop3Client thöïc hieän keát noái vôùi Pop3Server töø xa söû duïng giao thöùc POP3 (Post Office Protocol version 3) cho pheùp user coù theå laáy thö cuûa mình naèm treân hoäp thö cuûa moät maùy server töø xa. Nhieäm vuï cuûa Pop3Client laø laáy Mail naèm trong Mailbox cuûa Server Mail veà hoäp mail: “/var/spool/sharedmail/inbox” trong heä thoáng. Do giao thöùc POP3 ñoøi hoûi phaûi coù username vaø password trong quaù trình Authorization ñeå login neân chuùng ta caàn phaûi coù username vaø password duøng ñeå login vaøo hoäp Mail cuûa chuùng ta naèm treân maùy Server. Username vaø password ñöôïc cung caáp bôûi nhaø cung caáp dòch vuï. Sau khi login vaøo Server Mail, chöông trình seõ laáy taát caû caùc Mail coù trong Mailbox cuûa Server ñem veà Inbox trong heä thoáng (ôû ñaây khoâng thöïc hieän quaù trình loïc mail). Chöông trình Pop3 Client coù theå thöïc hieän laïi keát noái trong tröôøng hôïp keát noái bò ngaét giöõa chöøng, noù seõ laáy böùc thö ñang laáy maø bò ngaét giöõa chöøng vaø caùc böùc thö keå töø ñoù trôû ñi, khoâng phaûi laáy laïi töø ñaàu khi keát noái ñöôïc thieát laäp trôû laïi. Ñieàu naøy raát laø coù ích vì khi keát noái laïi, neáu chuùng ta cöù laáy laïi töø ñaàu caùc böùc mail trong Mailbox cuûa Server thì raát toán thôøi gian vaø noù thaät söï khoâng caàn thieát vì ñaõ nhaän ñöôïc roài. I. GIÔÙÙI THIEÄÄU CAÁÁU TRUÙÙC POP3_SERVER: struct POP3_SERVER { char host[POP3_HOST_L]; /*teân hay IP address cuûa maùy Server*/ char logid[POP3_LOGID_L]; /*username duøng ñeå login vaøo heä thoáng*/ char logpass[POP3_LOGPASS_L]; /*password cuûa username*/ char mailbox[POP3_MAILBOX_L]; /*nôi duøng ñeå löu giöõ mail laáu töø server veà*/ } II. HOAÏÏT ÑOÄÄNG CUÛÛA CHÖÔNG TRÌNH POP3CLIENT: Chöông trình Pop3Client ñöôïc thöïc thi ñaàu tieân khi coù keát noái vôùi Server Mail cuûa nhaø cung caáp dòch vuï. Khi ñöôïc thöïc thi, ñaàu tieân, noù seõ goïi haøm read_cf(), laø haøm ñöôïc söû duïng ñeå laáy caùc thoâng tin nhö: teân maùy hoaëc ñòa chæ IP Server Mail cuûa nhaø cung caáp dòch vuï, ñaây chính laø Server gôûi Mail, LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 36 username vaø password duøng ñeå login vaøo Mailbox treân maùy Server nhaän Mail, hoäp thö Inbox treân maùy cuïc boä duøng ñeå löu giöõ caùc thö ñöôïc nhaän veà, soá laàn keát noái laïi neáu chöông trình ñang nhaän maø bò ngaét giöõa chöøng, vaø thôøi gian timeout trong tröôøng hôïp Server khoâng traû lôøi. Keá tieáp, chöông trình seõ khôûi taïo caùc signal duøng ñeå xöû lyù caùc bieán coá coù theå xaûy ra trong quaù trình nhaän Mail, ví duï: ñöôøng truyeàn bò ngaét, timeout,…. Neáu caùc bieán coá naøy xaûy ra thì quaù trình seõ goïi caùc haøm caøi ñaët saún ñi keøm vôùi bieán coá ñeå xöû lyù. Tieáp theo, chöông trình seõ thöïc hieän vieäc kieåm tra laïi xem username vaø password duøng ñeå login vaøo Mailbox cuûa Server Mail ñaõ coù trong caáu truùc POP3_SERVER chöa, neáu ñaõ coù thì chöông trình seõ duøng username vaø password naøy ñeå thöïc hieän quaù trình login vaøo Mailbox cuûa Server, neáu chöa coù thì seõ hieån thò yeâu caàu nhaäp vaøo username vaø password ñeå thöïc hieän quaù trình login. Sau ñoù, Pop3Client seõ môû moät socket ñeå thöïc hieän moät keát noái tôùi Server nhaän Mail, maø teân hoaëc ñòa chæ IP cuûa computer maø chöông trình Pop3Server ñang chaïy ñöôïc löu giöõ trong tröôøng host cuûa caáu truùc POP3_SERVER. Neáu laø teân, chöông trình seõ thöïc hieän vieäc chuyeån ñoåi sang ñòa chæ IP ñeå thöïc hieän keát noái. Neáu keát noái thöïc hieän thaønh coâng, Pop3 Client seõ nhaän ñöôïc moät lôøi chaøo ñöôïc gôûi tôùi bôûi Pop3 Server vaø session seõ böôùc vaøo quaù trình AUTHORIZATION. Luùc naøy, Pop3Client seõ gôûi username vaø password tôùi cho Pop3Server kieåm tra. Neáu quaù trình AUTHORIZATION thöïc hieän thaønh coâng, session seõ böôùc vaøo quaù trình TRANSACTION, neáu khoâng thaønh coâng, Pop3Server seõ gôûi thoâng baùo loãi laïi cho Pop3Client. Luùc naøy, Pop3Client coù theå thöïc hieän vieäc ñaêng nhaäp laïi vôùi username vaø password khaùc hoaëc coù theå gôûi leänh “QUIT” ñeå thoaùt. Döôùi ñaây laø ñoaïn code thöïc hieän quaù trình login, haøm AskAnswer coù nhieäm vuï gôûi noäi dung cuûa boä ñeäm buf qua socket tôùi Server vaø nhaän keát quaû traû veà töø Server. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 37 /*gôûi leänh USER username tôùi Server*/ sprintf(buf, "USER %s", host->logid); if (AskAnswer(sfp, qsocket, buf, SVRBUFSIZ) != OK) return LOOKERRNO; if (buf[0] != '+') return LOGIN_FAIL; /* gôûi leänh PASS password tôùi Server */ sprintf(buf, "PASS %s", host->logpass); if (AskAnswer(sfp, qsocket, buf, SVRBUFSIZ) != OK) return LOOKERRNO; if (buf[0] != '+') return LOGIN_FAIL; Böôùc vaøo quaù trình TRANSATION, ñaàu tieân Pop3 Client seõ gôûi leänh “STAT” tôùi server ñeå kieåm tra xem coù mail trong mailbox hay khoâng. Neáu coù, server seõ traû veà toång soá thö hieän coù trong mailbox vaø kích thöôùc cuûa mailbox. Tieáp ñoù, Pop3Client seõ gôûi leänh “LIST” ñeå laáy kích thöôùc cuûa töøng message. Sau khi coù ñöôïc toång soá message coù trong mailbox, Pop3 Client seõ böôùc vaøo voøng laëp duøng ñeå nhaän mail, vôùi moãi böôùc cuûa voøng laëp seõ thöïc hieän moät leänh “RETR” vôùi soá thöù töï töông öùng vôùi chæ soá cuûa voøng laëp duøng ñeå nhaän message töông öùng. for ( i = 1; i <= num; i++) { sprintf(buf, “RETR %d”, i); if (AskAnswer(sfp, socket, buf, SVRBUFSIZ) != OK) return MISSOCKET; if (*buf != ‘+’) break; while ((cur = readline(sfp, buf, SVRBUFSIZ)) > 0) { if (!strcmp(buf, ".\n")) break; if (*buf == '.') fputs(buf+1, mboxfp); else fputs(buf, mboxfp); } fputs("\n", mboxfp); fflush(mboxfp); /*sau khi nhaän xong message, gôûi leänh DELE i, vôùi i laø chæ soá cuûa message ñeå baùo cho Server bieát böùc Mail naøy ñaõ ñöôïc nhaän roài, caàn phaûi xoùa boû noù.*/ sprintf(buf, "DELE %d", i); if (AskAnswer(sfp, qsocket, buf, SVRBUFSIZ) != OK) return MISSOCKET; return OK; } LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 38 Sau khi nhaän xong message, Pop3Client seõ gôûi leänh “DELE i” tôùi server ñeå xoùa message naøy. Sau khi laáy heát caùc message coù trong mailbox cuûa server, Pop3Client seõ gôûi leänh “QUIT” tôùi server ñeå yeâu caàu server chuyeån Pop session sang traïng thaùi Update vaø thoaùt. Ñoái vôùi Server, khi böôùc vaøo traïng thaùi UPDATE, noù seõ xoùa thaät söï caùc message ñaõ ñöôïc ñaùnh daáu xoùa trong Mailbox vaøo ñoùng keát noái. Neáu moät keát noái ñaõ ñoùng laïi maø Server khoâng böôùc vaøo traïng thaùi UPDATE thì caùc message ñöôïc ñaùnh daáu xoùa seõ khoâng ñöôïc xoùa trong Mailbox maø noù seõ trôû laïi traïng thaùi ban ñaàu. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 39 Yes Yes Yes Taïo socket Connect server taïi port 110 Gôûi leänh USER username \r\n Response = +OK Gôûi leänh PASS password \r\n Response = +OK Gôûi leänh STAT \r\n Response = +OK 1 Baùo loãi Ñoùng Socket No No No No LÖU ÑOÀ CHO GETMAIL LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 40 LÖU ÑOÀ CHO GETMAIL (Continue) No 1 Xöû lyù haøng nhaän ñöôïc laáy toång soá sessage Gaùn i=1 Gôûi leänh RETR i Ñoïc töøng vaøo töøng doøng töø socket vaø ghi File cho ñeán khi keát thuùc böùc mail. incr i i <= soá msg Gôûi leänh QUIT Ñoùng Socket Yes LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 41 CHÖÔNG II: CHÖÔNG TRÌNH DELIVER Chöông trình Deliver thöïc hieän vieäc phaân phoái Mail tôùi ñuùng caùc ngöôøi nhaän ôû trong heä thoáng cuïc boä cuûa chuùng ta. Chöông trình seõ döïa vaøo phaàn fullname ñeå tìm ra ngöôøi nhaän thöïc söï cuûa böùc Mail vaø gôûi böùc Mail vaøo Mailbox cuûa ngöôøi nhaän. I. CAÙÙC CAÁÁU TRUÙÙC DUØØNG ÑEÅÅ LÖU GIÖÕÕ ÑÒA CHÆ NGÖÔØØI NHAÄÄN VAØØ THOÂÂNG TIN CUÛÛA BÖÙÙC MAIL: struct DLVTO { char *host; /*address cuûa ngöôøi nhaän*/ struct DLVTO *next; }; Caáu truùc DLVTO duøng ñeå löu giöõ caùc ñòa chæ ngöôøi nhaän trong moät böùc mail. Tröôøng host coù theå chöùa phaàn ñòa chæ naèm trong caùc tröôøng “To:”, hoaëc “Cc:” cuûa böùc mail. struct SENDTO { int id; /*soá thöù töï cuûa böùc mail*/ char *from; /*ñòa chæ cuûa ngöôøi gôûi böùc mail*/ struct DLVTO *to; /*danh saùch ñòa chæ ngöôøi nhaän*/ long mleng; /*kích thöôùc cuûa böùc mail*/ long msgseek; /*khoaûng caùch cuûa böùc mail so vôùi ñaàu mail box*/ char *havemail; /*kieåm tra xem mail ñaõ ñöôïc nhaän hay chöa*/ struct SENDTO *next; }; LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 42 Caáu truùc SENDTO duøng ñeå löu giöõ caùc thoâng tin cuûa böùc mail caàn phaûi coù trong quaù trình phaân tích ñeå tìm ra ngöôøi nhaän thöïc söï trong heä thoáng cuûa chuùng ta. II. HOAÏÏT ÑOÄÄNG CUÛÛA CHÖÔNG TRÌNH DELIVER: Chöông trình Deliver seõ ñöôïc thöïc thi sau khi quaù trình gôûi caùc böùc Mail trong hoäp Mail: “/var/spool/sharedmail/outbox” keát thuùc, töùc laø sau khi chöông trình Smtp Client thöïc hieän xong. Khi thöïc thi, vieäc ñaàu tieân laø noù seõ goïi haøm read_cf() ñeå laáy caùc thoâng tin caàn thieát töø file caáu hình “Deliver.conf”. Caùc thoâng tin naøy bao goàm: thoâng tin veà hoäp thö chöùa caùc mail caàn phaân phoái, nôi löu tröõ thö cuûa caùc user, user admin. Tieáp ñeán, Deliver seõ goïi haøm OpenFolder() ñeå laáy toång soá mail coù trong hoäp thö caàn phaân phoái. Neáu khoâng coù mail caàn phaân phoái hoaëc coù loãi trong quaù trình môû hoäp thö thì seõ thoaùt khoûi chöông trình. Sau ñoù, Deliver seõ goïi haøm Delivery(int mails) ñeå phaân phoái caùc mail naøy tôùi töøng user trong heä thoáng. Trong quaù trình phaân phoái, neáu khoâng tìm ra ngöôøi nhaän cuûa moät böùc mail hoaëc böùc mail bò gôûi sai ñòa chæ thì caùc böùc mail naøy seõ ñöôïc gôûi tôùi user admin. Neáu xaûy ra loãi trong quaù trình phaân phoái thì Deliver seõ goïi haøm goïi haøm CloserFolder() ñeå giaûi phoùng caùc taøi nguyeân caáp phaùt tröôùc ñoù vaø thoaùt. Cuoái cuøng, sau khi phaân phoái caùc mail tôùi töøng ngöôøi nhaän thaønh coâng, Deliver seõ goïi haøm CloserFolder() ñeå giaûi phoùng caùc taøi nguyeân caáp phaùt tröôùc ñoù vaø thoaùt. 1. HAØØM OPENFOLDER(): Haøm OpenFolder() thöïc hieän moät loaït caùc taùc vuï, ñoù laø taïo ra moät file taïm duøng ñeå chöùa caùc mail ñöôïc ñoïc töø hoäp thö ñeå duøng cho quaù trình Deliver. Ñoàng thôøi taïo ra danh saùch ngöôøi nhaän *p cuûa böùc mail naøy. Trong ñoù, ñòa chæ ngöôøi nhaän ñöôïc xöû lyù sao cho coá gaéng ñöa ñöôïc veà daïng môû roäng cuûa mình. Khi ñöôïc goïi thöïc thi, ñaàu tieân, haøm OpenFolder() seõ taïo ra moät file taïm duøng ñeå chöùa caùc böùc Mail ñoïc ñöôïc töø outbox. Keá tieáp, noù seõ ñoïc laàn löôït caùc böùc mail trong hoäp thö caàn phaân phoái, moãi laàn ñoïc vaøo moät haøng cuûa böùc mail, vaø xöû lyù. · Neáu haøng ñoïc vaøo thuoäc phaàn header, noù seõ kieåm tra xem: + Neáu haøng baét ñaàu baèng “From: …” thì thoâng tin theo sau seõ ñöôïc löu vaøo p->from. + Neáu haøng baét ñaàu baèng “To:…” hoaëc baèng “Cc:…”, ñaây laø caùc haøng chöùa thoâng tin ñòa chæ cuûa ngöôøi nhaän. Caùc ngöôøi nhaän seõ ñöôïc taùch ra vaø löu vaøo p->to. + Ñoàng thôøi vôùi vieäc xöû lyù naøy laø ghi laïi caùc thoâng tin naøy vaøo file taïm. p = stInsert((struct SENDTO**) &send); if (p == NULL) goto tmperr; p->id = ++mails; /*soá thöù töï cuûa böùc Mail*/ LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 43 fputs(buf, fld); p->msgseek = ftell(fld); p->havemail = (char *)malloc(2*SVRBUFSIZ*sizeof(char)); strcpy(p->havemail,""); while (fgets(buf, SVRBUFSIZ, fp) != NULL) { if (!isheader(buf)) break; else if (ismailfrom(buf)) hf = S_FROM; else if (ismailto(buf) || ismailcc(buf)) hf = S_TO; else if (ismailbcc(buf)) hf = S_BCC; else if (*buf > ' ') hf = S_COMMON; switch (hf) { /*save sender addr, write to top header: from*/ case S_FROM: if (p->from == NULL) { p->from = (char*) malloc(strlen(buf)); if (p->from == NULL) goto tmperr; strcpy(p->from, &buf[5]); chop(p->from); } break; case S_TO: case S_BCC: { strcpy(addr_add, buf); make_addr(addr_add, mailbox); while (i = pos("\"", addr_add)) addr_add = delete(addr_add, i, 1); if (AddToAddr(p, addr_add)) goto tmperr; break; } } fflush(fld); · Neáu khoâng phaûi laø phaàn header thì ñaây chính laø phaàn data cuûa böùc mail, thöïc hieän ghi luoân leân file taïm. do { if (ismailstart(buf)) break; fputs(buf, fld); LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 44 } while (fgets(buf, SVRBUFSIZ, fp) != NULL); fputs("\n", fld); Neáu khoâng coù loãi xaûy ra thì haøm seõ traû laïi toång soá böùc mail coù trong hoäp thö caàn phaân phaùt, coøn ngöôïc laïi seõ traû veà maõ loãi. 2. HAØØM DELIVERY(): Nhieäm vuï chính cuûa haøm Delivery() laø phaân phoái caùc message tôùi töøng mailbox cuûa caùc user trong heä thoáng döïa vaøo phaàn ñòa chæ môû roäng cuûa mail. Khi baét ñaàu thöïc thi, noù seõ böôùc ngay vaøo voøng laëp for vôùi p = send chæ tôùi phaàn thoâng tin löu giöõ trong caáu truùc SENDTO cuûa böùc mail ñaàu tieân. for (p = send; p != NULL; p = p->next) { /*Thaân voøng for*/ } Delivery() seõ thöïc hieän kieåm tra xem coù ñòa chæ cuûa ngöôøi nhaän trong tröôøng “to” cuûa caáu truùc SENDTO, vaø trong tröôøng “to” naøy coù ngöôøi naøo hay khoâng, neáu khoâng coù, noù seõ thoâng baùo loãi vaø seõ chuyeån sang message keá tieáp. for (p = send; p != NULL; p = p->next) { if ((p->to == NULL) || (p->to->host == NULL)) { printf("no destinative address. abort mail %d#\n", p->id); continue; } /*caùc phaàn xöû lyù keá tieáp*/ } Sau khi kieåm tra ñaõ coù phaàn ñòa chæ cuûa ngöôøi nhaän, Delivery() seõ böôùc vaøo voøng for thöù hai loàng trong voøng for ñaàu vôùi r = p->to chæ tôùi ñòa chæ cuûa ngöôøi ñaàu tieân trong danh saùch ñòa chæ ñöôïc löu giöõ trong caáu truùc DLVTO. for (r = p->to; r != NULL; r = r->next) { /*thaân voøng for*/ } Tieáp theo, Delivery() seõ kieåm tra xem phaàn ñòa chæ thöïc söï cuûa böùc mail (phaân bieät vôùi ñòa chæ môû roäng) coù ñuùng laø ñòa chæ email internet cuûa mình khoâng. Neáu khoâng ñuùng thì böùc mail nay ñaõ ñöôïc gôûi sai ñòa chæ vaø noù seõ ñöôïc chuyeån cho admin. Neáu böùc mail naøy ñaõ gôûi ñuùng ñòa chæ cuûa chuùng ta, nhöng noù khoâng coù phaàn ñòa chæ môû roäng, ñaây laø moät böùc mail khoâng hôïp leä, vaø chuùng ta cuõng seõ chuyeån noù tôùi cho admin. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 45 Neáu coù phaàn môû roäng, chuùng ta seõ laáy phaàn môû roäng naøy vaø thöïc hieän vieäc tìm kieám trong file “/etc/passwd” ñeå laáy ra user öùng vôùi teân môû roäng naøy, neáu tìm trong file “/etc/passwd” khoâng coù, chuùng ta seõ tìm tieáp trong file “/etc/mapping”, laø moät file aùnh xaï töø teân môû roäng thaønh teân cuûa user trong heä thoáng, maø ñöôïc thöïc hieän bôûi ngöôøi quaûn trò. Neáu khoâng tìm thaáy user trong file naøy, coù nghóa laø user naøy khoâng coù trong heä thoáng. Do ñoù, ñòa chæ cuûa böùc mail naøy cuõng khoâng hôïp leä, vaø böùc mail naøy seõ ñöôïc chuyeån cho admin ñeå xöû lyù. Neáu tìm thaáy user trong heä thoáng thì böùc mail naøy seõ ñöôïc chuyeån tôùi mailbox cuûa user naøy. for (r = p->to; r != NULL; r = r->next) { tmp = emailaddr(r->host); /* kieåm tra domain cuûa böùc mail */ if (strcmp(tmp, mailbox/*MYDOMAIN*/)) tmp = admin; /* kieåm tra phaàn ñòa chæ môû roäng */ else if ((tmp = extendaddr(r->host)) == NULL) tmp = admin; /* kieåm tra coù user trong heä thoáng khoâng */ else if ((tmp = scanpasswd(tmp)) == NULL) tmp = admin; /* kieåm tra xem user ñaõ nhaän böùc mail naøy chöa */ if (strstr(p->havemail, tmp)) continue; /* ñaùnh daáu laø user ñaõ nhaän böùc mail naøy roài */ strcat(p->havemail, tmp); strcpy(pathname, inbox); strcat(pathname, tmp); /* lock file laïi, sau ñoù môùi ghi leân file */ dest_fi=open(pathname, O_CREAT | O_APPEND | O_RDWR); if (!(dest_fi > 0)) return 0; lock_file = flock(dest_fi, LOCK_EX); if (lock_file < 0) { close(dest_fi); return; } f = fdopen(dest_fi, "a+t"); if (f == NULL) { close(dest_fi); return; } /* taïo laïi phaàn header bò maát */ fprintf(f,"%s %s %s\n","From",emailaddr(p->from), timenow()); fseek(fld, p->msgseek, SEEK_SET); while (fgets(tmp1, SVRBUFSIZ - 1, fld) != NULL) LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 46 { if (ismailstart(tmp1)) break; fputs(tmp1, f); } flock(dest_fi, LOCK_UN); fclose(f); close(dest_fi); } Quaù trình naøy seõ ñöôïc laëp laïi cho ñeán khi khoâng coøn ngöôøi nhaän trong caáu truùc DLVTO, töùc laø r == NULL. Vaø luùc naøy, noù seõ chuyeån sang böùc mail keá tieáp ñeå xöû lyù. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 47 No Yes No No Yes No Yes No Yes Yes Yes No No Môû Inbox ? Ñoïc töøng doøng moät böùc Mail töø Inbox leân. Taïo ra file taïm ? Tröôøng “From” Tröôøng “To” Tröôøng “Cc” Thoâng baùo loãi töông öùng vaø thoaùt Ghi vaøo tröôøng From cuûa caáu truùc SENTO vaø ghi vaøo file taïm Ghi vaøo file taïm. Xöû lyù roài ghi vaøo danh saùch ngöôøi nhaän cuûa caáu truùc SENTO Data cuûa böùc Mail Yes Ghi vaøo file taïm. Coøn Mail trong Mailbox ? Ñoùng outbox vaø thoaùt. Löu ñoà ñoïc Mail LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 48 No No No No Yes Yes Yes Yes Ñoïc danh saùch ngöôøi nhaän vaø laáy ra ngöôøi ñaàu tieân Xöû lyù phaàn ñòa chæ môû roäng Coù ñòa chæ môû roäng ? Laø user trong heä thoáng ? Chuyeån thö tôùi ngöôøi nhaän töông öùng Môû hoäp mail cuûa user vaø lock laïi Heát ngöôøi nhaän? Thoaùt khoûi chöông trình Chuyeån thö tôùi admin Löu ñoà phaân phoái Mail LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 49 CHÖÔNG III: CHÖÔNG TRÌNH SMTPCLIENT I. CAÙÙC CAÁÁU TRUÙÙC DÖÕÕ LIEÄÄU DUØØNG TRONG MODULE SMTP CLIENT: struct DLVTO { char *host; struct DLVTO *next; }; struct SENTO { int id ; /*chæ soá id cuûa thö*/ char *from ; /*mail from*/ struct DLVTO *to ; /*send to*/ long mleng ; /*chieàu daøi cuûa noäi dung thö*/ long msgseek; /*vò trí cuûa thö coù chæ soá laø id trong file*/ }; LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 50 II. SÔ ÑOÀÀ KHOÁÁI: 1. SÔ ÑOÀÀ TOÅÅNG QUAÙÙT: Yes Deliver mail vaø taïo back up neáu coù yeâu caàu Ñoùng keát noái Môû vaø ñoïc file outbox Coù thö caàn gôûi? Taïo socket keát noái tôùi server Thoaùt vaø baùo loãi töông öùng No END BEGIN LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 51 2. SÔ ÑOÀÀ KHOÁÁI CHO KHOÁÁI MÔÛÛ VAØØ ÑOÏÏC FILE: Yes Môû file outbox ñeå ñoïc vaø xoùa. Taïo ra danh saùch ngöôøi nhaän ñoái vôùi mail naøy. Coù tröôøng Bcc? End of file? Thoaùt vaø ñoùng file Yes No No Taïo danh saùch send, ñoïc töø outbox va ghi vaøo file taïm BEGIN END LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 52 3. SÔ ÑOÀÀ KHOÁÁI CHO KHOÁÁI DELIVER: Yes Baùo Loãi vaø gôûi QUIT Yes No P = send ; P != NULL? Gôûi leänh HELO Reply == 250? Gôûi MAIL FROM: Reply == 250? No Yes No 2 BEGIN Baùo Loãi vaø Thoaùt R = p -> to ; LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 53 No Yes R != NULL? Gôûi RCPT TO:<ñòa chæ töøng ngöôøi nhaän> Reply == 250? Gôûi DATA vaø mail data Reply ==354? Gôûi QUIT, thoâng baùo thaønh coâng 2 Yes No Th oa ùt v aø ba ùo lo ãi Th oa ùt v aø ba ùo lo ãi END LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 54 III. HOAÏÏT ÑOÄÄNG CUÛÛA MODULE SMTP CLIENT: Khi chöông trình ñöôïc kích hoaït, haøm OpenFolder() ñöôïc goïi ñaåu tieân. Haøm naøy coù nhieäm vuï môû file outbox – file chöùa caùc thö caàn göûi ra ngoaøi – ñeå kieåm tra xem coù thö caàn göûi khoâng? Neáu coù noù seõ laøm caùc coâng vieäc sau: - Tìm ra vò trí ñaàu tieân cuûa mail trong file outbox ñeå laáy ra phaàn thoâng tin header cuûa mail, sau ñoù taïo ra danh saùch send maø moãi phaàn töû coù kieåu caáu truùc döõ lieäu laø SENDTO. - Kieåm tra xem trong thö coù tröôøng BCC khoâng? Neáu coù thì taïo ra danh saùch nhöõng ngöôøi nhaän seõ nhaän cuøng moät noäi dung mail naøy maø moãi phaàn töû cuûa danh saùch coù kieåu döõ lieäu laø DLVTO. - Neáu trong file sntpclient.conf coù chöùa phaàn header caàn cheøn vaøo thì cheøn vaøo file ñeå gôûi ñi. Sau khi haøm OpenFolder thöïc hieän song, chuùng ta coù ñöôïc moät danh saùch caùc laù thö caàn göûi ñoàng thôøi öùng vôùi moãi laù thö neáu coù tröôøng BCC thì chuùng ta laïi coù theâm moät danh saùch ngöôøi nhaän ñoái vôùi thö töông öùng naøy. Tieáp theo phaûi taïo ra caàu noái TCP tôùi server ñeå trao ñoåi thoâng tin. Khi taïo caàu noái thaønh coâng, haøm dilevery ñöôïc goïi. Haøm delivery hoaït ñoäng nhö sau: - Ñaàu tieân göûi ñi leänh HELO, neáu nhaän ñöôïc traû lôøi 250 thì chöông trình böôùc vaøo voøng for ñeå duyeät danh saùch caùc thö caàn göûi. for (p=send,p!=NULL,p=p->next) { göûi leänh MAIL FROM; /* duyeät danh saùch ngöôøi nhaän ñoái vôùi laù thö naøy*/ for ( r=p->to;p!=NULL;r=r->next) { göûi caùc leänh RCPT TO; } göûi leänh DATA vaø noäi dung thöïc söï cuûa mail, keát thuùc baèng daáu chaám “.”. } - Göûi leänh QUIT keát thuùc trao ñoåi. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 55 CHÖÔNG IV: CHÖÔNG TRÌNH SMTPD I. GIÔÙÙI THIEÄÄU: Chöông trình SMTPD laø moät chöông trình mail server. Noù hieän thöïc giao thöùc SMTP (Simple Mail Transfer Protocol) ñöôïc moâ taû trong RFC 821. ÔÛ ñaây, chuùng em chæ hieän thöïc moät phaàn cuûa giao thöùc naøy ñeå thöïc hieän yeâu caàu cuûa ñeà taøi. SMTPD seõ chaïy treân maùy tính ñöôïc chæ ñònh laøm server cuûa heä thoáng. Ñaây cuõng chính laø maùy keát noái tröïc tieáp vôùi Internet. Khi thöïc thi, noù seõ laéng nghe treân TCP port 25, nhaän caùc böùc mail töø caùc maùy client vaø gôûi tôùi caùc ñòa chæ ñaõ ñöôïc chæ ñònh trong böùc mail naøy. ÔÛ ñaây, chöông trình seõ phaân bieät: - Neáu böùc mail naøy ñöôc gôûi cho caùc user ôû trong heä thoáng, töùc laø ñòa chæ ngöôøi nhaän cuûa böùc mail naøy laø ñòa chæ cuïc boä, thì böùc mail naøy seõ ñöôïc chuyeån tröïc tieáp tôùi mailbox cuûa ngöôøi nhaän. - Neáu böùc mail naøy ñöôïc gôûi cho caùc user ôû beân ngoaøi heä thoáng, töùc laø ñòa chæ ngöôøi nhaän cuûa böùc mail khoâng phaûi laø ñòa chæ cuïc boä cuûa heä thoáng, thì böùc mail naøy seõ ñöôïc chuyeån ñeán hoäp thö outbox “/var/spool/sharedmail/outbox”. Ñaây laø hoäp thö duøng ñeå chöùa caùc böùc mail gôûi ra beân ngoaøi cuûa heä thoáng. Do heä thoáng cuûa chuùng ta khoâng keát noái vôùi Internet lieân tuïc neân khi coù yeâu caàu keát noái thì seõ coù moät chöông trình SMTP-Client thöïc hieän nhieäm vuï keát noái vôùi Server Mail cuûa nhaø dòch vuï cung caáp dòch vuï mail vaø nhôø chöông trình Server naøy gôûi caùc böùc mail naøy tôùi caùc ñòa chæ cuûa ngöôøi nhaän. Nhö vaäy, chöông trình SMTPD ôû ñaây phaûi phaân bieät ñöôïc ñòa chæ ngöôøi nhaän laø cuïc boä vaø ñòa chæ ngöôøi nhaän beân ngoaøi. Ñieàu naøy coù phaàn quan troïng trong böùc moät böùc mail, tröôøng “Return-path” löu giöõ ñòa chæ ngöôøi gôûi, ñòa chæ löu giöõ trong tröôøng naøy seõ ñöôïc söû duïng trong tröôøng hôïp ngöôøi nhaän ñöôïc mail muoán hoài ñaùp laïi vôùi ngöôøi gôûi hoaëc böùc mail khoâng theå ñeán ñöôïc ngöôøi nhaän do sai ñòa chæ hoaëc do moät lyù do naøo ñoù thì caùc chöông trình mail server seõ döïa vaøo ñòa chæ naøy ñeå gôûi traû laïi böùc mail cho ngöôøi gôûi. Do ñoù, neáu laø ngöôøi nhaän cuïc boä thì vieäc gôûi ñôn giaûn chæ laø ñöa böùc mail vaøo mailbox cuûa ngöôøi nhaän vaø tröôøng “Return-path” ñôn giaûn chæ chöùa ñòa chæ cuûa ngöôøi gôûi trong cuïc boä. Trong tröôøng hôïp böùc mail ñöôïc gôûi ra beân ngoaøi, töùc laø ngöôøi nhaän khoâng naèm trong heä thoáng. Luùc naøy, do heä thoáng mail cuûa chuùng ta laø duøng chung moät account Internet mail, neân beân ngoaøi chæ bieát ñöôïc chuùng ta döïa treân ñòa chæ mail naøy, ñieàu naøy coù nghóa laø coù theå beân trong heä thoáng cuûa chuùng ta LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 56 coù nhieàu users, account mail cuïc boä cuûa cac users naøy coù theå khaùc nhau. Nhöng khi caùc users naøy gôûi mail ra beân ngoaøi thì beân ngoaøi chæ nhìn thaáy ñöôïc hoï döôùi moät ñòa chæ duy nhaát, ñoù laø ñòa chæ mail ñaõ ñöôïc ñaêng kyù vôùi nhaø dòch vuï. Do ñoù, ñeå phaân bieät ñöôïc ai laø ngöôøi gôûi böùc mail ñeå ñöa vaøo tröôøng “Return- path”, chuùng ta ñaõ giaûi quyeát baèng caùch ñöa theâm vaøo tröôùc ñòa chæ mail ñaõ ñaêng kyù vôùi nhaø dòch vuï moät phaàn ñòa chæ môû roäng, ñoù chính laø phaàn teân ñaày ñuû cuûa user trong heä thoáng cuûa chuùng ta. Do ñoù, phaàn ñòa chæ mail trong tröôøng “Return-path” khi gôûi ra ngoaøi seõ coù daïng: fullname_of_user . Ñeå coù theå laøm ñöôïc ñieàu naøy, chöông trình SMTPD ñaõ thöïc hieän chuyeån ñoåi töø: username laø teân login cuûa user trong heä thoáng cuûa chuùng ta thaønh fullname cuûa user naøy. Quaù trình chuyeån ñoåi naøy döïa treân file: “/etc/passwd”, ñaây laø file chöùa caùc thoâng tin veà user cuûa heä thoáng. Trong file “/etc/passwd”, thoâng tin cuûa moãi user ñöôïc löu giöõ treân moät haøng, bao goàm nhieàu tröôøng, moãi tröôøng caùch nhau baèng daáu “:”. Daïng format cuûa moät haøng trong file “/etc/passwd” laø: login-name:encrypted-password:user-ID:group- ID:miscellany:login-directory:shell. Sau khi chuyeån ñoåi xong, phaàn môû roäng cuûa user seõ ñöôïc keát hôïp vôùi ñòa chæ mail ñöôïc caáp bôûi nhaø cung caáp dòch vuï ñeå ñöa vaøo tröôøng “Return-path”. II. CAÙÙC CAÁÁU TRUÙÙC CUÛÛA SMTPD: 1. CAÁÁU TRUÙÙC LÖU GIÖÕÕ TRAÏÏNG THAÙÙI: typedef fd_set smtp_state_set; typedef fd_set *smtp_state; Hai caáu truùc naøy duøng ñeå löu giöõ traïng thaùi cuûa SMTPD trong quaù trình nhaän caùc yeâu caàu töø client. Caùc traïng thaùi seõ ñöôïc thieát laäp khi nhaän ñöôïc leänh: “HELO” hoaëc “EHLO”, “MAIL FROM:”, “RCPT TO:”, “DATA” töø client, theo thöù töï. Trong tröôøng hôïp caùc leänh nhaän ñöôïc khoâng naèm trong caùc leänh treân thì chöông trình seõ thöïc hieän caùc leänh naøy vaø traïng thaùi seõ khoâng ñöôïc thieát laäp. Neáu caùc leänh nhaän ñöôïc laø caùc leänh treân, nhöng khoâng theo ñuùng thöù töï thì moät thoâng baùo loãi seõ ñöôïc traû laïi cho client. 2. CAÁÁU TRUÙÙC LÖU GIÖÕÕ THOÂÂNG TIN: typedef struct smtp_info { FILE *ifile; /*input socket*/ int ofile; /*output socket*/ char myhostname[MAXHOSTNAMELEN + 1]; /*computer run this program*/ char myaddr[15]; LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 57 /*address of this computer*/ char clientname[MAXHOSTNAMELEN + 1]; /*name of client*/ char clientaddr[15]; /*address of this client*/ unsigned short port; char sender[256]; /*user send this mail*/ char receiver[MAX_USER][256]; /*list of local reciever*/ int num_recv; /*number of local receiver*/ char userfar[MAX_USER][256]; /*list of non_local receiver*/ int num_userfar; /*number of non_local receiver*/ }smtp_info; 3. CAÙÙCH HOAÏÏT ÑOÄÄNG CUÛÛA CHÖÔNG TRÌNH SMTPD: Khi chöông trình SMTPD thöïc thi, ñaàu tieân, noù seõ khôûi taïo moät khoái smtp_info baèng caùch goïi haøm: smtp = (smtp_info *)malloc(sizeof (smtp_info)); Sau khi khôûi taïo khoái smtp_info xong, tieáp ñeán, noù löu laïi teân maùy vaø ñòa chæ IP maø chöông trình SMTPD ñang chaïy vaøo trong bieán smtp- >myhostname vaø smtp->myaddr. Sau khi hoaøn thaønh xong taùc vuï naøy, SMTPD seõ khôûi taïo socket vaø chôø yeâu caàu keát noái töø maùy client. Neáu coù yeâu caàu keát noái töø client, noù seõ löu laïi ñòa chæ IP cuûa maùy client trong smtp->clientaddr vaø thöïc hieän vieäc tìm kieám teân maùy client baèng gethostbyaddr(), neáu coù, seõ löu laïi teân maùy trong smtp->clientname. Sau ñoù, SMTPD seõ taïo ra hai stream duøng cho vieäc trao ñoåi döõ lieäu vôùi moät ñaàu vaøo ñöôïc löu giöõ bôûi smtp->ifile (vôùi FILE *smtp->ifile) vaø ñaàu ra ñöôïc löu giöõ bôûi smtp->ofile (vôùi int smtp->ofile), keát hôïp vôùi socket ôû treân. Sau khi keát noái thaønh coâng, SMTPD seõ gôûi laïi cho client thoâng baùo: 220 smtp->myhostname Simple Mail Transfer Service Ready. Sau ñoù, noù seõ baét ñaàu vaøo voøng laëp chôø nhaän caùc yeâu caàu töø client gôûi ñeán vaø thöïc hieän noù. while (1) { readlh(smtp->ifile, inbuf, SIZBUF); memcpy(last_state, current_state, sizeof(smtp_state_set)); chop(inbuf); smtp_parse_cmd(inbuf, current_state); ... } LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 58 Khi coù yeâu caàu töø phía client gôûi qua, SMTPD seõ löu giöõ noù vaøo bieán inbuf, sau ñoù noù seõ goïi haøm smtp_parse_cmd(inbuf, current_state) ñeå phaân tích yeâu caàu naøy vaø xöû lyù noù. Nhö chuùng ta bieát, caùc leänh cuûa giao thöùc SMTP (Simple Mail Transfer Protocol) thöôøng coù ñoä daøi laø 4 kyù töï. Do ñoù, khi ñöôïc goïi leân thöïc thi, haøm smtp_parse_cmd() seõ laáy 4 kyù töï ñaàu tieân cuûa inbuf ñeå kieåm tra xem ñoù laø leänh gì ñeå thöïc hieän theo yeâu caàu cuûa client. Trong tröôøng hôïp leänh bò sai hoaëc SMTPD khoâng hoå trôï leänh naøy thì noù seõ thoâng baùo laïi cho client bieát ñeå xöû lyù. Khi client gôûi leänh “helo” SMTPD seõ traû veà cho client chuoåi: “250 smtp->myhostname Hello smtp->clientname [ smtp->clientaddr ], please to meet you.” Ñeå baùo cho client bieát phieân thöïc hieän vöøa roài laø thaønh coâng, yeâu caàu client gôûi leänh tieáp theo theo trình töï cuûa nghi thöùc. Phaàn code moâ taû quaù trình thöïc hieän nhieäm vuï naøy: if ((strcasecmp(verb, "HELO") == 0) || (cmd_ok(EHLO, state) && (strcasecmp(verb, "EHLO") == 0))) { /*kieåm tra xem leänh “helo” ñaõ ñöôïc gôûi hay chöa */ if (!cmd_ok(HELO, state)) { sprintf(outbuf, "503 Duplicate HELO/EHLO\n"); writeline(smtp->ofile, outbuf); state_change(state, HELO, FAILURE); return; } SPANBLANK(buf); /*kieåm tra xem coù phaàn döõ lieäu ñi theo sau leänh helo hay khoâng*/ if (*buf == '\0') { sprintf(outbuf, "501 %s requires domain address\n",verb); writeline(smtp->ofile, outbuf); state_change(state, HELO, FAILURE); return; } sendinghost = strdup(buf); if (sendinghost == NULL) exit(-1); if (!strcasecmp(verb, "HELO")) { sprintf(outbuf, "250 %s Hello %s [%s], pleased to meet you\n", smtp->myhostname, smtp->clientname, smtp->clientaddr); writeline(smtp->ofile, outbuf); LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 59 } else { sprintf(outbuf, "250-%s Hello %s [%s], pleased to meet you\n", smtp->myhostname, smtp->clientname, smtp->clientaddr); writeline(smtp->ofile, outbuf); } state_change(state, HELO, SUCCESS); } Khi client gôûi tieáp leänh “mail from: sender@domain “, thoâng soá sender@domain seõ ñöôïc duøng laøm “Return-path” cuûa böùc mail trong tröôøng hôïp ngöôøi nhaän thuoäc heä thoáng cuûa chuùng ta. Neáu ngöôøi nhaän khoâng thuoäc heä thoáng (böùc mail gôûi ra beân ngoaøi thì chöông trình seõ thöïc hieän vieäc aùnh xaï töø sender@domain thaønh fullname_of_sender ñeå laøm “Return- path” cho böùc mail, vôùi fullname_of_sender laø teân ñaày ñuû cuûa user trong heä thoáng cuûa chuùng ta, vaø mail_address laø ñòa chæ mail do nhaø cung caáp dòch vuï mail caáp cho chuùng ta. Neáu thöïc hieän leänh naøy thaønh coâng, SMTPD seõ gôûi laïi cho client thoâng baùo: “250 sender@domain ... Sender Ok”. Trong tröôøng hôïp ngöôïc laïi, SMTPD seõ gôûi thoâng baùo loãi laïi cho client ñeå client xöû lyù. Phaàn code moâ taû quaù trình thöïc hieän nhieäm vuï naøy: if (strcasecmp(verb, "MAIL") == 0) { char *name; if (!cmd_ok(MAIL, state)) { /*kieåm tra xem ñaõ coù leänh “helo” chöa ?*/ if (cmd_ok(HELO, state)) { sprintf(outbuf, "503 Need HELO before MAIL\n"); writeline(smtp->ofile, outbuf); state_change(state, MAIL, FAILURE); } /*kieåm tra xem client ñaõ gôûi leänh “mail” chöa ?*/ else { sprintf(outbuf, "503 Sender already specified\n"); writeline(smtp->ofile, outbuf); state_change(state, MAIL, ERROR); } return; LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 60 } /*kieåm tra xem sau chuoåi “mail” coù phaûi laø chuoåi “from” khoâng ?*/ SPANBLANK(buf); if (strncasecmp(buf, "FROM:", 5) != 0) { sprintf(outbuf, "501 Syntax error in parameters or arguments\n"); writeline(smtp->ofile, outbuf); state_change(state, MAIL, ERROR); return; } buf += 5; SPANBLANK(buf); /*xöû lyù phaàn ñòa chæ nhaän ñöôïc*/ return_path = del_bracket(buf); if (strstr(return_path, smtp->myhostname) || strstr(return_path, "localhost")) { name = username(return_path); strcpy(smtp->sender, name); free(name); } else strcpy(smtp->sender, return_path); sprintf(outbuf, "250 %s... Sender ok\n", buf); writeline(smtp->ofile, outbuf); state_change(state, MAIL, SUCCESS); } Keá tieáp, client seõ gôûi leänh “rcpt to: receiver@domain” . Vì moät laù thö coù theå ñöôïc gôûi cho nhieàu ngöôøi neân phaàn ñòa chæ ngöôøi nhaän seõ ñöôïc kieåm tra vaø löu giöõ laïi. Neáu ngöôøi nhaän ôû trong cuøng heä thoáng thì phaàn ñòa chæ naøy ñöôïc löu giöõ laïi ôû trong daõy smtp->receiver (ñoái vôùi ngöôøi nhaän cuïc boä, ta coù theå chæ gôûi teân user thoâi, khoâng caàn theâm daáu “@” vaø teân domain cuûa noù). Vaø neáu ngöôøi nhaän khoâng ôû trong heä thoáng, töùc laø gôûi ra beân ngoaøi thì ñòa chæ ngöôøi nhaän seõ ñöôïc löu giöõ trong daõy smtp->userfar. Trong quùa trình kieåm tra ngöôøi nhaän, neáu coù loãi xaûy ra, thoâng baùo loãi seõ ñöôïc gôûi cho client. Trong tröôøng hôïp ngöôïc laïi, chuoåi “250 receiver@domain ... Receiver Ok” seõ ñöôïc gôûi laïi cho client. Phaàn code moâ taû quaù trình thöïc hieän nhieäm vuï naøy: if (strcasecmp(verb, "RCPT") == 0) { LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 61 char *victim, *name; struct passwd *pwd; int i, yes_user; /*kieåm tra xem client ñaõ gôûi leänh “mail” chöa*/ if (!cmd_ok(RCPT, state)) { sprintf(outbuf, "503 Need MAIL before RCPT\n"); writeline(smtp->ofile, outbuf); state_change(state, RCPT, ERROR); return; } /*kieåm tra xem ñi sau chuoåi “rcpt” coù phaûi laø chuoåi “to:” hay khoâng ?*/ SPANBLANK(buf); if ((strlen(buf) < 3) || strncasecmp(buf, "TO:", 3) != 0) { sprintf(outbuf, "501 Syntax error in parameters or arguments\n"); writeline(smtp->ofile, outbuf); state_change(state, RCPT, ERROR); return; } buf += 3; SPANBLANK(buf); /*tröôøng hôïp khoâng coù daáu “@”, ñaây laø ngöôøi nhaän cuïc boä, löu giöõ laïi vaøo daõy smtp->receiver*/ victim = del_bracket(buf); if (!strchr(victim, '@')) { if (smtp->num_recv < MAX_USER) { i = 0; yes_user = 0; while (i num_recv) { if (!strcmp(pwd->pw_name, smtp->receiver[i])) { yes_user = 1; break; } else i++; } if (!yes_user) { strcpy(smtp->receiver[smtp->num_recv], victim); LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 62 smtp->num_recv++; } } } else { name = username(victim); /*tröôøng hôïp coù daáu “@”, kieåm tra xem user coù naèm trong heä thoáng hay khoâng ?*/ if ((pwd = getpwnam(name)) && ((strstr(victim, smtp-> myhostname)) || (strstr(victim, "localhost")))) { if (smtp->num_recv < MAX_USER) { i = 0; yes_user = 0; while (i num_recv) { if (!strcmp(pwd->pw_name, smtp->receiver[i])) { yes_user = 1; break; } else i++; } if (!yes_user) { strcpy(smtp->receiver[smtp->num_recv], pwd-> pw_name); smtp->num_recv++; } } } else /*goi cho user o ben ngoai he thong*/ { if (smtp->num_userfar < MAX_USER) { i = 0; yes_user = 0; while (i num_userfar) { if (!strcmp(pwd->pw_name, smtp->userfar[i])) { yes_user = 1; LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 63 break; } else i++; } if (!yes_user) { strcpy(smtp->userfar[smtp->num_userfar], pwd-> pw_name); smtp->num_userfar++; } } } } sprintf(outbuf, "250 %s... Ricipient ok\n", victim); writeline(smtp->ofile, outbuf); state_change(state, RCPT, SUCCESS); } Tieáp ñeán, client seõ gôûi leänh “data” vaø sau ñoù, noù seõ tuaàn töï gôûi noäi dung cuûa böùc mail. Phaàn döõ lieäu naøy seõ khoâng qua xöû lyù cuûa haøm smtp_parse_cmd(), bôûi vì ñaây laø phaàn noäi dung cuûa böùc mail, khoâng phaûi laø leänh. SMTPD nhaän phaàn döõ lieäu naøy vaø löu giöõ vaøo trong moät file taïm. Döõ lieäu ñöôïc keát thuùc baèng chuoãi “.\r\n”. Phaàn code moâ taû quaù trình thöïc hieän nhieäm vuï naøy: if ((!test_state(SNARF_DATA, last_state)) && (test_state(SNARF_DATA, current_state))) { tempfile = (char *)malloc(80*sizeof(char)); strcpy(tempfile, TMPFILE); if ((f_tmp = fdopen(mkstemp(tempfile), "w+t")) == NULL) { /*tröôøng hôïp môû file khoâng thaønh coâng*/ clear_state(SNARF_DATA, current_state); clear_state(OK_RCPT, current_state); clear_state(OK_MAIL, current_state); } else { readlh(smtp->ifile, inbuf, SIZBUF); while (inbuf[0] != '.') { LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 64 fixcrlf(inbuf, 0); fputs(inbuf, f_tmp); readlh(smtp->ifile, inbuf, SIZBUF); } fclose(f_tmp); } } Ñoái vôùi ngöôøi nhaän cuïc boä thì thö seõ ñöôïc chuyeån ngay ñeán mailbox cuûa ngöôøi nhaän ngay sau khi client gôûi leänh “data” vaø döõ lieäu qua. Coøn ñoái vôùi caùc ngöôøi nhaän khoâng cuïc boä thì thö seõ ñöôïc chuyeån ñeán hoäp thö outbox “/var/spool/sharedmail/outbox” ñeå gôûi ra ngoaøi. Khi client gôûi leänh “quit”, SMTPD seõ gôûi laïi cho client chuoåi: “221 smtp->hostname Service closing transmission channel” vaø keát noái seõ ñöôïc ñoùng laïi. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 65 CAÙC LÖU ÑOÀ no yes Löu laïi domain cuûa sender return(message(250, ...)) ( Sender send “MAIL FROM:” ) Client ñaõ gôûi leänh “helo” chöa ? return(message(503, ...)) Löu ñoà leänh HELO return(message(221, ...)) Löu ñoà leänh QUIT LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 66 Löu ñoà leänh MAIL FROM yes no yes no Ñaõ coù leänh HELO chöa ? Ñaõ coù leänh MAIL chöa ? Löu laïi phaàn ñòa chæ ngöôøi gôûi. Return(message(250,...)). Return(message(503,...)). no yes Ngöôøi nhaän coù ôû trong heä thoáng ? yes no yes no Ñaõ coù leänh MAIL chöa ? Ñaõ coù leänh DATA chöa ? Löu laïi phaàn ñòa chæ ngöôøi trong danh saùch smtp->receiver. Return(message(250,...)). Return(message(503,...)). Löu laïi phaàn ñòa chæ ngöôøi trong danh saùch smtp->userfar. Return(message(250,...)). Löu ñoà leänh RCPT TO LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 67 Löu ñoà leänh DATA vôùi ngöôøi nhaän cuïc boä yes no Ñaõ coù leänh RCPT chöa ? Return(message(503,...)). Return(message(354,...)). (end with .) Môõ file taïm ñeå chöùa message töø client gôûi qua. yes no no yes Coù bao nhieâu ngöôøi nhaän. Môõ hoäp thö cuûa töøng ngöôøi nhaän vaø lock laïi Chuyeån thö tôùi ngöôøi nhaän töông öùng Heát ngöôøi nhaän chöa ? Return(quit()). Return(message(250,...)). Chuyeån thö thaønh coâng. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 68 Löu ñoà leänh DATA vôùi ngöôøi nhaän beân ngoaøi yes no Ñaõ coù leänh RCPT chöa ? Return(message(503,...)). Return(message(354,...)). (end with .) Môõ file taïm ñeå chöùa message töø client gôûi qua. yes no no yes Coù bao nhieâu ngöôøi nhaän. Môû outbox vaø lock laïi Chuyeån thö cuûa ngöôøi nhaän töø xa tôùi outbox. Heát ngöôøi nhaän chöa ? Return(quit()). Return(message(250,...)). Chuyeån thö thaønh coâng. LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 69 yes no no no yes yes Khôûi taïo khoái smtp_info Laáy teân Host cuûa maùy Server Laáy ñòa chæ IP cuûa maùy Client Taïo hai Stream cho Input, Return (+OK) Return (-1) Khôûi taïo caùc thoâng tin caàn thieát LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 70 no no yes yes yes no Khôûi taïo caùc thoâng tin caàn thieát Return (message(250, +0K)) Laáy message töø Input Return (message(550, -ERR)). Ñoùng keát noái vaø thoaùt. Phaân tích döõ lieäu nhaän ñöôïc ñeå laáy leänh caàn thöïc hieän Leänh nhaän ra ñöôïc bôûi Smtpd Thöïc hieän leänh töông öùng Thöïc hieän leänh thaønh coâng Return(message(250, +OK)). Return(message( , - ERR)) Quaù trình thöïc hieän leänh LUAÄN VAÊN TOÁT NGHIEÄP GVHD : NGUYEÃN CAO ÑAÏT SVTH : Traàn Ngoïc Sôn & Hoaøng Ñöùc Quang Trang 71 PHAÀÀN IV: NHAÄÄN XEÙÙT VAØØ HÖÔÙÙNG PHAÙÙT TRIEÅÅN 1. MOÄÄT SOÁÁ KHAÛÛ NAÊÊNG CUÛÛA CHÖÔNG TRÌNH: - Chöông trình ñaõ thöïc hieän ñöôïc taùc vuï cho pheùp nhieàu ngöôøi cuøng gôûi vaø nhaän Mail maø chæ söû duïng moät Account Mail ñöôïc caáp bôûi nhaø cung caáp dòch vuï. - Mail cuûa caùc user cuïc boä gôûi cho nhau seõ ñöôïc gôûi tröïc tieáp tôùi mailbox cuûa moãi ngöôøi. - Mail cuûa caùc user gôûi ra ngoaøi heä thoáng seõ ñöôïc löu giöõ laïi trong mailbox rieâng. Keát noái vôùi nhaø cung caáp dòch vuï thoâng qua modem vaøo nhöõng thôøi ñieåm ñònh tröôùc. Khi coù keát noái thì caùc mail naøy seõ ñöôïc gôûi ñi. - Cho pheùp Administrator coù theå caáu hình ñoái vôùi heä thoáng töø xa thoâng qua Webmin. 2. HÖÔÙÙNG PHAÙÙT TRIEÅÅN CUÛÛA CHÖÔNG TRÌNH: Tuy chöông trình ñaõ giaûi quyeát ñöôïc moät soá vaán ñeà ñaõ ñaët ra, nhöng chöông trình vaãn coøn nhieàu vaán ñeà coù theå phaùt trieån leân ñöôïc nhö: - Xöû lyù theâm caùc daïng ñòa chæ ñeå cho pheùp ngöôøi söû duïng ñöôïc uyeån chuyeån hôn trong vieäc gôûi vaø nhaän Mail. - Neân thöïc hieän taùc vuï loïc Mail khi nhaän Mail töø Server veà ñeå phoøng choáng Spam. - Cho pheùp coù theå laøm vieäc treân moät soá chuaån Mail khaùc. Trang chuû | Muïc luïc

Các file đính kèm theo tài liệu này:

  • pdfThư điện tử.pdf
Tài liệu liên quan