a super-server daemon on many Unix systems that provides Internet services.
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)
def:a server which supports the Internet Trivial File Transfer Protocol (RFC 1350)
-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
Each data packet contains one block of data, and must be acknowledged by an acknowledgment packet before the next packet can be sent.
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
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)
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 *)
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 )
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);
After read out of the UDP socket,we fork and exit
子Process會整個把母Process抄過來,變成兩個獨立但內容相同的記憶體空間
在同個終端機執行的若干process會共用一個stdout,產生資源共享的問題
Three modes of transfer are currently supported:
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]};
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
hanslu95@hanslu95:/usr/libexec % gdb -tui tftpd
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.
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
Host A sends a "RRQ" to host B with source= A's TID,
destination= 69.
Host B sends a "DATA" (with block number= 1) to host A with
source= B's TID, destination= A's TID.
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;
};
validate_access(peer, &filename, WRQ)–find_next_name
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