History log of /openbsd-current/usr.sbin/tftpd/tftpd.c
Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# 1.51 21-May-2024 jsg

remove prototypes with no matching function and externs with no var
partly checked by millert@


Revision tags: OPENBSD_7_3_BASE OPENBSD_7_4_BASE OPENBSD_7_5_BASE
# 1.50 09-Oct-2022 kn

Drop fattr promise unless file creation is allowed

This is only required for the single fchmod(2) ensuring default permissions
which only happens in the -c code path.

OK millert


# 1.49 04-Oct-2022 kn

Switch default to read-only, add -w for write access (previous default)

Write access seems less often required these days and other ways to ensure
effective read-only access are mere workarounds; worst case malicious users
can fill up the server's disk by writing to existing files.

diskless(8) only ever needs to read and running with "stdio rpath dns inet"
by default is much safer for a network daemon without any authentication.

Initially proposed as a new -R flag for read-only mode
new default suggestion dlg deraadt
"looks great" millert
OK sthen dlg


# 1.48 04-Oct-2022 kn

Drop cpath promise unless file creation is allowed

OK millert


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE
# 1.47 24-Oct-2021 deraadt

For open/openat, if the flags parameter does not contain O_CREAT, the
3rd (variadic) mode_t parameter is irrelevant. Many developers in the past
have passed mode_t (0, 044, 0644, or such), which might lead future people
to copy this broken idiom, and perhaps even believe this parameter has some
meaning or implication or application. Delete them all.
This comes out of a conversation where tb@ noticed that a strange (but
intentional) pledge behaviour is to always knock-out high-bits from
mode_t on a number of system calls as a safety factor, and his bewilderment
that this appeared to be happening against valid modes (at least visually),
but no sorry, they are all irrelevant junk. They could all be 0xdeafbeef.
ok millert


Revision tags: OPENBSD_6_9_BASE OPENBSD_7_0_BASE
# 1.46 17-Jan-2021 claudio

Remove a __KAME__ block for extracting the scope_id from IPV6_PKTINFO.
struct in6_pktinfo includes the interface index in ipi6_ifindex but no
struct sockaddr_in6.
OK jca@


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.50 09-Oct-2022 kn

Drop fattr promise unless file creation is allowed

This is only required for the single fchmod(2) ensuring default permissions
which only happens in the -c code path.

OK millert


# 1.49 04-Oct-2022 kn

Switch default to read-only, add -w for write access (previous default)

Write access seems less often required these days and other ways to ensure
effective read-only access are mere workarounds; worst case malicious users
can fill up the server's disk by writing to existing files.

diskless(8) only ever needs to read and running with "stdio rpath dns inet"
by default is much safer for a network daemon without any authentication.

Initially proposed as a new -R flag for read-only mode
new default suggestion dlg deraadt
"looks great" millert
OK sthen dlg


# 1.48 04-Oct-2022 kn

Drop cpath promise unless file creation is allowed

OK millert


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE
# 1.47 24-Oct-2021 deraadt

For open/openat, if the flags parameter does not contain O_CREAT, the
3rd (variadic) mode_t parameter is irrelevant. Many developers in the past
have passed mode_t (0, 044, 0644, or such), which might lead future people
to copy this broken idiom, and perhaps even believe this parameter has some
meaning or implication or application. Delete them all.
This comes out of a conversation where tb@ noticed that a strange (but
intentional) pledge behaviour is to always knock-out high-bits from
mode_t on a number of system calls as a safety factor, and his bewilderment
that this appeared to be happening against valid modes (at least visually),
but no sorry, they are all irrelevant junk. They could all be 0xdeafbeef.
ok millert


Revision tags: OPENBSD_6_9_BASE OPENBSD_7_0_BASE
# 1.46 17-Jan-2021 claudio

Remove a __KAME__ block for extracting the scope_id from IPV6_PKTINFO.
struct in6_pktinfo includes the interface index in ipi6_ifindex but no
struct sockaddr_in6.
OK jca@


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.49 04-Oct-2022 kn

Switch default to read-only, add -w for write access (previous default)

Write access seems less often required these days and other ways to ensure
effective read-only access are mere workarounds; worst case malicious users
can fill up the server's disk by writing to existing files.

diskless(8) only ever needs to read and running with "stdio rpath dns inet"
by default is much safer for a network daemon without any authentication.

Initially proposed as a new -R flag for read-only mode
new default suggestion dlg deraadt
"looks great" millert
OK sthen dlg


# 1.48 04-Oct-2022 kn

Drop cpath promise unless file creation is allowed

OK millert


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE
# 1.47 24-Oct-2021 deraadt

For open/openat, if the flags parameter does not contain O_CREAT, the
3rd (variadic) mode_t parameter is irrelevant. Many developers in the past
have passed mode_t (0, 044, 0644, or such), which might lead future people
to copy this broken idiom, and perhaps even believe this parameter has some
meaning or implication or application. Delete them all.
This comes out of a conversation where tb@ noticed that a strange (but
intentional) pledge behaviour is to always knock-out high-bits from
mode_t on a number of system calls as a safety factor, and his bewilderment
that this appeared to be happening against valid modes (at least visually),
but no sorry, they are all irrelevant junk. They could all be 0xdeafbeef.
ok millert


Revision tags: OPENBSD_6_9_BASE OPENBSD_7_0_BASE
# 1.46 17-Jan-2021 claudio

Remove a __KAME__ block for extracting the scope_id from IPV6_PKTINFO.
struct in6_pktinfo includes the interface index in ipi6_ifindex but no
struct sockaddr_in6.
OK jca@


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.48 04-Oct-2022 kn

Drop cpath promise unless file creation is allowed

OK millert


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE
# 1.47 24-Oct-2021 deraadt

For open/openat, if the flags parameter does not contain O_CREAT, the
3rd (variadic) mode_t parameter is irrelevant. Many developers in the past
have passed mode_t (0, 044, 0644, or such), which might lead future people
to copy this broken idiom, and perhaps even believe this parameter has some
meaning or implication or application. Delete them all.
This comes out of a conversation where tb@ noticed that a strange (but
intentional) pledge behaviour is to always knock-out high-bits from
mode_t on a number of system calls as a safety factor, and his bewilderment
that this appeared to be happening against valid modes (at least visually),
but no sorry, they are all irrelevant junk. They could all be 0xdeafbeef.
ok millert


Revision tags: OPENBSD_6_9_BASE OPENBSD_7_0_BASE
# 1.46 17-Jan-2021 claudio

Remove a __KAME__ block for extracting the scope_id from IPV6_PKTINFO.
struct in6_pktinfo includes the interface index in ipi6_ifindex but no
struct sockaddr_in6.
OK jca@


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.47 24-Oct-2021 deraadt

For open/openat, if the flags parameter does not contain O_CREAT, the
3rd (variadic) mode_t parameter is irrelevant. Many developers in the past
have passed mode_t (0, 044, 0644, or such), which might lead future people
to copy this broken idiom, and perhaps even believe this parameter has some
meaning or implication or application. Delete them all.
This comes out of a conversation where tb@ noticed that a strange (but
intentional) pledge behaviour is to always knock-out high-bits from
mode_t on a number of system calls as a safety factor, and his bewilderment
that this appeared to be happening against valid modes (at least visually),
but no sorry, they are all irrelevant junk. They could all be 0xdeafbeef.
ok millert


Revision tags: OPENBSD_6_9_BASE OPENBSD_7_0_BASE
# 1.46 17-Jan-2021 claudio

Remove a __KAME__ block for extracting the scope_id from IPV6_PKTINFO.
struct in6_pktinfo includes the interface index in ipi6_ifindex but no
struct sockaddr_in6.
OK jca@


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.46 17-Jan-2021 claudio

Remove a __KAME__ block for extracting the scope_id from IPV6_PKTINFO.
struct in6_pktinfo includes the interface index in ipi6_ifindex but no
struct sockaddr_in6.
OK jca@


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.45 17-Dec-2020 krw

Log reason a request is NAK'ed, as well as any problems sending the
NAK.

Suggestion & ok dlg@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.44 09-Jan-2020 dlg

resend the current block if the other end acks the previous block again.

without this we just bump the timeout, which delays resending the
block, which means the client gives up before they get the data.

this seems to fix "timeouts" ive had a lot recently with uefi pxe
stacks, and fetching firmware images on certain switches, all over
busy networks.


Revision tags: OPENBSD_6_6_BASE
# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.43 03-Jul-2019 deraadt

snprintf/vsnprintf return < 0 on error, rather than -1.


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.42 28-Jun-2019 deraadt

When system calls indicate an error they return -1, not some arbitrary
value < 0. errno is only updated in this case. Change all (most?)
callers of syscalls to follow this better, and let's see if this strictness
helps us in the future.


Revision tags: OPENBSD_6_3_BASE OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.41 26-Jan-2018 naddy

Handle the transfer size option when faking up /etc/random.seed.
Without this, clients that queried the size would receive 0 as response.
ok jca@


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision


# 1.40 07-Nov-2017 jca

Add support for client-specific directories (named after the client address)

tftpd -i will look up the requested path the directory named after the
client's IP address. For read requests, if the file is not found, there's
a fall back to its root directory.

From Jan Klemkow with input and tweaks from at least jmc@, bluhm@,
deraadt@, sthen@, semarie@ and myself. ok bluhm@


Revision tags: OPENBSD_6_2_BASE
# 1.39 26-May-2017 florian

Sync the severity of the syslog_* functions shared between identd, slowcgi,
tftp-proxy and tftpd to the severity used in log.c style loggers.
This also fixes an issue where syslog_err and syslog_errx logged with
different severities.

Sure deraadt@


Revision tags: OPENBSD_6_1_BASE
# 1.38 26-Sep-2016 jca

Exit early from rdaemon() is the passed fd is invalid.

fd == -1 check suggested by deraadt@, ok florian@


# 1.37 04-Sep-2016 florian

Add format attribute to logger functions.
Add syslog_debug to keep in sync with others.
Input & OK benno@


Revision tags: OPENBSD_6_0_BASE
# 1.36 31-Mar-2016 jca

For consistency, omit the variable name in rdaemon() prototype.


# 1.35 31-Mar-2016 jca

Go in the background much later, to reduce possible silent failures.

rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.

Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@


Revision tags: OPENBSD_5_9_BASE
# 1.34 14-Dec-2015 semarie

move daemon(3) call before chroot(2) in tftpd.

so daemon(3) will be able to redirect standard input, standard output and
standard error to /dev/null.

ok jca@


# 1.33 11-Dec-2015 mmcc

Remove NULL-checks before free().


# 1.32 18-Oct-2015 deraadt

Add "dns" to the pledges. Previously these worked because of "inet",
alas "dns" is now a mandatory statement if you want to do dns!


# 1.31 10-Oct-2015 deraadt

pledge "stdio rpath wpath cpath fattr inet" after chroot and such
appears to be good enough for the main loop processing.


# 1.30 06-Oct-2015 deraadt

do not need ioctl.h


# 1.29 20-Aug-2015 dlg

use SOCK_NONBLOCK when making a socket instead of ioctl FIONBIO.

for guenther@


Revision tags: OPENBSD_5_8_BASE
# 1.28 20-Jul-2015 dlg

tweak the /etc/random.seed interception so it provides a FILE* via
fmemopen for the rest of the code to chew on, rather than having
special casing for seed generation in the sending code.

this also means our fake random.seed files will get proper netascii
encoding by being read via the fgetc api instead of directly from
a buffer.

ok deraadt@ mcbride@


# 1.27 18-Jul-2015 mcbride

Have tftpd provide a block of random data when clients request the file
/etc/random.seed.

This allows netbooted systems to inject entropy early in the kernel start.
pxeboot requests it already, so no configuration or change is needed on
the client side.

ok deraadt@ beck@


Revision tags: OPENBSD_5_7_BASE
# 1.26 16-Jan-2015 deraadt

Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible. Annotate <sys/param.h> lines with their current reasons. Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution. These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)


# 1.25 17-Dec-2014 tedu

the easier way to put a buffer on the stack is to put it on the stack,
not with alloca(). found by dickman; ok kettenis


# 1.24 25-Nov-2014 dlg

evbuffer_read and evbuffer_write are wrappers around read and write,
so you have to check their return values in the same way and handle
errors the same way.

returning 0 from evbuffer_read means the other end of the socket
has gone away.

we should try again on both evbuffer_read and evbuffer_write if we
get EAGAIN or EINTR.

ok millert@ bluhm@


# 1.23 19-Nov-2014 dlg

move to stravis so doug@ will stop laughing at my misuse of strnvis.

ok doug@ millert@


# 1.22 13-Aug-2014 tobias

Always call freeaddrinfo after getaddrinfo.

ok dlg@


# 1.21 13-Aug-2014 dlg

use errc instead of juggling errno values in tftpd_listen.


# 1.20 13-Aug-2014 dlg

setsockopt sets errno on failure, so we can use err instead of errx when
handling the error.


Revision tags: OPENBSD_5_6_BASE
# 1.19 21-Apr-2014 dlg

th_code is in network byte order


Revision tags: OPENBSD_5_5_BASE
# 1.18 26-Nov-2013 deraadt

unsigned char for ctype


# 1.17 12-Nov-2013 deraadt

ensure there are prototypes


# 1.16 13-Aug-2013 dlg

when handling puts from a client (ie, tftpd is writing a file to
disk), we maintain the client state after we've finished writing
the file in case the client loses our ack of the last write.
unfortunately we didnt close the file we'd just written when we
knew it was finished, but only after we clean up the client state
after that wait.

because we use FILE stuff to write the file out, its likely some
io flushed to disk until we finish that wait and close the file as
part of cleaning up the client state. if something is coordinating
a bunch of uploads and expects the file to be there after the client
is happy its there, this can be "not good".

this closes the file after we know its finished before proceeding
to hang to handle lost acks to the client.

found by and ok henning@


Revision tags: OPENBSD_5_4_BASE
# 1.15 01-Jun-2013 deraadt

use the standardized names instead of S_IREAD and S_IWRITE
ok guenther dtucker


# 1.14 07-May-2013 dlg

getpwnam doesnt set errno on failure, so use errx, not err, to say it
failed.


# 1.13 17-Mar-2013 dlg

i missed the bit of maxime villards diff that took the client_free out of
oack on error.

his fix is better, so this marges all of it in.


# 1.12 15-Mar-2013 dlg

let oack use the full buffer space to build its packet, not just the size
negotiated for data tranfsers.

this lets people negotiate 2 byte transfers with other options too if they
want. im looking at you Maxime Villard.


# 1.11 15-Mar-2013 dlg

"correct" the order of calloc arguments.


# 1.10 15-Mar-2013 dlg

fix up some lwarn()s that should be lwarnx()s


# 1.9 15-Mar-2013 dlg

fix a huge bug in tftpd.

there was a double free if an option ack failed. if oack fails, the client
gets freed, then the oack caller tries to free the options which were just
freed.

found by Maxime Villard who provided a fix. unfortunately his fix still
had a double free but it was pretty close.
ok MALLOC_OPTIONS=S


Revision tags: OPENBSD_5_2_BASE OPENBSD_5_3_BASE
# 1.8 13-Jul-2012 gsoares

branches: 1.8.2; 1.8.4;
zap trailing whitespace; no binary change
ok dlg


# 1.7 10-Jul-2012 dlg

fix the last outstanding functionality difference i could find between
libexec and usr.sbin tftpd.

libexec waitied around after finishing a wrq in case our ack for the last
write from a client got lost. this does the same dance, or an arguably
better version of it compared to libexec tftpd.


# 1.6 10-Jul-2012 dlg

libexec/tftpd handled the case where we'd get an ack for the previous
block by flushing the data on the socket and waiting for a retransmit
by timeout to occur.

my stuff (usr.sbin/tftpd) had XXXs and failure in those places.

this diff fixes that.

this should address the problems that sthen and jcs have been having
(and which i was finally able to reproduce here).

it also avoids reusing the clients buffer to both send and recv
frames. we recv onto the stack now so retry always sends what we
originally built for the peer.

tested by and ok jcs@ sthen@


# 1.5 15-Mar-2012 nicm

Add sys/queue.h. ok dlg


# 1.4 07-Mar-2012 dlg

dont mix code and declarations.


# 1.3 02-Mar-2012 jmc

tweaks;


# 1.2 02-Mar-2012 dlg

CFLAGS+= -Wall -Werror and the resulting cleanup


# 1.1 02-Mar-2012 dlg

branches: 1.1.1;
Initial revision