# inetd ## def a super-server daemon on many Unix systems that provides Internet services. ## functionality inetd listens on designated ports used by Internet services such as FTP, POP3, and telnet. The server program is invoked with the service socket as its standard input, output and error descriptors. After the program is finished,inetd continues to listen on the socket(with exceptions) # TFTPd def:a server which supports the Internet Trivial File Transfer Protocol (RFC 1350) ## Motion * initiated by the client * request form:negotiated transfer parameters proposed by the client under the terms specified by RFC 2347 * If server grants:sent files that in fixed length blocks of 512 bytes by default or the number specified in the blocksize negotiated option defined by RFC 2348 ## flags -c: Changes the default root directory of a connecting host -C: same as -c -F: this strftime(3) compatible format string for the creation of the suffix if -W is specified. By default the string "%Y%m%d" is used. -d [value]: Enables debug output ## Purpose * implemented on top of the Internet User Datagram protocol * Can only read and write files (or mail) from/to a remote server * used to move files between machines on different networks. ## Overview * begins with a request to read or write a file and request a connection * file is sent in fixed length blocks of 512 bytes * a data packet less than 512 bytes signals termination of a transfer. Each data packet contains one block of data, and must be acknowledged by an acknowledgment packet before the next packet can be sent. ## Structure * file * io * transfer * util * main ### file initialization and convert of file memberfun: static size_t convert_from_net(char *,size_t) static size_t convert_to_net(char *buffer, size_t count, int init) int write_init(int fd, FILE *f, const char *mode) size_t write_file(char *buffer, int count) int write_close(void) off_t tell_file(void) int seek_file(off_t offset) int read_init(int fd, FILE *f, const char *mode) size_t read_file(char *buffer, int count) int read_close(void) int synchnet(int peer) -reflush socket ### io const char * errtomsg(int error) static int send_packet(int peer, uint16_t block, char *pkt, int size) void send_error(int peer, int error) int send_wrq(int peer, char *filename, char *mode) int send_rrq(int peer, char *filename, char *mode) int send_oack(int peer) int send_ack(int fp, uint16_t block) int send_data(int peer, uint16_t block, char *data, int size) int receive_packet(int,char, int, struct sockaddr_storage *,int) int tftp_send(int peer, uint16_t *block, struct tftp_stats *ts) int tftp_receive(int, uint16_t *, struct tftp_stats *,struct tftphdr *, size_t) ### utils int settimeouts(intn, int, int _maxtimeouts __unused) void unmappedaddr(struct sockaddr_in6 *sin6) size_t get_field(int peer, char *buffer, size_t size) void tftp_openlog(const char *ident, int logopt, int facility) void tftp_closelog(void) void tftp_log(int priority, const char *message, ...) const char * packettype(int type) int debug_find(char *s) int debug_finds(char *s) const char * debug_show(int d) char * rp_strerror(int error) void stats_init(struct tftp_stats *ts) void printstats(const char *, int , struct tftp_stats *) ### transfer int tftp_send(int peer, uint16_t *block, struct tftp_stats *ts) int tftp_receive(int , uint16_t *, struct tftp_stats *,struct tftphdr *, size_t ) ### options void init_options(void); uint16_t make_options(int peer, char *buffer, uint16_t size); int parse_options(int peer, char *buffer, uint16_t size); int option_tsize(int peer, struct tftphdr *, int, struct stat *); int option_timeout(int peer); int option_blksize(int peer); int option_blksize2(int peer); int option_rollover(int peer); int option_windowsize(int peer); ## When to fork? After read out of the UDP socket,we fork and exit 子Process會整個把母Process抄過來,變成兩個獨立但內容相同的記憶體空間 在同個終端機執行的若干process會共用一個stdout,產生資源共享的問題 Three modes of transfer are currently supported: * netascii * octet (This replaces the "binary" mode of previous versions of this document.) raw 8 bit bytes; * mail, netascii characters sent to a user rather than a file. (The mail mode is obsolete and should not be implemented or used.) Additional modes can be defined by pairs of cooperating hosts. ### Packets TFTP supports five types of packets, all of which have been mentioned above: opcode operation 1 Read request (RRQ) 2 Write request (WRQ) 3 Data (DATA) 4 Acknowledgment (ACK) 5 Error (ERROR) next_state <= {next_state[0], next_state[7:1]}; ## capability Capsicum capabilities are an extension of UNIX file descriptors, and reflect rights on specific objects, such as files or sockets ***example:*** For in- stance, if file descriptor 4 is a capability allowing ac- cess to /lib, then openat(4, "libc.so.7") will suc- ceed, whereas openat(4, "../etc/passwd") and openat(4, "/etc/passwd") will not ```shell hanslu95@hanslu95:/usr/libexec % gdb -tui tftpd ``` ## Casper idea:allow in simple way to obtain more rights in a sandboxed process When Casper was first implemented it was a daemon in an operating system. * It was divided to four parts • Casper daemon (called casperd(8)), • services (located in /libexec/casper), • list of services (located in /etc/casper), • IPC library (called libcapsicum(3)) ## PXEboot def:a form of smart boot ROM, built into Intel EtherExpress Pro/100 and 3Com 3c905c Ethernet cards, and Ethernet-equipped Intel motherboards **Background** Some application: PXE 環境建置區域網路安裝伺服器系統 TFTP Formats Type Op # Format without header 2 bytes string 1 byte string 1 byte ----------------------------------------------- RRQ/ | 01/02 | Filename | 0 | Mode | 0 | WRQ ----------------------------------------------- 2 bytes 2 bytes n bytes --------------------------------- DATA | 03 | Block # | Data | --------------------------------- 2 bytes 2 bytes ------------------- ACK | 04 | Block # | -------------------- 2 bytes 2 bytes string 1 byte ---------------------------------------- ERROR | 05 | ErrorCode | ErrMsg | 0 | ---------------------------------------- Initial Connection Protocol for reading a file 1. Host A sends a "RRQ" to host B with source= A's TID, destination= 69. 2. Host B sends a "DATA" (with block number= 1) to host A with source= B's TID, destination= A's TID. ## mode that needs to read file: tftp_wrq --- parse_header---validate_access rrq tftphdr -> recvbuffer ->filename some structs: struct tftphdr { unsigned short th_opcode; /* packet type */ union { unsigned short tu_block; /* block # */ unsigned short tu_code; /* error code */ char tu_stuff[1]; /* request packet stuff */ } __packed th_u; char th_data[1]; /* data or error string */ } __packed; struct block_data { off_t offset; uint16_t block; int size; }; ## openfile operation validate_access(peer, &filename, WRQ)--find_next_name ## TCP wrapper part It seems that I dont have to adjust it. ``` #ifdef LIBWRAP /* * See if the client is allowed to talk to me. * (This needs to be done before the chroot()) */ { printf("req\n"); struct request_info req; request_init(&req, RQ_CLIENT_ADDR, peername, 0); request_set(&req, RQ_DAEMON, "tftpd", 0); if (hosts_access(&req) == 0) { if (debug & DEBUG_ACCESS) tftp_log(LOG_WARNING, "Access denied by 'tftpd' entry " "in /etc/hosts.allow"); /* * Full access might be disabled, but maybe the * client is allowed to do read-only access. */ request_set(&req, RQ_DAEMON, "tftpd-ro", 0); allow_ro = hosts_access(&req); request_set(&req, RQ_DAEMON, "tftpd-wo", 0); allow_wo = hosts_access(&req); if (allow_ro == 0 && allow_wo == 0) { tftp_log(LOG_WARNING, "Unauthorized access from %s", peername); exit(1); } if (debug & DEBUG_ACCESS) { if (allow_ro) tftp_log(LOG_WARNING, "But allowed readonly access " "via 'tftpd-ro' entry"); if (allow_wo) tftp_log(LOG_WARNING, "But allowed writeonly access " "via 'tftpd-wo' entry"); } } else if (debug & DEBUG_ACCESS) tftp_log(LOG_WARNING, "Full access allowed" "in /etc/hosts.allow"); } #endif ```